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"
10 .include "em-kernel.inc"
11 .include "em-error.inc"
17 ; ------------------------------------------------------------------------
18 ; Header. Includes jump table
24 .byte $65, $6d, $64 ; "emd"
25 .byte EMD_API_VERSION ; EM API version number
38 ; ------------------------------------------------------------------------
41 VDC_ADDR_REG = $D600 ; VDC address
42 VDC_DATA_REG = $D601 ; VDC data
44 VDC_DATA_HI = 18 ; used registers
49 ; ------------------------------------------------------------------------
54 pagecount: .word 64 ; $0000-$3fff as 16k default
55 curpage: .word $ffff ; currently mapped-in page (invalid)
59 window: .res 256 ; memory window
63 ; ------------------------------------------------------------------------
64 ; INSTALL routine. Is called after the driver is loaded into memory. If
65 ; possible, check if the hardware is present and determine the amount of
67 ; Must return an EM_ERR_xx code in a/x.
71 ; do test for VDC presence here???
80 ldx #VDC_CSET ; determine size of RAM...
84 jsr vdcputreg ; turn on 64k
86 jsr settestadr1 ; save original value of test byte
90 lda #$55 ; write $55 here
92 jsr test64k ; read it here and there
93 lda #$aa ; write $aa here
95 jsr test64k ; read it here and there
99 jsr vdcputbyte ; restore original value of test byte
101 lda ptr1 ; do bytes match?
110 jsr vdcputreg ; restore 16/64k flag
111 jmp @endok ; and leave default values for 16k
133 jsr vdcputbyte ; write $55
135 jsr vdcgetbyte ; read here
138 jsr vdcgetbyte ; and there
147 ldy #$02 ; test page 2 (here)
150 ldy #$42 ; or page 64+2 (there)
154 ; ------------------------------------------------------------------------
155 ; UNINSTALL routine. Is called before the driver is removed from memory.
156 ; Can do cleanup or whatever. Must not return anything.
160 ;on C128 restore font and clear the screen?
163 ; ------------------------------------------------------------------------
164 ; PAGECOUNT: Return the total number of available pages in a/x.
172 ; ------------------------------------------------------------------------
173 ; MAP: Map the page in a/x into memory and return a pointer to the page in
174 ; a/x. The contents of the currently mapped page (if any) may be discarded
195 ; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
206 jsr vdcsetsrcaddr ; set source address in VDC
210 @L0: bit VDC_ADDR_REG
212 lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
213 sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
224 ; ------------------------------------------------------------------------
225 ; USE: Tell the driver that the window is now associated with a given page.
228 stx curpage+1 ; Remember the page
230 ldx #>window ; Return the window
233 ; ------------------------------------------------------------------------
234 ; COMMIT: Commit changes in the memory window to extended storage.
237 lda curpage ; jump if no page mapped
249 ; fall through to transferout
251 ; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
262 jsr vdcsetsrcaddr ; set source address in VDC
266 @L0: bit VDC_ADDR_REG
268 lda (ptr2),y ; speedup does not work for writing
277 ; ------------------------------------------------------------------------
278 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
279 ; describing the request is passed in a/x.
280 ; The function must not return anything.
285 beq @L2 ; Skip if no full pages
295 ; Copy the remainder of the page
297 @L2: ldy #EM_COPY::COUNT
298 lda (ptr3),y ; Get bytes in last page
302 ; Transfer the bytes in the last page
321 ; ------------------------------------------------------------------------
322 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
323 ; describing the request is passed in a/x.
324 ; The function must not return anything.
329 beq @L2 ; Skip if no full pages
339 ; Copy the remainder of the page
341 @L2: ldy #EM_COPY::COUNT
342 lda (ptr3),y ; Get bytes in last page
346 ; Transfer the bytes in the last page
365 ;-------------------------------------------------------------------------
366 ; Helper functions to handle VDC ram
372 @L0: bit VDC_ADDR_REG
385 @L0: bit VDC_ADDR_REG
394 @L0: bit VDC_ADDR_REG
399 ; ------------------------------------------------------------------------
400 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
401 ; structure and prepare data for the copy
406 stx ptr3+1 ; Save the passed em_copy pointer
422 ldy #EM_COPY::COUNT+1
423 lda (ptr3),y ; Get number of pages