Replaced whole bunch for Makefiles with a single generic Makefile.

- No complex shell logic.
- "Source file shadowing" for all targets via vpath.
- Dependency handling.
- True incremental build.
- Don't write into source directories.
- Easy cleanup by just removing 'wrk'.
This commit is contained in:
Oliver Schmidt
2013-05-04 22:10:48 +02:00
parent 2cd8e140ad
commit 008b4c4e1d
138 changed files with 36 additions and 3707 deletions

502
libsrc/c64/emd/c64-c256k.s Normal file
View File

@@ -0,0 +1,502 @@
;
; Extended memory driver for the C256K memory expansion
; 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 = $4000
PAGES = 3 * 256
TARGETLOC = $200 ; Target location for copy/check code
PIA = $DFC0
; ------------------------------------------------------------------------
; Data.
.data
; This function is used to copy code from and to the extended memory
.proc copy
template:
.org ::TARGETLOC ; Assemble for target location
entry:
stx PIA
stashop = $91 ; 'sta' opcode
operation := * ; Location and opcode is patched at runtime
address := *+1
lda ($00),y
ldx #$dc
stx PIA
rts
.reloc
.endproc
; This function is used to check for the existence of the extended memory
.proc check
template:
.org ::TARGETLOC
entry:
ldy #$00 ; Assume hardware not present
lda #$fc
sta PIA
lda $01
tax
and #$f8
sta $01
lda $4000
cmp $c000
bne done ; Jump if not found
inc $c000
cmp $4000
beq done ; Jump if not found
; Hardware is present
iny
done: stx $01
ldx #$dc
stx PIA
rts
.reloc
.endproc
.bss
curpage: .res 2 ; Current page number
curbank: .res 1 ; Current bank
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:
lda PIA+1 ; Select Peripheral Registers
ora #4
sta PIA+1
tax
lda PIA+3
ora #4
sta PIA+3
tay
lda #$DC ; Set the default memory bank data
sta PIA
lda #$FE
sta PIA+2
txa ; Select Data Direction Registers
and #$FB
sta PIA+1
tya
and #$FB
sta PIA+3
lda #$FF ; Set the ports to output
sta PIA
sta PIA+2
txa
and #$C7
ora #$30 ; Set CA1 and
sta PIA+1 ; select Peripheral Registers
sty PIA+3
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
ldx #>EM_ERR_NO_DEVICE
rts
@present:
lda #<EM_ERR_OK
ldx #>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
ldx #>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
stx curpage+1
jsr adjust_page_and_bank
stx curbank
clc
adc #>BASE
sta ptr1+1
ldy #0
sty ptr1
jsr backup_and_setup_copy_routine
ldx #<ptr1
stx copy::address
@L1:
ldx curbank
jsr copy::entry
ldx ptr1
sta window,x
inc ptr1
bne @L1
; Return the memory window
jsr restore_copy_routine
lda #<window
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
stx curpage+1
lda #<window
ldx #>window ; Return the window
rts
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT:
sei
lda curpage ; Get the current page
ldx curpage+1
jsr adjust_page_and_bank
stx curbank
clc
adc #>BASE
sta ptr1+1
ldy #0
sty ptr1
jsr backup_and_setup_copy_routine
ldx #<ptr1
stx copy::address
ldx #<copy::stashop
stx copy::operation
@L1:
ldx ptr1
lda window,x
ldx curbank
jsr copy::entry
inc ptr1
bne @L1
; Return the memory window
jsr restore_copy_routine
done:
cli
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:
sei
jsr setup
jsr backup_and_setup_copy_routine
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - ptr4 contains the page memory buffer plus offset
; - tmp1 contains zero (to be used for linear memory buffer offset)
; - tmp2 contains the bank value
lda #<ptr4
sta copy::address
jmp @L3
@L1:
ldx tmp2
ldy #0
jsr copy::entry
ldy tmp1
sta (ptr2),y
inc tmp1
bne @L2
inc ptr2+1
@L2:
inc ptr4
beq @L4
; Bump count and repeat
@L3:
inc ptr3
bne @L1
inc ptr3+1
bne @L1
jsr restore_copy_routine
cli
rts
; Bump page register
@L4:
inc ptr4+1
lda ptr4+1
cmp #$80
bne @L3
lda #>BASE
sta ptr4+1
lda tmp2
clc
adc #$10
sta tmp2
jmp @L3
; ------------------------------------------------------------------------
; 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:
sei
jsr setup
jsr backup_and_setup_copy_routine
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - ptr4 contains the page memory buffer plus offset
; - tmp1 contains zero (to be used for linear memory buffer offset)
; - tmp2 contains the bank value
lda #<ptr4
sta copy::address
lda #<copy::stashop
sta copy::operation
jmp @L3
@L1:
ldy tmp1
lda (ptr2),y
ldx tmp2
ldy #0
jsr copy::entry
inc tmp1
bne @L2
inc ptr2+1
@L2:
inc ptr4
beq @L4
; Bump count and repeat
@L3:
inc ptr3
bne @L1
inc ptr3+1
bne @L1
jsr restore_copy_routine
cli
rts
; Bump page register
@L4:
inc ptr4+1
lda ptr4+1
cmp #$80
bne @L3
lda #>BASE
sta ptr4+1
lda tmp2
clc
adc #$10
sta tmp2
jmp @L3
; ------------------------------------------------------------------------
; Helper function for COPYFROM and COPYTO: Store the pointer to the request
; structure and prepare data for the copy
setup:
sta ptr1
stx ptr1+1 ; Save passed pointer
; Get the page number from the struct and adjust it so that it may be used
; with the hardware. That is: ptr4 has the page address and page offset
; tmp2 will hold the bank value
ldy #EM_COPY::PAGE+1
lda (ptr1),y
tax
ldy #EM_COPY::PAGE
lda (ptr1),y
jsr adjust_page_and_bank
clc
adc #>BASE
sta ptr4+1
stx tmp2
; 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
; Helper routine to correct for the bank and page
adjust_page_and_bank:
sta tmp4
lda #$0C
sta tmp3
lda tmp4
and #$c0
lsr
lsr
ora tmp3
sta tmp3
txa
asl
asl
asl
asl
asl
asl
ora tmp3
tax
lda tmp4
and #$3f
rts

