page 255 .z80 global mmuinit global bnk2log,bnk2phy,hwl2phy,phy2log include config.inc include z180reg.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 ;==================================================================== 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