]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blobdiff - cbios/mm.180
Update IXON flag from character device table (@ctbl)
[z180-stamp-cpm3.git] / cbios / mm.180
index 8f63a2bf0d278137bd77af0f8a122e1e397f20c1..0c3fc363a3c782517ca0b4688b349ea1971131ad 100644 (file)
-       page    255
-       .z80
-
-
-       global mmuinit
-       global bnk2log,bnk2phy,hwl2phy
-
-       include config.inc
-       include z180reg.inc
-
-
-;----------------------------------------------------------------------
-; Memory Map:
-;
-;      Common  CAStart ...     0FFFF
-;      Bank 0    00000 ... CAStart-1
-;      Bank 1    10000 ...
-;      Bank 2
-;
-;----------------------------------------------------------------------
-
-       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
-
-bnk2log:
-       or      a               ;
-       ret     z               ; Bank 0 is at physical address 0
-
-       dec     a
-       push    bc              ;
-       ld      b,a             ;
-       ld      c,CA            ;
-       mlt     bc              ; bank size * bank number
-       ld      a,c             ;
-       add     a,10h           ; add bank0 + common
-       pop     bc              ;
-       ret                     ;
-
-;--------------------------------------------------------------
-
-;in  hl: Log. Address
-;     a: Bank number
-;
-;out ahl: Phys. (linear) Address
-
-
-bnk2phy:
-       call    bnk2log
-       ; 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                     ;
-
-;--------------------------------------------------------------
-;
-; de: Log. Address
-;
-;
-; OP: ahl = (bankbase<<12) + (d<<8) + e
-;
-;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                     ;
-
-
-;====================================================================
-
-  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
+       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      (i$stack),sp            ;save user stack pointer\r
+       ld      sp,i$stack\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,(i$stack)            ;\r
+       pop     hl                      ;\r
+       ei                              ;\r
+       ret                             ;\r
+\r
+   endif\r
+\r
+       public  i$stack\r
+       rept    24\r
+        db     '|'\r
+       endm\r
+i$stack:\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
+       cseg\r
+       public  bs$stack\r
+\r
+       rept bs$stack$size\r
+        db     '|'\r
+       endm\r
+bs$stack:\r
+       dw      0\r
+\r
+       end\r