441
libsrc/c64/emd/c64-dqbb.s Normal file
View File

@@ -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
ldx #>EM_ERR_NO_DEVICE
rts
@present:
lda #<EM_ERR_OK
ldx #>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
ldx #>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 #<ptr1
stx copy::fetch::address
@L1:
ldx #$14
jsr copy::fetch
ldx ptr1
sta window,x
inc ptr1
bne @L1
; Return the memory window
jsr restore_copy_routine
lda #<window
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
ldx #>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 #<ptr1
stx copy::stash::address
@L1:
ldx ptr1
lda window,x
ldx #$14
jsr copy::stash
inc ptr1
bne @L1
; Return the memory window
jsr restore_copy_routine
cli
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:
sei
pha
txa
pha
jsr backup_and_setup_copy_routine
pla
tax
pla
jsr setup
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - ptr4 contains the page memory buffer plus offset
; - tmp1 contains zero (to be used for linear memory buffer offset)
lda #<ptr4
sta copy::fetch::address
jmp @L3
@L1:
ldx #$14
ldy #0
jsr copy::fetch
ldy tmp1
sta (ptr2),y
inc tmp1
bne @L2
inc ptr2+1
@L2:
inc ptr4
beq @L4
; Bump count and repeat
@L3:
inc ptr3
bne @L1
inc ptr3+1
bne @L1
jsr restore_copy_routine
cli
rts
; Bump page register
@L4:
inc ptr4+1
jmp @L3
; ------------------------------------------------------------------------
; 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:
sei
pha
txa
pha
jsr backup_and_setup_copy_routine
pla
tax
pla
jsr setup
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - ptr4 contains the page memory buffer plus offset
; - tmp1 contains zero (to be used for linear memory buffer offset)
lda #<ptr4
sta copy::stash::address
jmp @L3
@L1:
ldy tmp1
lda (ptr2),y
ldx #$14
ldy #0
jsr copy::stash
inc tmp1
bne @L2
inc ptr2+1
@L2:
inc ptr4
beq @L4
; Bump count and repeat
@L3:
inc ptr3
bne @L1
inc ptr3+1
bne @L1
jsr restore_copy_routine
cli
rts
; Bump page register
@L4:
inc ptr4+1
jmp @L3
; ------------------------------------------------------------------------
; Helper function for COPYFROM and COPYTO: Store the pointer to the request
; structure and prepare data for the copy
setup:
sta ptr1
stx ptr1+1 ; Save passed pointer
; Get the page number from the struct and adjust it so that it may be used
; with the hardware. That is: ptr4 has the page address and page offset
; tmp2 will hold the bank value
ldy #EM_COPY::PAGE
lda (ptr1),y
clc
adc #>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

