]> git.sur5r.net Git - cc65/commitdiff
blackystardust pull request with post-review changes
authorPatrycjusz R. Łogiewa <patrycjusz.logiewa@srebrnysen.com>
Fri, 26 Feb 2016 22:51:37 +0000 (23:51 +0100)
committerPatrycjusz R. Łogiewa <patrycjusz.logiewa@srebrnysen.com>
Fri, 26 Feb 2016 22:51:37 +0000 (23:51 +0100)
libsrc/c64/emd/c64-65816.s [new file with mode: 0644]
testcode/lib/em-test.c

diff --git a/libsrc/c64/emd/c64-65816.s b/libsrc/c64/emd/c64-65816.s
new file mode 100644 (file)
index 0000000..bf44a0e
--- /dev/null
@@ -0,0 +1,376 @@
+;\r
+; Extended memory driver for 65816 based extra RAM. Driver works without\r
+; problems when statically linked.\r
+;\r
+; Marco van den Heuvel, 2015-12-01\r
+;\r
+\r
+        .include        "zeropage.inc"\r
+\r
+        .include        "em-kernel.inc"\r
+        .include        "em-error.inc"\r
+\r
+\r
+        .macpack        generic\r
+        .macpack        module\r
+\r
+\r
+; ------------------------------------------------------------------------\r
+; Header. Includes jump table\r
+\r
+        module_header   _c64_65816_emd\r
+\r
+; Driver signature\r
+\r
+        .byte   $65, $6d, $64           ; "emd"\r
+        .byte   EMD_API_VERSION         ; EM API version number\r
+\r
+; Library reference\r
+\r
+        .addr   $0000\r
+\r
+; Jump table\r
+\r
+        .addr   INSTALL\r
+        .addr   UNINSTALL\r
+        .addr   PAGECOUNT\r
+        .addr   MAP\r
+        .addr   USE\r
+        .addr   COMMIT\r
+        .addr   COPYFROM\r
+        .addr   COPYTO\r
+\r
+; ------------------------------------------------------------------------\r
+; Data.\r
+\r
+.bss\r
+isnotscpu:      .res    1               ; SuperCPU not present\r
+curpage:        .res    1               ; Current page number\r
+curbank:        .res    1               ; Current bank number (+1)\r
+bankcount:      .res    1               ; Number of available banks (pages = banks * 256)\r
+window:         .res    256             ; Memory "window"\r
+\r
+.code\r
+\r
+; ------------------------------------------------------------------------\r
+; INSTALL routine. Is called after the driver is loaded into memory. If\r
+; possible, check if the hardware is present and determine the amount of\r
+; memory available.\r
+; Must return an EM_ERR_xx code in a/x.\r
+;\r
+\r
+INSTALL:\r
+        sei\r
+        clc\r
+        sed\r
+        lda     #$99\r
+        adc     #$01                    ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly\r
+        cld\r
+        bne     @not_present\r
+        clc\r
+.P816\r
+        sep     #$01                    ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02\r
+.P02\r
+        bcc     @not_present\r
+        lda     $d0bc\r
+        and     #$80\r
+        sta     isnotscpu\r
+        lda     $07e8\r
+        pha                             ; save value incase it was used somewhere else\r
+        ldx     #$ff\r
+@fillloop:                              ; fill from top (bank 255) to bottom\r
+        txa\r
+        pha\r
+.P816\r
+        plb                             ; pull dbr\r
+.P02\r
+        stx     $07e8\r
+        dex\r
+        cpx     #$ff\r
+        bne     @fillloop\r
+        inx\r
+@compareloop:                           ; check from bottom to top\r
+        txa\r
+        pha\r
+.P816\r
+        plb\r
+.P02\r
+        cmp     $07e8\r
+        bne     @found_pages\r
+.P816\r
+        inc\r
+.P02\r
+        sta     $07e8\r
+        cmp     $07e8\r
+        bne     @found_pages\r
+        inx\r
+        bne     @compareloop\r
+@found_pages:\r
+        dex\r
+        lda     #$00\r
+        pha\r
+.P816\r
+        plb\r
+.P02\r
+        pla\r
+        sta     $07e8\r
+        cli\r
+        lda     isnotscpu\r
+        bne     @noextradex\r
+        dex\r
+@noextradex:\r
+        stx     bankcount\r
+        lda     #<EM_ERR_OK\r
+        ldx     #>EM_ERR_OK\r
+        rts\r
+@not_present:\r
+        cli\r
+        lda     #<EM_ERR_NO_DEVICE\r
+        ldx     #>EM_ERR_NO_DEVICE\r
+;       rts                             ; Run into UNINSTALL instead\r
+\r
+\r
+; ------------------------------------------------------------------------\r
+; UNINSTALL routine. Is called before the driver is removed from memory.\r
+; Can do cleanup or whatever. Must not return anything.\r
+;\r
+\r
+UNINSTALL:\r
+        rts\r
+\r
+\r
+; ------------------------------------------------------------------------\r
+; PAGECOUNT: Return the total number of available pages in a/x.\r
+;\r
+\r
+PAGECOUNT:\r
+        lda     #$00                   ; a whole bank is either usable or not\r
+        ldx     bankcount\r
+        rts\r
+\r
+; ------------------------------------------------------------------------\r
+; MAP: Map the page in a/x into memory and return a pointer to the page in\r
+; a/x. The contents of the currently mapped page (if any) may be discarded\r
+; by the driver.\r
+;\r
+\r
+MAP:    sta     curpage                 ; Remember the new page\r
+        stx     curbank                 ; Remember the new bank\r
+\r
+        sta     ptr2+1                  ; src address low\r
+        lda     #$00\r
+        sta     ptr2                    ; src address high\r
+        inx\r
+        ldy     isnotscpu               ; check if not scpu\r
+        bne     @notscpu\r
+        inx\r
+@notscpu:\r
+        stx     tmp2                    ; src bank\r
+\r
+        sta     tmp1                    ; dst bank\r
+\r
+        sta     ptr3+1                  ; length high\r
+        lda     #$ff\r
+        sta     ptr3                    ; length low\r
+\r
+        lda     #<window\r
+        sta     ptr1                    ; dst address low\r
+        ldx     #>window\r
+        stx     ptr1+1                  ; dst address high\r
+\r
+        jsr     transfer\r
+\r
+        rts\r
+\r
+; ------------------------------------------------------------------------\r
+; USE: Tell the driver that the window is now associated with a given page.\r
+\r
+USE:    sta     curpage                 ; Remember the page\r
+        stx     curbank                 ; Remember the bank\r
+        lda     #<window\r
+        ldx     #>window                ; Return the window\r
+        rts\r
+\r
+; ------------------------------------------------------------------------\r
+; COMMIT: Commit changes in the memory window to extended storage.\r
+\r
+COMMIT: lda     curpage                 ; Get the current page\r
+        sta     ptr1+1                  ; dst high\r
+        ldx     #$00\r
+        stx     ptr1                    ; dst low\r
+\r
+        lda     #<window\r
+        sta     ptr2                    ; src low\r
+        lda     #>window\r
+        sta     ptr2+1                  ; src high\r
+\r
+        stx     ptr3+1                  ; length high\r
+        lda     #$ff\r
+        sta     ptr3                    ; length low\r
+\r
+        stx     tmp2                    ; src bank\r
+        ldy     curbank                 ; Get the current bank\r
+        iny\r
+        ldx     isnotscpu\r
+        bne     @notascpu\r
+        iny\r
+@notascpu:\r
+        sty     tmp1                    ; dst bank\r
+\r
+        jsr     transfer\r
+\r
+        rts\r
+\r
+; ------------------------------------------------------------------------\r
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure\r
+; describing the request is passed in a/x.\r
+; The function must not return anything.\r
+;\r
+\r
+COPYFROM:\r
+        sta     ptr4\r
+        stx     ptr4+1                  ; Save the passed em_copy pointer\r
+\r
+        ldy     #EM_COPY::COUNT+1       ; start at the end of the struct\r
+        lda     (ptr4),y                ; get high byte of count\r
+        tax\r
+        dey\r
+        lda     (ptr4),y                ; get low byte of count\r
+        bne     @nodex\r
+        dex\r
+@nodex:\r
+.P816\r
+        dec\r
+.P02\r
+        sta     ptr3                    ; length low\r
+        stx     ptr3+1                  ; length high\r
+        dey\r
+        lda     (ptr4),y                ; get bank\r
+.P816\r
+        inc\r
+.P02\r
+        ldx     isnotscpu\r
+        bne     @notscpu64\r
+.P816\r
+        inc\r
+.P02\r
+@notscpu64:\r
+        sta     tmp2                    ; src bank\r
+        dey\r
+        lda     (ptr4),y                ; get page\r
+        sta     ptr2+1                  ; src high\r
+        dey\r
+        lda     (ptr4),y                ; get offset in page\r
+        sta     ptr2                    ; src low\r
+        dey\r
+        lda     (ptr4),y                ; get memory buffer high\r
+        sta     ptr1+1                  ; dst high\r
+        dey\r
+        lda     (ptr4),y                ; get memory buffer low\r
+        sta     ptr1                    ; dst low\r
+        lda     #$00\r
+        sta     tmp1                    ; dst bank\r
+\r
+        jsr     transfer\r
+\r
+        rts\r
+\r
+; ------------------------------------------------------------------------\r
+; COPYTO: Copy from linear into extended memory. A pointer to a structure\r
+; describing the request is passed in a/x.\r
+; The function must not return anything.\r
+;\r
+\r
+COPYTO: sta     ptr4\r
+        stx     ptr4+1                  ; Save the passed em_copy pointer\r
+\r
+        ldy     #EM_COPY::COUNT+1       ; start at the end of the struct\r
+        lda     (ptr4),y                ; get high byte of count\r
+        tax\r
+        dey\r
+        lda     (ptr4),y                ; get low byte of count\r
+        bne     @nodex2\r
+        dex\r
+@nodex2:\r
+.P816\r
+        dec\r
+.P02\r
+        sta     ptr3                    ; length low\r
+        txa\r
+        sta     ptr3+1                  ; length high\r
+        dey\r
+        lda     (ptr4),y                ; get bank\r
+.P816\r
+        inc\r
+.P02\r
+        ldx     isnotscpu\r
+        bne     @notascpu64\r
+.P816\r
+        inc\r
+.P02\r
+@notascpu64:\r
+        sta     tmp1                    ; dst bank\r
+        dey\r
+        lda     (ptr4),y                ; get page\r
+        sta     ptr1+1                  ; dst high\r
+        dey\r
+        lda     (ptr4),y                ; get page offset\r
+        sta     ptr1                    ; dst low\r
+        dey\r
+        lda     (ptr4),y                ; get memory buffer high\r
+        sta     ptr2+1                  ; src low\r
+        dey\r
+        lda     (ptr4),y                ; get memory buffer low\r
+        sta     ptr2                    ; src high\r
+        lda     #$00\r
+        sta     tmp2                    ; src bank\r
+\r
+        jsr     transfer\r
+\r
+        rts\r
+\r
+; ------------------------------------------------------------------------\r
+; Helper function for moving a block, the following is used:\r
+; ptr1: dst\r
+; ptr2: src\r
+; ptr3: length\r
+; tmp1: dst bank\r
+; tmp2: src bank\r
+\r
+transfer:\r
+.P816\r
+.A8\r
+.I8\r
+        sei\r
+        pha\r
+        phx\r
+        phy\r
+        ldx     tmp1                    ; load srcbank\r
+        stx     @move+1                 ; store srcbank in move + 1\r
+        ldy     tmp2                    ; load dstbank\r
+        sty     @move+2                 ; store dstbank in move + 2\r
+        clc                             ; switch to native mode\r
+        xce\r
+        php                             ; save status bits\r
+        rep     #%00110000              ; set A and index to 16bit\r
+.A16\r
+.I16\r
+        ldy     ptr1\r
+        ldx     ptr2\r
+        lda     ptr3\r
+@move:\r
+        mvn 0,0\r
+        plp                             ; restore status bits\r
+.A8\r
+.I8\r
+        lda     #$00\r
+        pha\r
+        plb                             ; restore dbr\r
+        sec\r
+        xce                             ; switch to emul mode\r
+        ply\r
+        plx\r
+        pla\r
+        cli\r
+        rts\r
+.P02\r
index f4a56029a2b13184f28933be4db5a2f9bcaf86e4..76f6400c1bf74c4fa065e750ea7603e00962727a 100644 (file)
@@ -87,6 +87,7 @@ static emd_test_t drivers[] = {
     { '6', "REU", "c64-reu.emd" },
     { '7', "C128 VDC (in C64 mode)", "c64-vdc.emd" },
     { '8', "C64DTV himem", "dtv-himem.emd" },
+    { '9', "65816 extra banks", "c64-65816.emd" },
 #endif
 
 #if defined(__C128__)