;******************************************** ; * ; KONAN MEDIA TEST * ; 9-8-799 * ; BY DAVE EVOY * ; * ;******************************************** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; TRANSFERED TO CPM FROM ;; ;; NORTH STAR USING PIP ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ORG 100H LXI H,0 ;SAVE CP/M STACK DAD SP SHLD SPSAV JMP START ; THE PURPOSE OF THE TEST IS TO LOCATE MEDIA FLAWS ; AND TO DIAGNOS SMC-100 SUBSYSTEM PROBLEMS. ; ; THE OPERATOR MAY OPTIONALLY SPECIFY BYTE FOR BYTE ; COMPAIR. THIS WILL SLOW THE TEST CONSIDERABLY ; BUT HAS THE ADVANTAGE OF ALSO TESTING MEMORY AND ; THE DMA. ; THE OPERATOR MAY OPTIONALLY SPECIFY THE TEST TO BE RUN ; AT ALL OFFSETS,FOWARD, BAKWARD, EARLY, AND LATE. THIS ; WILL GREATLY SLOW THE TEST BUT MAY HELP FIND MARGINAL ; AREAS ON THE MEDIA. ; ; ; EQUATES FOLLOW FALSE EQU 0 TRUE EQU NOT FALSE DMA EQU FALSE NONDMA EQU NOT DMA S512 EQU TRUE S256 EQU NOT S512 ESC EQU 1BH DOS EQU 0000H FDOS EQU 0005 IOBASE EQU 90H BUSU EQU IOBASE BUSL EQU IOBASE+1 SCMND EQU IOBASE+2 SCTAD EQU IOBASE+3 SCTBU EQU IOBASE+4 DMACL EQU IOBASE+5 DMACU EQU IOBASE+6 STATU EQU IOBASE+7 ; STORAGE LOCATIONS DRVTYP DB 'C' CRCSW DB 'N' ;CRCTEST N=NO, Y=YES UNIT DB 0 PAT DB 0 ; PATTERN PHASE DB 0 ; 0=ZEROS, 1=ONES, ; 2=RIPPLE UP, 3=RIPPLEDOWN, ; 4=FLOATING ONES, 5=FLOATING ZEROS.. TEMP DB 0 TRKU DB 0 ; CURRENT TRACK TRKL DB 0 HEAD DB 0 SECT DB 0 BASE DB 0 SECCNT DB 0 READT DB 0 ; SPACE = FIRST R=RTRY ERF DB 0 ; ERROR FORMAT ON SCREEN IF NONZERO FPASS DB 0 ; COUNT OF FULL PASSES RWPASS DS 2 ; READ/WRITE PASSES ERCTN DS 3 ; NUMBER OF ERRORS SCRED DS 4 ; TOTAL NUMBER OF SECTORS READ BFBC DB 0 ; BYTE FOR BYTE COMPAIR UNLESS OSBYTE DB 1 ; 80 = DISABLE OFFSETS AND STROBES PATTERN DB 4 MAXTRK DB 5 DB 0 MINTRK DB 0 DB 0 MXHD DB 1 MINHD DB 0 MAXSCT DB 35 SPSAV DW 0 ;********************************************* ; INITIALIZE DISK AND PAR. * ;******************************************** REVMES DB 0DH DB 0AH DB 'KONAN MEDIA TEST REVISION E 8-2-82' DB 0DH DB 0AH IF DMA DB 'DMA ENABLED' ENDIF IF NONDMA DB 'DMA DISABLED ' ENDIF DB ' BASE OF I.O. PORTS IS ' DB 0FFH DRVMES DB 'DRIVE TYPE : ( C=CMD M=MMD ) ? ' DB 0FFH CRCMES DB 'CRCTEST : ( N=NO Y=YES ) ? ' DB 0FFH UNTMES DB 'UNIT? ' DB 0FFH IF S256 SIZMES DB ' SECTOR SIZE =256' ENDIF IF S512 SIZMES DB ' SECTOR SIZE =512' ENDIF DB 0FFH START LXI SP,STACK+100 LXI H,REVMES CALL PMES MVI A,IOBASE CALL DBBCDO LXI H,SIZMES CALL PMES CALL CRLF LXI H,UNTMES CALL PMES CALL CHRIN MOV B,A CALL TTOUT CPI 0DH JZ $+8 ANI 0FH STA UNIT CALL CRLF LXI H,DRVMES ;ASK FOR DRIVE TYPE CALL PMES CALL CHRIN ;GET IT MOV B,A CALL TTOUT CPI 0DH ;DEFAULT ? JZ $+6 ;YUP - SKIP TO NEXT STA DRVTYP CALL CRLF LXI H,CRCMES ;ASK IF CRC TEST CALL PMES CALL CHRIN ;WAIT FOR ANSWER MOV B,A ;ECHO IT BACK CALL TTOUT CPI 0DH ;DEFAULT ? JZ RQUNT ;YES SKIP TO NEXT STEP STA CRCSW CPI 'Y' ;CRCTEST ? JNZ RQUNT ;NOP GET NEXT PARAMETER XRA A ;TURN OFF BYTE COMPARE STA BFBC MVI A,80H ; AND READ OFFSETS / STROBES STA OSBYTE RQUNT CALL CRLF XRA A MVI B,21 LXI H,PAT CLR MOV M,A DCR B INX H JNZ CLR LDA CRCSW ;CRC TEST SWITCH ON ? CPI 'Y' JZ GDSKP ;YUP - SKIP TO DISK PARAMETERS CALL BFBT ; IS BYTE FOR BYTE COMPAIR ON CALL ROSS ; ARE READ OFFSETS AND STROBES TRUE? GDSKP CALL DSKPAR ; GET MAX/MIN TRCK, HEAD, SECTOR ; ; INITIALIZE DISK ADDRESS SEL LDA UNIT RRC RRC RRC RRC ANI 0F0H OUT BUSU MVI A,10H OUT SCMND ; SELECT THE DISK IN STATU ANI 01H ; IS SELECT ON? JNZ SOK ; SOK IF SEEK OK CALL ERROR1 JMP SEL SOK XRA A XRA A STA SECCNT STA BASE STA SECT LDA MINHD STA HEAD CALL CMD OUT BUSL MVI A,40H OUT SCMND ; SELECT FIRST HEAD LHLD MINTRK MOV A,H ; TRACK UPPER STA TRKU MOV A,L STA TRKL CALL SEEK IN STATU ANI 02 CNZ ERROR2 ; IF SEEK ERROR ;************************** ; BUILD BUFFER ROUTNE ;********************************************** ; ; SIX PHASES, 0=ZEROS, 1=ONES, 2=FLOATING ONES, 3=FLOATING ZEROS ; 4=RIPPLE UP, 5=RIPPLE DOWN BB XRA A STA TEMP LXI H,STBUF RSTBB LDA PHASE MVI D,0 ANI 1 JZ $+5 MVI D,0FFH MVI B,0 LDA PAT MOV C,A LDA PHASE CPI 2 JM ZAO ; IF MINUS GO DO PHASE 0/1 CPI 4 JM TA3 FA5 MOV A,C ; RIPPLE UP OR DOWN XRA D INR C MOV M,A INX H INR B JNZ FA5 JMP CCFTW ZAO XRA A XRA D NXO1 MOV M,A INX H INR B JNZ NXO1 JMP CCFTW TA3 MVI A,2 DCR C JZ $+7 RLC JMP $-5 RLC XRA D NXTA3 MOV M,A INX H RLC INR B JNZ NXTA3 JMP CCFTW CCFTW LDA TEMP ;ALWAYS BUILDS 256 BYTE PATTERNS INR A STA TEMP CPI 2 JZ WRITE JMP RSTBB ;********************************************** ; WRITE ALL!!!!!!!!!!!! ;********************************************** ; WRITE LDA SECT OUT SCTAD LDA PHASE MVI D,0 ANI 1 JZ $+5 MVI D,0FFH OUT STATU ; ZERO SECTOR BUFFER MVI E,4 ; NUMBER OF HEADER CHARACTERS LXI H,TRKU NHEADR MOV A,M ; GET HEADER BYTE XRA D OUT SCTBU ; OUTPUT TO SECTOR BUFFER DCR E JZ HEADC ; IF ZERO HEADER COMPLETE INX H JMP NHEADR HEADC LXI H,STBUF IF DMA MOV A,H OUT DMACU ; SET DMA UPPER MOV A,L OUT DMACL ; SET DMA LOWER MVI A,02H ; WRITE DMA COMMAND OUT SCMND ; DO IT ENDIF IF NONDMA LXI D,512 SAS: MOV A,M OUT SCTBU INX H DCX D MOV A,D ORA E JNZ SAS ENDIF XRA A ;CLEAN UP THE BUS OUT BUSU OUT BUSL OUT STATU MVI A,1 ; WRITE DISK COMMAND OUT SCMND ; DO THE WRITE! CALL WAIT IN STATU ANI 20H CNZ ERROR3 ; IF DISK FAULT ; SET UP THE NEXT WRITE AND TEST FOR END OF WRITE ALL CALL INCSEC JNC WRITE LDA MXHD MOV B,A LDA HEAD ;GET HEAD CMP B JZ MAXHD INR A STA HEAD ; INCREMENT HEAD CALL CMD OUT BUSL ; PLACE ON BUS MVI A,40H ; HEAD SELECT COMMAND OUT SCMND ; SELECT IT CALL SEEK JMP WRITE MAXHD LDA MINHD STA HEAD ; SET TO MIN. CALL CMD OUT BUSL ; PLACE IT ON THE BUS MVI A,40H OUT SCMND ; SELECT IT IN STATU ANI 20H CNZ ERROR4 ; CHECK TO SEE IF THIS IS THE LAST TRACK, IF NOT INCREMENT LDA TRKU MOV B,A LDA TRKL MOV C,A ; B AND C CONTAIN THE OLD TRACK LHLD MAXTRK MOV A,H SUB B JNZ TOK ; TRACK OK IF NOT EQUAL TO MAX MOV A,L ; GET LSB OF MAX SUB C JNZ TOK ; TRACK OK IF NOT EQUAL TO MAX ;******************* ; END OF WRITE ALL * ;******************* ; JMP READAL CMD LDA DRVTYP ;SET ZERO FLAG IF DRIVE CPI 'C' ; TYPE = CMD LDA HEAD ;GET HEAD NO. IN A RNZ ;HEAD NO. OK IF NOT CMD CPI 0 RZ ORI 10H ;SET VOLUMN BIT SBI 1 RET ; ; INCREMENT TRACK, STORE IT, SEEK TOK INX B ; NEW TRACK MOV A,B STA TRKU MOV A,C STA TRKL ; NEW TRACK STORED CALL SEEK JMP WRITE ; DO NEXT WRITE ; ;**************************************** ; * ; BEGINNING OF THE READ ALL MESS * ; * ;**************************************** ; ; THIS SECTION NORMALLY READS EACH TRACK FIVE TIMES ; ONCE AT NOMINAL AND ONCE AT EACH OF THE OFFSET ; AND STROBES. COMBINATIONS OF OFFSETS AND STROBES ; ARE NOT NORMALLY USED. THE FOLLOWING TABLE DEFINES THE ; ERROR RECOVERY TRIED. TWO ENTRIES ARE REQURED FOR EACH ; RETRY, FIRST FOR THE UPPER BUS ADD THE SECOND FOR THE LOWER ; BUS. A FF TERMENATES THE TABLE. RECP IS THE TABLE POINTER. ; ; ERTBL DW 0000H ; NOMINAL DW 0004 ; OFFSET PLUS DW 0080H ; STROBE EARLY DW 0008 ; OFFSET MINUS DW 0100H ; STROBE LATE DB 0FFH ; END OF TABLE ; NOTE THAT DW STORES BACKWARDS!! RECP DB 00 ; RECOVERY TABLE POINTER ; ; ; SETUP FOR FIRST READ READAL LDA MINHD STA HEAD CALL CMD OUT BUSL MVI A,40H OUT SCMND XRA A STA SECT OUT SCTAD XRA A STA RECP ; RECOVERY TABLE PONTER LHLD MINTRK MOV A,H STA TRKU MOV A,L STA TRKL CALL SEEK XRA A ; ZERO OUT BUSU ; ZERO BUS OUT BUSL ; WE SHOULD NOW BE READY FOR THE FIRST READ NXTRD MVI A,' ' STA READT ; SET READ TYPE TO FIRST CALL READ LDA READT CPI 'R' JNZ CMPDON ; TO COMPAIR DONE IF NO ERROR CALL READ ; DO RETRY IF READ ERROR OCCURED JMP CMPDON READ OUT STATU LDA CRCSW ;CRC TEST ? CPI 'N' JZ XRDC ;NOP - EXECUTE READ IN SCTBU ;OFFSET TRANSFER BUFFER IN SCTBU ; FOR SHORT SECTOR READ IN SCTBU XRDC MVI A,88H ; READ COMMAND OUT SCMND ; DO IT TO IT !! LXI H,SCRED+3 ; INCREMENT THE NUMBER OF SECTORS READ MVI B,4 CALL INCC CALL WAIT OUT STATU IF DMA LXI H,RDBUF MOV A,H OUT DMACU MOV A,L OUT DMACL MVI A,84H OUT SCMND ENDIF IF NONDMA LXI H,RDBUF LXI D,516 RSAS: IN SCTBU MOV M,A INX H DCX D MOV A,D ORA E JNZ RSAS ENDIF LDA CRCSW ;GET CRC TEST SWITCH CPI 'Y' ;SET ZERO FLAG IF ON IN STATU JZ CRCTST ; CRCTEST SO, BAD CRC IS GOOD ANI 4 JNZ DATAER JMP HDRTST ;GO DO HEADER TEST CRCTST ANI 4 JZ DATAER ;OOPS CRC IS GOOD ; STRIP AND TEST THE HEADER HDRTST OUT STATU ; ZERO THE BUFFER LDA CRCSW ;CRC TEST ? CPI 'N' JZ RDHD ;NOP - JUST READ HEADER IN SCTBU ;HEADER IS OFFSET BY 3 IN SCTBU IN SCTBU RDHD LDA PHASE MVI D,0 ANI 1 JZ $+5 MVI D,0FFH MVI E,4 LXI H,TRKU NRHD MOV A,M ; XRA D MOV B,A ; SAVE PHASE ADJUSTED BYTE IN B IN SCTBU ; GET BYTE FROM THE BUFFER SUB B JNZ DATAER ; HEADER ERROR INX H DCR E JNZ NRHD ; IF NOT DONE GO 'NEXT READ HEADER' ;**************************************** ; OPTIONAL BYTE FOR BTE COMPAIR * ;**************************************** ; LDA BFBC ; GET BYTE FOR BYT COMPAIR OPTION, ZERO ; DISABLES CPI 0 RZ ; CMPDON IF ZERO THE BYTE FOR BYTE ; IS BYPASSED OUT STATU LXI H,STBUF ; H,L POINT TO RAM BUFFER IF S512 LXI B,512 ; DELETE THIS LINE FOR TIMING TEST ENDIF IF S256 LXI B,256 ENDIF LXI D,RDBUF+4 WTEST LDAX D ; GET WORD READ CMP M JNZ DATAER INX D INX H DCX B MOV A,B ORA C JNZ WTEST ; NOT YET DONE, DO ONE MORE RET DATAER CALL ERROR ; PRINT ERROR MVI A,'R' ; READ TYPE EQUAL RETRY STA READT RET ;******************************************** ; ADVANCE DISK ADDRESS FOR NEXT READ * ;******************************************* CMPDON CALL INCSEC JNC NXTRD ; WE MUST NOW STEP THROUGH THE RECOVERY TABLE LDA OSBYTE ; ARE OFSETS ENABLED? CPI 80H JZ BNXHD LDA RECP ; RECP IS POINTING TO THE FIRST BYTE ; OF THE CURRENT RECOVERY INR A INR A STA RECP ; SAVE NEW POINTER LXI H,ERTBL MVI D,0 MOV E,A DAD D MOV A,M CPI 0FFH JZ ENDTBL ; IF FF THE END OF THE TABLE HAS BEEN ; REACHED OUT BUSL ; TO 81 BECAUSE DW STORES BACKARDS INX H MOV A,M OUT BUSU ; BUS NOW SET FOR RECOVERY CALL DLY JMP NXTRD ;*************************** ; ADVANCE HEAD * ;*************************** ENDTBL XRA A ; GENERATE A ZERO OUT BUSU OUT BUSL OUT SCMND ; TURN OFF ANY OFFSET PRIOR TO ; READ/TRACK SELECT CALL DLY ; DELAY THE REQUIRED 40 MILLISECONDS BNXHD XRA A ; GENERATE A ZERO STA RECP ; ZERO THE ERROR TABLE POINTER LDA MXHD MOV B,A LDA HEAD ; GET HEAD CMP B JZ RMAXHD ; IF YES, GO ZERO HEAD AND INC TRACK INR A STA HEAD ; INCREMENT HEAD CALL CMD OUT BUSL ; PUT IT ON THE BUS MVI A,40H ; HEAD SEL COMMAND OUT SCMND ; SELECT IT XRA A OUT BUSL CALL SEEK JMP NXTRD RMAXHD LDA MINHD STA HEAD ; SET HEAD TO MINIMUM CALL CMD OUT BUSL ; PUT IT ON THE BUS MVI A,40H OUT SCMND ;*************************** ; ADVANCE TRACK * ;*************************** ; LDA TRKU MOV B,A LDA TRKL MOV C,A ; B AND C CONTAIN OLD TRACK LHLD MAXTRK MOV A,H SUB B JNZ GTRK ; GOOD TRACK IF NO MAX MOV A,L SUB C JNZ GTRK ; GOOD TRACK IF NOT MAX JMP NPAT GTRK INX B ; NEW TRACK MOV A,B STA TRKU MOV A,C STA TRKL ; NEW TRACK STORED CALL SEEK JMP NXTRD SEEK LDA TRKU OUT BUSU LDA TRKL OUT BUSL MVI A,20H OUT SCMND CALL CONTC ; CALL THE CONTROL C CHECK CZ BREAK CALL WAIT XRA A OUT BUSU OUT BUSL RET ; THE FOLLOWING WAITS FOR ONE, TIMEOUT, OR A CONTROL C WAIT MVI B,00 MVI C,00 WLOOP IN STATU ANI 80H RNZ ; RETURN IF DONE DCR B JNZ WLOOP DCR C JNZ WLOOP CALL ERROR6 ; TIMEOUT OCCURED JMP WLOOP NPAT LDA PHASE INR A CPI 6 JNZ $+4 XRA A STA PHASE LXI H,RWPASS+1 MVI B,2 CALL INCC ; INCREMENTS READ WRITE PASSES LDA PHASE CPI 00 ; IS FULL PASS DONE? JNZ SOK LDA FPASS INR A STA FPASS LXI H,PASM CALL PMES JMP SOK ; GO BUILD BUFFER PASM DB 'PASS ' DB 0FFH INCSEC LDA MAXSCT MOV B,A LDA SECCNT CMP B JZ LASTSC INR A STA SECCNT LDA PATTERN MOV C,A LDA SECT ADD C STA SECT OUT SCTAD CMP B ;MAX SECTOR JC SCTSET JZ SCTSET LDA BASE INR A STA BASE STA SECT OUT SCTAD SCTSET XRA A RET LASTSC XRA A STA PAT STA SECT STA BASE STA SECCNT OUT SCTAD STC RET ;********************************** ; INPUT AND OUTPUT ROUTINES * ;*********************************** ; THE FOLLOWING USER ROUTINE SHOULD TEST FOR A ; CONTROL 'C' OR USER SELECTED BREAK CHARACTER. ; THE ROUTINE SHOULD TEST THE LAST TYPED CHARACTER ; BUT MUST NOT WAIT FOR A CHARACTER IF ONE IS ; NOT PENDING. RETURN WITH Z SET IF LAST CHARACTER ; WAS A CONTROL AND WITH RESET IF IT WAS NOT. CONTC PUSH H PUSH D PUSH B MVI C,6 MVI E,0FFH CALL FDOS CPI 03 CMC POP B POP D POP H RET ; ;THE FOLLOWING USER SUPPLIED ROUTINE MUST GET A CHARACTER ; FROM THE INPUT DEVICE AND PLACE IT IN REGISTER A. CHRIN PUSH B PUSH D PUSH H CRNR MVI C,6 ;CONSOLE INPUT FUNCTION MVI E,0FFH CALL FDOS CPI 0 JZ CRNR ;CHARACTER NOT READY POP H POP D POP B RET DS 20 ; ; THE FOLLOWING USER SUPPLIED ROUTINE OUTPUTS CHRACTERS ; THE CHARACTER TO BE SENT IS IN B. ONLY A,B,&C MAY BE USED. CHROUT PUSH D PUSH H PUSH B MVI C,02H ; CONSOLE OUTPUT FUNCTION MOV E,B CALL FDOS POP B POP H POP D RET DS 20 ; ;************************************ ; BYTE FOR BYTE COMPAIR MESSAGE ;************************************ BFBT LXI H,BFBMES ; PRINT BYTE FOR BYTE COMPAIR? CALL PMES CALL CHRIN ; TTIN ADDRESS IN NORTH STAR MOV B,A CALL TTOUT MOV A,B CPI 'Y' JZ BFBYES CPI 'N' JZ BFBNO CPI 0DH JNZ $+7 CALL CRLF RET CALL CRLF JMP BFBT BFBNO XRA A STA BFBC ; DISABLE BYTE FOR BYTE CALL CRLF RET BFBYES MVI A,80H ; ENABLE BYTE FOR BYTE COMPAIR STA BFBC CALL CRLF RET BFBMES DB 'BYTE FOR BYTE COMPAIR? ' DB 0FFH ; TERMINATE MESSAGE ;************************************ ; ERROR PRINT ROUTINE ;*********************************** ERROR LXI H,ERCTN+2 ; INCREMENT ERROR COUNTER MVI B,3 ; NUMBER OF BYTES INCOUNTER CALL INCC LDA ERF CPI 00 ; IF ERROR FORMAT DONE? JNZ ERFD ; IF NON ZERO IT IS DONE ; PRINT FORMAT SERP LXI H,ERFMES CALL PMES MVI A,10 ; NUMBER OF ERRORS PER HEADER+1 STA ERF ; SET FORMAT DONE ;************************* ; OUTPUT DECIMAL ADDRESS * ;************************* ERFD DCR A STA ERF DADDR CALL PDADO JMP DADDRC PDADO LDA TRKU MOV H,A LDA TRKL MOV L,A LXI D,0FF9CH ; MINUS 100 MVI B,0 ; 100S COUNTER HUNST XRA A ADD H JNZ ADJ ; IF MSB IS NOT ZERO ADJUST (-100) MOV A,L CPI 100 JNC ADJ ; IF LSB > 99 ADJUST XRA A MOV A,B CALL DAAJ CALL DBBCDO ; PRINT MSB XRA A MOV A,L CALL DAAJ CALL DBBCDO CALL SPACE JMP PDND ADJ DAD D INR B JMP HUNST PDND LDA HEAD CALL ASCII CALL SPACE XRA A LDA SECT CALL DAAJ CALL DBBCDO CALL SPACE RET ;*************************************** ; PRINT GOOD AND BAD HEADERS IN HEX * ;*************************************** ; DADDRC LDA PHASE MVI D,0 ANI 1 JZ $+5 MVI D,0FFH LDA TRKU XRA D ; PHASE ADJUST THE GOOD TRACK CALL DBBCDO LDA TRKL XRA D CALL DBBCDO CALL SLACH OUT STATU IN SCTBU ; GET HEADER BYTE, TRACK CALL DBBCDO IN SCTBU CALL DBBCDO CALL SPACE LDA HEAD ; GET GOOD HEAD XRA D ; PHASE ADJUST CALL DBBCDO CALL SLACH IN SCTBU CALL DBBCDO CALL SPACE LDA SECT XRA D ; PHASE ADJUST CALL DBBCDO CALL SLACH IN SCTBU CALL DBBCDO CALL SPACE ;********************** ; PRINT TRANSFER TYPE * ;********************** ; LDA RECP CPI 0 JZ NOM CPI 2 JZ PLUS CPI 4 JZ MIN CPI 6 JZ EARLY MVI A,'L' JMP TTRDY NOM MVI A,'N' JMP TTRDY PLUS MVI A,'P' JMP TTRDY MIN MVI A,'E' JMP TTRDY EARLY MVI A,'-' TTRDY CALL TTOUT MVI A,',' CALL TTOUT IN STATU ; GET STATUS ANI 4 ; IS CHECKSUM TRUE? JZ GOODCC ; PRINT GD IF GOOD MVI A,'B' CALL TTOUT ; PRINT BD IF BAD MVI A,'D' CALL TTOUT JMP BDDONE GOODCC MVI A,'G' CALL TTOUT MVI A,'D' CALL TTOUT MVI A,',' CALL TTOUT LDA READT ; READ TYPE CALL TTOUT BDDONE CALL SPACE ;********************************* ; PRINT THE DATA ERRORS, IF ANY * ;********************************** XRA A STA TEMP MVI E,0 MVI D,0 LXI H,STBUF LXI B,RDBUF+4 NEXTD LDAX B CMP M CNZ BDATA MOV A,D CPI 4 ; MAX COUNT YET JZ FULLL ; REPORT IS DONE INX H INX B INR E JNZ NEXTD IF S512 LDA TEMP INR A STA TEMP CPI 2 JNZ NEXTD ENDIF FULLL CALL CRLF CALL CONTC CZ BREAK RET BDATA LDA TEMP PUSH H PUSH D PUSH B CALL ASCII POP B POP D POP H MOV A,E CALL DBBCDO ; PRINT WORD MVI A,',' CALL TTOUT MOV A,M CALL DBBCDO CALL SLACH LDAX B CALL DBBCDO CALL SPACE INR D RET ERFMES DB 'TRCK H SC TRACK HEAD SCTR' DB ' TYPE WORD,GOOD/BAD' DB 0AH DB 0DH DB 0FFH ; TERMINATE MESSAGE DAAJ MVI B,00 ; B IS TENS COUNT DAMTEN CPI 10 ; IS IT LESS THAN 10? JC DAAD ; IF YES FINISH DAA SBI 10 INR B JMP DAMTEN DAAD MOV C,A MOV A,B RLC RLC RLC RLC ANI 0F0H ORA C RET ;************************************ ; DBBCDO OUTPUT REG A AS TWO ASCII ; CHARACTERS. A IS IN HEX OR BCD ;************************************ DBBCDO PUSH B PUSH D PUSH H MOV B,A RRC RRC RRC RRC CALL ASCII MOV A,B CALL ASCII POP H POP D POP B RET ; OUTPUT 'A' AS AN ASCII DECIMAL NUMBER ASCII PUSH B ANI 0FH ORI 30H CPI 3AH JC GOODC ADI 7 ; MAKE INTO A TO F GOODC CALL TTOUT POP B RET TTOUT PUSH B PUSH A MOV B,A XRA A CALL CHROUT POP A POP B RET ;**************************************** ; H&L POINT TO A MESSAGE TERMINATED BY FF * ;**************************************** PMES MOV A,M ; GET FIRST CHAR CPI 0FFH RZ ; RETURN IF LAST CHARACTER DONE CALL TTOUT INX H JMP PMES ;**************************** ; NONDATA ERROR MESSAGES * ;**************************** ; 1 DISK FAILED TO SELECT ; 2 SEEK ERROR, INITIAL SEEK ; 3 FAULT AFTER WRITE ; 4 FAULT FOLLOWING HEAD SELECT, WRITE ; 6 TIMEOUT ERROR1 LXI H,SELM JMP ERMES ERROR2 LXI H,SEEKE JMP ERMES ERROR3 LXI H,WFAULT JMP ERMES ERROR4 LXI H,WHSEL JMP ERMES ERROR6 LXI H,TIMEO JMP ERMES ERMES CALL PMES LXI H,ERRORM CALL PMES CALL CRLF LXI H,ERCTN+2 MVI B,3 CALL INCC CALL STATUS RET ERRORM DB ' ERROR ' DB 0FFH SELM DB 'SELECT' DB 0FFH SEEKE DB 'SEEK' DB 0FFH WFAULT DB 'WRITE FAULT' DB 0FFH WHSEL DB 'HEAD SELECT' DB 0FFH TIMEO DB 'TIMEOUT' DB 0FFH SPACE MVI A,' ' CALL TTOUT RET SLACH MVI A,'/' CALL TTOUT RET ;********************************************** ; STATUS PRINTS IN RESPONCE TO A CONTROL 'C' * ;********************************************** STATUS CALL CRLF LXI H,FULMES ; PRINTS 'FULL PASSES' CALL PMES LDA FPASS CALL DBBCDO LXI H,RWPMES ; PRINTS RW PASSES CALL PMES LDA RWPASS CALL DBBCDO LDA RWPASS+1 CALL DBBCDO LXI H,PERMES ; PRINTS 'ERROR' CALL PMES LDA ERCTN CALL DBBCDO LDA ERCTN+1 CALL DBBCDO LDA ERCTN+2 CALL DBBCDO LXI H,SECMES ; PRINTS 'SECTORS READ' CALL PMES LXI H,SCRED MVI E,4 ANOTHER MOV A,M CALL DBBCDO INX H DCR E JNZ ANOTHER CALL CRLF MVI A,00 STA ERF ; FORCE HEADER TO PRINT CALL PDADO CALL CRLF CALL CONTC CZ BREAK RET FULMES DB 'FULL PASSES=' DB 0FFH RWPMES DB ' R,W PASSES=' DB 0FFH PERMES DB ' ERRORS=' DB 0FFH SECMES DB ' SECTORS READ=' DB 0FFH ; 40 MILLISEC DELAY DLY LXI H,1F40H DLY1 DCX H XRA A ADD L JNZ DLY1 ADD H JNZ DLY1 RET ;************************************************* ; INCC INCREMENTS THE COUNTER POINTED TO BY THE * ; H&L REGISTER PAIR. H&L ARE THE LSB OF THE * ; COUNT (AND THE HIGHEST MEMORY ADDRESS) AND * ; B IS THE BYTES IN THE COUNTER. * ;************************************************ INCC MOV A,M INR A MOV M,A CPI 00H RNZ ; RETURN UNLESS BYTE OVERFLOW DCX H ; NEXT BYTE DCR B RZ ; RETURN IF END OF COUNTER REACHED JMP INCC CRLF MVI A,0DH CALL TTOUT MVI A,0AH CALL TTOUT RET ;*********************** ; READ OFFSET OPTION * ;*********************** ROSS LXI H,ROSMES CALL PMES CALL CHRIN MOV B,A CALL TTOUT MOV A,B CPI 'Y' JZ OFFSET CPI 'N' JZ NOOFFS CPI 0DH JZ $+9 CALL CRLF JMP ROSS CALL CRLF RET OFFSET XRA A STA OSBYTE CALL CRLF RET NOOFFS MVI A,80H STA OSBYTE ; DISABLE OFFSETS CALL CRLF RET ROSMES DB 'TEST READ DATA AT ALL OFFSETS?' DB 0FFH ;********************************** ; GET TEST PARAMETERS * ; * ;********************************** RUBC EQU 5FH DSKPAR LXI H, FTMES ; FIRST TRACK CALL PMES CALL PARIN JC $+6 ; USE OLD SHLD MINTRK LXI H,LTMES ; LAST TRACK CALL PMES CALL PARIN JC $+6 ; USE OLD SHLD MAXTRK LXI H,FHMES ; FIRST HEAD CALL PMES CALL PARIN JC $+7 ; USE OLD MOV A,L STA MINHD LXI H,LHMES ; LAST HEAD CALL PMES CALL PARIN JC $+7 ; USE OLD MOV A,L STA MXHD LXI H,PATMES ; FIRST SECTOR CALL PMES CALL PARIN JC $+7 ; USE OLD MOV A,L STA PATTERN LXI H,LSMES ; LAST SECTOR CALL PMES CALL PARIN JC $+7 ; USE OLD MOV A,L STA MAXSCT CALL CRLF RET FTMES DB 0DH DB 'FIRST TRACK? ' DB 0FFH LTMES DB 0AH DB 0DH DB 'LAST TRACK? ' DB 0FFH FHMES DB 0AH DB 0DH DB 'FIRST HEAD? ' DB 0FFH LHMES DB 0AH DB 0DH DB 'LAST HEAD? ' DB 0FFH PATMES DB 0AH DB 0DH DB 'INTERLACE PATTERN? ' DB 0FFH LSMES DB 0AH DB 0DH DB 'LAST SECTOR? ' DB 0FFH ; GET UP TO THREE ASCII CARACTERS AND ; CONVERT TO HEX ; RETURN WITH CARRY SET TO USE OLD PARAMETERS ; RESULTS IN H AND L PARIN MVI B,0 MOV C,B MOV D,B ; ZERO B,C,D CALL CHRIN CPI 0DH ; CR JZ OLDP ; IF CR USE OLD PARAMETERS NEXTCH CPI 0DH JZ DECIMAL ; GO CONVERT CPI RUBC JZ RUB MOV B,A XRA A CALL CHROUT MOV A,B MOV B,C MOV C,D ANI 0FH CPI 10 CNC ATF MOV D,A ; PLACE BCD IN D CALL CHRIN JMP NEXTCH DECIMAL MOV L,D MVI H,0 MVI D,0 MOV A,C RLC MOV E,A DAD D ; ADD 10SX2 RLC RLC MOV E,A DAD D ; ADD 10A X 5 MOV A,B RLC RLC MOV E,A DAD D ; ADD 100S X 4 RLC RLC RAL MOV E,A MOV A,D RAL MOV D,A DAD D ;ADD 100S X 32 XRA A MOV A,E RAL MOV E,A MOV A,D RAL MOV D,A DAD D ; ADD 100S X 64 RET ; H&L NOW CONTAIN HEX EQUVALENT OLDP STC RET RUB MOV D,C MOV C,B XRA A MVI B,08H ; BACKUP CALL CHROUT MVI B,' ' CALL CHROUT MVI B,08H CALL CHROUT MVI B,0 CALL CHRIN JMP NEXTCH ATF SBI 05 RET BREAK LXI H,BRK CALL PMES CALL CHRIN CPI ESC JZ GDOS CPI 'R' JZ START JMP STATUS GDOS LHLD SPSAV ;GET CP/M STACK SPHL ; RESTORED RET BRK DB 0AH DB 0DH DB 'BREAK TYPE ESC FOR DOS,R TO RESTART ' DB 'AND CR TO CONTINUE' DB 0FFH RDBUF DS 516 STBUF DS 512 STACK DS 100