X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp-cpm3.git/blobdiff_plain/40df51aed30ddcd710c7356f8098516c27088392..1c7e396322093876bd5405aa6c2beed7c04608ec:/cbios/mm.180 diff --git a/cbios/mm.180 b/cbios/mm.180 index 9d1e256..9df0471 100644 --- a/cbios/mm.180 +++ b/cbios/mm.180 @@ -2,21 +2,38 @@ .z80 - global mmuinit - global bnk2log,bnk2phy,hwl2phy + public mmuinit + public bnk2log,bnk2phy,hwl2phy,phy2log + public isv_sw + public b_ld_a,b_ld_hl,b_st_a,b_st_hl - include config.inc - include z180reg.inc + + extrn @cbnk + extrn ijphl + + + maclib z180reg.inc + maclib config.inc ;---------------------------------------------------------------------- -; Memory Map: +; Memory Map 1: ; -; Common CAStart ... 0FFFF -; Bank 0 00000 ... CAStart-1 -; Bank 1 10000 ... +; 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 @@ -32,20 +49,55 @@ mmuinit: ; 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 + dec a ; push bc ; - ld b,a ; - ld c,CA ; + 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 @@ -62,13 +114,16 @@ bnk2phy: cp CA*16 ld a,c pop bc - jr c,b2p_banked - xor a ; address is in common - jr b2b_cont ; base is 0 + ; 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 -b2b_cont: ; fall thru @@ -102,10 +157,10 @@ l2p_i: ;-------------------------------------------------------------- ; -; de: Log. Address +; hl: Log. Address ; ; -; OP: ahl = (bankbase<<12) + (d<<8) + e +; OP: ahl = (bankbase<<12) + (h<<8) + l ; ;out ahl: Phys. (linear) Address @@ -137,6 +192,30 @@ hl2p_x: 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 @@ -232,9 +311,182 @@ 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 ;--------------------------------------------------------------------