349
libsrc/c64/emd/c64-georam.s Normal file
View File

@@ -0,0 +1,349 @@
;
; Extended memory driver for the GEORAM cartridge. Driver works without
; problems when statically linked.
;
; Ullrich von Bassewitz, 2002-11-29
;
; GEORAM page size checking routine by
; Marco van den Heuvel, 2010-01-21
;
.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
GR_WINDOW = $DE00 ; Address of GEORAM window
GR_PAGE_LO = $DFFE ; Page register low
GR_PAGE_HI = $DFFF ; Page register high
; ------------------------------------------------------------------------
; Data.
.data
pagecount: .res 2 ; Number of available pages
.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:
ldx GR_WINDOW
cpx GR_WINDOW
bne @notpresent
inc GR_WINDOW
cpx GR_WINDOW
beq @notpresent
lda #4
jsr check
cpy GR_WINDOW
beq @has64k
lda #8
jsr check
cpy GR_WINDOW
beq @has128k
lda #16
jsr check
cpy GR_WINDOW
beq @has256k
lda #32
jsr check
cpy GR_WINDOW
beq @has512k
lda #64
jsr check
cpy GR_WINDOW
beq @has1024k
lda #128
jsr check
cpy GR_WINDOW
beq @has2048k
ldx #>16384
bne @setok
@has64k:
ldx #>256
bne @setok
@has128k:
ldx #>512
bne @setok
@has256k:
ldx #>1024
bne @setok
@has512k:
ldx #>2048
bne @setok
@has1024k:
ldx #>4096
bne @setok
@has2048k:
ldx #>8192
bne @setok
@notpresent:
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
rts
@setok:
lda #0
sta pagecount
stx pagecount+1
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
check:
ldx #0
stx GR_PAGE_LO
stx GR_PAGE_HI
ldy GR_WINDOW
iny
sta GR_PAGE_HI
sty GR_WINDOW
ldx #0
stx GR_PAGE_HI
; 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 pagecount
ldx pagecount+1
rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
; The GeoRAM cartridge does not copy but actually map the window, so USE is
; identical to MAP.
USE = MAP
; ------------------------------------------------------------------------
; 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 tmp1
txa
asl tmp1
rol a
asl tmp1
rol a
sta GR_PAGE_HI
lda tmp1
lsr a
lsr a
sta GR_PAGE_LO
lda #<GR_WINDOW
ldx #>GR_WINDOW
; Use the RTS from COMMIT below to save a precious byte of storage
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: 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
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - tmp2 contains the high page register value
; - X contains the page offset
; - Y contains zero
jmp @L5
@L1: lda GR_WINDOW,x
sta (ptr2),y
iny
bne @L2
inc ptr2+1
@L2: inx
beq @L4
; Bump count and repeat
@L3: inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4: inc tmp1 ; Bump low page register
bit tmp1 ; Check for overflow in bit 6
bvc @L6 ; Jump if no overflow
inc tmp2
@L5: lda tmp2
sta GR_PAGE_HI
@L6: lda tmp1
sta GR_PAGE_LO
jmp @L3
; ------------------------------------------------------------------------
; 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
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - tmp2 contains the high page register value
; - X contains the page offset
; - Y contains zero
jmp @L5
@L1: lda (ptr2),y
sta GR_WINDOW,x
iny
bne @L2
inc ptr2+1
@L2: inx
beq @L4
; Bump count and repeat
@L3: inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4: inc tmp1 ; Bump low page register
bit tmp1 ; Check for overflow in bit 6
bvc @L6 ; Jump if no overflow
inc tmp2
@L5: lda tmp2
sta GR_PAGE_HI
@L6: lda tmp1
sta GR_PAGE_LO
jmp @L3
; ------------------------------------------------------------------------
; Helper function for COPYFROM and COPYTO: Store the pointer to the request
; structure and prepare data for the copy
setup: sta ptr1
stx ptr1+1 ; Save passed pointer
; Get the page number from the struct and adjust it so that it may be used
; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
ldy #EM_COPY::PAGE+1
lda (ptr1),y
sta tmp2
dey
lda (ptr1),y
asl a
rol tmp2
asl a
rol tmp2
lsr a
lsr a
sta tmp1
; 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 X and clear Y
ldy #EM_COPY::OFFS
lda (ptr1),y
tax
ldy #$00
; Done
rts

