]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/commitdiff
stack
authorLeo C <erbl259-lmu@yahoo.de>
Mon, 13 Jun 2016 15:34:12 +0000 (17:34 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Mon, 13 Jun 2016 16:21:20 +0000 (18:21 +0200)
cbios/mm.180

index 9df0471a4d6e8404d55dd5b6a694adcf23ccb6d5..4128fe9702a74df8e43cfb4273d36e7c089468f7 100644 (file)
-       page    255
-       .z80
-
-
-       public mmuinit
-       public bnk2log,bnk2phy,hwl2phy,phy2log
-       public isv_sw
-       public b_ld_a,b_ld_hl,b_st_a,b_st_hl
-
-
-       extrn @cbnk
-       extrn ijphl
-
-
-       maclib z180reg.inc
-       maclib config.inc
-
-
-;----------------------------------------------------------------------
-; Memory Map 1:
-;
-;      Common  CAStart ..     0FFFF
-;      Bank 0    00000 .. CAStart-1
-;      Bank 1    10000 ..
-;      Bank 2
-;
-; Memory Map 2:
-;
-;      Common    18000 .. 1BFFF        BANK1
-;
-;      Bank 0    00000 .. 0BFFF        0
-;      Bank 1    0C000 .. 17FFF        1*BNK_SIZE
-;      Bank 2    1C000 .. 27FFF        2*BNK_SIZE + CMN_SIZE
-;      Bank 3    28000 .. 33FFF        3*BNK_SIZE + CMN_SIZE
-;      Bank n                          n*BNK_SIZE + (n < 2) ? 0 : CMN_SIZE
-;
-;----------------------------------------------------------------------
-
-       cseg
-
-mmuinit:
-       ld      a,USR$CBAR
-       out0    (cbar),a
-       ret
-
-;--------------------------------------------------------------------
-; Return the BBR value for the given bank number
-;
-; in  a: Bank number
-; out a: bbr value
-
-   if 0        ; Memory Map 1
-
-bnk2log:
-       or      a               ;
-       ret     z               ; Bank 0 is at physical address 0
-
-       dec     a               ;
-       push    bc              ;
-       ld      c,a             ;
-       ld      b,BNK_SIZE      ;
-       mlt     bc              ; bank size * bank number
-       ld      a,c             ;
-       add     a,10h           ; add bank0 + common
-       pop     bc              ;
-       ret                     ;
-
-   else ; Memory Map 2
-
-bnk2log:
-       or      a
-       ret     z               ; Bank 0 is at physical address 0
-
-       push    bc
-       ld      c,a             ;
-       ld      b,BNK_SIZE      ;
-       mlt     bc              ; bank size * bank number
-       cp      2               ;
-       ld      a,c             ;
-       pop     bc
-       ret     c
-       add     a,CMN_SIZE
-       ret
-
-    endif
-
-    if 0 ; table version
-
-       push    hl
-       ld      hl,bnk_table    ;
-       add     a,l             ;
-       ld      l,a             ;
-       jr      nc,$+3          ;
-       inc     h               ;
-       ld      a,(hl)          ;
-       pop     hl
-       ret
-
-    endif
-
-;--------------------------------------------------------------
-
-;in  hl: Log. Address
-;     a: Bank number
-;
-;out ahl: Phys. (linear) Address
-
-
-bnk2phy:
-       push    bc
-       ld      c,a
-       ld      a,h
-       and     a,0f0h
-       cp      CA*16
-       ld      a,c
-       pop     bc
-       jr      c,b2p_banked
-                               ; address is in common
-    if 0 ; Memory Map 1
-       ld      a,0             ; base is 0
-    else ; Memory Map 2
-       ld      a,1             ; same as bank1
-    endif
-
-b2p_banked:
-       call    bnk2log         ; get address base
-
-       ; fall thru
-
-;--------------------------------------------------------------
-;
-; hl: Log. Address
-;  a: Bank base (bbr)
-;
-;           2           0       0
-;           0   6       8       0
-; hl             hhhhhhhhllllllll
-;  a   +     bbbbbbbb
-;
-; OP: ahl = (a<<12) + (h<<8) + l
-;
-;out ahl: Phys. (linear) Address
-
-log2phy:
-       push    bc              ;
-l2p_i:
-       ld      c,a             ;
-       ld      b,16            ;
-       mlt     bc              ; bc = a<<4
-       ld      a,c             ;
-       add     a,h             ;
-       ld      h,a             ;
-       ld      a,b             ;
-       adc     a,0             ;
-       pop     bc              ;
-       ret                     ;
-
-;--------------------------------------------------------------
-;
-; hl: Log. Address
-;
-;
-; OP: ahl = (bankbase<<12) + (h<<8) + l
-;
-;out ahl: Phys. (linear) Address
-
-
-hwl2phy:
-       push    bc              ;
-       in0     c,(cbar)        ;
-       ld      a,h             ;
-       or      00fh            ; log. addr in common1?
-       cp      c
-       jr      c,hlp_1
-
-       in0     a,(cbr)         ; yes, cbr is address base
-       jr      hl2p_x
-hlp_1:
-       ld      b,16            ; log. address in baked area?
-       mlt     bc
-       ld      a,h
-       cp      c
-       jr      c,hlp_2
-       in0     a,(bbr)         ; yes, bbr is address base
-       jr      hl2p_x
-hlp_2:
-       xor     a               ; common1
-hl2p_x:
-       jr      nz,l2p_i
-
-       pop     bc              ; bank part is 0, no translation
-       ret                     ;
-
-
-;--------------------------------------------------------------
-; return logical bank 0 address for given physical address.
-;
-; in: ahl: pyhsical addres (20 bit)
-; out  hl: logical address.
-;         logical address is in bank 0 or common, no bank number returned
-;
-
-phy2log:
-       or      a
-       ret     z
-
-       push    bc
-       push    hl
-       ld      l,h
-       ld      h,0
-       ld      bc,-16*SYS$CBR
-       add     hl,bc
-       ld      h,l
-       pop     bc
-       ld      l,c
-       pop     bc
-       ret
-
-;--------------------------------------------------------------
-; Trampoline for routines in banked ram.
-; Switch stack pointer to "system" stack in top ram
-; Save cbar
-;
-       extrn   bs$stack
-
-       cseg    ; common!
-
-       public  _b0call
-_b0call:
-       push    af
-       in0     a,(bbr)
-       jr      nz,b0c_doit
-       pop     af
-
-       ex      (sp),hl                 ;16
-       push    de
-       ld      e,(hl)
-       inc     hl
-       ld      d,(hl)
-       inc     hl
-       ld      (b0c_fast_go),de
-       pop     de
-       ex      (sp),hl                 ;16
-b0c_fast_go equ        $+1
-       jp      0
-
-b0c_doit:
-       ld      (b0_save_hl),hl
-       ld      (b0_save_de),de
-       pop     hl
-       ld      (b0_save_af),hl
-
-       pop     de                      ;get ptr to 'function address' in de
-       ld      hl,2
-       add     hl,de
-       push    hl                      ;put return address on stack
-
-   if 0 ; link80
-
-       ld      hl,0
-       add     hl,sp                   ;
-       ld      a,h
-       cp      high (bs$stack-bs$stack$size) ;link80 can't process this
-       jr      nc,$ + 5                ;skip if stack allready in common bios ram
-
-   else
-
-       ld      hl,bs$stack-bs$stack$size
-       ld      a,h
-       dec     a
-       ld      hl,0
-       add     hl,sp                   ;
-       cp      h
-       jr      c,$ + 5                 ;skip if stack allready in common bios ram
-   endif
-       ld      sp,bs$stack             ;
-
-       push    hl                      ;save   user stack pointer
-
-       in0     h,(bbr)                 ;
-       push    hl                      ;
-       ld      hl,b0c_ret
-       push    hl
-       xor     a
-       out0    (bbr),a                 ;
-       ex      de,hl                   ;ptr
-       ld      e,(hl)                  ;get 'function address'
-       inc     hl                      ;
-       ld      d,(hl)                  ;
-       push    de                      ;put on (switched) stack
-
-       ld      hl,(b0_save_af)         ;get back users registers
-       push    hl
-       pop     af
-       ld      de,(b0_save_de)
-       ld      hl,(b0_save_hl)
-       ret                             ;go to function
-b0c_ret:
-       ld      (b0_save_hl),hl
-
-       pop     hl                      ;
-       out0    (bbr),h                 ;
-       pop     hl                      ;
-       ld      sp,hl                   ;
-       ld      hl,(b0_save_hl)
-       ret                             ;
-
-
-b0_save_hl: dw 0
-b0_save_de: dw 0
-b0_save_af: dw 0
-
-
-;--------------------------------------------------------------------
-; Trampoline for interrupt routines in banked ram.
-; Switch stack pointer to "system" stack in top ram
-; Save bbr
-
-       cseg
-isv_sw:                                        ;
-       ex      (sp),hl                 ;save hl, 'return adr' in hl
-       push    de                      ;
-       push    af                      ;
-       ex      de,hl                   ;'return address' in de
-
-  if 0
-   if 0 ; link80
-
-       ld      hl,0
-       add     hl,sp                   ;
-       ld      a,h
-       cp      high (bs$stack-bs$stack$size) ;link80 can't process this
-       jr      nc,$ + 5                ;skip if stack allready in common bios ram
-
-   else
-
-       ld      hl,bs$stack-bs$stack$size
-       ld      a,h
-       dec     a
-       ld      hl,0
-       add     hl,sp                   ;
-       cp      h
-       jr      c,$ + 5                 ;skip if stack allready in common bios ram
-   endif
-       ld      sp,bs$stack             ;
-  else
-       ld      hl,0
-       add     hl,sp
-       ld      sp,istack
-  endif
-       push    hl                      ;save user stack pointer
-       in0     h,(bbr)                 ;
-       push    hl                      ;
-       xor     a                       ;
-       out0    (bbr),a                 ;
-       ex      de,hl                   ;
-       ld      e,(hl)                  ;
-       inc     hl                      ;
-       ld      d,(hl)                  ;
-       ex      de,hl                   ;
-       push    bc                      ;
-       call    ijphl                   ;
-
-       pop     bc                      ;
-       pop     hl                      ;
-       out0    (bbr),h                 ;
-       pop     hl                      ;
-       ld      sp,hl                   ;
-       pop     af                      ;
-       pop     de                      ;
-       pop     hl                      ;
-       ei                              ;
-       ret                             ;
-
-
-       ds      24
-istack:
-
-       dseg
-
-;--------------------------------------------------------------------
-; Load byte/word from user ram
-;
-;   de:  src address in users bank
-; return
-;    a:  value (byte)
-;   hl:  value (word)
-
-b_ld_a:
-       push    hl
-       or      a               ; clear carry == byte store
-       jr      $+3
-b_ld_hl:
-       scf                     ; set carry == word store
-       push    af              ; save flag
-       push    hl              ; make space on stack
-
-       ld      a,(@cbnk)
-       ld      b,a             ; b = src bank
-
-       ld      hl,0
-       ld      a,l
-       ld      c,l             ; c = dst bank (0)
-       add     hl,sp           ; hl = dst
-       adc     a,1             ; a = count
-       ex      de,hl
-       call    dma_move
-       ex      de,hl
-       pop     hl
-       pop     af
-       ret     c
-       ld      a,l
-       pop     hl
-       ret
-
-;--------------------------------------------------------------------
-; Store byte/word to user ram
-;
-;   de:  dst address in users bank
-;    a:  value (byte)
-;   hl:  value (word)
-
-b_st_a:
-       push    hl
-       ld      l,a
-       or      a               ; clear carry == byte store
-       jr      $+3
-b_st_hl:
-       scf                     ; set carry == word store
-       push    af              ; save flag
-       push    hl              ; put value on stack
-
-       ld      a,(@cbnk)       ;
-       ld      c,a             ; c = dst bank
-       ld      a,0
-       ld      l,a
-       ld      h,a
-       ld      b,a             ; b = src bank (0)
-       add     hl,sp           ; hl = src
-       adc     a,1             ; a = count
-
-       call    dma_move
-
-       pop     hl              ; restore value
-       pop     af              ; carry
-       ret     c
-       pop     hl
-       ret
-
-;--------------------------------------------------------------------
-;
-;    hl: src
-;    de: dst
-;     b: src bank
-;     c: dst bank
-;     a: count
-
-dma_move:
-       out0    (bcr0l),a       ; setup DMA count
-       xor     a
-       out0    (bcr0h),a
-
-       push    hl
-       ld      a,b
-       call    bnk2phy
-       out0    (sar0l),l       ; setup DMA src address
-       out0    (sar0h),h
-       out0    (sar0b),a
-
-       ld      l,e
-       ld      h,d
-       ld      a,c
-       call    bnk2phy
-       out0    (dar0l),l       ; setup DMA dst address
-       out0    (dar0h),h
-       out0    (dar0b),a
-
-       ld      a,M_MMOD        ; DMA burst mode
-       out0    (dmode),a
-       ld      a,M_DE0+M_NDWE1 ; enable DMA0
-       out0    (dstat),a       ; move ...
-       pop     hl
-       ret
-
-
-;====================================================================
-
-       cseg
-
-  if 0
-
-;--------------------------------------------------------------------
-; Return the BBR value for the given bank number
-
-bnk2bbr:
-       or      a               ; 4
-       ret     z               ; 5/10 | 11             14
-
-       push    bc              ;11 | 11
-       ld      b,a             ; 4
-       ld      c,CA            ; 6
-       mlt     bc              ;17                         >45
-       ld      a,c             ; 4
-       add     a,10h           ; 6
-       pop     bc              ; 9 | 10
-       ret                     ; 9 | 10                76
-
-       push    ix              ;2 / 14 | 15
-       ld      ix,bnktbl       ;4 / 12 | 14
-       ld      ($+3+2),a       ;3 / 15 | 19
-       ld      a,(ix+0)        ;3 / 14 | 19
-       pop     ix              ;2 / 12 | 14
-       ret                     ;1 /  9 | 10            15 / 76|91
-
-       push    hl              ;1 / 11 | 11
-       ld      hl,bnktbl       ;3 /  9 | 10
-       add     a,l             ;1 /  4 | 4
-       ld      l,a             ;1 /  4 | 4
-       ld      a,0             ;1 /  6 | 7
-       adc     a,h             ;1 /  4 | 4
-       ld      h,a             ;1 /  4 | 4
-       ld      a,(hl)          ;1 /  6 | 7
-       pop     hl              ;1 /  9 | 10
-       ret                     ;1 /  9 | 10            12 / 66|71
-
-       push    hl              ;1 / 11 | 11
-       add     a,low bnktbl    ;2 /  6 | 7
-       ld      l,a             ;1 /  4 | 4
-       ld      a,0             ;1 /  6 | 7
-       adc     a,high bnktbl   ;2 /  6 | 7
-       ld      h,a             ;1 /  4 | 4
-       ld      a,(hl)          ;1 /  6 | 7
-       pop     hl              ;1 /  9 | 10
-       ret                     ;1 /  9 | 10            11 / 61|67
-
-  endif
-
-
-       end
+       page    255\r
+       .z80\r
+\r
+\r
+       public mmuinit\r
+       public bnk2log,bnk2phy,hwl2phy,phy2log\r
+       public isv_sw\r
+       public b_ld_a,b_ld_hl,b_st_a,b_st_hl\r
+\r
+\r
+       extrn @cbnk\r
+       extrn ijphl\r
+\r
+\r
+       maclib z180reg.inc\r
+       maclib config.inc\r
+\r
+\r
+;----------------------------------------------------------------------\r
+; Memory Map 1:\r
+;\r
+;      Common  CAStart ..     0FFFF\r
+;      Bank 0    00000 .. CAStart-1\r
+;      Bank 1    10000 ..\r
+;      Bank 2\r
+;\r
+; Memory Map 2:\r
+;\r
+;      Common    18000 .. 1BFFF        BANK1\r
+;\r
+;      Bank 0    00000 .. 0BFFF        0\r
+;      Bank 1    0C000 .. 17FFF        1*BNK_SIZE\r
+;      Bank 2    1C000 .. 27FFF        2*BNK_SIZE + CMN_SIZE\r
+;      Bank 3    28000 .. 33FFF        3*BNK_SIZE + CMN_SIZE\r
+;      Bank n                          n*BNK_SIZE + (n < 2) ? 0 : CMN_SIZE\r
+;\r
+;----------------------------------------------------------------------\r
+\r
+       cseg\r
+\r
+mmuinit:\r
+       ld      a,USR$CBAR\r
+       out0    (cbar),a\r
+       ret\r
+\r
+;--------------------------------------------------------------------\r
+; Return the BBR value for the given bank number\r
+;\r
+; in  a: Bank number\r
+; out a: bbr value\r
+\r
+   if 0        ; Memory Map 1\r
+\r
+bnk2log:\r
+       or      a               ;\r
+       ret     z               ; Bank 0 is at physical address 0\r
+\r
+       dec     a               ;\r
+       push    bc              ;\r
+       ld      c,a             ;\r
+       ld      b,BNK_SIZE      ;\r
+       mlt     bc              ; bank size * bank number\r
+       ld      a,c             ;\r
+       add     a,10h           ; add bank0 + common\r
+       pop     bc              ;\r
+       ret                     ;\r
+\r
+   else ; Memory Map 2\r
+\r
+bnk2log:\r
+       or      a\r
+       ret     z               ; Bank 0 is at physical address 0\r
+\r
+       push    bc\r
+       ld      c,a             ;\r
+       ld      b,BNK_SIZE      ;\r
+       mlt     bc              ; bank size * bank number\r
+       cp      2               ;\r
+       ld      a,c             ;\r
+       pop     bc\r
+       ret     c\r
+       add     a,CMN_SIZE\r
+       ret\r
+\r
+    endif\r
+\r
+    if 0 ; table version\r
+\r
+       push    hl\r
+       ld      hl,bnk_table    ;\r
+       add     a,l             ;\r
+       ld      l,a             ;\r
+       jr      nc,$+3          ;\r
+       inc     h               ;\r
+       ld      a,(hl)          ;\r
+       pop     hl\r
+       ret\r
+\r
+    endif\r
+\r
+;--------------------------------------------------------------\r
+\r
+;in  hl: Log. Address\r
+;     a: Bank number\r
+;\r
+;out ahl: Phys. (linear) Address\r
+\r
+\r
+bnk2phy:\r
+       push    bc\r
+       ld      c,a\r
+       ld      a,h\r
+       and     a,0f0h\r
+       cp      CA*16\r
+       ld      a,c\r
+       pop     bc\r
+       jr      c,b2p_banked\r
+                               ; address is in common\r
+    if 0 ; Memory Map 1\r
+       ld      a,0             ; base is 0\r
+    else ; Memory Map 2\r
+       ld      a,1             ; same as bank1\r
+    endif\r
+\r
+b2p_banked:\r
+       call    bnk2log         ; get address base\r
+\r
+       ; fall thru\r
+\r
+;--------------------------------------------------------------\r
+;\r
+; hl: Log. Address\r
+;  a: Bank base (bbr)\r
+;\r
+;           2           0       0\r
+;           0   6       8       0\r
+; hl             hhhhhhhhllllllll\r
+;  a   +     bbbbbbbb\r
+;\r
+; OP: ahl = (a<<12) + (h<<8) + l\r
+;\r
+;out ahl: Phys. (linear) Address\r
+\r
+log2phy:\r
+       push    bc              ;\r
+l2p_i:\r
+       ld      c,a             ;\r
+       ld      b,16            ;\r
+       mlt     bc              ; bc = a<<4\r
+       ld      a,c             ;\r
+       add     a,h             ;\r
+       ld      h,a             ;\r
+       ld      a,b             ;\r
+       adc     a,0             ;\r
+       pop     bc              ;\r
+       ret                     ;\r
+\r
+;--------------------------------------------------------------\r
+;\r
+; hl: Log. Address\r
+;\r
+;\r
+; OP: ahl = (bankbase<<12) + (h<<8) + l\r
+;\r
+;out ahl: Phys. (linear) Address\r
+\r
+\r
+hwl2phy:\r
+       push    bc              ;\r
+       in0     c,(cbar)        ;\r
+       ld      a,h             ;\r
+       or      00fh            ; log. addr in common1?\r
+       cp      c\r
+       jr      c,hlp_1\r
+\r
+       in0     a,(cbr)         ; yes, cbr is address base\r
+       jr      hl2p_x\r
+hlp_1:\r
+       ld      b,16            ; log. address in baked area?\r
+       mlt     bc\r
+       ld      a,h\r
+       cp      c\r
+       jr      c,hlp_2\r
+       in0     a,(bbr)         ; yes, bbr is address base\r
+       jr      hl2p_x\r
+hlp_2:\r
+       xor     a               ; common1\r
+hl2p_x:\r
+       jr      nz,l2p_i\r
+\r
+       pop     bc              ; bank part is 0, no translation\r
+       ret                     ;\r
+\r
+\r
+;--------------------------------------------------------------\r
+; return logical bank 0 address for given physical address.\r
+;\r
+; in: ahl: pyhsical addres (20 bit)\r
+; out  hl: logical address.\r
+;         logical address is in bank 0 or common, no bank number returned\r
+;\r
+\r
+phy2log:\r
+       or      a\r
+       ret     z\r
+\r
+       push    bc\r
+       push    hl\r
+       ld      l,h\r
+       ld      h,0\r
+       ld      bc,-16*SYS$CBR\r
+       add     hl,bc\r
+       ld      h,l\r
+       pop     bc\r
+       ld      l,c\r
+       pop     bc\r
+       ret\r
+\r
+;--------------------------------------------------------------\r
+; Trampoline for routines in banked ram.\r
+; Switch stack pointer to "system" stack in top ram\r
+; Save cbar\r
+;\r
+       extrn   bs$stack\r
+\r
+       cseg    ; common!\r
+\r
+       public  _b0call\r
+\r
+   if 0\r
+\r
+_b0call:\r
+       push    af\r
+       in0     a,(bbr)\r
+       jr      nz,b0c_doit\r
+       pop     af\r
+\r
+       ex      (sp),hl                 ;16\r
+       push    de\r
+       ld      e,(hl)\r
+       inc     hl\r
+       ld      d,(hl)\r
+       inc     hl\r
+       ld      (b0c_fast_go),de\r
+       pop     de\r
+       ex      (sp),hl                 ;16\r
+b0c_fast_go equ        $+1\r
+       jp      0\r
+\r
+b0c_doit:\r
+       ld      (b0_save_hl),hl\r
+       ld      (b0_save_de),de\r
+       pop     hl\r
+       ld      (b0_save_af),hl\r
+\r
+       pop     de                      ;get ptr to 'function address' in de\r
+       ld      hl,2\r
+       add     hl,de\r
+       push    hl                      ;put return address on stack\r
+\r
+   if 0 ; link80\r
+\r
+       ld      hl,0\r
+       add     hl,sp                   ;\r
+       ld      a,h\r
+       cp      high (bs$stack-bs$stack$size) ;link80 can't process this\r
+       jr      nc,$ + 5                ;skip if stack allready in common bios ram\r
+\r
+   else\r
+\r
+       ld      hl,bs$stack-bs$stack$size\r
+       ld      a,h\r
+       dec     a\r
+       ld      hl,0\r
+       add     hl,sp                   ;\r
+       cp      h\r
+       jr      c,$ + 5                 ;skip if stack allready in common bios ram\r
+   endif\r
+       ld      sp,bs$stack             ;\r
+\r
+       push    hl                      ;save   user stack pointer\r
+\r
+       in0     h,(bbr)                 ;\r
+       push    hl                      ;\r
+       ld      hl,b0c_ret\r
+       push    hl\r
+       xor     a\r
+       out0    (bbr),a                 ;\r
+       ex      de,hl                   ;ptr\r
+       ld      e,(hl)                  ;get 'function address'\r
+       inc     hl                      ;\r
+       ld      d,(hl)                  ;\r
+       push    de                      ;put on (switched) stack\r
+\r
+       ld      hl,(b0_save_af)         ;get back users registers\r
+       push    hl\r
+       pop     af\r
+       ld      de,(b0_save_de)\r
+       ld      hl,(b0_save_hl)\r
+       ret                             ;go to function\r
+b0c_ret:\r
+       ld      (b0_save_hl),hl\r
+\r
+       pop     hl                      ;\r
+       out0    (bbr),h                 ;\r
+       pop     hl                      ;\r
+       ld      sp,hl                   ;\r
+       ld      hl,(b0_save_hl)\r
+       ret                             ;\r
+   else\r
+\r
+_b0call:\r
+       push    af\r
+       ld      (b0_save_hl),hl\r
+       ld      (b0_save_de),de\r
+       pop     hl\r
+       ld      (b0_save_af),hl\r
+\r
+       pop     de                      ;get ptr to 'function address' in de\r
+       ld      hl,2\r
+       add     hl,de\r
+       push    hl                      ;put return address on stack\r
+\r
+   if 0 ; link80\r
+\r
+       ld      hl,0\r
+       add     hl,sp                   ;\r
+       ld      a,h\r
+       cp      high (bs$stack-bs$stack$size) ;link80 can't process this\r
+       jr      nc,$ + 5                ;skip if stack allready in common bios ram\r
+\r
+   else\r
+\r
+       ld      hl,bs$stack-bs$stack$size\r
+       ld      a,h\r
+       dec     a\r
+       ld      hl,0\r
+       add     hl,sp                   ;\r
+       cp      h\r
+       jr      c,$ + 5                 ;skip if stack allready in common bios ram\r
+   endif\r
+       ld      sp,bs$stack             ;\r
+\r
+       push    hl                      ;save   user stack pointer\r
+\r
+       in0     h,(bbr)                 ;\r
+       push    hl                      ;\r
+       ld      hl,b0c_ret\r
+       push    hl\r
+       xor     a\r
+       out0    (bbr),a                 ;\r
+       ex      de,hl                   ;ptr\r
+       ld      e,(hl)                  ;get 'function address'\r
+       inc     hl                      ;\r
+       ld      d,(hl)                  ;\r
+       push    de                      ;put on (switched) stack\r
+\r
+       ld      hl,(b0_save_af)         ;get back users registers\r
+       push    hl\r
+       pop     af\r
+       ld      de,(b0_save_de)\r
+       ld      hl,(b0_save_hl)\r
+       ret                             ;go to function\r
+b0c_ret:\r
+       ld      (b0_save_hl),hl\r
+\r
+       pop     hl                      ;\r
+       out0    (bbr),h                 ;\r
+       pop     hl                      ;\r
+       ld      sp,hl                   ;\r
+       ld      hl,(b0_save_hl)\r
+       ret                             ;\r
+   endif\r
+\r
+b0_save_hl: dw 0\r
+b0_save_de: dw 0\r
+b0_save_af: dw 0\r
+\r
+\r
+;--------------------------------------------------------------------\r
+; Trampoline for interrupt routines in banked ram.\r
+; Switch stack pointer to "system" stack in top ram\r
+; Save bbr\r
+\r
+       cseg\r
+\r
+   if 0\r
+\r
+isv_sw:                                        ;\r
+       ex      (sp),hl                 ;save hl, 'return adr' in hl\r
+       push    de                      ;\r
+       push    af                      ;\r
+       ex      de,hl                   ;'return address' in de\r
+\r
+  if 0\r
+   if 0 ; link80\r
+\r
+       ld      hl,0\r
+       add     hl,sp                   ;\r
+       ld      a,h\r
+       cp      high (bs$stack-bs$stack$size) ;link80 can't process this\r
+       jr      nc,$ + 5                ;skip if stack allready in common bios ram\r
+\r
+   else\r
+\r
+       ld      hl,bs$stack-bs$stack$size\r
+       ld      a,h\r
+       dec     a\r
+       ld      hl,0\r
+       add     hl,sp                   ;\r
+       cp      h\r
+       jr      c,$ + 5                 ;skip if stack allready in common bios ram\r
+   endif\r
+       ld      sp,bs$stack             ;\r
+  else\r
+       ld      hl,0\r
+       add     hl,sp\r
+       ld      sp,istack\r
+  endif\r
+       push    hl                      ;save user stack pointer\r
+       in0     h,(bbr)                 ;\r
+       push    hl                      ;\r
+       xor     a                       ;\r
+       out0    (bbr),a                 ;\r
+       ex      de,hl                   ;\r
+       ld      e,(hl)                  ;\r
+       inc     hl                      ;\r
+       ld      d,(hl)                  ;\r
+       ex      de,hl                   ;\r
+       push    bc                      ;\r
+       call    ijphl                   ;\r
+\r
+       pop     bc                      ;\r
+       pop     hl                      ;\r
+       out0    (bbr),h                 ;\r
+       pop     hl                      ;\r
+       ld      sp,hl                   ;\r
+       pop     af                      ;\r
+       pop     de                      ;\r
+       pop     hl                      ;\r
+       ei                              ;\r
+       ret                             ;\r
+\r
+   else\r
+\r
+isv_sw:                                        ;\r
+       ex      (sp),hl                 ;save hl, 'return adr' in hl\r
+\r
+       ld      (istack),sp             ;save user stack pointer\r
+       ld      sp,istack\r
+       push    de                      ;\r
+       push    bc                      ;\r
+       push    af                      ;\r
+       in0     a,(bbr)                 ;\r
+       push    af                      ;\r
+       xor     a                       ;\r
+       out0    (bbr),a                 ;\r
+       ld      e,(hl)                  ;\r
+       inc     hl                      ;\r
+       ld      d,(hl)                  ;\r
+       ex      de,hl                   ;\r
+       call    ijphl                   ;\r
+\r
+       pop     af                      ;\r
+       out0    (bbr),a                 ;\r
+       pop     af                      ;\r
+       pop     bc                      ;\r
+       pop     de                      ;\r
+       ld      sp,(istack)             ;\r
+       pop     hl                      ;\r
+       ei                              ;\r
+       ret                             ;\r
+\r
+   endif\r
+       ds      24\r
+istack:\r
+       dw      0\r
+\r
+       dseg\r
+\r
+;--------------------------------------------------------------------\r
+; Load byte/word from user ram\r
+;\r
+;   de:  src address in users bank\r
+; return\r
+;    a:  value (byte)\r
+;   hl:  value (word)\r
+\r
+b_ld_a:\r
+       push    hl\r
+       or      a               ; clear carry == byte store\r
+       jr      $+3\r
+b_ld_hl:\r
+       scf                     ; set carry == word store\r
+       push    af              ; save flag\r
+       push    hl              ; make space on stack\r
+\r
+       ld      a,(@cbnk)\r
+       ld      b,a             ; b = src bank\r
+\r
+       ld      hl,0\r
+       ld      a,l\r
+       ld      c,l             ; c = dst bank (0)\r
+       add     hl,sp           ; hl = dst\r
+       adc     a,1             ; a = count\r
+       ex      de,hl\r
+       call    dma_move\r
+       ex      de,hl\r
+       pop     hl\r
+       pop     af\r
+       ret     c\r
+       ld      a,l\r
+       pop     hl\r
+       ret\r
+\r
+;--------------------------------------------------------------------\r
+; Store byte/word to user ram\r
+;\r
+;   de:  dst address in users bank\r
+;    a:  value (byte)\r
+;   hl:  value (word)\r
+\r
+b_st_a:\r
+       push    hl\r
+       ld      l,a\r
+       or      a               ; clear carry == byte store\r
+       jr      $+3\r
+b_st_hl:\r
+       scf                     ; set carry == word store\r
+       push    af              ; save flag\r
+       push    hl              ; put value on stack\r
+\r
+       ld      a,(@cbnk)       ;\r
+       ld      c,a             ; c = dst bank\r
+       ld      a,0\r
+       ld      l,a\r
+       ld      h,a\r
+       ld      b,a             ; b = src bank (0)\r
+       add     hl,sp           ; hl = src\r
+       adc     a,1             ; a = count\r
+\r
+       call    dma_move\r
+\r
+       pop     hl              ; restore value\r
+       pop     af              ; carry\r
+       ret     c\r
+       pop     hl\r
+       ret\r
+\r
+;--------------------------------------------------------------------\r
+;\r
+;    hl: src\r
+;    de: dst\r
+;     b: src bank\r
+;     c: dst bank\r
+;     a: count\r
+\r
+dma_move:\r
+       out0    (bcr0l),a       ; setup DMA count\r
+       xor     a\r
+       out0    (bcr0h),a\r
+\r
+       push    hl\r
+       ld      a,b\r
+       call    bnk2phy\r
+       out0    (sar0l),l       ; setup DMA src address\r
+       out0    (sar0h),h\r
+       out0    (sar0b),a\r
+\r
+       ld      l,e\r
+       ld      h,d\r
+       ld      a,c\r
+       call    bnk2phy\r
+       out0    (dar0l),l       ; setup DMA dst address\r
+       out0    (dar0h),h\r
+       out0    (dar0b),a\r
+\r
+       ld      a,M_MMOD        ; DMA burst mode\r
+       out0    (dmode),a\r
+       ld      a,M_DE0+M_NDWE1 ; enable DMA0\r
+       out0    (dstat),a       ; move ...\r
+       pop     hl\r
+       ret\r
+\r
+\r
+;====================================================================\r
+\r
+       cseg\r
+\r
+  if 0\r
+\r
+;--------------------------------------------------------------------\r
+; Return the BBR value for the given bank number\r
+\r
+bnk2bbr:\r
+       or      a               ; 4\r
+       ret     z               ; 5/10 | 11             14\r
+\r
+       push    bc              ;11 | 11\r
+       ld      b,a             ; 4\r
+       ld      c,CA            ; 6\r
+       mlt     bc              ;17                         >45\r
+       ld      a,c             ; 4\r
+       add     a,10h           ; 6\r
+       pop     bc              ; 9 | 10\r
+       ret                     ; 9 | 10                76\r
+\r
+       push    ix              ;2 / 14 | 15\r
+       ld      ix,bnktbl       ;4 / 12 | 14\r
+       ld      ($+3+2),a       ;3 / 15 | 19\r
+       ld      a,(ix+0)        ;3 / 14 | 19\r
+       pop     ix              ;2 / 12 | 14\r
+       ret                     ;1 /  9 | 10            15 / 76|91\r
+\r
+       push    hl              ;1 / 11 | 11\r
+       ld      hl,bnktbl       ;3 /  9 | 10\r
+       add     a,l             ;1 /  4 | 4\r
+       ld      l,a             ;1 /  4 | 4\r
+       ld      a,0             ;1 /  6 | 7\r
+       adc     a,h             ;1 /  4 | 4\r
+       ld      h,a             ;1 /  4 | 4\r
+       ld      a,(hl)          ;1 /  6 | 7\r
+       pop     hl              ;1 /  9 | 10\r
+       ret                     ;1 /  9 | 10            12 / 66|71\r
+\r
+       push    hl              ;1 / 11 | 11\r
+       add     a,low bnktbl    ;2 /  6 | 7\r
+       ld      l,a             ;1 /  4 | 4\r
+       ld      a,0             ;1 /  6 | 7\r
+       adc     a,high bnktbl   ;2 /  6 | 7\r
+       ld      h,a             ;1 /  4 | 4\r
+       ld      a,(hl)          ;1 /  6 | 7\r
+       pop     hl              ;1 /  9 | 10\r
+       ret                     ;1 /  9 | 10            11 / 61|67\r
+\r
+  endif\r
+\r
+\r
+       end\r