From 2533cc8d751400daea6cfd4b694b2c5a76cd6cd7 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel Date: Mon, 19 Mar 2018 11:34:41 -0700 Subject: [PATCH] Added the vic20 georam emd. --- doc/vic20.sgml | 6 + include/vic20.h | 1 + libsrc/vic20/emd/vic20-georam.s | 352 ++++++++++++++++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100755 libsrc/vic20/emd/vic20-georam.s diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 13f2a5cc8..1a8f9dfef 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -153,6 +153,12 @@ No graphics drivers are currently available for the VIC20. A driver for any RAM at $A000-$BFFF. Supports 32 256 byte pages. Written and contributed by Marco van den Heuvel. + + A driver for the Berkeley Softworks GeoRam cartridge connected by means of + the MasC=erade c64 cartridge adapter. The driver will determine the + available RAM from the connected cartridge. It supports 64KB + up to 2048KB of RAM. +

diff --git a/include/vic20.h b/include/vic20.h index 1e8c4ceb5..44512b3fd 100644 --- a/include/vic20.h +++ b/include/vic20.h @@ -106,6 +106,7 @@ extern void vic20_ptvjoy_joy[]; extern void vic20_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void vic20_rama_emd[]; +extern void vic20_georam_emd[]; /* End of vic20.h */ #endif diff --git a/libsrc/vic20/emd/vic20-georam.s b/libsrc/vic20/emd/vic20-georam.s new file mode 100755 index 000000000..a960e9a1a --- /dev/null +++ b/libsrc/vic20/emd/vic20-georam.s @@ -0,0 +1,352 @@ +; +; Extended memory driver for the GEORAM cartridge through the masC=erade +; c64 cartridge adapter. Driver works without problems when statically +; linked. +; +; Marco van den Heuvel, 2018-03-18 +; + + .include "zeropage.inc" + + .include "em-kernel.inc" + .include "em-error.inc" + + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _vic20_georam_emd + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr PAGECOUNT + .addr MAP + .addr USE + .addr COMMIT + .addr COPYFROM + .addr COPYTO + +; ------------------------------------------------------------------------ +; Constants + +GR_WINDOW = $9800 ; Address of GEORAM window +GR_PAGE_LO = $9CFE ; Page register low +GR_PAGE_HI = $9CFF ; 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 + rts + +@setok: + lda #0 + sta pagecount + stx pagecount+1 + lda #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 + +; 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 + + -- 2.39.5