]> git.sur5r.net Git - cc65/commitdiff
Moved the extended RAM driver to c128-ram2.emd and restored the old one.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 4 Feb 2010 18:28:56 +0000 (18:28 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 4 Feb 2010 18:28:56 +0000 (18:28 +0000)
Machines with RAM in pages 2+3 are quite rare, so it's better to have the
additional code+features in a separate driver.

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

doc/c128.sgml
libsrc/c128/Makefile
libsrc/c128/c128-ram.s
libsrc/c128/c128-ram2.s [new file with mode: 0644]

index 41e026e130541ba8f533a908791bfea9dac62a17..f30286439b46f3f56a035d348275fe7729352238 100644 (file)
@@ -195,6 +195,15 @@ missing on VDC and are translated to the two colors missing from VIC palette.
   An extended memory driver for the RAM in page 1. The common memory area is
   excluded, so this driver supports 251 pages of 256 bytes each.
 
+  <tag><tt/c128-ram2.emd/</tag>
+
+  An extended memory driver for the RAM in pages 1-3. The common memory area
+  is excluded, so this driver supports up to 731 pages of 256 bytes each. The
+  driver can be used as a full replacement for <tt/c128-ram.emd/, because RAM
+  in pages 2+3 is autodetected, but it's larger and there are not many
+  machines with RAM in banks 2+3, so it has been made a separate driver. The
+  additional code was contributed by Marco van den Heuvel.
+
   <tag><tt/c128-ramcart.emd/</tag>
   A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak.
   Will test the hardware for the available RAM.
index ee176650b247ac55e9221ab96d051cf4cf606bd7..248c36fd29a013d289fa0e90e19179c498d412ca 100644 (file)
@@ -73,15 +73,24 @@ OBJS =      _scrsize.o              \
 #--------------------------------------------------------------------------
 # Drivers
 
-EMDS = c128-georam.emd c128-ram.emd c128-ramcart.emd c128-reu.emd c128-vdc.emd
+EMDS =  c128-georam.emd         \
+        c128-ram.emd            \
+        c128-ram2.emd           \
+        c128-ramcart.emd        \
+        c128-reu.emd            \
+        c128-vdc.emd
 
-JOYS = c128-ptvjoy.joy c128-stdjoy.joy
+JOYS =  c128-ptvjoy.joy         \
+        c128-stdjoy.joy
 
-MOUS = c128-1351.mou c128-joymouse.mou c128-potmouse.mou
+MOUS =  c128-1351.mou           \
+        c128-joymouse.mou       \
+        c128-potmouse.mou
 
-SERS = c128-swlink.ser
+SERS =  c128-swlink.ser
 
-TGIS = c128-640-200-2.tgi c128-640-480-2.tgi
+TGIS =  c128-640-200-2.tgi      \
+        c128-640-480-2.tgi
 
 #--------------------------------------------------------------------------
 # Targets
index 6b384392c64562de5fdca8ea25d9093142a66692..1211c444dad03dfb9c87fdc3786230a350fb143d 100644 (file)
@@ -1,11 +1,8 @@
 ;
-; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
+; Extended memory driver for the C128 RAM in bank #1. Driver works without
 ; problems when statically linked.
 ;
 ; Ullrich von Bassewitz, 2002-12-04
-;
-; Updated to use banks 2 and 3 as well by
-; Marco van den Heuvel, 2010-01-21
 ;
 
        .include        "zeropage.inc"
 ; Constants
 
 BASE   = $400
+TOPMEM  = $FF00
+PAGES          = (TOPMEM - BASE) / 256
 
 ; ------------------------------------------------------------------------
 ; Data.
 
 .bss
-curpage:        .res    2               ; Current page number
-curbank:        .res    1               ; Current bank number
-copybank:       .res    2               ; temp bank number
+curpage:        .res    1               ; Current page number
 
 window:         .res    256             ; Memory "window"
 
-pagecount:      .res    2               ; Number of available pages
-
 .code
 
 ; ------------------------------------------------------------------------
@@ -66,46 +61,12 @@ pagecount:      .res    2               ; Number of available pages
 ;
 
 INSTALL:
-        ldx     #0
-        stx     ptr1
-        ldx     #4
-        stx     ptr1+1
-        ldx     #<ptr1
-        stx     FETVEC
-        stx     STAVEC
-        ldy     #0
-        ldx     #MMU_CFG_RAM1
-        jsr     FETCH
-        sta     tmp1
-        ldx     #MMU_CFG_RAM3
-        jsr     FETCH
-        cmp     tmp1
-        bne     @has_4_banks
-        tax
-        inx
-        txa
-        ldx     #MMU_CFG_RAM1
-        jsr     STASH
-        ldx     #MMU_CFG_RAM3
-        jsr     FETCH
-        cmp     tmp1
-        beq     @has_4_banks
-        ldx     #0
-        lda     #251
-        bne     @setok
-
-@has_4_banks:
-        ldx     #2
-        lda     #241
-@setok:
-        sta     pagecount
-        stx     pagecount+1
         ldx     #$FF
         stx     curpage
-        stx     curpage+1       ; Invalidate the current page
-       inx
-               txa                     ; A = X = EM_ERR_OK
-;      rts                     ; Run into UNINSTALL instead
+        stx     curpage+1               ; Invalidate the current page
+        inx
+        txa                             ; A = X = EM_ERR_OK
+        rts
 
 ; ------------------------------------------------------------------------
 ; UNINSTALL routine. Is called before the driver is removed from memory.
@@ -121,8 +82,8 @@ UNINSTALL:
 ;
 
 PAGECOUNT:
-        lda     pagecount
-        ldx     pagecount+1
+        lda     #<PAGES
+        ldx     #>PAGES
         rts
 
 ; ------------------------------------------------------------------------
@@ -131,25 +92,21 @@ PAGECOUNT:
 ; by the driver.
 ;
 
-MAP:    sei
-        sta     curpage
+MAP:    sta     curpage
         stx     curpage+1               ; Remember the new page
 
-        jsr     calculate_bank_and_correct_page
-        stx     curbank
-
         clc
-        adc     #>BASE
-        sta     ptr1+1
-        ldy     #$00
-        sty     ptr1
+        adc    #>BASE
+        sta    ptr1+1
+        ldy    #$00
+        sty            ptr1
+
         lda     #<ptr1
         sta     FETVEC
 
 ; Transfer one page
 
-@L1:    ldx     curbank
-        jsr     getcurbankmmu
+@L1:    ldx     #MMU_CFG_RAM1
         jsr     FETCH
         sta     window,y
         iny
@@ -159,7 +116,6 @@ MAP:    sei
 
         lda     #<window
         ldx     #>window                ; Return the window address
-        cli
         rts
 
 ; ------------------------------------------------------------------------
@@ -174,19 +130,15 @@ USE:    sta     curpage
 ; ------------------------------------------------------------------------
 ; COMMIT: Commit changes in the memory window to extended storage.
 
-COMMIT: sei
-        lda     curpage                        ; Get the current page
+COMMIT: lda     curpage                        ; Get the current page
         ldx     curpage+1
         bmi     done                    ; Jump if no page mapped
 
-        jsr     calculate_bank_and_correct_page
-        stx     curbank
-
         clc
         adc    #>BASE
         sta    ptr1+1
         ldy    #$00
-        sty     ptr1
+        sty            ptr1
 
         lda     #<ptr1
         sta     STAVEC
@@ -194,12 +146,10 @@ COMMIT: sei
 ; Transfer one page. Y must be zero on entry
 
 @L1:    lda     window,y
-        ldx     curbank
-        jsr     getcurbankmmu
+        ldx     #MMU_CFG_RAM1
         jsr     STASH
         iny
         bne     @L1
-        cli
 
 ; Done
 
@@ -212,55 +162,64 @@ done:   rts
 ;
 
 COPYFROM:
-        sei
-        jsr     setup
+        sta     ptr3
+        stx     ptr3+1                  ; Save the passed em_copy pointer
 
-; Setup is:
-;
-;   - ptr1 contains the struct pointer
-;   - ptr2 contains the linear memory buffer
-;   - ptr3 contains -(count-1)
-;   - ptr4 contains the page buffer and offset
-;   - tmp1 contains the bank
-;   - tmp2 contains zero (used for linear memory buffer offset)
-
-        lda     #<ptr4
+        ldy     #EM_COPY::OFFS
+        lda     (ptr3),y
+        sta     ptr1
+        ldy     #EM_COPY::PAGE
+        lda     (ptr3),y
+        clc
+        adc     #>BASE
+        sta     ptr1+1                  ; From
+
+        ldy     #EM_COPY::BUF
+        lda     (ptr3),y
+        sta     ptr2
+        iny
+        lda     (ptr3),y
+        sta     ptr2+1                  ; To
+
+        lda     #<ptr1
         sta     FETVEC
-        jmp     @L3
 
-@L1:    ldx     tmp1
-        jsr     getcurbankmmu
-        ldy     #0
-        jsr     FETCH
-        ldy     tmp2
-        sta     (ptr2),y
-        inc     tmp2
-        bne     @L2
-        inc     ptr2+1
-@L2:    inc     ptr4
-        beq     @L4
+        ldy     #EM_COPY::COUNT+1
+        lda     (ptr3),y                ; Get number of pages
+        beq     @L2                     ; Skip if no full pages
+        sta     tmp1
 
-; Bump count and repeat
+; Copy full pages
 
-@L3:    inc     ptr3
+        ldy     #$00
+@L1:    ldx     #MMU_CFG_RAM1
+        jsr     FETCH
+        sta     (ptr2),y
+        iny
         bne     @L1
-        inc     ptr3+1
+        inc     ptr1+1
+        inc     ptr2+1
+        dec     tmp1
         bne     @L1
-        cli
-        rts
 
-; Bump page register
+; Copy the remainder of the page
 
-@L4:    inc     ptr4+1
-        lda     ptr4+1
-        cmp     #$ff
+@L2:    ldy     #EM_COPY::COUNT
+        lda     (ptr3),y                ; Get bytes in last page
+        beq     @L4
+        sta     tmp1
+
+        ldy     #$00
+@L3:    ldx     #MMU_CFG_RAM1
+        jsr     FETCH
+        sta    (ptr2),y
+        iny
+        dec     tmp1
         bne     @L3
-        lda     #4
-        sta     ptr4+1
-        inc     tmp1
-@L5:
-        jmp     @L3
 
+; Done
+
+@L4:    rts
 
 ; ------------------------------------------------------------------------
 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
@@ -268,159 +227,62 @@ COPYFROM:
 ; The function must not return anything.
 ;
 
-COPYTO:
-        sei
-        jsr     setup
+COPYTO: sta     ptr3
+        stx     ptr3+1                  ; Save the passed em_copy pointer
 
-; Setup is:
-;
-;   - ptr1 contains the struct pointer
-;   - ptr2 contains the linear memory buffer
-;   - ptr3 contains -(count-1)
-;   - ptr4 contains the page buffer and offset
-;   - tmp1 contains the bank
-;   - tmp2 contains zero (used for linear memory buffer offset)
-
-        lda     #<ptr4
-        sta     STAVEC
-        jmp     @L3
-
-@L1:
-        ldy     tmp2
-        lda     (ptr2),y
-        ldx     tmp1
-        jsr     getcurbankmmu
-        ldy     #0
-        jsr     STASH
-        inc     tmp2
-        bne     @L2
-        inc     ptr2+1
-@L2:    inc     ptr4
-        beq     @L4
-
-; Bump count and repeat
-
-@L3:    inc     ptr3
-        bne     @L1
-        inc     ptr3+1
-        bne     @L1
-        cli
-        rts
-
-; Bump page register
-
-@L4:    inc     ptr4+1
-        lda     ptr4+1
-        cmp     #$ff
-        bne     @L3
-        inc     tmp1
-        lda     #4
-        sta     ptr4+1
-@L5:
-        jmp     @L3
-
-; ------------------------------------------------------------------------
-; Helper function to calculate the correct bank and page
-; when addressing bank 2 or 3
-
-calculate_bank_and_correct_page:
-        cpx     #2
-        beq     @calculate_bank_3_with_2
-        cpx     #1
-        beq     @calculate_bank_2_or_3_with_1
-        sec
-        sbc     #251
-        bcs     @calculate_bank_2_with_0
-        ldx     #1
-        lda     curpage
-        rts
-
-@calculate_bank_3_with_2:
-        lda     curpage
-        clc
-        adc     #10
-@calculate_bank_3_with_1:
-        ldx     #3
-        rts
-
-@calculate_bank_2_or_3_with_1:
-        sec
-        sbc     #246
-        bcs     @calculate_bank_3_with_1
-        lda     curpage
-        clc
-        adc     #5
-@calculate_bank_2_with_0:
-        ldx     #2
-        rts
-
-; ------------------------------------------------------------------------
-; Helper function to get the correct mmu value in x
-
-getcurbankmmu:
-        cpx     #1
-        beq     @bank1
-        cpx     #2
-        beq     @bank2
-        ldx     #MMU_CFG_RAM3
-        rts
-@bank2:
-        ldx     #MMU_CFG_RAM2
-        rts
-@bank1:
-        ldx     #MMU_CFG_RAM1
-        rts
-
-; ------------------------------------------------------------------------
-; 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: page pointer in ptr4 and bank in tmp1
-
-        ldy     #EM_COPY::PAGE+1
-        lda     (ptr1),y
-        tax
-        dey
-        lda     (ptr1),y
-        sta     curpage
-        jsr     calculate_bank_and_correct_page
+        ldy     #EM_COPY::OFFS
+        lda     (ptr3),y
+        sta     ptr1
+        ldy     #EM_COPY::PAGE
+        lda     (ptr3),y
         clc
-        adc     #4
-        sta     ptr4+1
-        stx     tmp1
-
-; Get the buffer pointer into ptr2
+        adc     #>BASE
+        sta     ptr1+1                  ; To
 
         ldy     #EM_COPY::BUF
-        lda     (ptr1),y
+        lda     (ptr3),y
         sta     ptr2
         iny
-        lda     (ptr1),y
-        sta     ptr2+1
+        lda     (ptr3),y
+        sta     ptr2+1                  ; From
 
-; Get the count, calculate -(count-1) and store it into ptr3
+        lda     #<ptr1
+        sta     STAVEC
 
-        ldy     #EM_COPY::COUNT
-        lda     (ptr1),y
-        eor     #$FF
-        sta     ptr3
+        ldy     #EM_COPY::COUNT+1
+        lda     (ptr3),y                ; Get number of pages
+        beq     @L2                     ; Skip if no full pages
+        sta     tmp1
+
+; Copy full pages
+
+        ldy     #$00
+@L1:    lda     (ptr2),y
+        ldx     #MMU_CFG_RAM1
+        jsr     STASH
         iny
-        lda     (ptr1),y
-        eor     #$FF
-        sta     ptr3+1
+        bne     @L1
+        inc     ptr1+1
+        inc     ptr2+1
+        dec     tmp1
+        bne     @L1
 
-; Get the page offset into the low byte of ptr4 clear tmp2
+; Copy the remainder of the page
 
-        ldy     #EM_COPY::OFFS
-        lda     (ptr1),y
-        sta     ptr4
-        lda     #0
-        sta     tmp2
+@L2:    ldy     #EM_COPY::COUNT
+        lda     (ptr3),y                ; Get bytes in last page
+        beq     @L4
+        sta     tmp1
+
+        ldy     #$00
+@L3:    lda     (ptr2),y
+        ldx     #MMU_CFG_RAM1
+        jsr     STASH
+        iny
+        dec     tmp1
+        bne     @L3
 
 ; Done
 
-        rts
+@L4:    rts
+
diff --git a/libsrc/c128/c128-ram2.s b/libsrc/c128/c128-ram2.s
new file mode 100644 (file)
index 0000000..6b38439
--- /dev/null
@@ -0,0 +1,426 @@
+;
+; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-12-04
+;
+; Updated to use banks 2 and 3 as well by
+; Marco van den Heuvel, 2010-01-21
+;
+
+       .include        "zeropage.inc"
+
+       .include        "em-kernel.inc"
+        .include        "em-error.inc"
+        .include        "c128.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   UNINSTALL
+        .word   PAGECOUNT
+        .word   MAP
+        .word   USE
+        .word   COMMIT
+       .word   COPYFROM
+        .word   COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE   = $400
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage:        .res    2               ; Current page number
+curbank:        .res    1               ; Current bank number
+copybank:       .res    2               ; temp bank number
+
+window:         .res    256             ; Memory "window"
+
+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     #0
+        stx     ptr1
+        ldx     #4
+        stx     ptr1+1
+        ldx     #<ptr1
+        stx     FETVEC
+        stx     STAVEC
+        ldy     #0
+        ldx     #MMU_CFG_RAM1
+        jsr     FETCH
+        sta     tmp1
+        ldx     #MMU_CFG_RAM3
+        jsr     FETCH
+        cmp     tmp1
+        bne     @has_4_banks
+        tax
+        inx
+        txa
+        ldx     #MMU_CFG_RAM1
+        jsr     STASH
+        ldx     #MMU_CFG_RAM3
+        jsr     FETCH
+        cmp     tmp1
+        beq     @has_4_banks
+        ldx     #0
+        lda     #251
+        bne     @setok
+
+@has_4_banks:
+        ldx     #2
+        lda     #241
+@setok:
+        sta     pagecount
+        stx     pagecount+1
+        ldx     #$FF
+        stx     curpage
+        stx     curpage+1       ; Invalidate the current page
+       inx
+               txa                     ; A = X = EM_ERR_OK
+;      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
+
+; ------------------------------------------------------------------------
+; 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:    sei
+        sta     curpage
+        stx     curpage+1               ; Remember the new page
+
+        jsr     calculate_bank_and_correct_page
+        stx     curbank
+
+        clc
+        adc     #>BASE
+        sta     ptr1+1
+        ldy     #$00
+        sty     ptr1
+        lda     #<ptr1
+        sta     FETVEC
+
+; Transfer one page
+
+@L1:    ldx     curbank
+        jsr     getcurbankmmu
+        jsr     FETCH
+        sta     window,y
+        iny
+        bne     @L1
+
+; Return the memory window
+
+        lda     #<window
+        ldx     #>window                ; Return the window address
+        cli
+        rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE:    sta     curpage
+        stx     curpage+1               ; Remember the page
+        lda     #<window
+        ldx     #>window                ; Return the window
+        rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: sei
+        lda     curpage                        ; Get the current page
+        ldx     curpage+1
+        bmi     done                    ; Jump if no page mapped
+
+        jsr     calculate_bank_and_correct_page
+        stx     curbank
+
+        clc
+        adc    #>BASE
+        sta    ptr1+1
+        ldy    #$00
+        sty     ptr1
+
+        lda     #<ptr1
+        sta     STAVEC
+
+; Transfer one page. Y must be zero on entry
+
+@L1:    lda     window,y
+        ldx     curbank
+        jsr     getcurbankmmu
+        jsr     STASH
+        iny
+        bne     @L1
+        cli
+
+; 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:
+        sei
+        jsr     setup
+
+; Setup is:
+;
+;   - ptr1 contains the struct pointer
+;   - ptr2 contains the linear memory buffer
+;   - ptr3 contains -(count-1)
+;   - ptr4 contains the page buffer and offset
+;   - tmp1 contains the bank
+;   - tmp2 contains zero (used for linear memory buffer offset)
+
+        lda     #<ptr4
+        sta     FETVEC
+        jmp     @L3
+
+@L1:    ldx     tmp1
+        jsr     getcurbankmmu
+        ldy     #0
+        jsr     FETCH
+        ldy     tmp2
+        sta     (ptr2),y
+        inc     tmp2
+        bne     @L2
+        inc     ptr2+1
+@L2:    inc     ptr4
+        beq     @L4
+
+; Bump count and repeat
+
+@L3:    inc     ptr3
+        bne     @L1
+        inc     ptr3+1
+        bne     @L1
+        cli
+        rts
+
+; Bump page register
+
+@L4:    inc     ptr4+1
+        lda     ptr4+1
+        cmp     #$ff
+        bne     @L3
+        lda     #4
+        sta     ptr4+1
+        inc     tmp1
+@L5:
+        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:
+        sei
+        jsr     setup
+
+; Setup is:
+;
+;   - ptr1 contains the struct pointer
+;   - ptr2 contains the linear memory buffer
+;   - ptr3 contains -(count-1)
+;   - ptr4 contains the page buffer and offset
+;   - tmp1 contains the bank
+;   - tmp2 contains zero (used for linear memory buffer offset)
+
+        lda     #<ptr4
+        sta     STAVEC
+        jmp     @L3
+
+@L1:
+        ldy     tmp2
+        lda     (ptr2),y
+        ldx     tmp1
+        jsr     getcurbankmmu
+        ldy     #0
+        jsr     STASH
+        inc     tmp2
+        bne     @L2
+        inc     ptr2+1
+@L2:    inc     ptr4
+        beq     @L4
+
+; Bump count and repeat
+
+@L3:    inc     ptr3
+        bne     @L1
+        inc     ptr3+1
+        bne     @L1
+        cli
+        rts
+
+; Bump page register
+
+@L4:    inc     ptr4+1
+        lda     ptr4+1
+        cmp     #$ff
+        bne     @L3
+        inc     tmp1
+        lda     #4
+        sta     ptr4+1
+@L5:
+        jmp     @L3
+
+; ------------------------------------------------------------------------
+; Helper function to calculate the correct bank and page
+; when addressing bank 2 or 3
+
+calculate_bank_and_correct_page:
+        cpx     #2
+        beq     @calculate_bank_3_with_2
+        cpx     #1
+        beq     @calculate_bank_2_or_3_with_1
+        sec
+        sbc     #251
+        bcs     @calculate_bank_2_with_0
+        ldx     #1
+        lda     curpage
+        rts
+
+@calculate_bank_3_with_2:
+        lda     curpage
+        clc
+        adc     #10
+@calculate_bank_3_with_1:
+        ldx     #3
+        rts
+
+@calculate_bank_2_or_3_with_1:
+        sec
+        sbc     #246
+        bcs     @calculate_bank_3_with_1
+        lda     curpage
+        clc
+        adc     #5
+@calculate_bank_2_with_0:
+        ldx     #2
+        rts
+
+; ------------------------------------------------------------------------
+; Helper function to get the correct mmu value in x
+
+getcurbankmmu:
+        cpx     #1
+        beq     @bank1
+        cpx     #2
+        beq     @bank2
+        ldx     #MMU_CFG_RAM3
+        rts
+@bank2:
+        ldx     #MMU_CFG_RAM2
+        rts
+@bank1:
+        ldx     #MMU_CFG_RAM1
+        rts
+
+; ------------------------------------------------------------------------
+; 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: page pointer in ptr4 and bank in tmp1
+
+        ldy     #EM_COPY::PAGE+1
+        lda     (ptr1),y
+        tax
+        dey
+        lda     (ptr1),y
+        sta     curpage
+        jsr     calculate_bank_and_correct_page
+        clc
+        adc     #4
+        sta     ptr4+1
+        stx     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 the low byte of ptr4 clear tmp2
+
+        ldy     #EM_COPY::OFFS
+        lda     (ptr1),y
+        sta     ptr4
+        lda     #0
+        sta     tmp2
+
+; Done
+
+        rts