270
libsrc/c64/emd/c64-isepic.s Normal file
View File

@@ -0,0 +1,270 @@
;
; Extended memory driver for the ISEPIC cartridge.
; Marco van den Heuvel, 2010-01-24
;
.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
IP_WINDOW = $DF00 ; Address of ISEPIC window
IP_CTRL_BASE = $DE00
PAGES = 8
; ------------------------------------------------------------------------
; Code.
.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 #0
sta IP_CTRL_BASE
ldx IP_WINDOW
cpx IP_WINDOW
bne @notpresent
inc IP_WINDOW
cpx IP_WINDOW
beq @notpresent
ldx IP_WINDOW
sta IP_CTRL_BASE+1
inx
stx IP_WINDOW
dex
sta IP_CTRL_BASE
cpx IP_WINDOW
beq @setok
@notpresent:
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
rts
@setok:
lda #<EM_ERR_OK
ldx #>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
ldx #>PAGES
rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
; The Isepic cartridge does not copy but actually map the window, so USE is
; identical to MAP.
USE := MAP
; ------------------------------------------------------------------------
; 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:
tax
sta IP_CTRL_BASE,x
lda #<IP_WINDOW
ldx #>IP_WINDOW
; Use the RTS from COMMIT below to save a precious byte of storage
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT:
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
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - X contains the page offset
; - Y contains zero
jmp @L5
@L1:
lda IP_WINDOW,x
sta (ptr2),y
iny
bne @L2
inc ptr2+1
@L2:
inx
beq @L4
; Bump count and repeat
@L3:
inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4:
inc tmp1 ; Bump low page register
@L5:
stx tmp2
ldx tmp1
sta IP_CTRL_BASE,x
ldx tmp2
jmp @L3
; ------------------------------------------------------------------------
; 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
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - X contains the page offset
; - Y contains zero
jmp @L5
@L1:
lda (ptr2),y
sta IP_WINDOW,x
iny
bne @L2
inc ptr2+1
@L2:
inx
beq @L4
; Bump count and repeat
@L3:
inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4:
inc tmp1 ; Bump page register
@L5:
stx tmp2
ldx tmp1
sta IP_CTRL_BASE,x
ldx tmp2
jmp @L3
; ------------------------------------------------------------------------
; Helper function for COPYFROM and COPYTO: Store the pointer to the request
; structure and prepare data for the copy
setup:
sta ptr1
stx ptr1+1 ; Save passed pointer
; Get the page number from the struct and remember it.
ldy #EM_COPY::PAGE
lda (ptr1),y
sta tmp1
; 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 X and clear Y
ldy #EM_COPY::OFFS
lda (ptr1),y
tax
ldy #0
; Done
rts

266
libsrc/c64/emd/c64-ram.s Normal file
View File

