2 ; Extended memory driver for 65816 based extra RAM. Driver works without
3 ; problems when statically linked.
5 ; Marco van den Heuvel, 2015-12-01
8 .include "zeropage.inc"
10 .include "em-kernel.inc"
11 .include "em-error.inc"
18 ; ------------------------------------------------------------------------
19 ; Header. Includes jump table
21 module_header _c64_65816_emd
25 .byte $65, $6d, $64 ; "emd"
26 .byte EMD_API_VERSION ; EM API version number
43 ; ------------------------------------------------------------------------
47 isnotscpu: .res 1 ; SuperCPU not present
48 curpage: .res 1 ; Current page number
49 curbank: .res 1 ; Current bank number (+1)
50 bankcount: .res 1 ; Number of available banks (pages = banks * 256)
51 window: .res 256 ; Memory "window"
55 ; ------------------------------------------------------------------------
56 ; INSTALL routine. Is called after the driver is loaded into memory. If
57 ; possible, check if the hardware is present and determine the amount of
59 ; Must return an EM_ERR_xx code in a/x.
67 adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly
72 sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02
79 pha ; save value incase it was used somewhere else
81 @fillloop: ; fill from top (bank 255) to bottom
92 @compareloop: ; check from bottom to top
128 lda #<EM_ERR_NO_DEVICE
129 ldx #>EM_ERR_NO_DEVICE
130 ; rts ; Run into UNINSTALL instead
133 ; ------------------------------------------------------------------------
134 ; UNINSTALL routine. Is called before the driver is removed from memory.
135 ; Can do cleanup or whatever. Must not return anything.
142 ; ------------------------------------------------------------------------
143 ; PAGECOUNT: Return the total number of available pages in a/x.
147 lda #$00 ; a whole bank is either usable or not
151 ; ------------------------------------------------------------------------
152 ; MAP: Map the page in a/x into memory and return a pointer to the page in
153 ; a/x. The contents of the currently mapped page (if any) may be discarded
157 MAP: sta curpage ; Remember the new page
158 stx curbank ; Remember the new bank
160 sta ptr2+1 ; src address low
162 sta ptr2 ; src address high
164 ldy isnotscpu ; check if not scpu
172 sta ptr3+1 ; length high
174 sta ptr3 ; length low
177 sta ptr1 ; dst address low
179 stx ptr1+1 ; dst address high
185 ; ------------------------------------------------------------------------
186 ; USE: Tell the driver that the window is now associated with a given page.
188 USE: sta curpage ; Remember the page
189 stx curbank ; Remember the bank
191 ldx #>window ; Return the window
194 ; ------------------------------------------------------------------------
195 ; COMMIT: Commit changes in the memory window to extended storage.
197 COMMIT: lda curpage ; Get the current page
198 sta ptr1+1 ; dst high
205 sta ptr2+1 ; src high
207 stx ptr3+1 ; length high
209 sta ptr3 ; length low
212 ldy curbank ; Get the current bank
224 ; ------------------------------------------------------------------------
225 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
226 ; describing the request is passed in a/x.
227 ; The function must not return anything.
232 stx ptr4+1 ; Save the passed em_copy pointer
234 ldy #EM_COPY::COUNT+1 ; start at the end of the struct
235 lda (ptr4),y ; get high byte of count
238 lda (ptr4),y ; get low byte of count
245 sta ptr3 ; length low
246 stx ptr3+1 ; length high
248 lda (ptr4),y ; get bank
260 lda (ptr4),y ; get page
261 sta ptr2+1 ; src high
263 lda (ptr4),y ; get offset in page
266 lda (ptr4),y ; get memory buffer high
267 sta ptr1+1 ; dst high
269 lda (ptr4),y ; get memory buffer low
278 ; ------------------------------------------------------------------------
279 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
280 ; describing the request is passed in a/x.
281 ; The function must not return anything.
285 stx ptr4+1 ; Save the passed em_copy pointer
287 ldy #EM_COPY::COUNT+1 ; start at the end of the struct
288 lda (ptr4),y ; get high byte of count
291 lda (ptr4),y ; get low byte of count
298 sta ptr3 ; length low
300 sta ptr3+1 ; length high
302 lda (ptr4),y ; get bank
314 lda (ptr4),y ; get page
315 sta ptr1+1 ; dst high
317 lda (ptr4),y ; get page offset
320 lda (ptr4),y ; get memory buffer high
323 lda (ptr4),y ; get memory buffer low
332 ; ------------------------------------------------------------------------
333 ; Helper function for moving a block, the following is used:
348 ldx tmp1 ; load srcbank
349 stx @move+1 ; store srcbank in move + 1
350 ldy tmp2 ; load dstbank
351 sty @move+2 ; store dstbank in move + 2
352 clc ; switch to native mode
354 php ; save status bits
355 rep #%00110000 ; set A and index to 16bit
363 plp ; restore status bits
370 xce ; switch to emul mode