2 ; Extended memory driver for the VDC RAM available on all C128 machines
3 ; version for GEOS enters safe I/O config on C64 (transparent on C128)
5 ; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
8 .include "zeropage.inc"
9 .include "em-kernel.inc"
10 .include "em-error.inc"
16 ; ------------------------------------------------------------------------
17 ; Header. Includes jump table
19 module_header _geos_vdc_emd
23 .byte $65, $6d, $64 ; "emd"
24 .byte EMD_API_VERSION ; EM API version number
41 ; ------------------------------------------------------------------------
44 VDC_ADDR_REG = $D600 ; VDC address
45 VDC_DATA_REG = $D601 ; VDC data
47 VDC_DATA_HI = 18 ; used registers
52 ; ------------------------------------------------------------------------
58 .word 64 ; $0000-$3fff as 16k default
60 .word $ffff ; currently mapped-in page (invalid)
65 .res 256 ; memory window
69 ; ------------------------------------------------------------------------
70 ; INSTALL routine. Is called after the driver is loaded into memory. If
71 ; possible, check if the hardware is present and determine the amount of
73 ; Must return an EM_ERR_xx code in a/x.
77 ; do test for VDC presence here???
86 ldx #VDC_CSET ; determine size of RAM...
90 jsr vdcputreg ; turn on 64k
92 jsr settestadr1 ; save original value of test byte
96 lda #$55 ; write $55 here
98 jsr test64k ; read it here and there
99 lda #$aa ; write $aa here
101 jsr test64k ; read it here and there
105 jsr vdcputbyte ; restore original value of test byte
107 lda ptr1 ; do bytes match?
116 jsr vdcputreg ; restore 16/64k flag
117 jmp @endok ; and leave default values for 16k
139 jsr vdcputbyte ; write $55
141 jsr vdcgetbyte ; read here
144 jsr vdcgetbyte ; and there
153 ldy #$02 ; test page 2 (here)
156 ldy #$42 ; or page 64+2 (there)
160 ; ------------------------------------------------------------------------
161 ; UNINSTALL routine. Is called before the driver is removed from memory.
162 ; Can do cleanup or whatever. Must not return anything.
166 ;on C128 restore font and clear the screen?
169 ; ------------------------------------------------------------------------
170 ; PAGECOUNT: Return the total number of available pages in a/x.
178 ; ------------------------------------------------------------------------
179 ; MAP: Map the page in a/x into memory and return a pointer to the page in
180 ; a/x. The contents of the currently mapped page (if any) may be discarded
201 ; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
212 jsr vdcsetsrcaddr ; set source address in VDC
216 @L0: bit VDC_ADDR_REG
218 lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
219 sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
230 ; ------------------------------------------------------------------------
231 ; USE: Tell the driver that the window is now associated with a given page.
234 stx curpage+1 ; Remember the page
236 ldx #>window ; Return the window
239 ; ------------------------------------------------------------------------
240 ; COMMIT: Commit changes in the memory window to extended storage.
243 lda curpage ; jump if no page mapped
255 ; fall through to transferout
257 ; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
268 jsr vdcsetsrcaddr ; set source address in VDC
272 @L0: bit VDC_ADDR_REG
274 lda (ptr2),y ; speedup does not work for writing
283 ; ------------------------------------------------------------------------
284 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
285 ; describing the request is passed in a/x.
286 ; The function must not return anything.
291 beq @L2 ; Skip if no full pages
301 ; Copy the remainder of the page
303 @L2: ldy #EM_COPY::COUNT
304 lda (ptr3),y ; Get bytes in last page
308 ; Transfer the bytes in the last page
327 ; ------------------------------------------------------------------------
328 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
329 ; describing the request is passed in a/x.
330 ; The function must not return anything.
335 beq @L2 ; Skip if no full pages
345 ; Copy the remainder of the page
347 @L2: ldy #EM_COPY::COUNT
348 lda (ptr3),y ; Get bytes in last page
352 ; Transfer the bytes in the last page
371 ;-------------------------------------------------------------------------
372 ; Helper functions to handle VDC ram
378 @L0: bit VDC_ADDR_REG
391 @L0: bit VDC_ADDR_REG
400 @L0: bit VDC_ADDR_REG
405 ; ------------------------------------------------------------------------
406 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
407 ; structure and prepare data for the copy
412 stx ptr3+1 ; Save the passed em_copy pointer
428 ldy #EM_COPY::COUNT+1
429 lda (ptr3),y ; Get number of pages