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
--- /dev/null
+;
+; Extended memory driver for the VDC RAM available on all C128 machines
+; (based on code by Ullrich von Bassewitz)
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 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
+ ldx #>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
+ lda #>window
+ sta ptr2+1
+
+ jsr transferin
+
+ lda #<window
+ ldx #>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
+ ldx #>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
+ 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
+
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
--- /dev/null
+;
+; Extended memory driver for the VDC RAM available on all C128 machines
+; (based on code by Ullrich von Bassewitz)
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 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
+ ldx #>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
+ lda #>window
+ sta ptr2+1
+
+ jsr transferin
+
+ lda #<window
+ ldx #>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
+ ldx #>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
+ 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
+