From 947c5868f3a9d8c9e5a35862f24a046d4db9f6b9 Mon Sep 17 00:00:00 2001 From: Leo C Date: Mon, 13 Jun 2016 17:28:19 +0200 Subject: [PATCH] correct merge errors. --- cbios/Makefile | 2 +- cbios/bioskrnl.180 | 1 + cbios/boot.180 | 2 - cbios/gencpm.dat | 8 +- cbios/misc.180 | 374 +++++++--------- cbios/termios.inc | 128 +++--- cbios/time.180 | 420 +++++++++--------- cbios/utils.180 | 1012 ++++++++++++++++++++++---------------------- 8 files changed, 944 insertions(+), 1003 deletions(-) diff --git a/cbios/Makefile b/cbios/Makefile index 53fa589..0b21a4a 100644 --- a/cbios/Makefile +++ b/cbios/Makefile @@ -2,7 +2,7 @@ SRC := bioskrnl.180 boot.180 stampf.180 chario.180 drvtbl.180 SRC += move.180 time.180 mm.180 misc.180 utils.180 fifo.180 -SRC += msgbuf.180 conbuf.180 ascii.180 asci-cmn.180 +SRC += msgbuf.180 conbuf.180 ascii.180 SRC += sdio.180 cfio.180 SRC += scb.180 ALLSRC := $(SRC) ldrbios.180 diff --git a/cbios/bioskrnl.180 b/cbios/bioskrnl.180 index 834a2fa..339a759 100644 --- a/cbios/bioskrnl.180 +++ b/cbios/bioskrnl.180 @@ -481,6 +481,7 @@ seldsk: ld h,(hl) ld l,a call ijphl ; call LOGIN +notfirst: ld hl,(@xdph) ; recover DPH pointer ret diff --git a/cbios/boot.180 b/cbios/boot.180 index 8e41728..18a53f4 100644 --- a/cbios/boot.180 +++ b/cbios/boot.180 @@ -3,7 +3,6 @@ public hwinit,?init,?ldccp,?rlccp - public signon public f_cpu extrn boot,?conin @@ -78,7 +77,6 @@ hwini_skip: ld (@cbnk),a ; right now in bank 0 call pr.inln ; print signon message -signon: db 13,10,13,10,'CP/M Version 3.0, Z180-Stamp BIOS v' defvers db 13,10 diff --git a/cbios/gencpm.dat b/cbios/gencpm.dat index 874b2b1..e848376 100644 --- a/cbios/gencpm.dat +++ b/cbios/gencpm.dat @@ -9,7 +9,7 @@ BNKSWT = Y COMBAS = F0 LERROR = Y NUMSEGS = 03 -MEMSEG00 = 50,3E,00 +MEMSEG00 = 50,38,00 MEMSEG01 = 10,E0,02 MEMSEG02 = 01,EF,03 MEMSEG03 = 00,C0,04 @@ -57,8 +57,8 @@ ALTBNKSM = N ALTBNKSN = N ALTBNKSO = N ALTBNKSP = N -NDIRRECA = 0C -NDIRRECB = 0C +NDIRRECA = 0A +NDIRRECB = 0A NDIRRECC = 00 NDIRRECD = 00 NDIRRECE = 00 @@ -155,4 +155,4 @@ OVLYDTAO = Y OVLYDTAP = Y CRDATAF = N DBLALV = Y - + \ No newline at end of file diff --git a/cbios/misc.180 b/cbios/misc.180 index d39f632..10eb83c 100644 --- a/cbios/misc.180 +++ b/cbios/misc.180 @@ -1,216 +1,158 @@ - - 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 cpu_frq + public get_tmr + + 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 + +;---------------------------------------------------------------------- + + end diff --git a/cbios/termios.inc b/cbios/termios.inc index 12b1d3a..d1d322c 100644 --- a/cbios/termios.inc +++ b/cbios/termios.inc @@ -1,64 +1,64 @@ -; tcflag_t c_iflag; /* input mode flags */ -IGNBRK equ 00000001B ;Ignore BREAK condition on input. -BRKINT equ 00000010B -IGNPAR equ 00000100B ;Ignore framing errors and parity errors. -PARMRK equ 00001000B ;Prefix a character with a parity error or framing error with FFH 00H. -INPCK equ 00010000B ;Enable input parity checking. -ISTRIP equ 00100000B ;Strip off eighth bit. -IXON equ 01000000B ;Enable XON/XOFF flow control on output. -IXANY equ 10000000B ;Typing any character will restart stopped output. -IXOFF equ 00000000B ;Enable XON/XOFF flow control on input. - -; tcflag_t c_cflag; /* control mode flags */ -CBAUD equ 0x1F ;Baud speed mask - B0 equ 0x00 ;hang up - B50 equ 0x11 - B75 equ 0x12 - B110 equ 0x13 - B134 equ 0x14 - B150 equ 0x05 - B300 equ 0x06 - B600 equ 0x07 - B1200 equ 0x08 - B1800 equ 0x09 - B2400 equ 0x0A - B3600 equ 0x0B - B4800 equ 0x0C - B7200 equ 0x0D - B9600 equ 0x0E - B19200 equ 0x0F - B28800 equ 0x01 - B38400 equ 0x02 - B57600 equ 0x03 - B115200 equ 0x04 - B144000 equ 0x14 - B192000 equ 0x16 - B288000 equ 0x17 -CSIZE equ 00000000B ;Character size mask. - CS7 equ 00000000B ; - CS8 equ 00000000B ; -CSTOPB equ 00000000B ;Set two stop bits, rather than one. -CREAD equ 00000000B ;Enable receiver. -PARENB equ 00000000B ;Enable parity generation on output and parity checking for input. -PARODD equ 00000000B ;If set, then parity for input and output is odd. -CLOCAL equ 00000000B ;Ignore modem control lines. -CRTS_IFLOW equ 00000000B ;RTS flow control of input. -CCTS_OFLOW equ 00000000B ;CTS flow control of output. - -; tcflag_t c_lflag; /* local mode flags */ -ECHO equ 00000001B - - -; tcflow() and TCXONC use these */ -TCOOFF equ 0 -TCOON equ 1 -TCIOFF equ 2 -TCION equ 3 -; tcflush() and TCFLSH use these */ -TCIFLUSH equ 0 -TCOFLUSH equ 1 -TCIOFLUSH equ 2 -; tcsetattr uses these */ -TCSANOW equ 0 -TCSADRAIN equ 1 -TCSAFLUSH equ 2 +; tcflag_t c_iflag; /* input mode flags */ +IGNBRK equ 00000001B ;Ignore BREAK condition on input. +BRKINT equ 00000010B +IGNPAR equ 00000100B ;Ignore framing errors and parity errors. +PARMRK equ 00001000B ;Prefix a character with a parity error or framing error with FFH 00H. +INPCK equ 00010000B ;Enable input parity checking. +ISTRIP equ 00100000B ;Strip off eighth bit. +IXON equ 01000000B ;Enable XON/XOFF flow control on output. +IXANY equ 10000000B ;Typing any character will restart stopped output. +IXOFF equ 00000000B ;Enable XON/XOFF flow control on input. + +; tcflag_t c_cflag; /* control mode flags */ +CBAUD equ 0x1F ;Baud speed mask + B0 equ 0x00 ;hang up + B50 equ 0x11 + B75 equ 0x12 + B110 equ 0x13 + B134 equ 0x14 + B150 equ 0x05 + B300 equ 0x06 + B600 equ 0x07 + B1200 equ 0x08 + B1800 equ 0x09 + B2400 equ 0x0A + B3600 equ 0x0B + B4800 equ 0x0C + B7200 equ 0x0D + B9600 equ 0x0E + B19200 equ 0x0F + B28800 equ 0x01 + B38400 equ 0x02 + B57600 equ 0x03 + B115200 equ 0x04 + B144000 equ 0x14 + B192000 equ 0x16 + B288000 equ 0x17 +CSIZE equ 00000000B ;Character size mask. + CS7 equ 00000000B ; + CS8 equ 00000000B ; +CSTOPB equ 00000000B ;Set two stop bits, rather than one. +CREAD equ 00000000B ;Enable receiver. +PARENB equ 00000000B ;Enable parity generation on output and parity checking for input. +PARODD equ 00000000B ;If set, then parity for input and output is odd. +CLOCAL equ 00000000B ;Ignore modem control lines. +CRTS_IFLOW equ 00000000B ;RTS flow control of input. +CCTS_OFLOW equ 00000000B ;CTS flow control of output. + +; tcflag_t c_lflag; /* local mode flags */ +ECHO equ 00000001B + + +; tcflow() and TCXONC use these */ +TCOOFF equ 0 +TCOON equ 1 +TCIOFF equ 2 +TCION equ 3 +; tcflush() and TCFLSH use these */ +TCIFLUSH equ 0 +TCOFLUSH equ 1 +TCIOFLUSH equ 2 +; tcsetattr uses these */ +TCSANOW equ 0 +TCSADRAIN equ 1 +TCSAFLUSH equ 2 diff --git a/cbios/time.180 b/cbios/time.180 index befd0ec..24f92ef 100644 --- a/cbios/time.180 +++ b/cbios/time.180 @@ -1,210 +1,210 @@ - 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 ; 11 - in0 a,(tcr) ;reset TIF0 flag 12 - in0 a,(tmdr0l) ; 12 - in0 a,(tmdr0h) ; 12 - ; - - push hl ;11 - ld hl,uptime ; 9 - inc (hl) ; 10 77 - jr nz,iprt_1 ; 6/8 -2 - inc hl ; 4 - inc (hl) ; 10 14 - jr nz,iprt_1 ; 6/8 - inc hl ; 4 - inc (hl) ;10 - jr nz,iprt_1 ;6/8 - inc hl ; 4 - inc (hl) ;10 -iprt_1: ; 85 138 - pop hl ; 9 - ld a,(time_to) ; 12 - sub a,1 ; 6 112 - jr c,iprt_0 ; 6/8 - ld (time_to),a ; 13 -iprt_0: ; 120 178 - pop af ; 9 - ei ; 3 - ret ; 9 141 199 - ; +intack 18 159 217 - -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 ; 11 + in0 a,(tcr) ;reset TIF0 flag 12 + in0 a,(tmdr0l) ; 12 + in0 a,(tmdr0h) ; 12 + ; + + push hl ;11 + ld hl,uptime ; 9 + inc (hl) ; 10 77 + jr nz,iprt_1 ; 6/8 -2 + inc hl ; 4 + inc (hl) ; 10 14 + jr nz,iprt_1 ; 6/8 + inc hl ; 4 + inc (hl) ;10 + jr nz,iprt_1 ;6/8 + inc hl ; 4 + inc (hl) ;10 +iprt_1: ; 85 138 + pop hl ; 9 + ld a,(time_to) ; 12 + sub a,1 ; 6 112 + jr c,iprt_0 ; 6/8 + ld (time_to),a ; 13 +iprt_0: ; 120 178 + pop af ; 9 + ei ; 3 + ret ; 9 141 199 + ; +intack 18 159 217 + +uptime: + dw 0,0 +time_to: + db 0 + + end diff --git a/cbios/utils.180 b/cbios/utils.180 index 1fdb6ca..08c5fd0 100644 --- a/cbios/utils.180 +++ b/cbios/utils.180 @@ -1,506 +1,506 @@ - title 'general utility routines' - - ; i/o port init routines - - public ioiniml,ioini1l ; - - ; math - - public ijphl ; vectored CALL point - 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.idx ; print message from table indexed by - public pr.inln,pr.crlf ; print message inline, print newline - public phex2,phex4 ; print 2 digit hex or 4 digit hex - public pr.dec,pr.decl ; print 16 or 32 bit decimal number - public pr.errors ; print BIOS disk error message header - - - - extrn ?const,?conin,?cono - extrn @adrv,@trk,@sect ; used by disk error message - extrn @op,@ermde - -;------------------------------------------------------------------------------- - -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 - - cseg - -;-------------------------------------------------------------------- -; vectored CALL point - -ijphl: - jp (hl) - - dseg - -;-------------------------------------------------------------------- -; 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 from table @, indexed by -; saves & - -pr.idx: - push bc - push de - push hl ; put pointer to first message on stack - ld e,a ; save message number - xor a - ld b,a - ld c,a - inc e -pdc_nxt_str: - dec e - ex (sp),hl - jr z,pdc_found - ex (sp),hl - cpir - cp (hl) - jr nz,pdc_nxt_str - ; End of List, msg not found. - ; Print first msg. -pdc_found: - pop hl - call ?pmsg - 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) - jp pr.dec ; sector number - - ; error message components -drive$msg: db cr,lf,bell,'BIOS Error on ',0 -track$msg: db ': T-',0 -sector$msg: db ', S-',0 - - -;------------------------------------------------------------------------------- -; get console input, echo it, and shift to upper case -; save hl,de,bc - -uciecho: - push hl - push de - push bc -u$c0: - call ?const - or a - jr z,u$c1 ; see if any char already struck - call ?conin - jr u$c0 ; yes, eat it and try again -u$c1: - call ?conin - push af - ld c,a - cp ' '-1 - call nc,?cono - pop af - pop bc - pop de - pop hl - cp 'a' - ret c - sub 'a'-'A' ; make upper case - ret - -;------------------------------------------------------------------------------- -; - -pr.errors: - - ; suppress error message if BDOS - ; is returning errors to application... - - ld a,(@ermde) - inc a - jr nz,pre1 - dec a ;return NZ, if @ermde == 0FFH - ret -pre1: - push hl - ld hl,pre2 - ex (sp),hl - push hl - - ; Had permanent error, print message like: - ; BIOS Err on d: T-nn, S-mm, , Retry ? - - call ?pderr ; print message header - - ld hl,op$msg - ld a,(@op) - jp pr.idx ; last function (read or write) - -pre2: - ; prompt for retry - call pr.inln - db ' Retry (Y/N) ? ',0 - - call uciecho ; get operator response - cp 'Y' - ret ; return Z-flag for yes - - -op$msg: - db ', Unknown op, ',0 - db ', Read, ',0 - db ', Write, ',0 - db 0 - - end + title 'general utility routines' + + ; i/o port init routines + + public ioiniml,ioini1l ; + + ; math + + public ijphl ; vectored CALL point + 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.idx ; print message from table indexed by + public pr.inln,pr.crlf ; print message inline, print newline + public phex2,phex4 ; print 2 digit hex or 4 digit hex + public pr.dec,pr.decl ; print 16 or 32 bit decimal number + public pr.errors ; print BIOS disk error message header + + + + extrn ?const,?conin,?cono + extrn @adrv,@trk,@sect ; used by disk error message + extrn @op,@ermde + +;------------------------------------------------------------------------------- + +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 + + cseg + +;-------------------------------------------------------------------- +; vectored CALL point + +ijphl: + jp (hl) + + dseg + +;-------------------------------------------------------------------- +; 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 from table @, indexed by +; saves & + +pr.idx: + push bc + push de + push hl ; put pointer to first message on stack + ld e,a ; save message number + xor a + ld b,a + ld c,a + inc e +pdc_nxt_str: + dec e + ex (sp),hl + jr z,pdc_found + ex (sp),hl + cpir + cp (hl) + jr nz,pdc_nxt_str + ; End of List, msg not found. + ; Print first msg. +pdc_found: + pop hl + call ?pmsg + 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) + jp pr.dec ; sector number + + ; error message components +drive$msg: db cr,lf,bell,'BIOS Error on ',0 +track$msg: db ': T-',0 +sector$msg: db ', S-',0 + + +;------------------------------------------------------------------------------- +; get console input, echo it, and shift to upper case +; save hl,de,bc + +uciecho: + push hl + push de + push bc +u$c0: + call ?const + or a + jr z,u$c1 ; see if any char already struck + call ?conin + jr u$c0 ; yes, eat it and try again +u$c1: + call ?conin + push af + ld c,a + cp ' '-1 + call nc,?cono + pop af + pop bc + pop de + pop hl + cp 'a' + ret c + sub 'a'-'A' ; make upper case + ret + +;------------------------------------------------------------------------------- +; + +pr.errors: + + ; suppress error message if BDOS + ; is returning errors to application... + + ld a,(@ermde) + inc a + jr nz,pre1 + dec a ;return NZ, if @ermde == 0FFH + ret +pre1: + push hl + ld hl,pre2 + ex (sp),hl + push hl + + ; Had permanent error, print message like: + ; BIOS Err on d: T-nn, S-mm, , Retry ? + + call ?pderr ; print message header + + ld hl,op$msg + ld a,(@op) + jp pr.idx ; last function (read or write) + +pre2: + ; prompt for retry + call pr.inln + db ' Retry (Y/N) ? ',0 + + call uciecho ; get operator response + cp 'Y' + ret ; return Z-flag for yes + + +op$msg: + db ', Unknown op, ',0 + db ', Read, ',0 + db ', Write, ',0 + db 0 + + end -- 2.39.2