An extended memory driver for the RAM in page 1. The common memory area is
excluded, so this driver supports 251 pages of 256 bytes each.
+ <tag><tt/c128-ram2.emd/</tag>
+
+ An extended memory driver for the RAM in pages 1-3. The common memory area
+ is excluded, so this driver supports up to 731 pages of 256 bytes each. The
+ driver can be used as a full replacement for <tt/c128-ram.emd/, because RAM
+ in pages 2+3 is autodetected, but it's larger and there are not many
+ machines with RAM in banks 2+3, so it has been made a separate driver. The
+ additional code was contributed by Marco van den Heuvel.
+
<tag><tt/c128-ramcart.emd/</tag>
A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak.
Will test the hardware for the available RAM.
#--------------------------------------------------------------------------
# Drivers
-EMDS = c128-georam.emd c128-ram.emd c128-ramcart.emd c128-reu.emd c128-vdc.emd
+EMDS = c128-georam.emd \
+ c128-ram.emd \
+ c128-ram2.emd \
+ c128-ramcart.emd \
+ c128-reu.emd \
+ c128-vdc.emd
-JOYS = c128-ptvjoy.joy c128-stdjoy.joy
+JOYS = c128-ptvjoy.joy \
+ c128-stdjoy.joy
-MOUS = c128-1351.mou c128-joymouse.mou c128-potmouse.mou
+MOUS = c128-1351.mou \
+ c128-joymouse.mou \
+ c128-potmouse.mou
-SERS = c128-swlink.ser
+SERS = c128-swlink.ser
-TGIS = c128-640-200-2.tgi c128-640-480-2.tgi
+TGIS = c128-640-200-2.tgi \
+ c128-640-480-2.tgi
#--------------------------------------------------------------------------
# Targets
;
-; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
+; Extended memory driver for the C128 RAM in bank #1. Driver works without
; problems when statically linked.
;
; Ullrich von Bassewitz, 2002-12-04
-;
-; Updated to use banks 2 and 3 as well by
-; Marco van den Heuvel, 2010-01-21
;
.include "zeropage.inc"
; Constants
BASE = $400
+TOPMEM = $FF00
+PAGES = (TOPMEM - BASE) / 256
; ------------------------------------------------------------------------
; Data.
.bss
-curpage: .res 2 ; Current page number
-curbank: .res 1 ; Current bank number
-copybank: .res 2 ; temp bank number
+curpage: .res 1 ; Current page number
window: .res 256 ; Memory "window"
-pagecount: .res 2 ; Number of available pages
-
.code
; ------------------------------------------------------------------------
;
INSTALL:
- ldx #0
- stx ptr1
- ldx #4
- stx ptr1+1
- ldx #<ptr1
- stx FETVEC
- stx STAVEC
- ldy #0
- ldx #MMU_CFG_RAM1
- jsr FETCH
- sta tmp1
- ldx #MMU_CFG_RAM3
- jsr FETCH
- cmp tmp1
- bne @has_4_banks
- tax
- inx
- txa
- ldx #MMU_CFG_RAM1
- jsr STASH
- ldx #MMU_CFG_RAM3
- jsr FETCH
- cmp tmp1
- beq @has_4_banks
- ldx #0
- lda #251
- bne @setok
-
-@has_4_banks:
- ldx #2
- lda #241
-@setok:
- sta pagecount
- stx pagecount+1
ldx #$FF
stx curpage
- stx curpage+1 ; Invalidate the current page
- inx
- txa ; A = X = EM_ERR_OK
-; rts ; Run into UNINSTALL instead
+ stx curpage+1 ; Invalidate the current page
+ inx
+ txa ; A = X = EM_ERR_OK
+ rts
; ------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
;
PAGECOUNT:
- lda pagecount
- ldx pagecount+1
+ lda #<PAGES
+ ldx #>PAGES
rts
; ------------------------------------------------------------------------
; by the driver.
;
-MAP: sei
- sta curpage
+MAP: sta curpage
stx curpage+1 ; Remember the new page
- jsr calculate_bank_and_correct_page
- stx curbank
-
clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
lda #<ptr1
sta FETVEC
; Transfer one page
-@L1: ldx curbank
- jsr getcurbankmmu
+@L1: ldx #MMU_CFG_RAM1
jsr FETCH
sta window,y
iny
lda #<window
ldx #>window ; Return the window address
- cli
rts
; ------------------------------------------------------------------------
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
-COMMIT: sei
- lda curpage ; Get the current page
+COMMIT: lda curpage ; Get the current page
ldx curpage+1
bmi done ; Jump if no page mapped
- jsr calculate_bank_and_correct_page
- stx curbank
-
clc
adc #>BASE
sta ptr1+1
ldy #$00
- sty ptr1
+ sty ptr1
lda #<ptr1
sta STAVEC
; Transfer one page. Y must be zero on entry
@L1: lda window,y
- ldx curbank
- jsr getcurbankmmu
+ ldx #MMU_CFG_RAM1
jsr STASH
iny
bne @L1
- cli
; Done
;
COPYFROM:
- sei
- jsr setup
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page buffer and offset
-; - tmp1 contains the bank
-; - tmp2 contains zero (used for linear memory buffer offset)
-
- lda #<ptr4
+ 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
+
+ lda #<ptr1
sta FETVEC
- jmp @L3
-@L1: ldx tmp1
- jsr getcurbankmmu
- ldy #0
- jsr FETCH
- ldy tmp2
- sta (ptr2),y
- inc tmp2
- bne @L2
- inc ptr2+1
-@L2: inc ptr4
- beq @L4
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ beq @L2 ; Skip if no full pages
+ sta tmp1
-; Bump count and repeat
+; Copy full pages
-@L3: inc ptr3
+ ldy #$00
+@L1: ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta (ptr2),y
+ iny
bne @L1
- inc ptr3+1
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
bne @L1
- cli
- rts
-; Bump page register
+; Copy the remainder of the page
-@L4: inc ptr4+1
- lda ptr4+1
- cmp #$ff
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+ ldy #$00
+@L3: ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta (ptr2),y
+ iny
+ dec tmp1
bne @L3
- lda #4
- sta ptr4+1
- inc tmp1
-@L5:
- jmp @L3
+; Done
+
+@L4: rts
; ------------------------------------------------------------------------
; COPYTO: Copy from linear into extended memory. A pointer to a structure
; The function must not return anything.
;
-COPYTO:
- sei
- jsr setup
+COPYTO: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page buffer and offset
-; - tmp1 contains the bank
-; - tmp2 contains zero (used for linear memory buffer offset)
-
- lda #<ptr4
- sta STAVEC
- jmp @L3
-
-@L1:
- ldy tmp2
- lda (ptr2),y
- ldx tmp1
- jsr getcurbankmmu
- ldy #0
- jsr STASH
- inc tmp2
- bne @L2
- inc ptr2+1
-@L2: inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- cli
- rts
-
-; Bump page register
-
-@L4: inc ptr4+1
- lda ptr4+1
- cmp #$ff
- bne @L3
- inc tmp1
- lda #4
- sta ptr4+1
-@L5:
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function to calculate the correct bank and page
-; when addressing bank 2 or 3
-
-calculate_bank_and_correct_page:
- cpx #2
- beq @calculate_bank_3_with_2
- cpx #1
- beq @calculate_bank_2_or_3_with_1
- sec
- sbc #251
- bcs @calculate_bank_2_with_0
- ldx #1
- lda curpage
- rts
-
-@calculate_bank_3_with_2:
- lda curpage
- clc
- adc #10
-@calculate_bank_3_with_1:
- ldx #3
- rts
-
-@calculate_bank_2_or_3_with_1:
- sec
- sbc #246
- bcs @calculate_bank_3_with_1
- lda curpage
- clc
- adc #5
-@calculate_bank_2_with_0:
- ldx #2
- rts
-
-; ------------------------------------------------------------------------
-; Helper function to get the correct mmu value in x
-
-getcurbankmmu:
- cpx #1
- beq @bank1
- cpx #2
- beq @bank2
- ldx #MMU_CFG_RAM3
- rts
-@bank2:
- ldx #MMU_CFG_RAM2
- rts
-@bank1:
- ldx #MMU_CFG_RAM1
- rts
-
-; ------------------------------------------------------------------------
-; 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: page pointer in ptr4 and bank in tmp1
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- tax
- dey
- lda (ptr1),y
- sta curpage
- jsr calculate_bank_and_correct_page
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
clc
- adc #4
- sta ptr4+1
- stx tmp1
-
-; Get the buffer pointer into ptr2
+ adc #>BASE
+ sta ptr1+1 ; To
ldy #EM_COPY::BUF
- lda (ptr1),y
+ lda (ptr3),y
sta ptr2
iny
- lda (ptr1),y
- sta ptr2+1
+ lda (ptr3),y
+ sta ptr2+1 ; From
-; Get the count, calculate -(count-1) and store it into ptr3
+ lda #<ptr1
+ sta STAVEC
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ beq @L2 ; Skip if no full pages
+ sta tmp1
+
+; Copy full pages
+
+ ldy #$00
+@L1: lda (ptr2),y
+ ldx #MMU_CFG_RAM1
+ jsr STASH
iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
+ bne @L1
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
-; Get the page offset into the low byte of ptr4 clear tmp2
+; Copy the remainder of the page
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- sta ptr4
- lda #0
- sta tmp2
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+ ldy #$00
+@L3: lda (ptr2),y
+ ldx #MMU_CFG_RAM1
+ jsr STASH
+ iny
+ dec tmp1
+ bne @L3
; Done
- rts
+@L4: rts
+
--- /dev/null
+;
+; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-12-04
+;
+; Updated to use banks 2 and 3 as well by
+; Marco van den Heuvel, 2010-01-21
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "c128.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 = $400
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage: .res 2 ; Current page number
+curbank: .res 1 ; Current bank number
+copybank: .res 2 ; temp bank number
+
+window: .res 256 ; Memory "window"
+
+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 #0
+ stx ptr1
+ ldx #4
+ stx ptr1+1
+ ldx #<ptr1
+ stx FETVEC
+ stx STAVEC
+ ldy #0
+ ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta tmp1
+ ldx #MMU_CFG_RAM3
+ jsr FETCH
+ cmp tmp1
+ bne @has_4_banks
+ tax
+ inx
+ txa
+ ldx #MMU_CFG_RAM1
+ jsr STASH
+ ldx #MMU_CFG_RAM3
+ jsr FETCH
+ cmp tmp1
+ beq @has_4_banks
+ ldx #0
+ lda #251
+ bne @setok
+
+@has_4_banks:
+ ldx #2
+ lda #241
+@setok:
+ sta pagecount
+ stx pagecount+1
+ ldx #$FF
+ stx curpage
+ stx curpage+1 ; Invalidate the current page
+ inx
+ 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 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: sei
+ sta curpage
+ stx curpage+1 ; Remember the new page
+
+ jsr calculate_bank_and_correct_page
+ stx curbank
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+ lda #<ptr1
+ sta FETVEC
+
+; Transfer one page
+
+@L1: ldx curbank
+ jsr getcurbankmmu
+ jsr FETCH
+ sta window,y
+ iny
+ bne @L1
+
+; Return the memory window
+
+ 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
+ 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: sei
+ lda curpage ; Get the current page
+ ldx curpage+1
+ bmi done ; Jump if no page mapped
+
+ jsr calculate_bank_and_correct_page
+ stx curbank
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<ptr1
+ sta STAVEC
+
+; Transfer one page. Y must be zero on entry
+
+@L1: lda window,y
+ ldx curbank
+ jsr getcurbankmmu
+ jsr STASH
+ iny
+ bne @L1
+ 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:
+ sei
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page buffer and offset
+; - tmp1 contains the bank
+; - tmp2 contains zero (used for linear memory buffer offset)
+
+ lda #<ptr4
+ sta FETVEC
+ jmp @L3
+
+@L1: ldx tmp1
+ jsr getcurbankmmu
+ ldy #0
+ jsr FETCH
+ ldy tmp2
+ sta (ptr2),y
+ inc tmp2
+ bne @L2
+ inc ptr2+1
+@L2: inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ cli
+ rts
+
+; Bump page register
+
+@L4: inc ptr4+1
+ lda ptr4+1
+ cmp #$ff
+ bne @L3
+ lda #4
+ sta ptr4+1
+ inc tmp1
+@L5:
+ 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
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page buffer and offset
+; - tmp1 contains the bank
+; - tmp2 contains zero (used for linear memory buffer offset)
+
+ lda #<ptr4
+ sta STAVEC
+ jmp @L3
+
+@L1:
+ ldy tmp2
+ lda (ptr2),y
+ ldx tmp1
+ jsr getcurbankmmu
+ ldy #0
+ jsr STASH
+ inc tmp2
+ bne @L2
+ inc ptr2+1
+@L2: inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ cli
+ rts
+
+; Bump page register
+
+@L4: inc ptr4+1
+ lda ptr4+1
+ cmp #$ff
+ bne @L3
+ inc tmp1
+ lda #4
+ sta ptr4+1
+@L5:
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function to calculate the correct bank and page
+; when addressing bank 2 or 3
+
+calculate_bank_and_correct_page:
+ cpx #2
+ beq @calculate_bank_3_with_2
+ cpx #1
+ beq @calculate_bank_2_or_3_with_1
+ sec
+ sbc #251
+ bcs @calculate_bank_2_with_0
+ ldx #1
+ lda curpage
+ rts
+
+@calculate_bank_3_with_2:
+ lda curpage
+ clc
+ adc #10
+@calculate_bank_3_with_1:
+ ldx #3
+ rts
+
+@calculate_bank_2_or_3_with_1:
+ sec
+ sbc #246
+ bcs @calculate_bank_3_with_1
+ lda curpage
+ clc
+ adc #5
+@calculate_bank_2_with_0:
+ ldx #2
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function to get the correct mmu value in x
+
+getcurbankmmu:
+ cpx #1
+ beq @bank1
+ cpx #2
+ beq @bank2
+ ldx #MMU_CFG_RAM3
+ rts
+@bank2:
+ ldx #MMU_CFG_RAM2
+ rts
+@bank1:
+ ldx #MMU_CFG_RAM1
+ rts
+
+; ------------------------------------------------------------------------
+; 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: page pointer in ptr4 and bank in tmp1
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ tax
+ dey
+ lda (ptr1),y
+ sta curpage
+ jsr calculate_bank_and_correct_page
+ clc
+ adc #4
+ sta ptr4+1
+ stx 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 the low byte of ptr4 clear tmp2
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ sta ptr4
+ lda #0
+ sta tmp2
+
+; Done
+
+ rts