- page 255\r
- .z80\r
-\r
-\r
- global mmuinit\r
- global bnk2log,bnk2phy,hwl2phy,phy2log\r
-\r
- include config.inc\r
- include z180reg.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
-_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
-\r
-\r
-b0_save_hl: dw 0\r
-b0_save_de: dw 0\r
-b0_save_af: dw 0\r
-\r
-\r
-\r
-;====================================================================\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
+ page 255
+ .z80
+
+
+ public mmuinit
+ public bnk2log,bnk2phy,hwl2phy,phy2log
+ public isv_sw
+
+ 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
+
+
+;--------------------------------------------------------------------
+; 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 jphl ;
+
+ pop bc ;
+ pop hl ;
+ out0 (bbr),h ;
+ pop hl ;
+ ld sp,hl ;
+ pop af ;
+ pop de ;
+ pop hl ;
+ ei ;
+ ret ;
+jphl:
+ jp (hl) ;
+
+
+ ds 24
+istack:
+
+;====================================================================
+
+ 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