From: izydorst Date: Fri, 20 Dec 2002 17:01:02 +0000 (+0000) Subject: em drivers for VDC (both C128 native and C128 in C64 mode) X-Git-Tag: V2.12.0~1878 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=46773e5e9b104e7925ef7b62e82441b6226f821d;p=cc65 em drivers for VDC (both C128 native and C128 in C64 mode) git-svn-id: svn://svn.cc65.org/cc65/trunk@1793 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/c128/Makefile b/libsrc/c128/Makefile index fc7e52a9b..fbf3c96b8 100644 --- a/libsrc/c128/Makefile +++ b/libsrc/c128/Makefile @@ -46,7 +46,7 @@ OBJS = _scrsize.o \ TGIS = -EMDS = c128-georam.emd c128-ram.emd c128-reu.emd +EMDS = c128-georam.emd c128-ram.emd c128-reu.emd c128-vdc.emd #-------------------------------------------------------------------------- # Targets diff --git a/libsrc/c128/c128-vdc.s b/libsrc/c128/c128-vdc.s new file mode 100644 index 000000000..3e324e5d9 --- /dev/null +++ b/libsrc/c128/c128-vdc.s @@ -0,0 +1,389 @@ +; +; Extended memory driver for the VDC RAM available on all C128 machines +; (based on code by Ullrich von Bassewitz) +; Maciej 'YTM/Elysium' Witkowiak +; 06,20.12.2002 + + .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 $00 ; EM API version number + +; Jump table. + + .word INSTALL + .word DEINSTALL + .word PAGECOUNT + .word MAP + .word USE + .word COMMIT + .word COPYFROM + .word COPYTO + +; ------------------------------------------------------------------------ +; Constants + +VDC_ADDR_REG = $D600 ; VDC address +VDC_DATA_REG = $D601 ; VDC data + +VDC_DATA_HI = 18 ; used registers +VDC_DATA_LO = 19 +VDC_CSET = 28 +VDC_DATA = 31 + +; ------------------------------------------------------------------------ +; Data. + +.data + +pagecount: .word 64 ; $0000-$3fff as 16k default +curpage: .word $ffff ; currently mapped-in page (invalid) + +.bss + +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: + ; do test for VDC presence here??? + + ldx #VDC_CSET ; determine size of RAM... + jsr vdcgetreg + sta tmp1 + ora #%00010000 + jsr vdcputreg ; turn on 64k + + jsr settestadr1 ; save original value of test byte + jsr vdcgetbyte + sta tmp2 + + lda #$55 ; write $55 here + ldy #ptr1 + jsr test64k ; read it here and there + lda #$aa ; write $aa here + ldy #ptr2 + jsr test64k ; read it here and there + + jsr settestadr1 + lda tmp2 + jsr vdcputbyte ; restore original value of test byte + + lda ptr1 ; do bytes match? + cmp ptr1+1 + bne @have64k + lda ptr2 + cmp ptr2+1 + bne @have64k + + ldx #VDC_CSET + lda tmp1 + jsr vdcputreg ; restore 16/64k flag + jmp @endok ; and leave default values for 16k + +@have64k: + lda #<256 + ldx #>256 + sta pagecount + stx pagecount+1 +@endok: + lda #EM_ERR_OK + rts + +test64k: + sta tmp1 + sty ptr3 + lda #0 + sta ptr3+1 + jsr settestadr1 + lda tmp1 + jsr vdcputbyte ; write $55 + jsr settestadr1 + jsr vdcgetbyte ; read here + pha + jsr settestadr2 + jsr vdcgetbyte ; and there + ldy #1 + sta (ptr3),y + pla + dey + sta (ptr3),y + rts + +settestadr1: + ldy #$02 ; test page 2 (here) + .byte $2c +settestadr2: + ldy #$42 ; or page 64+2 (there) + lda #0 + jmp vdcsetsrcaddr + +; ------------------------------------------------------------------------ +; DEINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +DEINSTALL: + ;on C128 restore font and clear the screen? + rts + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda pagecount + ldx pagecount+1 + 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 + stx curpage+1 + sta ptr1+1 + ldy #0 + sty ptr1 + + lda #window + sta ptr2+1 + + jsr transferin + + lda #window + rts + +; copy a single page from (ptr1):VDCRAM to (ptr2):RAM + +transferin: + lda ptr1 + ldy ptr1+1 + jsr vdcsetsrcaddr ; set source address in VDC + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + lda VDC_DATA_REG ; get 2 bytes at a time to speed-up + sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config) + iny + lda VDC_DATA_REG + sta (ptr2),y + iny + bne @L0 + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. + +USE: sta curpage + stx curpage+1 ; Remember the page + lda #window ; Return the window +done: rts + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: + lda curpage ; jump if no page mapped + ldx curpage+1 + bmi done + sta ptr1+1 + ldy #0 + sty ptr1 + + lda #window + sta ptr2+1 + +; fall through to transferout + +; copy a single page from (ptr2):RAM to (ptr1):VDCRAM + +transferout: + lda ptr1 + ldy ptr1+1 + jsr vdcsetsrcaddr ; set source address in VDC + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + lda (ptr2),y ; speedup does not work for writing + sta VDC_DATA_REG + iny + bne @L0 + 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: + jsr setup + beq @L2 ; Skip if no full pages + +; Copy full pages + +@L1: jsr transferin + 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 + sta tmp1 + +; Transfer the bytes in the last page + + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L3: bit VDC_ADDR_REG + bpl @L3 + lda VDC_DATA_REG + sta (ptr2),y + iny + dec tmp1 + lda tmp1 + bne @L3 +@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: + jsr setup + beq @L2 ; Skip if no full pages + +; Copy full pages + +@L1: jsr transferout + 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 + sta tmp1 + +; Transfer the bytes in the last page + + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L3: bit VDC_ADDR_REG + bpl @L3 + lda (ptr2),y + sta VDC_DATA_REG + iny + dec tmp1 + lda tmp1 + bne @L3 +@L4: rts + +;------------------------------------------------------------------------- +; Helper functions to handle VDC ram +; + +vdcsetsrcaddr: + ldx #VDC_DATA_LO + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + sta VDC_DATA_REG + dex + tya + stx VDC_ADDR_REG + sta VDC_DATA_REG + rts + +vdcgetbyte: + ldx #VDC_DATA +vdcgetreg: + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + lda VDC_DATA_REG + rts + +vdcputbyte: + ldx #VDC_DATA +vdcputreg: + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + sta VDC_DATA_REG + rts + +; ------------------------------------------------------------------------ +; Helper function for COPYFROM and COPYTO: Store the pointer to the request +; structure and prepare data for the copy +; + +setup: + 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 + sta ptr1+1 ; From + + ldy #EM_COPY_BUF + lda (ptr3),y + sta ptr2 + iny + lda (ptr3),y + sta ptr2+1 ; To + + ldy #EM_COPY_COUNT+1 + lda (ptr3),y ; Get number of pages + sta tmp1 + rts + diff --git a/libsrc/c64/Makefile b/libsrc/c64/Makefile index a336320ec..768d84efc 100644 --- a/libsrc/c64/Makefile +++ b/libsrc/c64/Makefile @@ -47,7 +47,7 @@ OBJS = _scrsize.o \ TGIS = c64-320-200-2.tgi -EMDS = c64-georam.emd c64-ram.emd c64-reu.emd +EMDS = c64-georam.emd c64-ram.emd c64-reu.emd c64-vdc.emd #-------------------------------------------------------------------------- # Targets diff --git a/libsrc/c64/c64-vdc.s b/libsrc/c64/c64-vdc.s new file mode 100644 index 000000000..3e324e5d9 --- /dev/null +++ b/libsrc/c64/c64-vdc.s @@ -0,0 +1,389 @@ +; +; Extended memory driver for the VDC RAM available on all C128 machines +; (based on code by Ullrich von Bassewitz) +; Maciej 'YTM/Elysium' Witkowiak +; 06,20.12.2002 + + .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 $00 ; EM API version number + +; Jump table. + + .word INSTALL + .word DEINSTALL + .word PAGECOUNT + .word MAP + .word USE + .word COMMIT + .word COPYFROM + .word COPYTO + +; ------------------------------------------------------------------------ +; Constants + +VDC_ADDR_REG = $D600 ; VDC address +VDC_DATA_REG = $D601 ; VDC data + +VDC_DATA_HI = 18 ; used registers +VDC_DATA_LO = 19 +VDC_CSET = 28 +VDC_DATA = 31 + +; ------------------------------------------------------------------------ +; Data. + +.data + +pagecount: .word 64 ; $0000-$3fff as 16k default +curpage: .word $ffff ; currently mapped-in page (invalid) + +.bss + +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: + ; do test for VDC presence here??? + + ldx #VDC_CSET ; determine size of RAM... + jsr vdcgetreg + sta tmp1 + ora #%00010000 + jsr vdcputreg ; turn on 64k + + jsr settestadr1 ; save original value of test byte + jsr vdcgetbyte + sta tmp2 + + lda #$55 ; write $55 here + ldy #ptr1 + jsr test64k ; read it here and there + lda #$aa ; write $aa here + ldy #ptr2 + jsr test64k ; read it here and there + + jsr settestadr1 + lda tmp2 + jsr vdcputbyte ; restore original value of test byte + + lda ptr1 ; do bytes match? + cmp ptr1+1 + bne @have64k + lda ptr2 + cmp ptr2+1 + bne @have64k + + ldx #VDC_CSET + lda tmp1 + jsr vdcputreg ; restore 16/64k flag + jmp @endok ; and leave default values for 16k + +@have64k: + lda #<256 + ldx #>256 + sta pagecount + stx pagecount+1 +@endok: + lda #EM_ERR_OK + rts + +test64k: + sta tmp1 + sty ptr3 + lda #0 + sta ptr3+1 + jsr settestadr1 + lda tmp1 + jsr vdcputbyte ; write $55 + jsr settestadr1 + jsr vdcgetbyte ; read here + pha + jsr settestadr2 + jsr vdcgetbyte ; and there + ldy #1 + sta (ptr3),y + pla + dey + sta (ptr3),y + rts + +settestadr1: + ldy #$02 ; test page 2 (here) + .byte $2c +settestadr2: + ldy #$42 ; or page 64+2 (there) + lda #0 + jmp vdcsetsrcaddr + +; ------------------------------------------------------------------------ +; DEINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +DEINSTALL: + ;on C128 restore font and clear the screen? + rts + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda pagecount + ldx pagecount+1 + 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 + stx curpage+1 + sta ptr1+1 + ldy #0 + sty ptr1 + + lda #window + sta ptr2+1 + + jsr transferin + + lda #window + rts + +; copy a single page from (ptr1):VDCRAM to (ptr2):RAM + +transferin: + lda ptr1 + ldy ptr1+1 + jsr vdcsetsrcaddr ; set source address in VDC + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + lda VDC_DATA_REG ; get 2 bytes at a time to speed-up + sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config) + iny + lda VDC_DATA_REG + sta (ptr2),y + iny + bne @L0 + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. + +USE: sta curpage + stx curpage+1 ; Remember the page + lda #window ; Return the window +done: rts + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: + lda curpage ; jump if no page mapped + ldx curpage+1 + bmi done + sta ptr1+1 + ldy #0 + sty ptr1 + + lda #window + sta ptr2+1 + +; fall through to transferout + +; copy a single page from (ptr2):RAM to (ptr1):VDCRAM + +transferout: + lda ptr1 + ldy ptr1+1 + jsr vdcsetsrcaddr ; set source address in VDC + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + lda (ptr2),y ; speedup does not work for writing + sta VDC_DATA_REG + iny + bne @L0 + 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: + jsr setup + beq @L2 ; Skip if no full pages + +; Copy full pages + +@L1: jsr transferin + 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 + sta tmp1 + +; Transfer the bytes in the last page + + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L3: bit VDC_ADDR_REG + bpl @L3 + lda VDC_DATA_REG + sta (ptr2),y + iny + dec tmp1 + lda tmp1 + bne @L3 +@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: + jsr setup + beq @L2 ; Skip if no full pages + +; Copy full pages + +@L1: jsr transferout + 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 + sta tmp1 + +; Transfer the bytes in the last page + + ldy #0 + ldx #VDC_DATA + stx VDC_ADDR_REG +@L3: bit VDC_ADDR_REG + bpl @L3 + lda (ptr2),y + sta VDC_DATA_REG + iny + dec tmp1 + lda tmp1 + bne @L3 +@L4: rts + +;------------------------------------------------------------------------- +; Helper functions to handle VDC ram +; + +vdcsetsrcaddr: + ldx #VDC_DATA_LO + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + sta VDC_DATA_REG + dex + tya + stx VDC_ADDR_REG + sta VDC_DATA_REG + rts + +vdcgetbyte: + ldx #VDC_DATA +vdcgetreg: + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + lda VDC_DATA_REG + rts + +vdcputbyte: + ldx #VDC_DATA +vdcputreg: + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + sta VDC_DATA_REG + rts + +; ------------------------------------------------------------------------ +; Helper function for COPYFROM and COPYTO: Store the pointer to the request +; structure and prepare data for the copy +; + +setup: + 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 + sta ptr1+1 ; From + + ldy #EM_COPY_BUF + lda (ptr3),y + sta ptr2 + iny + lda (ptr3),y + sta ptr2+1 ; To + + ldy #EM_COPY_COUNT+1 + lda (ptr3),y ; Get number of pages + sta tmp1 + rts +