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: push bc ld c,a ld a,h and a,0f0h cp CA*16 ld a,c pop bc jr c,b2p_banked xor a ; address is in common jr b2b_cont ; base is 0 b2p_banked: call bnk2log ; get address base b2b_cont: ; 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 ; ;-------------------------------------------------------------- ; 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 ;==================================================================== 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