]> git.sur5r.net Git - cc65/commitdiff
Added the first EMD driver for the atari, written and contributed by Shawn
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 5 Sep 2012 11:25:28 +0000 (11:25 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 5 Sep 2012 11:25:28 +0000 (11:25 +0000)
Jefferson <sjefferson@shaw.ca>.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5816 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/atari/Makefile
libsrc/atari/atari-130xe.s [new file with mode: 0644]

index 068a244ba4b80e88d9ec278567aa7c2b24771161..b81b78abfa2134dbc2d712dd30b574f7fdc6516a 100644 (file)
@@ -126,7 +126,7 @@ OBJS =      _scrsize.o      \
 #--------------------------------------------------------------------------
 # Drivers
 
-EMDS =
+EMDS = atari-130xe.emd
 
 JOYS = atari-stdjoy.joy atari-multijoy.joy
 
diff --git a/libsrc/atari/atari-130xe.s b/libsrc/atari/atari-130xe.s
new file mode 100644 (file)
index 0000000..6951bd3
--- /dev/null
@@ -0,0 +1,483 @@
+;
+; Extended memory driver for the Atari 130XE memory standard
+; Shawn Jefferson, 2012-08-11
+;
+; Banking Register $D301:
+; Bit 7: Self-Test on/off
+; Bit 6: Unused
+; Bit 5: Antic sees bank
+; Bit 4: CPU sees bank
+; Bit 3: bank control
+; Bit 2: bank control
+; Bit 1: BASIC on/off
+; Bit 0: OS RAM on/off
+; 
+; Masks: %11100011  $E3     Bank 0
+;        %11100111  $E7     Bank 1
+;        %11101011  $EB     Bank 2
+;        %11101111  $EF     Bank 3
+;        %11111111  $FF     Off
+;
+; Based on the Extended memory driver for the Apple II auxiliary memory
+;  by
+; Stefan Haubenthal, 2003-12-12
+; 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   DEINSTALL
+       .word   PAGECOUNT
+       .word   MAP
+       .word   USE
+       .word   COMMIT
+       .word   COPYFROM
+       .word   COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BANK    = $4000                         ; bank window
+STACK   = $0100                         ; stack location 
+PAGES   = 256                           ; 4 x 16k banks
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+.rodata
+banks:          .byte $E3,$E7,$EB,$EF   ; 130XE banks for cpu banking
+
+stacktest:      sei
+               ldy banks
+               sty $D301
+               tax                     ; A is set by caller
+               inx
+               stx $4000               ; change $4000
+               ldy #$FF                ; STACK+13
+               sty $D301
+               cmp $4000               ; changed?
+               beq @1
+               sec                     ; error
+               bcs @2
+@1:             clc
+@2:             sta $4000               ; restore
+               cli
+               rts
+stacktest_end: 
+
+stackcopy:      sei                     ; disable interrupts
+@1:             dex                     ; pre-decrement (full page x=0)
+               ldy #$FF                ; this will be replaced  STACK+3
+               sty $D301               ; set bank 
+               lda $FF00,x             ; address to copy from   STACK+8,+9
+               ldy #$FF                ; this will be replaced  STACK+11
+               sty $D301 
+               sta $FF00,x             ; address to copy to     STACK+16,+17
+               cpx #0 
+               bne @1
+               ldy #$FF                ; portb_save             STACK+23
+               sty $D301
+               cli                     ; enable interrupts
+               rts
+stackcopy_end:
+
+stackcopy_byte: sei
+               ldy #$FF                ; STACK+2
+               sty $D301
+               lda $FFFF               ; STACK+7 +8
+               ldy #$FF                ; STACK+10
+               sty $D301
+               sta $FFFF               ; STACK+15 +16
+               ldy #$FF                ; STACK+18
+               sty $D301
+               cli
+               rts
+stackcopy_byte_end: 
+
+
+.data
+curpage:        .byte   $FF             ; Current page number in bank (invalid)
+curbank:        .byte   $FF             ; Current bank number
+
+.bss
+window:         .res    256             ; Memory "window"
+portb_save:     .res    1               ; portb state
+
+.code
+
+install_transfer:
+               ldx #stackcopy_end - stackcopy - 1
+@1:             lda stackcopy,x
+               sta STACK,x
+               dex
+               bpl @1
+               rts
+
+install_byte_transfer:
+               ldx #stackcopy_byte_end - stackcopy_byte - 1
+@2:             lda stackcopy_byte,x
+               sta STACK,x
+               dex
+               bpl @2
+               rts
+
+install_test:
+               ldx #stacktest_end - stacktest - 1
+@3:             lda stacktest,x
+               sta STACK,x
+               dex
+               bpl @3
+               rts
+
+setpage:
+               tax                             ; save page
+               and     #$C0                    ; mask out bank
+               clc
+               ror
+               ror                             ; divide by 64
+               ror                             ; 64 pages in each bank
+               ror
+               ror
+               ror
+               sta     curbank                 ; Remember the new bank
+               txa                             ; bring back page
+               and     #$3F                    ; mask out page
+               sta     curpage                 ; curpage in bank
+               rts
+
+
+; ------------------------------------------------------------------------
+; 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     $D301                   ; save state of portb
+       sta     portb_save
+       tay 
+
+       jsr     install_test            ; doesn't touch Y
+       sty     STACK+13
+
+       lda     $4000                   ; test for extended memory
+       jsr     STACK
+       bcs     @1 
+       lda     #EM_ERR_OK
+       rts
+@1:     lda     #EM_ERR_NO_DEVICE
+       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     #<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:    jsr setpage                     ; extract the bank/page
+       add     #>BANK                  ; $4000 + page  (carry is cleared)
+       sta     ptr1+1
+       ;ldy     #$00
+       ;sty     ptr1
+
+       lda     #<window
+       sta     ptr2
+       lda     #>window
+       sta     ptr2+1
+
+; Transfer one page
+
+       jsr     install_transfer        ; Transfer one page
+
+       ldx     curbank
+       lda     banks,x
+       sta     STACK+3                 ; set bank to copy from
+;        lda     ptr1
+;        sta     STACK+8 
+       lda     ptr1+1
+       sta     STACK+9                 ; set copy from address
+       lda     portb_save
+       sta     STACK+11                ; set portb restore
+       sta     STACK+23                ; set final portb restore
+       lda     ptr2
+       sta     STACK+16
+       lda     ptr2+1
+       sta     STACK+17                ; set copy to address 
+
+       ldx     #0                      ; full page copy
+       jsr     STACK                   ; do the copy! 
+
+; 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
+       jsr setpage                     ; extract bank/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
+       cmp     #$FF
+       beq     commit_done             ; Jump if no page mapped
+
+       clc
+       add     #>BANK
+       sta     ptr2+1
+       ;ldy     #$00
+       ;sty     ptr2
+
+       lda     #<window
+       sta     ptr1
+       lda     #>window
+       sta     ptr1+1
+
+; Transfer one page/all bytes
+
+       jsr     install_transfer        ; Transfer one page
+
+       lda     portb_save
+       sta     STACK+3                 ; set bank to copy from
+       sta     STACK+23                ; set final portb restore
+       lda     ptr1
+       sta     STACK+8 
+       lda     ptr1+1
+       sta     STACK+9                 ; set copy from address
+       ldx     curbank
+       lda     banks,x
+       sta     STACK+11                ; set bank to copy to
+       ;lda     ptr2
+       ;sta     STACK+16
+       lda     ptr2+1
+       sta     STACK+17                ; set copy to address 
+
+       ldx     #0                      ; full page copy
+       jsr     STACK                   ; do the copy! 
+
+commit_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
+
+       jsr     install_byte_transfer   ; install the stack copy routine
+
+       ldy     #EM_COPY::OFFS
+       lda     (ptr3),y
+       sta     STACK+7                 ; offset goes into BANK low 
+
+       ldy     #EM_COPY::PAGE
+       lda     (ptr3),y
+       sta     tmp1                    ; save page for later
+       ;add     #>BANK
+       ;sta     STACK+8                 ; BANK + page goes into BANK high
+
+       ldy     #EM_COPY::BUF
+       lda     (ptr3),y
+       sta     STACK+15                ; buffer goes into dest low
+       iny
+       lda     (ptr3),y
+       sta     STACK+16                ; buffer goes into dest high
+
+       ldy     #EM_COPY::COUNT
+       lda     (ptr3),y                ; Get bytes in last page
+       sta     ptr4
+       iny
+       lda     (ptr3),y                ; Get number of pages
+       sta     ptr4+1
+
+       lda     tmp1                    ; extract bank/page
+       jsr     setpage                 ; sets curbank/curpage
+       lda     curpage
+       add     #>BANK                  ; add to BANK address
+       sta     STACK+8                 ; current page in bank
+       ldx     curbank
+       lda     banks,x 
+       sta     STACK+2                 ; set bank in stack 
+       lda     portb_save 
+       sta     STACK+10                ; set bank restore in stack
+       sta     STACK+18                ; set final restore too
+
+copyfrom_copy:
+       lda     ptr4                    ; check if count is zero
+       bne     @4
+       lda     ptr4+1
+       beq     done
+
+@4:     jsr     STACK                   ; copy one byte
+
+       sec
+       lda     ptr4
+       sub     #1
+       sta     ptr4
+       bcs     @1
+       lda     ptr4+1
+       beq     @1
+       sub     #1
+       sta     ptr4+1
+
+@1:     inc     STACK+7                 ; increment address in BANK
+       bne     @2
+       inc     STACK+8
+       lda     STACK+8
+       cmp     #$80                    ; we stepped outside bank
+       bne     @2
+
+       inc     curbank                 ; get next bank
+       ldx     curbank
+       lda     banks,x
+       sta     STACK+2                 ; set new bank
+       lda     #$40                    ; set address back to $4000
+       sta     STACK+8
+
+@2:     inc     STACK+15                ; increment buffer address
+       bne     @3
+       inc     STACK+16
+
+@3:     jmp     copyfrom_copy           ; copy another byte 
+
+done:
+       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
+
+       jsr     install_byte_transfer   ; install the stack copy routine
+
+       ldy     #EM_COPY::OFFS
+       lda     (ptr3),y
+       sta     STACK+15                 ; offset goes into BANK low 
+
+       ldy     #EM_COPY::PAGE
+       lda     (ptr3),y
+       sta     tmp1                    ; save page for later
+       ;add     #>BANK
+       ;sta     STACK+16                ; BANK + page goes into BANK high
+
+       ldy     #EM_COPY::BUF
+       lda     (ptr3),y
+       sta     STACK+7                ; buffer goes into dest low
+       iny
+       lda     (ptr3),y
+       sta     STACK+8                ; buffer goes into dest high
+
+       ldy     #EM_COPY::COUNT
+       lda     (ptr3),y                ; Get bytes in last page
+       sta     ptr4
+       iny
+       lda     (ptr3),y                ; Get number of pages
+       sta     ptr4+1
+
+       lda     tmp1                    ; extract bank/page
+       jsr     setpage                 ; sets curbank/curpage
+       lda     curpage
+       add     #>BANK                  ; add to BANK address
+       sta     STACK+16                ; current page in bank
+       ldx     curbank
+       lda     banks,x 
+       sta     STACK+10                ; set bank in stack 
+       lda     portb_save 
+       sta     STACK+2                 ; set bank restore in stack
+       sta     STACK+18                ; set final restore too
+
+copyto_copy:
+       lda     ptr4                    ; check if count is zero
+       bne     @4
+       lda     ptr4+1
+       beq     done
+
+@4:     jsr     STACK                   ; copy one byte
+
+       sec
+       lda     ptr4
+       sub     #1
+       sta     ptr4
+       bcs     @1
+       lda     ptr4+1
+       beq     @1
+       sub     #1
+       sta     ptr4+1
+
+@1:     inc     STACK+15               ; increment address in BANK
+       bne     @2
+       inc     STACK+16
+       lda     STACK+16
+       cmp     #$80                    ; we stepped outside bank
+       bne     @2
+
+       inc     curbank                 ; get next bank
+       ldx     curbank
+       lda     banks,x
+       sta     STACK+10                ; set new bank
+       lda     #$40                    ; set address back to $4000
+       sta     STACK+16
+
+@2:     inc     STACK+7                ; increment buffer address
+       bne     @3
+       inc     STACK+8
+
+@3:     jmp     copyto_copy           ; copy another byte 
+