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"
16 ; ------------------------------------------------------------------------
17 ; Header. Includes jump table
19 module_header _c64_c256k_emd
23 .byte $65, $6d, $64 ; "emd"
24 .byte EMD_API_VERSION ; EM API version number
41 ; ------------------------------------------------------------------------
46 TARGETLOC = $200 ; Target location for copy/check code
49 ; ------------------------------------------------------------------------
55 ; This function is used to copy code from and to the extended memory
58 .org ::TARGETLOC ; Assemble for target location
61 stashop = $91 ; 'sta' opcode
62 operation := * ; Location and opcode is patched at runtime
71 ; This function is used to check for the existence of the extended memory
76 ldy #$00 ; Assume hardware not present
86 bne done ; Jump if not found
89 beq done ; Jump if not found
104 curpage: .res 2 ; Current page number
105 curbank: .res 1 ; Current bank
106 window: .res 256 ; Memory "window"
108 ; Since the functions above are copied to $200, the current contents of this
109 ; memory area must be saved into backup storage. Allocate enough space.
110 backup: .res .max (.sizeof (copy), .sizeof (check))
115 ; ------------------------------------------------------------------------
116 ; INSTALL routine. Is called after the driver is loaded into memory. If
117 ; possible, check if the hardware is present and determine the amount of
119 ; Must return an EM_ERR_xx code in a/x.
123 lda PIA+1 ; Select Peripheral Registers
132 lda #$DC ; Set the default memory bank data
137 txa ; Select Data Direction Registers
144 lda #$FF ; Set the ports to output
150 ora #$30 ; Set CA1 and
151 sta PIA+1 ; select Peripheral Registers
154 jsr backup_and_setup_check_routine
157 ldx #.sizeof (check) - 1
161 lda #<EM_ERR_NO_DEVICE
162 ldx #>EM_ERR_NO_DEVICE
168 ; rts ; Run into UNINSTALL instead
170 ; ------------------------------------------------------------------------
171 ; UNINSTALL routine. Is called before the driver is removed from memory.
172 ; Can do cleanup or whatever. Must not return anything.
179 ; ------------------------------------------------------------------------
180 ; PAGECOUNT: Return the total number of available pages in a/x.
188 ; ------------------------------------------------------------------------
189 ; MAP: Map the page in a/x into memory and return a pointer to the page in
190 ; a/x. The contents of the currently mapped page (if any) may be discarded
196 sta curpage ; Remember the new page
198 jsr adjust_page_and_bank
205 jsr backup_and_setup_copy_routine
216 ; Return the memory window
218 jsr restore_copy_routine
220 ldx #>window ; Return the window address
224 ; ------------------------------------------------------------------------
225 ; USE: Tell the driver that the window is now associated with a given page.
227 USE: sta curpage ; Remember the page
230 ldx #>window ; Return the window
233 ; ------------------------------------------------------------------------
234 ; COMMIT: Commit changes in the memory window to extended storage.
238 lda curpage ; Get the current page
241 jsr adjust_page_and_bank
248 jsr backup_and_setup_copy_routine
261 ; Return the memory window
263 jsr restore_copy_routine
268 ; ------------------------------------------------------------------------
269 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
270 ; describing the request is passed in a/x.
271 ; The function must not return anything.
278 jsr backup_and_setup_copy_routine
282 ; - ptr1 contains the struct pointer
283 ; - ptr2 contains the linear memory buffer
284 ; - ptr3 contains -(count-1)
285 ; - ptr4 contains the page memory buffer plus offset
286 ; - tmp1 contains zero (to be used for linear memory buffer offset)
287 ; - tmp2 contains the bank value
306 ; Bump count and repeat
313 jsr restore_copy_routine
332 ; ------------------------------------------------------------------------
333 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
334 ; describing the request is passed in a/x.
335 ; The function must not return anything.
341 jsr backup_and_setup_copy_routine
345 ; - ptr1 contains the struct pointer
346 ; - ptr2 contains the linear memory buffer
347 ; - ptr3 contains -(count-1)
348 ; - ptr4 contains the page memory buffer plus offset
349 ; - tmp1 contains zero (to be used for linear memory buffer offset)
350 ; - tmp2 contains the bank value
371 ; Bump count and repeat
378 jsr restore_copy_routine
397 ; ------------------------------------------------------------------------
398 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
399 ; structure and prepare data for the copy
403 stx ptr1+1 ; Save passed pointer
405 ; Get the page number from the struct and adjust it so that it may be used
406 ; with the hardware. That is: ptr4 has the page address and page offset
407 ; tmp2 will hold the bank value
414 jsr adjust_page_and_bank
420 ; Get the buffer pointer into ptr2
429 ; Get the count, calculate -(count-1) and store it into ptr3
440 ; Get the page offset into ptr4 and clear tmp1
452 ; Helper routines for copying to and from the +256k ram
454 backup_and_setup_copy_routine:
455 ldx #.sizeof (copy) - 1
465 backup_and_setup_check_routine:
466 ldx #.sizeof (check) - 1
470 lda check::template,x
476 restore_copy_routine:
477 ldx #.sizeof (copy) - 1
485 ; Helper routine to correct for the bank and page
486 adjust_page_and_bank: