From 4cd9d9817858107c42aaebd868942f882a6dcd6a Mon Sep 17 00:00:00 2001 From: Leo C Date: Thu, 9 Jun 2016 16:36:28 +0200 Subject: [PATCH] Convert line endings of some source files (back) to CR/LF. SLR180 works with both, CR/LF and LF only, but M80 does not. --- cbios/drvtbl.180 | 26 +- cbios/misc.180 | 432 +++++++++++++------------- cbios/mm.180 | 718 +++++++++++++++++++++---------------------- cbios/move.180 | 254 ++++++++-------- cbios/time.180 | 416 ++++++++++++------------- cbios/utils.180 | 776 +++++++++++++++++++++++------------------------ 6 files changed, 1311 insertions(+), 1311 deletions(-) diff --git a/cbios/drvtbl.180 b/cbios/drvtbl.180 index dc2d59c..41d8cfb 100644 --- a/cbios/drvtbl.180 +++ b/cbios/drvtbl.180 @@ -1,13 +1,13 @@ - public @dtbl - extrn sd0,sd1,sd2,sd3 - extrn sd4,sd5,sd6,sd7 - extrn cf0,cf1,cf2,cf3 - - cseg - -@dtbl dw sd0,sd1,sd2,sd3 ; drives A-D - dw sd4,sd5,sd6,sd7 ; drives E-H - dw cf0,cf1,cf2,cf3 ; drives I-L - dw 0,0,0,0 ; drives M-P - - end + public @dtbl + extrn sd0,sd1,sd2,sd3 + extrn sd4,sd5,sd6,sd7 + extrn cf0,cf1,cf2,cf3 + + cseg + +@dtbl dw sd0,sd1,sd2,sd3 ; drives A-D + dw sd4,sd5,sd6,sd7 ; drives E-H + dw cf0,cf1,cf2,cf3 ; drives I-L + dw 0,0,0,0 ; drives M-P + + end diff --git a/cbios/misc.180 b/cbios/misc.180 index d39f632..28c0123 100644 --- a/cbios/misc.180 +++ b/cbios/misc.180 @@ -1,216 +1,216 @@ - - public intinit - public bufinit - public cpu_frq - public get_tmr - - public fifolst - - extrn div32_r,?pmsg - extrn msg.sm,msg.recv,hwl2phy - - include config.inc - include z180reg.inc - - -;---------------------------------------------------------------------- - - dseg - -intinit: - ld hl,ivtab ; - ld a,h ; - ld i,a ; - out0 (il),l ; - im 2 - -; Let all vectors point to spurious int routines. - - ld de,sp.int0 - ld bc,sp.int.len - ld a,9 -ivt_i1: - ld (hl),e - inc l - ld (hl),d - inc l - ex de,hl - add hl,bc - ex de,hl - dec a - jr nz,ivt_i1 - ret - - -;-------------------------------------------------------------------- -; Spurious interrupt handler - - cseg ; common area -sp.int0: - ld a,00h - jr sp.i.1 -sp.int.len equ $-sp.int0 - ld a,01h - jr sp.i.1 - ld a,02h - jr sp.i.1 - ld a,03h - jr sp.i.1 - ld a,04h - jr sp.i.1 - ld a,05h - jr sp.i.1 - ld a,06h - jr sp.i.1 - ld a,07h - jr sp.i.1 - ld a,08h -sp.i.1: -; out (80h),a - - add a,'0' - ld (spi$nr),a - ld hl,spi$msg - call ?pmsg -sp.i.2: - halt - jr sp.i.2 - -spi$msg: - db 13,10,'Spurious Int: ' -spi$nr: db '0' - db 0 - -;-------------------------------------------------------------------- -; -; Get/compute CPU clock -; -; return: -; hlde: CPU frequency (Hz) -; - - dseg - -cpu_frq: - ld hl,0 - ld d,h - ld e,l - call get_tmr - push de - push hl - -; delay ~8ms @ 18.432MHz --> 147456 clock cycles -; delay ~10ms @ 18.432MHz --> 184320 clock cycles -; - -; ld hl,8192 ; 147456/18 - ld hl,(10240-100)*5 ; 184320/18 - ld de,1 - or a -dly_lp: - sbc hl,de ; 10 - jr nz,dly_lp ; 6/8 -> 18 cycles - - pop hl - pop de - call get_tmr - - ld b,h - ld c,l - ld de,036EEh ;18432000/(2**16) * 50 - ld hl,08000h ;18432000%(2**16) * 50 - - ld a,b - or a - jr nz,cpuf_div - ld a,c - cp 2 - jr c,cpuf_done -cpuf_div: - call div32_r -cpuf_done: - ret - -;-------------------------------------------------------------------- - - dseg -get_tmr: - push de - push hl - ld hl,1*256 + 3 ; h = subcommand, l = command - push hl - ld hl,0 - add hl,sp - ld b,6 - call msg.sm - - dec sp - ld hl,0 - add hl,sp - ld b,7 ; max receive message len - call msg.recv - - pop bc - inc sp - pop hl - pop de - ret - -;-------------------------------------------------------------------- - - dseg - -fifolst: - rept 4 - dw 0 - endm - -;-------------------------------------------------------------------- - - dseg - -bufinit: - ld (ix+o.in_idx),0 ;reset pointers (empty fifo) - ld (ix+o.out_idx),0 - ld a,(ix+o.id) - ld hl,fifolst - ld e,a - ld d,0 - add hl,de - add hl,de - push ix - pop de - cp 4 - jr nc,bfi_skip - - ld (hl),e - inc hl - ld (hl),d - -bfi_skip: - ex de,hl - call hwl2phy ;get phys. address of fifo - ld c,a - ld a,(ix+o.id) ;fifo id - or a ;test if fifo 0 - ret z - - ld b,a - push bc ;c: bank-addr, b: ignored - push hl ;address - ld c,0 - push bc ;c: function, b:subf - ld b,5 - ld h,c - ld l,c - add hl,sp - call msg.sm - pop hl - pop hl - pop hl - ret - -;---------------------------------------------------------------------- - - - end + + public intinit + public bufinit + public cpu_frq + public get_tmr + + public fifolst + + extrn div32_r,?pmsg + extrn msg.sm,msg.recv,hwl2phy + + include config.inc + include z180reg.inc + + +;---------------------------------------------------------------------- + + dseg + +intinit: + ld hl,ivtab ; + ld a,h ; + ld i,a ; + out0 (il),l ; + im 2 + +; Let all vectors point to spurious int routines. + + ld de,sp.int0 + ld bc,sp.int.len + ld a,9 +ivt_i1: + ld (hl),e + inc l + ld (hl),d + inc l + ex de,hl + add hl,bc + ex de,hl + dec a + jr nz,ivt_i1 + ret + + +;-------------------------------------------------------------------- +; Spurious interrupt handler + + cseg ; common area +sp.int0: + ld a,00h + jr sp.i.1 +sp.int.len equ $-sp.int0 + ld a,01h + jr sp.i.1 + ld a,02h + jr sp.i.1 + ld a,03h + jr sp.i.1 + ld a,04h + jr sp.i.1 + ld a,05h + jr sp.i.1 + ld a,06h + jr sp.i.1 + ld a,07h + jr sp.i.1 + ld a,08h +sp.i.1: +; out (80h),a + + add a,'0' + ld (spi$nr),a + ld hl,spi$msg + call ?pmsg +sp.i.2: + halt + jr sp.i.2 + +spi$msg: + db 13,10,'Spurious Int: ' +spi$nr: db '0' + db 0 + +;-------------------------------------------------------------------- +; +; Get/compute CPU clock +; +; return: +; hlde: CPU frequency (Hz) +; + + dseg + +cpu_frq: + ld hl,0 + ld d,h + ld e,l + call get_tmr + push de + push hl + +; delay ~8ms @ 18.432MHz --> 147456 clock cycles +; delay ~10ms @ 18.432MHz --> 184320 clock cycles +; + +; ld hl,8192 ; 147456/18 + ld hl,(10240-100)*5 ; 184320/18 + ld de,1 + or a +dly_lp: + sbc hl,de ; 10 + jr nz,dly_lp ; 6/8 -> 18 cycles + + pop hl + pop de + call get_tmr + + ld b,h + ld c,l + ld de,036EEh ;18432000/(2**16) * 50 + ld hl,08000h ;18432000%(2**16) * 50 + + ld a,b + or a + jr nz,cpuf_div + ld a,c + cp 2 + jr c,cpuf_done +cpuf_div: + call div32_r +cpuf_done: + ret + +;-------------------------------------------------------------------- + + dseg +get_tmr: + push de + push hl + ld hl,1*256 + 3 ; h = subcommand, l = command + push hl + ld hl,0 + add hl,sp + ld b,6 + call msg.sm + + dec sp + ld hl,0 + add hl,sp + ld b,7 ; max receive message len + call msg.recv + + pop bc + inc sp + pop hl + pop de + ret + +;-------------------------------------------------------------------- + + dseg + +fifolst: + rept 4 + dw 0 + endm + +;-------------------------------------------------------------------- + + dseg + +bufinit: + ld (ix+o.in_idx),0 ;reset pointers (empty fifo) + ld (ix+o.out_idx),0 + ld a,(ix+o.id) + ld hl,fifolst + ld e,a + ld d,0 + add hl,de + add hl,de + push ix + pop de + cp 4 + jr nc,bfi_skip + + ld (hl),e + inc hl + ld (hl),d + +bfi_skip: + ex de,hl + call hwl2phy ;get phys. address of fifo + ld c,a + ld a,(ix+o.id) ;fifo id + or a ;test if fifo 0 + ret z + + ld b,a + push bc ;c: bank-addr, b: ignored + push hl ;address + ld c,0 + push bc ;c: function, b:subf + ld b,5 + ld h,c + ld l,c + add hl,sp + call msg.sm + pop hl + pop hl + pop hl + ret + +;---------------------------------------------------------------------- + + + end diff --git a/cbios/mm.180 b/cbios/mm.180 index d9efd16..b4e6f61 100644 --- a/cbios/mm.180 +++ b/cbios/mm.180 @@ -1,359 +1,359 @@ - 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 + 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 diff --git a/cbios/move.180 b/cbios/move.180 index aac1840..bfe3207 100644 --- a/cbios/move.180 +++ b/cbios/move.180 @@ -1,127 +1,127 @@ - title 'Bank & Move Module for the Modular CP/M 3 BIOS' - -; CP/M-80 Version 3 -- Modular BIOS -; Bank and Move Module for Z180-Stamp -; Initial version 1.0 -; Compile with M80, slr180, or compatible - - public ?move,?xmove,?bank - - extrn bnk2log,bnk2phy - extrn @cbnk - - - include config.inc - include z180reg.inc - - - cseg ; must be in common memory - -?xmove: - if banked - ld (src$bnk),bc ; c -> src$bnk, b -> dst$bnk - endif - ret - -?move: - ex de,hl ; we are passed source in DE and dest in HL - if banked - ld a,(src$bnk) ; contains 0FEh if normal block move - cp 0FEh - jr nz,inter_bank_move - endif - ldir ; use Z80 block move instruction - ex de,hl ; need next address in same regs - ret - -; select bank in A - -?bank: - if banked - call bnk2log - out0 (bbr),a - endif - ret - - if banked - -inter_bank_move: ; source in HL, dest in DE, count in BC - - if 1 ; works with new memory map - - out0 (bcr0l),c ; setup DMA count - out0 (bcr0h),b - - push hl - push de - ld a,(src$bnk) - call bnk2phy - out0 (sar0l),l ; setup DMA src address - out0 (sar0h),h - out0 (sar0b),a - - ex de,hl - ld a,(dst$bnk) - 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 the block - - pop de - pop hl - add hl,bc ; src must point past end block - ex de,hl - add hl,bc ; and so must dst - ld bc,0 - - ld a,0FEh - ld (src$bnk),a - - ret ; return with src in DE, dst in HL, count = 0 - - else ; inefficient fall back - - ld (tmp$sp),sp - ld sp,tmp$stk - ex af,af' ; - push af -mv$blk: - ld a,(src$bnk) ; - call ?bank - ld a,(hl) - ex af,af' ; - ld a,(dst$bnk) - call ?bank - ex af,af' ; - ld (de),a - inc de - cpi - jp pe,mv$blk - ld a,(@cbnk) - call ?bank - ld a,0FEh - ld (src$bnk),a - ex de,hl - pop af - ex af,af' ; - ld sp,(tmp$sp) - ret - - ds 16 -tmp$stk: -tmp$sp: ds 2 - - endif - -src$bnk: db 0FEh -dst$bnk: db 0FEh - - - endif ;banked - - end + title 'Bank & Move Module for the Modular CP/M 3 BIOS' + +; CP/M-80 Version 3 -- Modular BIOS +; Bank and Move Module for Z180-Stamp +; Initial version 1.0 +; Compile with M80, slr180, or compatible + + public ?move,?xmove,?bank + + extrn bnk2log,bnk2phy + extrn @cbnk + + + include config.inc + include z180reg.inc + + + cseg ; must be in common memory + +?xmove: + if banked + ld (src$bnk),bc ; c -> src$bnk, b -> dst$bnk + endif + ret + +?move: + ex de,hl ; we are passed source in DE and dest in HL + if banked + ld a,(src$bnk) ; contains 0FEh if normal block move + cp 0FEh + jr nz,inter_bank_move + endif + ldir ; use Z80 block move instruction + ex de,hl ; need next address in same regs + ret + +; select bank in A + +?bank: + if banked + call bnk2log + out0 (bbr),a + endif + ret + + if banked + +inter_bank_move: ; source in HL, dest in DE, count in BC + + if 1 ; works with new memory map + + out0 (bcr0l),c ; setup DMA count + out0 (bcr0h),b + + push hl + push de + ld a,(src$bnk) + call bnk2phy + out0 (sar0l),l ; setup DMA src address + out0 (sar0h),h + out0 (sar0b),a + + ex de,hl + ld a,(dst$bnk) + 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 the block + + pop de + pop hl + add hl,bc ; src must point past end block + ex de,hl + add hl,bc ; and so must dst + ld bc,0 + + ld a,0FEh + ld (src$bnk),a + + ret ; return with src in DE, dst in HL, count = 0 + + else ; inefficient fall back + + ld (tmp$sp),sp + ld sp,tmp$stk + ex af,af' ; + push af +mv$blk: + ld a,(src$bnk) ; + call ?bank + ld a,(hl) + ex af,af' ; + ld a,(dst$bnk) + call ?bank + ex af,af' ; + ld (de),a + inc de + cpi + jp pe,mv$blk + ld a,(@cbnk) + call ?bank + ld a,0FEh + ld (src$bnk),a + ex de,hl + pop af + ex af,af' ; + ld sp,(tmp$sp) + ret + + ds 16 +tmp$stk: +tmp$sp: ds 2 + + endif + +src$bnk: db 0FEh +dst$bnk: db 0FEh + + + endif ;banked + + end diff --git a/cbios/time.180 b/cbios/time.180 index 1c63144..2eb8123 100644 --- a/cbios/time.180 +++ b/cbios/time.180 @@ -1,208 +1,208 @@ - title 'Time module for the Modular CP/M 3 BIOS' - - public ?time, gs_rtc - public prt0ini - public gtimer,gstimer - - extrn @date,@hour,@min,@sec - extrn f_cpu - extrn ioiniml,div32_16 - extrn msg.sm,msg.recv - extrn _b0call - - include config.inc - include z180reg.inc - - -;---------------------------------------------------------------------- -; c == 00h: get time -; c == ffh: set time - - cseg ; time must be done from resident memory -?time: - inc c ;zero if ff - ld c,3 - jr z,time_set - - ld a,(time_to) - or a - ret nz - - dec c -time_set: - b0call gs_rtc - ld a,0ffh - ld (time_to),a - ret - -;---------------------------------------------------------------------- -; c = 2: get time -; c = 3: set time - - dseg -gs_rtc: - - push hl - push de - - ld hl,(@date) - ld a,(@hour) - ld d,a - ld a,(@min) - ld e,a - ld a,(@sec) - ld b,a ;b = sec, c = subcommand - push hl ;2 - push de ;4 - push bc ;6 - ld hl,3 * 256 + 0 ;h = command, l = 0 - push hl ;8 - - ld h,l ;hl = 0 - add hl,sp - push hl - inc hl ;7 - - ld b,7 - call msg.sm - - pop hl ;8 - ld b,8 ; max receive message len - call msg.recv - - pop hl ;len/command (discard) - pop bc ;subc/sec - pop de - pop hl - ld a,b - ld (@sec),a - ld a,e - ld (@min),a - ld a,d - ld (@hour),a - ld (@date),hl - - pop de - pop hl - ret - -;---------------------------------------------------------------------- - -;uint32_t get_timer(uint32_t base) -;{ -; uint32_t ret; -; ATOMIC_BLOCK(ATOMIC_FORCEON) -; { -; ret = timestamp; -; } -; return ret - base; -;} - - dseg ; called from banked only -gstimer: - push de - ex de,hl - ld hl,(uptime) - or a - sbc hl,de - pop de - ret - -;---------------------------------------------------------------------- - -gtimer: - push bc - ld b,h - ld c,l - or a - di - ld hl,(uptime) - sbc hl,bc - push hl - ei - ld hl,(uptime+2) - sbc hl,de - ex de,hl - pop hl - pop bc - ret - -;---------------------------------------------------------------------- -; intit timer interrupt - - dseg - -prt0ini: - in0 a,(tcr) - push af - and ~(M_TIE0+M_TDE0) ;stop timer 0 - out0 (tcr),a - - ld a,i - ld h,a - in0 a,(il) - and 0E0h - or IV$PRT0 - ld l,a - ld de,isvprt0 - ld (hl),e - inc hl - ld (hl),d - - ld hl,(f_cpu) - ld de,(f_cpu+2) - ld bc,PRT_PRE * 800 ;1/800 s == 1,25 ms interrupt rate - call div32_16 - - out0 (tmdr0l),l - out0 (tmdr0h),h - out0 (rldr0l),l - out0 (rldr0h),h - pop af - or (M_TIE0+M_TDE0) - out0 (tcr),a - ret - - -;---------------------------------------------------------------------- -; timer interrupt -; -; 1,25 ms clock tick - - - cseg ;common! -isvprt0: - push af - in0 a,(tcr) ;reset TIF0 flag - in0 a,(tmdr0l) - in0 a,(tmdr0h) - - push hl ;11 - ld hl,uptime ; 9 - inc (hl) ;10 - jr nz,iprt_1 ;6/8 38 - inc hl ; 4 - inc (hl) ;10 - jr nz,iprt_1 ;6/8 58 - inc hl ; 4 - inc (hl) ;10 - jr nz,iprt_1 ;6/8 - inc hl ; 4 - inc (hl) ;10 -iprt_1: - pop hl ; 9 - ld a,(time_to) - sub a,1 - jr c,iprt_0 - ld (time_to),a -iprt_0: - pop af - ei - ret - -uptime: - dw 0,0 -time_to: - db 0 - - end + title 'Time module for the Modular CP/M 3 BIOS' + + public ?time, gs_rtc + public prt0ini + public gtimer,gstimer + + extrn @date,@hour,@min,@sec + extrn f_cpu + extrn ioiniml,div32_16 + extrn msg.sm,msg.recv + extrn _b0call + + include config.inc + include z180reg.inc + + +;---------------------------------------------------------------------- +; c == 00h: get time +; c == ffh: set time + + cseg ; time must be done from resident memory +?time: + inc c ;zero if ff + ld c,3 + jr z,time_set + + ld a,(time_to) + or a + ret nz + + dec c +time_set: + b0call gs_rtc + ld a,0ffh + ld (time_to),a + ret + +;---------------------------------------------------------------------- +; c = 2: get time +; c = 3: set time + + dseg +gs_rtc: + + push hl + push de + + ld hl,(@date) + ld a,(@hour) + ld d,a + ld a,(@min) + ld e,a + ld a,(@sec) + ld b,a ;b = sec, c = subcommand + push hl ;2 + push de ;4 + push bc ;6 + ld hl,3 * 256 + 0 ;h = command, l = 0 + push hl ;8 + + ld h,l ;hl = 0 + add hl,sp + push hl + inc hl ;7 + + ld b,7 + call msg.sm + + pop hl ;8 + ld b,8 ; max receive message len + call msg.recv + + pop hl ;len/command (discard) + pop bc ;subc/sec + pop de + pop hl + ld a,b + ld (@sec),a + ld a,e + ld (@min),a + ld a,d + ld (@hour),a + ld (@date),hl + + pop de + pop hl + ret + +;---------------------------------------------------------------------- + +;uint32_t get_timer(uint32_t base) +;{ +; uint32_t ret; +; ATOMIC_BLOCK(ATOMIC_FORCEON) +; { +; ret = timestamp; +; } +; return ret - base; +;} + + dseg ; called from banked only +gstimer: + push de + ex de,hl + ld hl,(uptime) + or a + sbc hl,de + pop de + ret + +;---------------------------------------------------------------------- + +gtimer: + push bc + ld b,h + ld c,l + or a + di + ld hl,(uptime) + sbc hl,bc + push hl + ei + ld hl,(uptime+2) + sbc hl,de + ex de,hl + pop hl + pop bc + ret + +;---------------------------------------------------------------------- +; intit timer interrupt + + dseg + +prt0ini: + in0 a,(tcr) + push af + and ~(M_TIE0+M_TDE0) ;stop timer 0 + out0 (tcr),a + + ld a,i + ld h,a + in0 a,(il) + and 0E0h + or IV$PRT0 + ld l,a + ld de,isvprt0 + ld (hl),e + inc hl + ld (hl),d + + ld hl,(f_cpu) + ld de,(f_cpu+2) + ld bc,PRT_PRE * 800 ;1/800 s == 1,25 ms interrupt rate + call div32_16 + + out0 (tmdr0l),l + out0 (tmdr0h),h + out0 (rldr0l),l + out0 (rldr0h),h + pop af + or (M_TIE0+M_TDE0) + out0 (tcr),a + ret + + +;---------------------------------------------------------------------- +; timer interrupt +; +; 1,25 ms clock tick + + + cseg ;common! +isvprt0: + push af + in0 a,(tcr) ;reset TIF0 flag + in0 a,(tmdr0l) + in0 a,(tmdr0h) + + push hl ;11 + ld hl,uptime ; 9 + inc (hl) ;10 + jr nz,iprt_1 ;6/8 38 + inc hl ; 4 + inc (hl) ;10 + jr nz,iprt_1 ;6/8 58 + inc hl ; 4 + inc (hl) ;10 + jr nz,iprt_1 ;6/8 + inc hl ; 4 + inc (hl) ;10 +iprt_1: + pop hl ; 9 + ld a,(time_to) + sub a,1 + jr c,iprt_0 + ld (time_to),a +iprt_0: + pop af + ei + ret + +uptime: + dw 0,0 +time_to: + db 0 + + end diff --git a/cbios/utils.180 b/cbios/utils.180 index 613cec0..bbe5ac3 100644 --- a/cbios/utils.180 +++ b/cbios/utils.180 @@ -1,388 +1,388 @@ - title 'general utility routines' - - ; i/o port init routines - - public ioiniml,ioini1l ; - - ; math - - public add_hla ; add a to hl - public div32_16,div32_r ; divide 32 bit by 16 bit number (rounded) - - ; print utils - - public ?pmsg ; print message - public pr.inln,pr.crlf ; print message inline, print newline - public phex2,phex4 ; print 2 digit hex (A) or 4 digit hex (HL) - public pr.dec,pr.decl ; print 16 or 32 bit decimal number - public ?pderr ; print BIOS disk error message header - - - - extrn ?cono - extrn @adrv,@trk,@sect ; used by disk error message - -;------------------------------------------------------------------------------- - -cr equ 13 -lf equ 10 -bell equ 7 - - - dseg - -;---------------------------------------------------------------------- -; output bytes to consecutive portaddresses -; -; hl: table with following structure: -; db n, port1, val1, val2,... valn -; db m, port1, val1, val2,... valm -; ... -; db 0 ; Terminate table - -ioiniml: - push bc - xor a -ioml_lp: - ld b,(hl) - inc hl - cp b - jr z,ioml_e - - ld c,(hl) - inc hl - otimr - jr ioml_lp -ioml_e: - pop bc - ret - -;---------------------------------------------------------------------- -; output bytes to ports -; -; hl: tables of port,value pairs: -; db n, port1,val1, port2,val2,... portn,valn -; ... -; db 0 ; Terminate table - -ioini1l: - push bc - jr io1_nxt -io1_lp: - ld c,(hl) ;port address - inc hl - otim - jr nz,io1_lp -io1_nxt: - ld b,(hl) ;count - inc hl - inc b - djnz io1_lp - - pop bc - ret - -;-------------------------------------------------------------------- -; add a to hl -; -; return: -; hl = hl + a -; Flags undefined - -add_hla: - add a,l - ld l,a - ret nc - inc h - ret - -;-------------------------------------------------------------------- -; rounded div 32 by 16 bit -; -; DEHL: Dividend (x) -; BC: Divisor (y) -; return: -; HLDE: Rounded Quotient (q) -; BC: Remainder (r) - -div32_r: - push bc - srl b ;y/2 - rr c - add hl,bc ;low x + y/2 - pop bc - jr nc,div_r1 - inc de -div_r1: - ;fall thru - -;-------------------------------------------------------------------- -; Divide 32 bit by 16 -; -; DEHL: Dividend (x) -; BC: Divisor (y) -; -; return: -; DEHL: Quotient -; BC: Reminder - -div32_16: - exx ;low - push de ;save alternate registers (de,bc) - push bc - exx ;high - push hl ;lx - push bc ;ly - ld bc,0 ;bc = hy = 0 - ld h,b ;hl = hr = 0 - ld l,c - ;de = x, hl = r - exx ;low - pop bc ;bc' = ly - ex (sp),hl ;hl' = lx, save alternate hl - ld de,0 ;de' = lr = 0 - ex de,hl ;de = x, hl = r - exx ;high - ld a,32 ;count -; -; start: -; de: x (de: hx, de': lx) -; bc: y (bc: hy, bc': ly) -; hl: 0 -; -div_lp: ;do - exx ; low - ex de,hl ; x - add hl,hl ; x <<= 1 - exx ; high - ex de,hl ; x - adc hl,hl ; x <<= 1 - exx ; low - ex de,hl ; r - adc hl,hl ; r <<= 1 - exx ; high - ex de,hl ; r - adc hl,hl ; r <<= 1 - exx ; low - inc de ; x/q += 1 - or a ; - sbc hl,bc ; - exx ; high - sbc hl,bc ; - jr nc,div_no_restore - exx ; low - dec de ; - add hl,bc ; r += y - exx ; high - adc hl,bc ; - -div_no_restore: ; - dec a ; - jr nz,div_lp ;while (--count) - -; result: -; de: q (de: hq, de': lq) -; hl: r (hl: hr, hl': lr) - - exx ;low - ex de,hl ;hl = lq, de = lr - - ex (sp),hl ;lq - push de ;lr - exx ;high - pop bc ;bc = lr - pop hl ;de = lq - - exx ;low - pop bc ;restore alternate registers - pop de - exx ;high - ret - -;------------------------------------------------------------------------------- -; print message @ up to a null -; saves & - -?pmsg: - push bc - push de -pmsg$loop: - ld a,(hl) - inc hl - or a - jr z,pmsg$exit - ld c,a - push hl - call ?cono - pop hl - jr pmsg$loop -pmsg$exit: - pop de - pop bc - ret - -;------------------------------------------------------------------------------- -; print message inline up to a null -; saves all registers - -pr.inln: - ex (sp),hl - push af - call ?pmsg - pop af - ex (sp),hl - ret - -;------------------------------------------------------------------------------- -; print -; saves all registers - -pr.crlf: - call pr.inln - db cr,lf,0 - ret - -;------------------------------------------------------------------------------- -; print hl as a 4 digit hexadecimal number -; saves all registers - -phex4: - ld a,h - call phex2 - ld a,l - ; fall thru - -;------------------------------------------------------------------------------- -; print a as a 2 digit hexadecimal number -; saves all registers - -phex2: - push af - rra - rra - rra - rra - call print.digit - pop af - -print.digit: - push hl - push de - push bc - push af - and 00fh - cp 10 - jr c,prd_1 - add a,007h -prd_1: - add a,'0' - - ld c,a - call ?cono - pop af - pop bc - pop de - pop hl - ret - - -;------------------------------------------------------------------------------- -; print decimal 16 bit number from HL -; -; HL: unsigned binary number to print -; C: minimum print field width -; number is prined right-aligned -; B: pad character, typically ' ' or '0' - -pr.dec: - push de - ld de,0 - call pr.decl - pop de - ret - -;------------------------------------------------------------------------------- -; print decimal 32 bit number from DEHL -; -; DEHL: unsigned binary number to print -; C: minimum print field width -; number is prined right-aligned -; B: pad character, typically ' ' or '0' - -pr.decl: - push bc ;save width and fillchar - push bc - exx ;(alt) - ex (sp),hl ;save hl', get width and fill - push de ;save de' - - xor a - ld d,a ;clear counter - ld e,a - push af ; string terminator - inc sp - -prd_divloop: ;do - exx ; (main) - ld bc,10 ; - call div32_16 ; get a digit - ld a,c ; - add a,'0' ; make it printable - push af ; - - ld a,h ; - or l ; - or d ; - or e ; - exx ; (alt) - inc sp ; - inc de ; - jr nz,prd_divloop ; - -prd_filloop: ;h=filler, l=field width - ld a,e - cp l - jr nc,prd_out - push hl - inc sp - inc de - jr prd_filloop -prd_out: - ld hl,0 - add hl,sp ;ptr to beginning of number string (hl==0 here) - call ?pmsg - ex de,hl - add hl,sp - ld sp,hl - inc sp ;remove string terminator - pop de - pop hl - exx ;(main) - pop bc - ret - - -;------------------------------------------------------------------------------- - -?pderr: - ld hl,drive$msg - call ?pmsg ; error header - ld a,(@adrv) - add a,'A' - ld c,a - call ?cono ; drive code - ld hl,track$msg - call ?pmsg ; track header - ld c,0 - ld hl,(@trk) - call pr.dec ; track number - ld hl,sector$msg - call ?pmsg ; sector header - ld hl,(@sect) - call pr.dec ; sector number - ret - - ; error message components -drive$msg: db cr,lf,bell,'BIOS Error on ',0 -track$msg: db ': T-',0 -sector$msg: db ', S-',0 + title 'general utility routines' + + ; i/o port init routines + + public ioiniml,ioini1l ; + + ; math + + public add_hla ; add a to hl + public div32_16,div32_r ; divide 32 bit by 16 bit number (rounded) + + ; print utils + + public ?pmsg ; print message + public pr.inln,pr.crlf ; print message inline, print newline + public phex2,phex4 ; print 2 digit hex (A) or 4 digit hex (HL) + public pr.dec,pr.decl ; print 16 or 32 bit decimal number + public ?pderr ; print BIOS disk error message header + + + + extrn ?cono + extrn @adrv,@trk,@sect ; used by disk error message + +;------------------------------------------------------------------------------- + +cr equ 13 +lf equ 10 +bell equ 7 + + + dseg + +;---------------------------------------------------------------------- +; output bytes to consecutive portaddresses +; +; hl: table with following structure: +; db n, port1, val1, val2,... valn +; db m, port1, val1, val2,... valm +; ... +; db 0 ; Terminate table + +ioiniml: + push bc + xor a +ioml_lp: + ld b,(hl) + inc hl + cp b + jr z,ioml_e + + ld c,(hl) + inc hl + otimr + jr ioml_lp +ioml_e: + pop bc + ret + +;---------------------------------------------------------------------- +; output bytes to ports +; +; hl: tables of port,value pairs: +; db n, port1,val1, port2,val2,... portn,valn +; ... +; db 0 ; Terminate table + +ioini1l: + push bc + jr io1_nxt +io1_lp: + ld c,(hl) ;port address + inc hl + otim + jr nz,io1_lp +io1_nxt: + ld b,(hl) ;count + inc hl + inc b + djnz io1_lp + + pop bc + ret + +;-------------------------------------------------------------------- +; add a to hl +; +; return: +; hl = hl + a +; Flags undefined + +add_hla: + add a,l + ld l,a + ret nc + inc h + ret + +;-------------------------------------------------------------------- +; rounded div 32 by 16 bit +; +; DEHL: Dividend (x) +; BC: Divisor (y) +; return: +; HLDE: Rounded Quotient (q) +; BC: Remainder (r) + +div32_r: + push bc + srl b ;y/2 + rr c + add hl,bc ;low x + y/2 + pop bc + jr nc,div_r1 + inc de +div_r1: + ;fall thru + +;-------------------------------------------------------------------- +; Divide 32 bit by 16 +; +; DEHL: Dividend (x) +; BC: Divisor (y) +; +; return: +; DEHL: Quotient +; BC: Reminder + +div32_16: + exx ;low + push de ;save alternate registers (de,bc) + push bc + exx ;high + push hl ;lx + push bc ;ly + ld bc,0 ;bc = hy = 0 + ld h,b ;hl = hr = 0 + ld l,c + ;de = x, hl = r + exx ;low + pop bc ;bc' = ly + ex (sp),hl ;hl' = lx, save alternate hl + ld de,0 ;de' = lr = 0 + ex de,hl ;de = x, hl = r + exx ;high + ld a,32 ;count +; +; start: +; de: x (de: hx, de': lx) +; bc: y (bc: hy, bc': ly) +; hl: 0 +; +div_lp: ;do + exx ; low + ex de,hl ; x + add hl,hl ; x <<= 1 + exx ; high + ex de,hl ; x + adc hl,hl ; x <<= 1 + exx ; low + ex de,hl ; r + adc hl,hl ; r <<= 1 + exx ; high + ex de,hl ; r + adc hl,hl ; r <<= 1 + exx ; low + inc de ; x/q += 1 + or a ; + sbc hl,bc ; + exx ; high + sbc hl,bc ; + jr nc,div_no_restore + exx ; low + dec de ; + add hl,bc ; r += y + exx ; high + adc hl,bc ; + +div_no_restore: ; + dec a ; + jr nz,div_lp ;while (--count) + +; result: +; de: q (de: hq, de': lq) +; hl: r (hl: hr, hl': lr) + + exx ;low + ex de,hl ;hl = lq, de = lr + + ex (sp),hl ;lq + push de ;lr + exx ;high + pop bc ;bc = lr + pop hl ;de = lq + + exx ;low + pop bc ;restore alternate registers + pop de + exx ;high + ret + +;------------------------------------------------------------------------------- +; print message @ up to a null +; saves & + +?pmsg: + push bc + push de +pmsg$loop: + ld a,(hl) + inc hl + or a + jr z,pmsg$exit + ld c,a + push hl + call ?cono + pop hl + jr pmsg$loop +pmsg$exit: + pop de + pop bc + ret + +;------------------------------------------------------------------------------- +; print message inline up to a null +; saves all registers + +pr.inln: + ex (sp),hl + push af + call ?pmsg + pop af + ex (sp),hl + ret + +;------------------------------------------------------------------------------- +; print +; saves all registers + +pr.crlf: + call pr.inln + db cr,lf,0 + ret + +;------------------------------------------------------------------------------- +; print hl as a 4 digit hexadecimal number +; saves all registers + +phex4: + ld a,h + call phex2 + ld a,l + ; fall thru + +;------------------------------------------------------------------------------- +; print a as a 2 digit hexadecimal number +; saves all registers + +phex2: + push af + rra + rra + rra + rra + call print.digit + pop af + +print.digit: + push hl + push de + push bc + push af + and 00fh + cp 10 + jr c,prd_1 + add a,007h +prd_1: + add a,'0' + + ld c,a + call ?cono + pop af + pop bc + pop de + pop hl + ret + + +;------------------------------------------------------------------------------- +; print decimal 16 bit number from HL +; +; HL: unsigned binary number to print +; C: minimum print field width +; number is prined right-aligned +; B: pad character, typically ' ' or '0' + +pr.dec: + push de + ld de,0 + call pr.decl + pop de + ret + +;------------------------------------------------------------------------------- +; print decimal 32 bit number from DEHL +; +; DEHL: unsigned binary number to print +; C: minimum print field width +; number is prined right-aligned +; B: pad character, typically ' ' or '0' + +pr.decl: + push bc ;save width and fillchar + push bc + exx ;(alt) + ex (sp),hl ;save hl', get width and fill + push de ;save de' + + xor a + ld d,a ;clear counter + ld e,a + push af ; string terminator + inc sp + +prd_divloop: ;do + exx ; (main) + ld bc,10 ; + call div32_16 ; get a digit + ld a,c ; + add a,'0' ; make it printable + push af ; + + ld a,h ; + or l ; + or d ; + or e ; + exx ; (alt) + inc sp ; + inc de ; + jr nz,prd_divloop ; + +prd_filloop: ;h=filler, l=field width + ld a,e + cp l + jr nc,prd_out + push hl + inc sp + inc de + jr prd_filloop +prd_out: + ld hl,0 + add hl,sp ;ptr to beginning of number string (hl==0 here) + call ?pmsg + ex de,hl + add hl,sp + ld sp,hl + inc sp ;remove string terminator + pop de + pop hl + exx ;(main) + pop bc + ret + + +;------------------------------------------------------------------------------- + +?pderr: + ld hl,drive$msg + call ?pmsg ; error header + ld a,(@adrv) + add a,'A' + ld c,a + call ?cono ; drive code + ld hl,track$msg + call ?pmsg ; track header + ld c,0 + ld hl,(@trk) + call pr.dec ; track number + ld hl,sector$msg + call ?pmsg ; sector header + ld hl,(@sect) + call pr.dec ; sector number + ret + + ; error message components +drive$msg: db cr,lf,bell,'BIOS Error on ',0 +track$msg: db ': T-',0 +sector$msg: db ', S-',0 -- 2.39.2