%.joy: %.o ../runtime/zeropage.o
@$(LD) -t module -o $@ $^
+%.ser: %.o ../runtime/zeropage.o
+ @$(LD) -t module -o $@ $^
+
%.tgi: %.o ../runtime/zeropage.o
@$(LD) -t module -o $@ $^
#--------------------------------------------------------------------------
# Drivers
-EMDS =
+EMDS = c16-ram.emd
JOYS = c16-stdjoy.joy
+SERS =
+
TGIS =
#--------------------------------------------------------------------------
.PHONY: all clean zap
-all: $(OBJS) $(EMDS) $(JOYS) $(TGIS)
+all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
../runtime/zeropage.o:
$(MAKE) -C $(dir $@) $(notdir $@)
clean:
- @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(TGIS:.tgi=.o)
+ @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o)
zap: clean
- @$(RM) $(EMDS) $(JOYS) $(TGIS)
+ @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
--- /dev/null
+;
+; Extended memory driver for the C16 hidden RAM. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2003-12-15
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "../plus4/plus4.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 UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $8000
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+pages: .res 1 ; Number of pages
+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:
+
+; Determine how much memory is available. We will use all memory above
+; $8000 up to MEMTOP
+
+ sec
+ jsr $FF99 ; MEMTOP: Get top memory into Y/X
+ tya
+ sub #>BASE ; Low 32 K are used
+ bcc nomem
+ beq nomem ; Offering zero pages is a bad idea
+ sta pages
+
+ ldx #$FF
+ stx curpage ; Invalidate the current page
+ inx ; X = 0
+ txa ; A = X = EM_ERR_OK
+ rts
+
+nomem: ldx #>EM_ERR_NO_DEVICE
+ lda #<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 pages
+ ldx #$00 ; 128 pages max
+ 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
+
+ add #>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
+
+ add #>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. Because we bank out the
+; kernal, we will run the routine with interrupts disabled but leave
+; short breath times. Unroll the following loop to make it somewhat faster.
+
+transfer:
+ sei
+ sta ENABLE_RAM
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+
+ sta ENABLE_ROM
+ cli
+
+ bne transfer
+
+; 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
+ add #>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
+
+ sei ; Disable ints
+ sta ENABLE_RAM ; Bank out the ROM
+
+; 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
+
+ sta ENABLE_ROM
+ 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
+ add #>BASE
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY_BUF
+ lda (ptr3),y
+ sta ptr1
+ iny
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ jmp common
+
+