diff --git a/libsrc/c64/.cvsignore b/libsrc/c64/.cvsignore index a19e3c8e1..b3753bbb6 100644 --- a/libsrc/c64/.cvsignore +++ b/libsrc/c64/.cvsignore @@ -1 +1,2 @@ +*.emd *.tgi diff --git a/libsrc/c64/Makefile b/libsrc/c64/Makefile index 10cd36fc2..cecd10859 100644 --- a/libsrc/c64/Makefile +++ b/libsrc/c64/Makefile @@ -11,6 +11,9 @@ %.o: %.s @$(AS) -g -o $@ $(AFLAGS) $< +%.emd: %.o ../runtime/zeropage.o + @$(LD) -t module -o $@ $^ + %.tgi: %.o ../runtime/zeropage.o @$(LD) -t module -o $@ $^ @@ -32,16 +35,17 @@ OBJS = _scrsize.o \ TGIS = c64-320-200-2.tgi +EMDS = c64-georam.emd #-------------------------------------------------------------------------- # Targets -all: $(OBJS) $(TGIS) +all: $(OBJS) $(EMDS) $(TGIS) ../runtime/zeropage.o: $(MAKE) -C $(dir $@) $(notdir $@) clean: - @rm -f $(OBJS) $(TGIS:.tgi=.o) + @rm -f $(OBJS) $(EMDS:.emd=.o) $(TGIS:.tgi=.o) diff --git a/libsrc/c64/c64-georam.s b/libsrc/c64/c64-georam.s new file mode 100644 index 000000000..288850acc --- /dev/null +++ b/libsrc/c64/c64-georam.s @@ -0,0 +1,266 @@ +; +; Extended memory driver for the GEORAM cartridge +; +; 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 $00 ; EM API version number + +; Jump table. + + .word INSTALL + .word DEINSTALL + .word PAGECOUNT + .word MAP + .word MAPCLEAN + .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: .word 2048 ; Currently fixed + +.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 #EM_ERR_OK + rts + +; ------------------------------------------------------------------------ +; DEINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +DEINSTALL: + 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) are assumed to be +; dirty and must be saved into secondary storage if this is necessary. +; + +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 + rts + +; ------------------------------------------------------------------------ +; MAPCLEAN: 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) are assumed to +; be clean, so if this is an advantage for the driver, the current contents +; may be discarded. + +MAPCLEAN = MAP ; Identical for GEORAM + + +; ------------------------------------------------------------------------ +; 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 + +