@@ -0,0 +1,266 @@
;
; Extended memory driver for the C64 hidden RAM. Driver works without
; problems when statically linked.
;
; Ullrich von Bassewitz, 2002-12-02
;
.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 = $D000
PAGES = ($10000 - 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:
ldx #$FF
stx curpage ; Invalidate the current page
inx ; X = 0
txa ; A = X = 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
ldx #>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
lda #>window
sta ptr2+1
; Transfer one page
jsr transfer ; Transfer one page
; Return the memory window
lda #<window
ldx #>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
ldx #>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
lda #>window
sta ptr1+1
; Transfer one page. Y must be zero on entry
transfer:
ldx $01 ; Remember c64 control port
txa
and #$F8 ; Bank out ROMs, I/O
sei
sta $01
; Unroll the following loop
loop: .repeat 8
lda (ptr1),y
sta (ptr2),y
iny
.endrepeat
bne loop
; Restore the old memory configuration, allow interrupts
stx $01 ; Restore the old configuration
cli
; 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
lda $01 ; Remember c64 control port
pha
and #$F8 ; Bank out ROMs, I/O
sei
sta $01
; Transfer the bytes in the last page
ldy #$00
@L3: lda (ptr1),y
sta (ptr2),y
iny
dex
bne @L3
; Restore the old memory configuration, allow interrupts
pla
sta $01 ; Restore the old configuration
cli
; 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

View File

@@ -0,0 +1,292 @@
;
; Extended memory driver for the RamCart 64/128KB cartridge. Driver works
; without problems when statically linked.
; Code is based on GEORAM code by Ullrich von Bassewitz.
; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
; 06,22.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 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
RAMC_WINDOW = $DF00 ; Address of RamCart window
RAMC_PAGE_LO = $DE00 ; Page register low
RAMC_PAGE_HI = $DE01 ; Page register high (only for RC128)
; ------------------------------------------------------------------------
; Data.
.bss
pagecount: .res 2 ; Number of available pages
.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:
ldx RAMC_WINDOW
cpx RAMC_WINDOW
bne @notpresent
lda #0
sta RAMC_PAGE_LO
sta RAMC_PAGE_HI
ldx RAMC_WINDOW
cpx RAMC_WINDOW
bne @notpresent
lda #2
sta RAMC_WINDOW
cmp RAMC_WINDOW
beq @cont
cpx RAMC_WINDOW
beq @readonly
@cont: ldy #1
sty RAMC_PAGE_HI
sty RAMC_WINDOW
dey
sty RAMC_PAGE_HI
iny
cpy RAMC_WINDOW
beq @rc64
; we're on rc128
ldx #>512
bne @setsize
@rc64: ldx #>256
@setsize:
lda #0
sta pagecount
stx pagecount+1
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
@notpresent:
@readonly:
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
; 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 pagecount
ldx pagecount+1
rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
; The RamCart cartridge does not copy but actually map the window, so USE is
; identical to MAP.
USE = MAP
; ------------------------------------------------------------------------
; 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 RAMC_PAGE_LO
stx RAMC_PAGE_HI
lda #<RAMC_WINDOW
ldx #>RAMC_WINDOW
; Use the RTS from COMMIT below to save a precious byte of storage
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: 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
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - tmp2 contains the high page register value
; - X contains the page offset
; - Y contains zero
jmp @L5
@L1: lda RAMC_WINDOW,x
sta (ptr2),y
iny
bne @L2
inc ptr2+1
@L2: inx
beq @L4
; Bump count and repeat
@L3: inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4: inc tmp1
bne @L5
inc tmp2
@L5: lda tmp1
sta RAMC_PAGE_LO
lda tmp2
sta RAMC_PAGE_HI
jmp @L3
; ------------------------------------------------------------------------
; 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
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - tmp2 contains the high page register value
; - X contains the page offset
; - Y contains zero
jmp @L5
@L1: lda (ptr2),y
sta RAMC_WINDOW,x
iny
bne @L2
inc ptr2+1
@L2: inx
beq @L4
; Bump count and repeat
@L3: inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4: inc tmp1
bne @L5
inc tmp2
@L5: lda tmp1
sta RAMC_PAGE_LO
lda tmp2
sta RAMC_PAGE_HI
jmp @L3
; ------------------------------------------------------------------------
; Helper function for COPYFROM and COPYTO: Store the pointer to the request
; structure and prepare data for the copy
setup: sta ptr1
stx ptr1+1 ; Save passed pointer
; Get the page number from the struct and adjust it so that it may be used
; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
ldy #EM_COPY::PAGE+1
lda (ptr1),y
sta tmp2
dey
lda (ptr1),y
sta tmp1
; 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 X and clear Y
ldy #EM_COPY::OFFS
lda (ptr1),y
tax
ldy #$00
; Done
rts

236
libsrc/c64/emd/c64-reu.s Normal file
View File

@@ -0,0 +1,236 @@
;
; Extended memory driver for the Commodore REU. Driver works without
; problems when statically linked.
;
; Ullrich von Bassewitz, 2002-11-29
;
.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
REU_STATUS = $DF00 ; Status register
REU_COMMAND = $DF01 ; Command register
REU_C64ADDR = $DF02 ; C64 base address register
REU_REUADDR = $DF04 ; REU base address register
REU_COUNT = $DF07 ; Transfer count register
REU_IRQMASK = $DF09 ; IRQ mask register
REU_CONTROL = $DF0A ; Control register
REU_TRIGGER = $FF00 ; REU command trigger
OP_COPYFROM = $ED
OP_COPYTO = $EC
; ------------------------------------------------------------------------
; Data.
.bss
pagecount: .res 2 ; Number of pages available
curpage: .res 2 ; Current page number
window: .res 256 ; Memory "window"
reu_params: .word $0000 ; Host address, lo, hi
.word $0000 ; Exp address, lo, hi
.byte $00 ; Expansion bank no.
.word $0000 ; # bytes to move, lo, hi
.byte $00 ; Interrupt mask reg.
.byte $00 ; Adress control reg.
.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:
ldx #$00 ; High byte of return code
lda #$55
sta REU_REUADDR
cmp REU_REUADDR ; Check for presence of REU
bne nodevice
asl a ; A = $AA
sta REU_REUADDR
cmp REU_REUADDR ; Check for presence of REU
bne nodevice
ldy #>(128*4) ; Assume 128KB
lda REU_STATUS
and #$10 ; Check size bit
beq @L1
ldy #>(256*4) ; 256KB when size bit is set
@L1: sty pagecount+1
ldy #$FF
sty curpage
sty curpage+1 ; Invalidate the current page
txa ; X = A = EM_ERR_OK
rts
; No REU found
nodevice:
lda #EM_ERR_NO_DEVICE
; 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 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 ; Remember the new page
ldy #OP_COPYFROM
jsr common ; Copy the window
lda #<window
ldx #>window ; Return the window address
done: 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
rts
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: lda curpage
ldx curpage+1 ; Do we have a page mapped?
bmi done ; Jump if no page mapped
ldy #OP_COPYTO
common: sty tmp1
ldy #<window
sty REU_C64ADDR
ldy #>window
sty REU_C64ADDR+1
ldy #0
sty REU_REUADDR+0
sta REU_REUADDR+1
stx REU_REUADDR+2
sty REU_COUNT+0
ldy #1
sty REU_COUNT+1 ; Move 256 bytes
bne transfer1 ; Transfer 256 bytes into REU
; ------------------------------------------------------------------------
; 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:
ldy #OP_COPYFROM
.byte $2C
; ------------------------------------------------------------------------
; 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:
ldy #OP_COPYTO
sty tmp1
; Remember the passed pointer
sta ptr1
stx ptr1+1 ; Save the pointer
; The structure passed to the functions has the same layout as the registers
; of the Commodore REU, so register programming is easy.
ldy #7-1
@L1: lda (ptr1),y
sta REU_C64ADDR,y
dey
bpl @L1
; Invalidate the page in the memory window
sty curpage+1 ; Y = $FF
; Reload the REU command and start the transfer
transfer1:
ldy tmp1
; Transfer subroutine for the REU. Expects command in Y.
transfer:
sty REU_COMMAND ; Issue command
ldy $01 ; Save the value of the c64 control port...
tya ;
and #$F8 ; Disable ROMs and I/O.
sei ;
sta $01
lda REU_TRIGGER ; Don't change $FF00
sta REU_TRIGGER ; Start the transfer...
sty $01 ; Restore the old configuration
cli
rts

399
libsrc/c64/emd/c64-vdc.s Normal file
View File

@@ -0,0 +1,399 @@
;
; 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
;
; VDC test added by
; Marco van den Heuvel, 2010-01-22
;
.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
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:
ldx #0
ldy #0
lda #VDC_CSET ; determine size of RAM...
sta VDC_ADDR_REG
@L0: bit VDC_ADDR_REG
bmi @present
inx
bne @L0
iny
bne @L0
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
rts
@present:
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
; ------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; Can do cleanup or whatever. Must not return anything.
;
UNINSTALL:
;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
@L3: jsr vdcgetbyte
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
@L3: lda (ptr2),y
jsr vdcputbyte
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

245
libsrc/c64/emd/dtv-himem.s Normal file
View File

@@ -0,0 +1,245 @@
;
; Extended memory driver for the C64 D2TV (the second or PAL version).
; Driver works without problems when statically linked.
;
; Ullrich von Bassewitz, 2005-11-27
;
.include "zeropage.inc"
.include "em-kernel.inc"
.include "em-error.inc"
.import _get_ostype
.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
OP_COPYFROM = %00001101
OP_COPYTO = %00001111
START_BANK = 2 ; Start at $20000
PAGES = (2048 - 128) * 4
; ------------------------------------------------------------------------
; Data.
.bss
window: .res 256 ; Memory "window"
.data
; The MAP and COMMIT entries will actually call COPYFROM/COPYTO with
; a pointer to the following data structure:
dma_params: .word window ; Host address
.byte 0 ; Offset in page
curpage: .word $0000 ; Page
.word .sizeof (window); # bytes to move, lo, hi
.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:
; Check for a DTV
ldx #1
stx $d03f
ldx $d040
cpx $d000
bne @present
inc $d000
cpx $d040
beq @present
dec $d000
; DTV not found
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
rts
@present:
ldx #$FF
stx curpage+1 ; Invalidate curpage
inx ; X = 0
txa ; A/X = 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
ldx #>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
stx curpage+1 ; Remember the new page
lda #<dma_params
ldx #>dma_params
jsr COPYFROM ; Copy data into the window
lda #<window
ldx #>window ; Return the window address
done: 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
rts
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: lda curpage+1 ; Do we have a page mapped?
bmi done ; Jump if no page mapped
lda #<dma_params
ldx #>dma_params
; Run into COPYTO
; ------------------------------------------------------------------------
; 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 ptr1
stx ptr1+1 ; Save the pointer
ldx #OP_COPYTO ; Load the command
bne transfer
; ------------------------------------------------------------------------
; 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 ptr1
stx ptr1+1 ; Save the pointer
ldx #OP_COPYFROM
; DTV DMA transfer routine. Expects the command in X.
; NOTE: We're using knowledge about field order in the EM_COPY struct here!
transfer:
jsr WAIT ; Wait until DMA is finished
; Modulo disable
ldy #$00
sty $d31e
; Setup the target address and the source and target steps. Y contains zero,
; which is EM_COPY::BUF.
sty $d307 ; Source step high = 0
sty $d309 ; Dest step high = 0
lda (ptr1),y
sta $d303 ; Dest address low
iny ; Y = 1
sty $d306 ; Source step low = 1
sty $d308 ; Dest step low = 1
lda (ptr1),y
sta $d304
lda #$40 ; Dest is always RAM, start at $00000
sta $d305
; Setup the source address. Incrementing Y will make it point to EM_COPY::OFFS.
; We will allow page numbers higher than PAGES and map them to ROM. This will
; allow reading the ROM by specifying a page starting with PAGES.
iny ; EM_COPY::OFFS
lda (ptr1),y
sta $d300
iny ; EM_COPY::PAGE
lda (ptr1),y
sta $d301
iny
lda (ptr1),y
adc #START_BANK ; Carry clear here from WAIT
and #$3f
cmp #>PAGES+START_BANK ; Valid range?
bcs @L1 ; Jump if no
ora #$40 ; Address RAM
@L1: sta $d302
; Length
iny ; EM_COPY::COUNT
lda (ptr1),y
sta $d30a
iny
lda (ptr1),y
sta $d30b
; Start DMA
stx $d31f
; Wait until DMA is done
WAIT: lda $d31f
lsr a
bcs WAIT
rts