2 ; Extended memory driver for the C256K memory expansion
3 ; Marco van den Heuvel, 2010-01-27
6 .include "zeropage.inc"
8 .include "em-kernel.inc"
9 .include "em-error.inc"
15 ; ------------------------------------------------------------------------
16 ; Header. Includes jump table
22 .byte $65, $6d, $64 ; "emd"
23 .byte EMD_API_VERSION ; EM API version number
36 ; ------------------------------------------------------------------------
41 TARGETLOC = $200 ; Target location for copy/check code
44 ; ------------------------------------------------------------------------
50 ; This function is used to copy code from and to the extended memory
53 .org ::TARGETLOC ; Assemble for target location
56 stashop = $91 ; 'sta' opcode
57 operation := * ; Location and opcode is patched at runtime
66 ; This function is used to check for the existence of the extended memory
71 ldy #$00 ; Assume hardware not present
81 bne done ; Jump if not found
84 beq done ; Jump if not found
99 curpage: .res 2 ; Current page number
100 curbank: .res 1 ; Current bank
101 window: .res 256 ; Memory "window"
103 ; Since the functions above are copied to $200, the current contents of this
104 ; memory area must be saved into backup storage. Allocate enough space.
105 backup: .res .max (.sizeof (copy), .sizeof (check))
110 ; ------------------------------------------------------------------------
111 ; INSTALL routine. Is called after the driver is loaded into memory. If
112 ; possible, check if the hardware is present and determine the amount of
114 ; Must return an EM_ERR_xx code in a/x.
118 lda PIA+1 ; Select Peripheral Registers
127 lda #$DC ; Set the default memory bank data
132 txa ; Select Data Direction Registers
139 lda #$FF ; Set the ports to output
145 ora #$30 ; Set CA1 and
146 sta PIA+1 ; select Peripheral Registers
149 jsr backup_and_setup_check_routine
152 ldx #.sizeof (check) - 1
156 lda #<EM_ERR_NO_DEVICE
157 ldx #>EM_ERR_NO_DEVICE
163 ; rts ; Run into UNINSTALL instead
165 ; ------------------------------------------------------------------------
166 ; UNINSTALL routine. Is called before the driver is removed from memory.
167 ; Can do cleanup or whatever. Must not return anything.
174 ; ------------------------------------------------------------------------
175 ; PAGECOUNT: Return the total number of available pages in a/x.
183 ; ------------------------------------------------------------------------
184 ; MAP: Map the page in a/x into memory and return a pointer to the page in
185 ; a/x. The contents of the currently mapped page (if any) may be discarded
191 sta curpage ; Remember the new page
193 jsr adjust_page_and_bank
200 jsr backup_and_setup_copy_routine
211 ; Return the memory window
213 jsr restore_copy_routine
215 ldx #>window ; Return the window address
219 ; ------------------------------------------------------------------------
220 ; USE: Tell the driver that the window is now associated with a given page.
222 USE: sta curpage ; Remember the page
225 ldx #>window ; Return the window
228 ; ------------------------------------------------------------------------
229 ; COMMIT: Commit changes in the memory window to extended storage.
233 lda curpage ; Get the current page
236 jsr adjust_page_and_bank
243 jsr backup_and_setup_copy_routine
256 ; Return the memory window
258 jsr restore_copy_routine
263 ; ------------------------------------------------------------------------
264 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
265 ; describing the request is passed in a/x.
266 ; The function must not return anything.
273 jsr backup_and_setup_copy_routine
277 ; - ptr1 contains the struct pointer
278 ; - ptr2 contains the linear memory buffer
279 ; - ptr3 contains -(count-1)
280 ; - ptr4 contains the page memory buffer plus offset
281 ; - tmp1 contains zero (to be used for linear memory buffer offset)
282 ; - tmp2 contains the bank value
301 ; Bump count and repeat
308 jsr restore_copy_routine
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.
336 jsr backup_and_setup_copy_routine
340 ; - ptr1 contains the struct pointer
341 ; - ptr2 contains the linear memory buffer
342 ; - ptr3 contains -(count-1)
343 ; - ptr4 contains the page memory buffer plus offset
344 ; - tmp1 contains zero (to be used for linear memory buffer offset)
345 ; - tmp2 contains the bank value
366 ; Bump count and repeat
373 jsr restore_copy_routine
392 ; ------------------------------------------------------------------------
393 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
394 ; structure and prepare data for the copy
398 stx ptr1+1 ; Save passed pointer
400 ; Get the page number from the struct and adjust it so that it may be used
401 ; with the hardware. That is: ptr4 has the page address and page offset
402 ; tmp2 will hold the bank value
409 jsr adjust_page_and_bank
415 ; Get the buffer pointer into ptr2
424 ; Get the count, calculate -(count-1) and store it into ptr3
435 ; Get the page offset into ptr4 and clear tmp1
447 ; Helper routines for copying to and from the +256k ram
449 backup_and_setup_copy_routine:
450 ldx #.sizeof (copy) - 1
460 backup_and_setup_check_routine:
461 ldx #.sizeof (check) - 1
465 lda check::template,x
471 restore_copy_routine:
472 ldx #.sizeof (copy) - 1
480 ; Helper routine to correct for the bank and page
481 adjust_page_and_bank: