From 2f3fb51884761902c0a2561fdd3093462b7f99ad Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Wed, 15 Feb 2023 19:31:05 -0800 Subject: [PATCH] More Cleanup - Tweaks to SURVEY and PORTSWP to improve port detection accuracy and handle Z280 better - Recover a **lot** of wasted space in dbgmon using a few built-in utility routines instead of entire util.asm - Improve the (D)evice command in romldr to use the HBIOS routine which is much more complete and saves space --- Source/Apps/Survey/survey.mac | 51 ++++-- Source/Apps/Test/portswp/portswp.asm | 26 ++- Source/HBIOS/dbgmon.asm | 229 ++++++++++++++++++++++++++- Source/HBIOS/hbios.asm | 3 + Source/HBIOS/romldr.asm | 94 ++--------- Source/ver.inc | 2 +- Source/ver.lib | 2 +- 7 files changed, 297 insertions(+), 110 deletions(-) diff --git a/Source/Apps/Survey/survey.mac b/Source/Apps/Survey/survey.mac index e26a9f77..23b2fb9f 100644 --- a/Source/Apps/Survey/survey.mac +++ b/Source/Apps/Survey/survey.mac @@ -641,27 +641,41 @@ PORTLP: jr nz,rd180 ; ; Z80 port read + ; Read port using IN A,(C), push result ld a,d ld c,a - ld (pnum),a ; dynamic update + ld (pnum0a),a ; dynamic update + ld (pnum0b),a ; dynamic update + ld b,0 in a,(c) push af - ld b,0 - in a,(0FFH) -pnum equ $-1 + ; Read port using IN A,(port), push result + in a,(0ffh) ; IN0 +pnum0a equ $-1 + push af + ; Read port using IN A,(port), push result + in a,(0ffh) ; IN0 +pnum0b equ $-1 push af jr rdz ; rd180: ; Z180 port read + ; Read port using IN A,(C), push result ld a,d ld c,a - ld (pnum1),a ; dynamic update + ld (pnum1a),a ; dynamic update + ld (pnum1b),a ; dynamic update + ld b,0 in a,(c) push af - ld b,0 + ; Read port using IN0 A,(port), push result db 0EDH,038H,0FFH ; IN0 -pnum1 equ $-1 +pnum1a equ $-1 + push af + ; Read port using IN0 A,(port), push result + db 0EDH,038H,0FFH ; IN0 +pnum1b equ $-1 push af ; rdz: @@ -674,15 +688,20 @@ rdz: ei ; interrupts back on now ; ; port is considered inactive if values read from different port -; read mechanisms differ or if the value $FF is read consistently -; - pop af - ld c,a - pop af - cp c - jr nz,NEXTPT - cp 0FFH - jr z,NEXTPT +; read mechanisms differ or if the value $FF is read consistently, +; or if the value read is equal to the port number itself +; + pop bc ; second IN0 (port) value + pop af ; first IN0 (port) valule + cp b ; same? + pop bc ; IN (C) value + jr nz,ISPORT ; if no, active running ctr port + cp b ; same? + jr nz,NEXTPT ; if not, inactive port + cp 0FFh ; pullup value??? + jr z,NEXTPT ; if so, consider not active + cp d ; value same as port num??? + jr z,NEXTPT ; if so, consider not active ; .8080 ISPORT: diff --git a/Source/Apps/Test/portswp/portswp.asm b/Source/Apps/Test/portswp/portswp.asm index dd6d49c2..5e30c4b5 100644 --- a/Source/Apps/Test/portswp/portswp.asm +++ b/Source/Apps/Test/portswp/portswp.asm @@ -104,10 +104,22 @@ process: mlt de ; de = 30 if z180 ld a,e ; result to A cp 30 ; check if multiply happened - jr nz,loop ; if invalid, then Z80 + jr nz,prtcpu ; if invalid, then Z80 or $FF ; flag value for Z180 ld (is180),a ; save it ; +prtcpu: + ld de,msgcpu + call prtstr + ld a,(is180) + or a + ld de,msgz80 + jr z,prtcpu1 + ld de,msgz180 +prtcpu1: + call prtstr + call crlf +; loop: call crlf ld a,(curport) @@ -149,7 +161,6 @@ done: call crlf2 ld de,msgdone ; message to print call prtstr ; do it -; ret ; all done ; ; @@ -159,10 +170,12 @@ portread: or a jr nz,portread_z180 ; -portread_z80: ; user traditional "IN" +portread_z80: ; use traditional "IN" ; read port using IN ld a,(curport) ; get current port ld (port),a ; modify IN instruction + nop ; defeat Z280 pipeline + nop in a,($FF) ; read the port port .equ $-1 ld (hl),a ; save it @@ -583,10 +596,11 @@ msgbio .db "Incompatible BIOS or version, " .db "HBIOS v", '0' + rmj, ".", '0' + rmn, " required",0 str_sep .db ": ",0 ; -;msgcur .db "Initial Bank ID = 0x",0 -;msg80 .db "Hello from bank 0x80!",0 -;msgxcal .db "Inter-bank procedure call test...",0 +msgcpu .db "CPU is ",0 +msgz80 .db "Z80",0 +msgz180 .db "Z180",0 msgdone .db "End of Port Sweep",0 + ; ; ; diff --git a/Source/HBIOS/dbgmon.asm b/Source/HBIOS/dbgmon.asm index d8792bc3..a2a0ceac 100644 --- a/Source/HBIOS/dbgmon.asm +++ b/Source/HBIOS/dbgmon.asm @@ -40,8 +40,6 @@ ENA_XM .EQU TRUE ; INCLUDE XMODEM IF SPACE AVAILABLE ; ENA_MBC6502 .EQU FALSE ; ENABLE OR DISABLE MBC6502 OPTION ; -#INCLUDE "util.asm" -; ;__UART_ENTRY_________________________________________________________________ ; ; SERIAL MONITOR STARTUP @@ -1846,6 +1844,233 @@ DSKY_ENTRY: ; #ENDIF ; +;================================================================================================== +; UTILITY FUNCTIONS +;================================================================================================== +; +; +CHR_BEL .EQU 07H +CHR_CR .EQU 0DH +CHR_LF .EQU 0AH +CHR_BS .EQU 08H +CHR_ESC .EQU 1BH +; +;__________________________________________________________________________________________________ +; +; UTILITY PROCS TO PRINT SINGLE CHARACTERS WITHOUT TRASHING ANY REGISTERS +; +PC_SPACE: + PUSH AF + LD A,' ' + JR PC_PRTCHR +PC_COLON: + PUSH AF + LD A,':' + JR PC_PRTCHR +PC_CR: + PUSH AF + LD A,CHR_CR + JR PC_PRTCHR + +PC_LF: + PUSH AF + LD A,CHR_LF + JR PC_PRTCHR + +PC_PRTCHR: + CALL COUT + POP AF + RET + +NEWLINE2: + CALL NEWLINE +NEWLINE: + CALL PC_CR + CALL PC_LF + RET +PRTSTR: + LD A,(HL) + INC HL + CP '$' + RET Z + CALL COUT + JR PRTSTR +; +; PRINT THE HEX BYTE VALUE IN A +; +PRTHEXBYTE: + PUSH AF + PUSH DE + CALL HEXASCII + LD A,D + CALL COUT + LD A,E + CALL COUT + POP DE + POP AF + RET +; +; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE +; +HEXASCII: + LD D,A + CALL HEXCONV + LD E,A + LD A,D + RLCA + RLCA + RLCA + RLCA + CALL HEXCONV + LD D,A + RET +; +; CONVERT LOW NIBBLE OF A TO ASCII HEX +; +HEXCONV: + AND 0FH ;LOW NIBBLE ONLY + ADD A,90H + DAA + ADC A,40H + DAA + RET +; +; ADD HL,A +; +; A REGISTER IS DESTROYED! +; +ADDHLA: + ADD A,L + LD L,A + RET NC + INC H + RET +; +; DELAY 16US (CPU SPEED COMPENSATED) INCUDING CALL/RET INVOCATION +; REGISTER A AND FLAGS DESTROYED +; NO COMPENSATION FOR Z180 MEMORY WAIT STATES +; THERE IS AN OVERHEAD OF 3TS PER INVOCATION +; IMPACT OF OVERHEAD DIMINISHES AS CPU SPEED INCREASES +; +; CPU SCALER (CPUSCL) = (CPUHMZ - 2) FOR 16US + 3TS DELAY +; NOTE: CPUSCL MUST BE >= 1! +; +; EXAMPLE: 8MHZ CPU (DELAY GOAL IS 16US) +; LOOP = ((6 * 16) - 5) = 91TS +; TOTAL COST = (91 + 40) = 131TS +; ACTUAL DELAY = (131 / 8) = 16.375US +; + ; --- TOTAL COST = (LOOP COST + 40) TS -----------------+ +DELAY: ; 17TS (FROM INVOKING CALL) | + LD A,(CPUSCL) ; 13TS | +; | +DELAY1: ; | + ; --- LOOP = ((CPUSCL * 16) - 5) TS ------------+ | + DEC A ; 4TS | | + #IF (BIOS == BIOS_WBW) ; | | + #IF (CPUFAM == CPU_Z180) ; | | + OR A ; +4TS FOR Z180 | | + #ENDIF ; | | + #ENDIF ; | | + JR NZ,DELAY1 ; 12TS (NZ) / 7TS (Z) | | + ; ----------------------------------------------+ | +; | + RET ; 10TS (RETURN) | + ;-------------------------------------------------------+ +; +; DELAY 16US * DE (CPU SPEED COMPENSATED) +; REGISTER DE, A, AND FLAGS DESTROYED +; NO COMPENSATION FOR Z180 MEMORY WAIT STATES +; THERE IS A 27TS OVERHEAD FOR CALL/RET PER INVOCATION +; IMPACT OF OVERHEAD DIMINISHES AS DE AND/OR CPU SPEED INCREASES +; +; CPU SCALER (CPUSCL) = (CPUHMZ - 2) FOR 16US OUTER LOOP COST +; NOTE: CPUSCL MUST BE > 0! +; +; EXAMPLE: 8MHZ CPU, DE=6250 (DELAY GOAL IS .1 SEC OR 100,000US) +; INNER LOOP = ((16 * 6) - 5) = 91TS +; OUTER LOOP = ((91 + 37) * 6250) = 800,000TS +; ACTUAL DELAY = ((800,000 + 27) / 8) = 100,003US +; + ; --- TOTAL COST = (OUTER LOOP + 27) TS ------------------------+ +VDELAY: ; 17TS (FROM INVOKING CALL) | +; | + ; --- OUTER LOOP = ((INNER LOOP + 37) * DE) TS ---------+ | + LD A,(CPUSCL) ; 13TS | | +; | | +VDELAY1: ; | | + ; --- INNER LOOP = ((CPUSCL * 16) - 5) TS ------+ | | + #IF (BIOS == BIOS_WBW) ; | | | + #IF (CPUFAM == CPU_Z180) ; | | | + OR A ; +4TS FOR Z180 | | | + #ENDIF ; | | | + #ENDIF ; | | | + DEC A ; 4TS | | | + JR NZ,VDELAY1 ; 12TS (NZ) / 7TS (Z) | | | + ; ----------------------------------------------+ | | +; | | + DEC DE ; 6TS | | + #IF (BIOS == BIOS_WBW) ; | | | + #IF (CPUFAM == CPU_Z180) ; | | + OR A ; +4TS FOR Z180 | | + #ENDIF ; | | + #ENDIF ; | | + LD A,D ; 4TS | | + OR E ; 4TS | | + JP NZ,VDELAY ; 10TS | | + ;-------------------------------------------------------+ | +; | + RET ; 10TS (FINAL RETURN) | + ;---------------------------------------------------------------+ +; +; DELAY ABOUT 0.5 SECONDS +; 500000US / 16US = 31250 +; +LDELAY: + PUSH AF + PUSH DE + LD DE,31250 + CALL VDELAY + POP DE + POP AF + RET +; +; INITIALIZE DELAY SCALER BASED ON OPERATING CPU SPEED +; ENTER WITH A = CPU SPEED IN MHZ +; +DELAY_INIT: + CP 3 ; TEST FOR <= 2 (SPECIAL HANDLING) + JR C,DELAY_INIT1 ; IF <= 2, SPECIAL PROCESSING + SUB 2 ; ADJUST AS REQUIRED BY DELAY FUNCTIONS + JR DELAY_INIT2 ; AND CONTINUE +DELAY_INIT1: + LD A,1 ; USE THE MIN VALUE OF 1 +DELAY_INIT2: + LD (CPUSCL),A ; UPDATE CPU SCALER VALUE + RET + + #IF (CPUMHZ < 3) +CPUSCL .DB 1 ; CPU SCALER MUST BE > 0 + #ELSE +CPUSCL .DB CPUMHZ - 2 ; OTHERWISE 2 LESS THAN PHI MHZ + #ENDIF +; +; SHORT DELAY FUNCTIONS. NO CLOCK SPEED COMPENSATION, SO THEY +; WILL RUN LONGER ON SLOWER SYSTEMS. THE NUMBER INDICATES THE +; NUMBER OF CALL/RET INVOCATIONS. A SINGLE CALL/RET IS +; 27 T-STATES ON A Z80, 25 T-STATES ON A Z180 +; +; ; Z80 Z180 +; ; ---- ---- +DLY64: CALL DLY32 ; 1728 1600 +DLY32: CALL DLY16 ; 864 800 +DLY16: CALL DLY8 ; 432 400 +DLY8: CALL DLY4 ; 216 200 +DLY4: CALL DLY2 ; 108 100 +DLY2: CALL DLY1 ; 54 50 +DLY1: RET ; 27 25 +; +; ; .FILL 16,0 ; SET MINIMUM STACK DEPTH SLACK .EQU (MON_END - $) diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 03116f61..d17e3c9c 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1020,6 +1020,9 @@ HB_ENTRYTBL .EQU $ ; JP HB_START ; HBIOS INITIALIZATION JP HB_DISPATCH ; VECTOR TO DISPATCHER + JP PRTSUM + ; !!! DO NOT ADD ADDTIONAL VECTORS HERE WITHOUT + ; CHECKING W/ WAYNE !!! ; HB_STKSIZ .EQU $100 - ($ & $FF) ; diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index 51441a62..58107b5b 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -464,8 +464,6 @@ applst2: ; Device list ; devlst: - ld hl,str_devlst ; device list header string - call pstr ; display it jp prtall ; do it ; ; Set console interface unit @@ -1826,99 +1824,26 @@ CST .equ cst ; Device inventory display ;======================================================================= ; -; Print list of all drives (WBW) -; #if (BIOS == BIOS_WBW) ; -prtall: - call nl ; formatting - ld b,BF_SYSGET - ld c,BF_SYSGET_DIOCNT - rst 08 ; E := disk unit count - ld b,e ; count to B - ld a,b ; count to A - or a ; set flags - ret z ; bail out if zero - ld c,0 ; init device index -; -prtall1: - ld hl,str_disk ; prefix string - call pstr ; display it - ld a,c ; index - call prtdecb ; print it - ld hl,str_on ; separator string - call pstr - push bc ; save loop control - ld b,BF_DIODEVICE ; HBIOS func: report device info - rst 08 ; call HBIOS - call prtdrv ; print it - pop bc ; restore loop control - inc c ; bump index - djnz prtall1 ; loop as needed - ret ; done -; -; Print the device info -; On input D has device type, E has device number -; Destroy no registers other than A +; Print list of all drives (WBW) ; -prtdrv: - push de ; preserve de - push hl ; preserve HL - ld a,d ; load device/unit - rrca ; rotate device - rrca ; ... bits - rrca ; ... into - rrca ; ... lowest 4 bits - and $0F ; isolate device bits - add a,a ; multiple by two for word table - ld hl,devtbl ; point to start of table - call addhla ; add A to HL for table entry - ld a,(hl) ; deref HL for string adr - inc hl ; ... - ld h,(hl) ; ... - ld l,a ; ... - call pstr ; print the device nmemonic - pop hl ; recover HL - pop de ; recover DE - ld a,e ; device number - call prtdecb ; print it - ld a,':' ; suffix - call cout ; print it - ret +; Just invoke the existing HBIOS routine... ; -devtbl: ; device table - .dw dev00, dev01, dev02, dev03 - .dw dev04, dev05, dev06, dev07 - .dw dev08, dev09, dev10, dev11 - .dw dev12, dev13, dev14, dev15 -; -devunk .db "???",0 -dev00 .db "MD",0 -dev01 .db "FD",0 -dev02 .db "RAMF",0 -dev03 .db "IDE",0 -dev04 .db "ATAPI",0 -dev05 .db "PPIDE",0 -dev06 .db "SD",0 -dev07 .db "PRPSD",0 -dev08 .db "PPPSD",0 -dev09 .db "HDSK",0 -dev10 .equ devunk -dev11 .equ devunk -dev12 .equ devunk -dev13 .equ devunk -dev14 .equ devunk -dev15 .equ devunk +prtall: + ld a,BID_BIOS ; BIOS Bank please + ld ix,$0406 ; HBIOS PRTSUM vector + jp HB_BNKCALL ; do it ; #endif ; -; -; #if (BIOS == BIOS_UNA) ; ; Print list of all drives (UNA) ; prtall: + ld hl,str_devlst ; device list header string + call pstr ; display it call nl ; formatting ld b,0 ; start with unit 0 ; @@ -1997,6 +1922,8 @@ devsd .db "SD",0 devdsd .db "DSD",0 devunk .db "UNK",0 ; +str_devlst .db "\r\n\r\nDisk Devices:",0 +; #endif ; ;======================================================================= @@ -2090,7 +2017,6 @@ str_reboot .db "\r\n\r\nRestarting System...",0 str_newcon .db "\r\n\r\n Console on Unit #",0 str_chspeed .db "\r\n\r\n Change speed now. Press a key to resume.",0 str_applst .db "\r\n\r\nROM Applications:",0 -str_devlst .db "\r\n\r\nDisk Devices:",0 str_invcmd .db "\r\n\r\n*** Invalid Command ***",bel,0 str_load .db "\r\n\r\nLoading ",0 str_disk .db "\r\n Disk Unit ",0 diff --git a/Source/ver.inc b/Source/ver.inc index 81181ce0..553c9948 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1.1-pre.197" +#DEFINE BIOSVER "3.1.1-pre.198" diff --git a/Source/ver.lib b/Source/ver.lib index b10a6bff..74b71a36 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 1 rtp equ 0 biosver macro - db "3.1.1-pre.197" + db "3.1.1-pre.198" endm