2 ; Extended memory driver for the VDC RAM available on all C128 machines
3 ; (based on code by Ullrich von Bassewitz)
4 ; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
8 ; Marco van den Heuvel, 2010-01-22
11 .include "zeropage.inc"
13 .include "em-kernel.inc"
14 .include "em-error.inc"
21 ; ------------------------------------------------------------------------
22 ; Header. Includes jump table
24 module_header _c64_vdc_emd
28 .byte $65, $6d, $64 ; "emd"
29 .byte EMD_API_VERSION ; EM API version number
46 ; ------------------------------------------------------------------------
49 VDC_ADDR_REG = $D600 ; VDC address
50 VDC_DATA_REG = $D601 ; VDC data
52 VDC_DATA_HI = 18 ; used registers
57 ; ------------------------------------------------------------------------
62 pagecount: .word 64 ; $0000-$3fff as 16k default
63 curpage: .word $ffff ; currently mapped-in page (invalid)
67 window: .res 256 ; memory window
71 ; ------------------------------------------------------------------------
72 ; INSTALL routine. Is called after the driver is loaded into memory. If
73 ; possible, check if the hardware is present and determine the amount of
75 ; Must return an EM_ERR_xx code in a/x.
81 lda #VDC_CSET ; determine size of RAM...
90 lda #<EM_ERR_NO_DEVICE
91 ldx #>EM_ERR_NO_DEVICE
95 ldx #VDC_CSET ; determine size of RAM...
99 jsr vdcputreg ; turn on 64k
101 jsr settestadr1 ; save original value of test byte
105 lda #$55 ; write $55 here
107 jsr test64k ; read it here and there
108 lda #$aa ; write $aa here
110 jsr test64k ; read it here and there
114 jsr vdcputbyte ; restore original value of test byte
116 lda ptr1 ; do bytes match?
125 jsr vdcputreg ; restore 16/64k flag
126 jmp @endok ; and leave default values for 16k
145 jsr vdcputbyte ; write $55
147 jsr vdcgetbyte ; read here
150 jsr vdcgetbyte ; and there
159 ldy #$02 ; test page 2 (here)
162 ldy #$42 ; or page 64+2 (there)
166 ; ------------------------------------------------------------------------
167 ; UNINSTALL routine. Is called before the driver is removed from memory.
168 ; Can do cleanup or whatever. Must not return anything.
172 ;on C128 restore font and clear the screen?
175 ; ------------------------------------------------------------------------
176 ; PAGECOUNT: Return the total number of available pages in a/x.
184 ; ------------------------------------------------------------------------
185 ; MAP: Map the page in a/x into memory and return a pointer to the page in
186 ; a/x. The contents of the currently mapped page (if any) may be discarded
207 ; 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)
227 ; ------------------------------------------------------------------------
228 ; USE: Tell the driver that the window is now associated with a given page.
231 stx curpage+1 ; Remember the page
233 ldx #>window ; Return the window
236 ; ------------------------------------------------------------------------
237 ; COMMIT: Commit changes in the memory window to extended storage.
240 lda curpage ; jump if no page mapped
252 ; fall through to transferout
254 ; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
259 jsr vdcsetsrcaddr ; set source address in VDC
263 @L0: bit VDC_ADDR_REG
265 lda (ptr2),y ; speedup does not work for writing
271 ; ------------------------------------------------------------------------
272 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
273 ; describing the request is passed in a/x.
274 ; The function must not return anything.
279 beq @L2 ; Skip if no full pages
289 ; Copy the remainder of the page
291 @L2: ldy #EM_COPY::COUNT
292 lda (ptr3),y ; Get bytes in last page
296 ; Transfer the bytes in the last page
307 ; ------------------------------------------------------------------------
308 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
309 ; describing the request is passed in a/x.
310 ; The function must not return anything.
315 beq @L2 ; Skip if no full pages
325 ; Copy the remainder of the page
327 @L2: ldy #EM_COPY::COUNT
328 lda (ptr3),y ; Get bytes in last page
332 ; Transfer the bytes in the last page
343 ;-------------------------------------------------------------------------
344 ; Helper functions to handle VDC ram
350 @L0: bit VDC_ADDR_REG
363 @L0: bit VDC_ADDR_REG
372 @L0: bit VDC_ADDR_REG
377 ; ------------------------------------------------------------------------
378 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
379 ; structure and prepare data for the copy
384 stx ptr3+1 ; Save the passed em_copy pointer
400 ldy #EM_COPY::COUNT+1
401 lda (ptr3),y ; Get number of pages