From 0c7496f08b8a450dc5e963602c72b737687ba544 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel Date: Fri, 16 Mar 2018 14:23:52 -0700 Subject: [PATCH] Added vic20 - ram emd. --- include/vic20.h | 2 +- libsrc/vic20/emd/vic20-rama.s | 258 ++++++++++++++++++++++++++++++++++ libsrc/vic20/libref.s | 2 + 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 libsrc/vic20/emd/vic20-rama.s diff --git a/include/vic20.h b/include/vic20.h index c6ad9632d..1e8c4ceb5 100644 --- a/include/vic20.h +++ b/include/vic20.h @@ -105,7 +105,7 @@ extern void vic20_ptvjoy_joy[]; extern void vic20_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ - +extern void vic20_rama_emd[]; /* End of vic20.h */ #endif diff --git a/libsrc/vic20/emd/vic20-rama.s b/libsrc/vic20/emd/vic20-rama.s new file mode 100644 index 000000000..a48959c13 --- /dev/null +++ b/libsrc/vic20/emd/vic20-rama.s @@ -0,0 +1,258 @@ +; +; Extended memory driver for the VIC20 $A000-$BFFF RAM. Driver works without +; problems when statically linked. +; +; Marco van den Heuvel, 2018-03-16 +; + + .include "zeropage.inc" + + .include "em-kernel.inc" + .include "em-error.inc" + + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _vic20_rama_emd + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr PAGECOUNT + .addr MAP + .addr USE + .addr COMMIT + .addr COPYFROM + .addr COPYTO + +; ------------------------------------------------------------------------ +; Constants + +BASE = $A000 +PAGES = ($C000 - BASE) / 256 + +; ------------------------------------------------------------------------ +; Data. + +.bss +curpage: .res 1 ; Current page number +window: .res 256 ; Memory "window" + +.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: + lda $A000 ; see what is at address $A000 + inc $A000 ; see if it can be changed + cmp $A000 ; did it stick ? + beq nomem + dec $A000 + + ldx #$FF + stx curpage ; Invalidate the current page + inx ; X = 0 + txa ; A = X = EM_ERR_OK + rts + +nomem: ldx #>EM_ERR_NO_DEVICE + 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: sta curpage ; Remember the new page + + clc + adc #>BASE + sta ptr1+1 + ldy #$00 + sty ptr1 + + lda #window + sta ptr2+1 + +; Transfer one page + + jsr transfer ; Transfer one page + +; Return the memory window + + lda #window ; Return the window address + 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: lda curpage ; Get the current page + bmi done ; Jump if no page mapped + + clc + adc #>BASE + sta ptr2+1 + ldy #$00 + sty ptr2 + + lda #window + sta ptr1+1 + +; Transfer one page. Y must be zero on entry + +transfer: + +; Unroll the following loop + +loop: .repeat 8 + lda (ptr1),y + sta (ptr2),y + iny + .endrepeat + + bne loop + +; Done + +done: rts + +; ------------------------------------------------------------------------ +; COPYFROM: Copy from extended into linear memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYFROM: + sta ptr3 + stx ptr3+1 ; Save the passed em_copy pointer + + ldy #EM_COPY::OFFS + lda (ptr3),y + sta ptr1 + ldy #EM_COPY::PAGE + lda (ptr3),y + clc + adc #>BASE + sta ptr1+1 ; From + + ldy #EM_COPY::BUF + lda (ptr3),y + sta ptr2 + iny + lda (ptr3),y + sta ptr2+1 ; To + +common: ldy #EM_COPY::COUNT+1 + lda (ptr3),y ; Get number of pages + beq @L2 ; Skip if no full pages + sta tmp1 + +; Copy full pages allowing interrupts after each page copied + + ldy #$00 +@L1: jsr transfer + inc ptr1+1 + inc ptr2+1 + dec tmp1 + bne @L1 + +; Copy the remainder of the page + +@L2: ldy #EM_COPY::COUNT + lda (ptr3),y ; Get bytes in last page + beq @L4 + tax + +; Transfer the bytes in the last page + + ldy #$00 +@L3: lda (ptr1),y + sta (ptr2),y + iny + dex + bne @L3 + +; Done + +@L4: rts + +; ------------------------------------------------------------------------ +; COPYTO: Copy from linear into extended memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYTO: sta ptr3 + stx ptr3+1 ; Save the passed em_copy pointer + + ldy #EM_COPY::OFFS + lda (ptr3),y + sta ptr2 + ldy #EM_COPY::PAGE + lda (ptr3),y + clc + adc #>BASE + sta ptr2+1 ; To + + ldy #EM_COPY::BUF + lda (ptr3),y + sta ptr1 + iny + lda (ptr3),y + sta ptr1+1 ; From + + jmp common + diff --git a/libsrc/vic20/libref.s b/libsrc/vic20/libref.s index e4afa7eb1..468c540f1 100644 --- a/libsrc/vic20/libref.s +++ b/libsrc/vic20/libref.s @@ -3,6 +3,8 @@ ; .export joy_libref + .export em_libref .import _exit joy_libref := _exit +em_libref := _exit -- 2.39.5