From d4592d1a7ca7c2c882f03281c3b0620c31d53b05 Mon Sep 17 00:00:00 2001 From: uz Date: Fri, 12 Feb 2010 11:09:23 +0000 Subject: [PATCH] New EMD driver for the Double Quick Brown Box cartridge, written and contributed by Marco van den Heuvel with quite some cleanup by me. git-svn-id: svn://svn.cc65.org/cc65/trunk@4587 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/c64/Makefile | 1 + libsrc/c64/c64-dqbb.s | 441 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 442 insertions(+) create mode 100755 libsrc/c64/c64-dqbb.s diff --git a/libsrc/c64/Makefile b/libsrc/c64/Makefile index 126807676..0b3eddeea 100644 --- a/libsrc/c64/Makefile +++ b/libsrc/c64/Makefile @@ -72,6 +72,7 @@ OBJS = _scrsize.o \ # Drivers EMDS = c64-c256k.emd \ + c64-dqbb.emd \ c64-georam.emd \ c64-isepic.emd \ c64-ram.emd \ diff --git a/libsrc/c64/c64-dqbb.s b/libsrc/c64/c64-dqbb.s new file mode 100755 index 000000000..3f581e11a --- /dev/null +++ b/libsrc/c64/c64-dqbb.s @@ -0,0 +1,441 @@ +; +; Extended memory driver for the Double Quick Brown Box cartridge +; Marco van den Heuvel, 2010-01-27 +; + + .include "zeropage.inc" + + .include "em-kernel.inc" + .include "em-error.inc" + + + .macpack generic + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + +.segment "JUMPTABLE" + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Jump table. + + .word INSTALL + .word UNINSTALL + .word PAGECOUNT + .word MAP + .word USE + .word COMMIT + .word COPYFROM + .word COPYTO + +; ------------------------------------------------------------------------ +; Constants + +BASE = $8000 +PAGES = ($C000 - BASE) / 256 +TARGETLOC = $200 ; Target location for copy/check code +CONTROL = $DE00 + +; ------------------------------------------------------------------------ +; Data. + +.proc check +template: +.org ::TARGETLOC ; Assemble for target location +entry: + lda $01 + pha + lda #$37 + sta $01 + ldx #$14 + ldy #$90 + sty CONTROL + lda $8000 + stx CONTROL + cmp $8000 + bne present + sty CONTROL + inc $8000 + stx CONTROL + cmp $8000 + beq present + dec $8000 + ldy #$00 + +done: pla + sta $01 + rts + +present: + sty CONTROL + ldy #$01 + bne done +.reloc +.endproc + + +.proc copy +template: +.org ::TARGETLOC ; Assemble for target location +entry: +.proc fetch + stx CONTROL + ldx $01 + lda #$37 + sta $01 +address := *+1 ; Patched at runtime + lda ($00),y + stx $01 + ldx #$90 + stx CONTROL + rts +.endproc + +.proc stash + stx CONTROL + ldx $01 + ldy #$37 + sty $01 + ldy #$00 +address := *+1 ; Patched at runtime + sta ($00),y + stx $01 + ldx #$90 + stx CONTROL + rts +.endproc +.reloc +.endproc + + +.bss + +curpage: .res 1 ; Current page number +window: .res 256 ; Memory "window" + +; Since the functions above are copied to $200, the current contents of this +; memory area must be saved into backup storage. Allocate enough space. +backup: .res .max (.sizeof (copy), .sizeof (check)) + + + +.code + +; ------------------------------------------------------------------------ +; INSTALL routine. Is called after the driver is loaded into memory. If +; possible, check if the hardware is present and determine the amount of +; memory available. +; Must return an EM_ERR_xx code in a/x. +; + +INSTALL: + sei + jsr backup_and_setup_check_routine + jsr check::entry + cli + ldx #.sizeof (check) - 1 + jsr restore_data + cpy #$01 + beq @present + lda #EM_ERR_NO_DEVICE + rts + +@present: + lda #EM_ERR_OK +; rts ; Run into UNINSTALL instead + +; ------------------------------------------------------------------------ +; UNINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +UNINSTALL: + rts + + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda #PAGES + rts + +; ------------------------------------------------------------------------ +; MAP: Map the page in a/x into memory and return a pointer to the page in +; a/x. The contents of the currently mapped page (if any) may be discarded +; by the driver. +; + +MAP: + sei + sta curpage ; Remember the new page + clc + adc #>BASE + sta ptr1+1 + ldy #0 + sty ptr1 + jsr backup_and_setup_copy_routine + ldx #window ; Return the window address + cli + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. + +USE: sta curpage ; Remember the page + lda #window ; Return the window + rts + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: + sei + lda curpage ; Get the current page + clc + adc #>BASE + sta ptr1+1 + ldy #0 + sty ptr1 + jsr backup_and_setup_copy_routine + ldx #BASE + sta ptr4+1 + +; Get the buffer pointer into ptr2 + + ldy #EM_COPY::BUF + lda (ptr1),y + sta ptr2 + iny + lda (ptr1),y + sta ptr2+1 + +; Get the count, calculate -(count-1) and store it into ptr3 + + ldy #EM_COPY::COUNT + lda (ptr1),y + eor #$FF + sta ptr3 + iny + lda (ptr1),y + eor #$FF + sta ptr3+1 + +; Get the page offset into ptr4 and clear tmp1 + + ldy #EM_COPY::OFFS + lda (ptr1),y + sta ptr4 + lda #0 + sta tmp1 + +; Done + + rts + +; Helper routines for copying to and from the +256k ram + +backup_and_setup_copy_routine: + ldx #.sizeof (copy) - 1 +@L1: + lda copy::entry,x + sta backup,x + lda copy::template,x + sta copy::entry,x + dex + bpl @L1 + rts + +backup_and_setup_check_routine: + ldx #.sizeof (check) - 1 +@L1: + lda check::entry,x + sta backup,x + lda check::template,x + sta check::entry,x + dex + bpl @L1 + rts + +restore_copy_routine: + ldx #.sizeof (copy) - 1 +restore_data: + lda backup,x + sta TARGETLOC,x + dex + bpl restore_data + rts -- 2.39.5