From: Leo C Date: Mon, 13 Jun 2016 15:34:12 +0000 (+0200) Subject: stack X-Git-Tag: hexrel-6.9~23 X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp-cpm3.git/commitdiff_plain/2a7e38b4febad6275ebb1fe6268b6b60c6b5abec stack --- diff --git a/cbios/mm.180 b/cbios/mm.180 index 9df0471..4128fe9 100644 --- a/cbios/mm.180 +++ b/cbios/mm.180 @@ -1,539 +1,639 @@ - 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 + .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 + + if 0 + +_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 ; + else + +_b0call: + push af + 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 ; + endif + +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 + + if 0 + +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 ; + + else + +isv_sw: ; + ex (sp),hl ;save hl, 'return adr' in hl + + ld (istack),sp ;save user stack pointer + ld sp,istack + push de ; + push bc ; + push af ; + in0 a,(bbr) ; + push af ; + xor a ; + out0 (bbr),a ; + ld e,(hl) ; + inc hl ; + ld d,(hl) ; + ex de,hl ; + call ijphl ; + + pop af ; + out0 (bbr),a ; + pop af ; + pop bc ; + pop de ; + ld sp,(istack) ; + pop hl ; + ei ; + ret ; + + endif + ds 24 +istack: + dw 0 + + 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