;DRIVE TEST ; ORIGINAL 3_15_82 NORM TILLSBARY (SP?) ; FIRST REVISION 10_MAY_82 ZALABAK ;******************************************************************** ;BEGIN DATA DEFINITIONS ;******************************************************************** ;CONDITIONAL ASSEMBLY EQUATES ON EQU 0FFFFH ;DEFINE ON OFF EQU NOT ON ;AND OFF STOP EQU OFF ;CONDITION `ON` YIELDS RST 7 ON ERROR IF STOP ;EXAMINES CONDITION TRAP EQU 0FFH ;RESTART 7 OP CODE ENDIF IF NOT STOP ;OTHERWISE TRAP EQU 0 ;NOP CODE ENDIF ;-------------------------------------------------------------------- ;CONTROLLER COMMAND SET RDSEC EQU 20H ;READ A SECTOR WRSEC EQU 21H ;WRITE A SECTOR SNSTA EQU 22H ;SENSE DRIVE STATUS SETMA EQU 23H ;SET DMA ADDRESS CONHLT EQU 25H ;HALT CONTROLLER BRNCH EQU 26H ;BRANCH IN CHANNEL SETCHN EQU 27H ;SET CHANNEL ADDRESS STRTRY EQU 28H ;SET ERROR RETRY COUNT RDTRK EQU 29H ;READ A TRACK WRTRK EQU 2AH ;WRITE A TRACK STTKSZ EQU 2DH ;SET TRACK SIZE STLGCL EQU 2EH ;SET LOGICAL DRIVE STTIME EQU 2FH ;HEAD UNLOAD/DRIVE DESELECT TIMEOUT ;-------------------------------------------------------------------- ;BIT MASKS GOOD EQU 40H ;NORMAL COMMAND COMPLETION FIVER EQU 04H ;FIVE INCH DRIVE FLAG WRTPRO EQU 40H ;WRITE PROTECT FLAG DBLSID EQU 04H ;DOUBLE SIDED DRIVE & MEDIA FLAG SD2BIT EQU 80H ;SIDE TWO BIT INDEX EQU 10H ;DELTA INDEX STATUS BIT WPRTCT EQU 40H ;WRITE PROTECTED STATUS BIT PROERR EQU 90H ;WRITE-PROTECTED ERROR CODE DREADY EQU 80H ;DRIVE READY STATUS BIT NOTRDY EQU 82H ;DRIVE NOT READY ;-------------------------------------------------------------------- ;DEFINE DATA AREAS AND SIZES TBLSZ EQU 26 ;TRACK TABLE SIZE EIGHTK EQU 2000H ;DISK BUFFER SIZE MAPSIZ EQU 152 ;BADMAP 76 X 2 SIDES ;-------------------------------------------------------------------- ;CPM DEFINITIONS AND ENTRY POINTS CONIN EQU 1 ;CHARACTER IN CONSOLE COUT EQU 2 ;CHARACTER OUT CONSOLE WRSTRN EQU 9H ;BDOS WRITE STRING CONSTA EQU 0BH ;GET CONSOLE STATUS WBOOT EQU 0 ;WARM BOOT ADDRESS BDOS EQU 5 ;BDOS ENTRY ADDRESS ;-------------------------------------------------------------------- ;MISC DEFINITIONS LF EQU 0AH ;LINE FEED CR EQU 0DH ;CARRIAGE RETURN ESC EQU 1BH ;ESCAPE CHARACTER RETRIES EQU 05H ;DISK RETRIES BEFORE VERIFY ERROR CHANNL EQU 50H ;START CHANNEL ADDRESS VECTOR EQU CHANNL+1 ;BRANCH ADDRESS STARTR EQU 0EFH ;PORT ADDRESS TO START THE CONTROLLER ;******************************************************************** ;START OF MAIN LINE ;******************************************************************** START: ORG 100H LXI SP,STACK LXI D,ONMS ;START-UP MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LXI H,DRVLOG ;LOAD LOG ADDRESS SHLD LOGPNT ;INITIALIZE POINTER MVI A,BRNCH ;BRANCH COMMAND STA CHANNL ;CONTROLLER STARTS HERE LXI H,SETDMA ;SET DMA ADDRESS COMMAND SHLD VECTOR ;GUIDE CONTROLLER SUB A ;ZERO A STA VECTOR+2 ;EXTENDED ADDRESS BYTE STA HLTED ;ZERO HALT RESULT BYTE OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT TO FINISH LXI H,RETRYS ;ADDRESS OF SET TRIES CMND SHLD VECTOR ;TO GUIDE CONTROLLER SUB A ;ZERO A STA HLTED ;CLEAR HALT RESULT BYTE OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT TO FINISH CALL DRVCKS ;LOOK FOR DRIVES CALL TEST ;TESTEM JMP START ;RUN TEST AGAIN ;==================================================================== ;CHECK FOR ACTIVE DRIVES ;==================================================================== DRVCKS: MVI C,8 ;MAXIMUM NUMBER OF DRIVES LXI H,SNSTAT ;GET ADDRESS OF SENSE COMMAND SHLD VECTOR ;STORE IT IN VECTOR DRVLP: MVI A,8 ;# OF POSSIBLE DRIVES SUB C ;TO FIND CURRENT DRIVE MOV B,A ;SAVE DRIVE # IN B PUSH B ;SAVE COUNT STA SNSDRV ;TELL SENSE COMMAND SUB A ;ZERO A STA SNSRLT ;CLEAR RESULT BYTE OF SENSE COMMAND STA HLTED ;CLEAR HALT COMMAND RESULT BYTE OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT TO FINISH LDA SNSRLT ;SENSE COMMAND RESULT STATUS CALL LOGIN ;RECORD RESULTS IN TABLE POP B ;RECOVER COUNT DCR C ;DRIVE COUNT-DOWN JNZ DRVLP ;NEXT DRIVE RET ;ELSE RETURN ;-------------------------------------------------------------------- ;LOG ON ACTIVE DRIVES ; 1) THIS ROUTINE IS ONLY USED BY THE CHECK FOR ACTIVE DRIVES ; ROUTINE (DRVCKS). LOGIN: CPI GOOD ;ZERO MEANS ACTIVE DRIVE JZ CKIT ;TO FIND OUT ABOUT IT CPI NOTRDY ;APPROPRIATE RESULT CNZ LOGERR ;REPORT TO TERMINAL SPEC: LHLD LOGPNT ;GET POINTER MVI M,0 ;INDICATES INACTIVE DRIVE INX H ;UPDATE POINTER MVI M,0 ;INDICATES INACTIVE DRIVE INX H ;FOR NEXT DRIVE SHLD LOGPNT ;STORE POINTER RET CKIT: PUSH B ;SAVE BC PAIR LXI D,DRVMSG ;FOR OPERATOR MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS POP B ;RECOVER BC MOV A,B ;PUT DRIVE # IN A CALL BCDOUT ;SEND TO TERMINAL LDA DSTAT3 ;LOAD STATUS BYTE ANI WRTPRO ;CK WRITE-PROTECTED BIT JZ NOTPRO ;IF ITS OFF MVI A,PROERR ;WRITE-PROTECTED ERROR CODE CALL LOGER2 ;ADVISES TERMINAL JMP SPEC ;GOES ON TO NEXT DRIVE NOTPRO: LDA DSTAT1 ;TO FIND WHETHER 5 OR 8 INCH ANI 4H ;ON MEANS 5 INCH JZ EIGHIN ;ELSE ITS AN 8 INCH LHLD LOGPNT ;GET LOG POINTER MVI M,40 ;NUMBER OF TRACKS INX H ;TO NEXT ENTRY (SNGL OR DBLE SIDED) CALL ASKOP ;ASK OPERATOR # OF SIDES MVI B,0 ;ZERO B CPI '1' ;SINGLE-SIDED? JZ SKPDBL ;SKIP DOUBLE-SIDED ENTRY MVI B,80H ;DOUBLE-SIDED BIT SKPDBL: LDA DSTAT2 ;SECTOR SIZE ADD B ;COMBINE WITH B MOV M,A ;STORE RESULT IN DRIVE LOG INX H ;TO NEXT DRIVE SHLD LOGPNT ;STORE THE UPDATED POINTER RET EIGHIN: LHLD LOGPNT ;LOAD LOG POINTER MVI M,77 ;NUMBER OF TRACKS INX H ;NEXT LOG ENTRY LDA DSTAT2 ;SECTOR SIZE CPI 0 ;MAY BE WRONG IF ON TRACK 0 CZ RECHK ;MOVES TO TRACK 1 AND RECHECKS MOV B,A ;SAVE IN B LDA DSTAT3 ;3 BIT TELLS SIDES ANI 4H ;ON MEANS DBL SIDED JZ SNGL ;SINGLE SIDED MVI A,80H ;DBLE SIDED BIT SNGL: ADD B ;COMBINE WITH SECTOR SIZE MOV M,A ;RECORD IT INX H ;INCREMENT POINTER FOR NEXT DRIVE SHLD LOGPNT ;SAVE IT RET ;-------------------------------------------------------------------- ;GET THE NUMBER OF SIDES ; 1) THIS ROUTINE IS ONLY USED BY THE LOG ON ACTIVE DISKS ; ROUTINE (ASKOP). ASKOP: PUSH H ;SAVE HL PUSH B ;SAVE BC LXI D,SIDESQ ;NUMBER OF SIDES QUESTION MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LXI D,0 ;INITIALIZE COUNTER ASKWT: PUSH D ;SAVE COUNTER MVI C,CONSTA ;BDOS CONSOLE STATUS CODE CALL BDOS POP D ;RESTORE COUNTER DCR A ;A IS 1 IF DATA READY JZ CKANS ;GET THE ANSWER DCX D ;ELSE WAIT AWHILE MOV A,E ORA D JNZ ASKWT MVI E,'2' ;PROVIDE DEFAULT ANSWER MVI C,COUT ;CONSOLE OUT CALL BDOS ;SEND IT MVI A,'2' ;DEFAULT IS TWO-SIDED JMP EVAL ;INSERT IT FOR RETURN CKANS: MVI C,CONIN ;CONSOLE-IN CODE CALL BDOS ;GET ANSWER EVAL: POP B ;RECOVER BC POP H ;RECOVER HL CPI CR ;IS IT A NULL ANSWER? JZ START ;IF SO, RESTART PROGRAM CPI '1' ;OR 1 RZ ;GOOD ANSWER JM ASKOP ;BAD ANSWER, ASK AGAIN CPI '2' ;GOOD ANSWER JNZ ASKOP ;ASK AGAIN MVI A,80H ;DBLE-SIDED BIT RET ;-------------------------------------------------------------------- ; 1) THIS ROUTINE IS ONLY USED BY THE LOG IN ACTIVE DRIVES ; ROUTINE (LOGIN). RECHK: PUSH H ;SAVE HL LXI H,RDTRAK ;SET-UP TO READ A TRACK SHLD VECTOR ;TO GUIDE CONTROLLER MVI A,1 ;DESIRED TRACK STA RDTKTK ;STORE IN COMMAND OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT LXI H,SNSTAT ;SENSE STATUS COMMAND SHLD VECTOR ;GUIDE CONTROLLER OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT LDA DSTAT2 ;LOAD DESIRED RESULT BYTE POP H ;RESTORE HL RET ;==================================================================== ;MAIN LINE TEST DRIVES ;==================================================================== TEST: MVI C,8 ;NUMBER OF DRIVE POSSIBILITIES LXI H,DRVLOG ;PICKUP LOG ADDRESS NEXT: MOV A,M ;LOAD TRACKS CPI 0 ;ACTIVE? JNZ GO ;YES INX H ;ELSE ADVANCE POINTER INX H ;TO NEXT DRIVE DCR C ;DECREMENT DRIVE COUNTER JNZ NEXT ;LOOP TILL DONE RET GO: SHLD LOGPNT ;SAVE POINTER MVI A,8 ;NUMBER OF DRIVE POSSIBILITIES SUB C ;CURRENT DRIVE NUMBER STA WRTKDR ;TELL COMMANDS STA RDTKDR PUSH H ;SAVE HL PUSH B ;AND BC CALL SEEKS ;DO SEEK TESTS CALL RDWRTS ;DO DATA TESTS POP B ;RECOVER POINTERS POP H INX H ;ADVANCE POINTER INX H ;FOR NEXT DRIVE DCR C ;DRIVE COUNT DOWN JNZ NEXT ;AND LOOP RET ;NO MORE DRIVES ;==================================================================== ;MAIN LINE SEEK TEST SEEKS: LXI D,SEEKNG ;ADDRESS OF SEEK MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS CALL DRTYPE ;TELLS TRACK AND DRIVE NUMBER LXI H,RDTRAK ;READ TRACK COMMAND ADDRESS SHLD VECTOR ;GUIDE CONTROLLER MVI A,80H ;TO ABORT COMMAND CALL CLRTBL ;WRITES A TO COMMAND TABLE LHLD LOGPNT ;PICKUP POINTER MOV D,M ;PUT # OF TRACKS IN D DCR D ;TO GET HIGHEST TRACK NUMBER MVI E,0 ;ZERO E CALL PAT1 ;SHORT-LONG-SHORT LHLD LOGPNT ;PICKUP LOG POINTER MOV D,M ;NUMBER OF TRACKS TO D DCR D ;TO GET HIGHEST TRACK NUMBER CALL PAT2 ;LONG-SHORT-LONG MVI D,0 ;START AT 0 CALL PAT3 ;BUTTERFLY (+2-1 OUT, THEN -2+1 BACK) RET ;-------------------------------------------------------------------- ;SHORT-LONG-SHORT? ; 1) THE SEEK ROUTINE RETURNS THE CARRY (ERROR_FLAG) CLEAR IF ; THE SEEK WAS SUCCESSFUL, SET IF THERE WAS AN ERROR. PAT1: MOV A,D ;D STARTS AT HIGHEST TRACK NUMBER CALL SEEK ;SEEKS TO TRACK IN A RC ;IF (ERROR_FLAG = SET) THEN RETURN MOV A,E ;E STARTS AT TRACK 0 CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN DCR D ;COUNT DOWN JM REVERSE ;NO TRACKS LEFT INR E ;COUNT UP CMP M ;NUMBER OF TRACKS JNZ PAT1 REVERSE:INR D ;COUNT UP MOV A,D CMP M ;M HAS NUMBER OF TRACKS RZ CALL SEEK ;ELSE SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN DCR E RM ;NO TRACKS LEFT MOV A,E CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN JMP REVERSE ;-------------------------------------------------------------------- ;LONG-SHORT-LONG? ; 1) THE SEEK ROUTINE RETURNS THE CARRY (ERROR_FLAG) CLEAR IF ; THE SEEK WAS SUCCESSFUL, SET IF THERE WAS AN ERROR. PAT2: MOV A,D ;D STARTS AT HIGHEST TRACK NUMBER RAR ;DIVIDE BY 2 MOV D,A ;RESET D MOV E,A ;SET E=D AT START PAT2LP: MOV A,D ;START AT MIDDLE TRACK CALL SEEK ;SEEKS TO TRACK IN A RC ;IF (ERROR_FLAG = SET) THEN RETURN DCR E ;COUNT E DOWN, D UP JM PHASE2 ;REVERSE DIRECTION MOV A,E ;ELSE READ IT CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN INR D ;COUNT UP IN FIRST PHASE CMP M ;NUMBER OF TRACKS JNZ PAT2LP PHASE2: INR E ;COUNT UP MOV A,E CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN DCR D ;COUNT DOWN MOV A,D ;TO CHECK CMP E ;LOOKING FOR CROSSING POINT RM ;FINISHED CALL SEEK ;ELSE CONTINUE RC ;IF (ERROR_FLAG = SET) THEN RETURN JMP PHASE2 ;LOOP ;-------------------------------------------------------------------- ;BUTTERFLY (+2-1 OUT, THEN -2+1 BACK) ; 1) THE SEEK ROUTINE RETURNS THE CARRY (ERROR_FLAG) CLEAR IF ; THE SEEK WAS SUCCESSFUL, SET IF THERE WAS AN ERROR. PAT3: MOV A,D ;D STARTS AT 0 CALL SEEK ;TAKES DRIVE BACK ONE IN LOOP RC ;IF (ERROR_FLAG = SET) THEN RETURN MOV A,D ADI 2 ;JUMP AHEAD TWO CMP M ;NUMBER OF TRACKS JZ PHAZE2 ;REVERSE PATTERN CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN INR D ;AND BACK ONE JMP PAT3 ;REPEAT PHAZE2: DCR A ;FOR FIRST SHOT ONLY PHLP: CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN MOV A,D SBI 2 ;IN TWO RM CALL SEEK RC ;IF (ERROR_FLAG = SET) THEN RETURN DCR D ;AND BACK ONE MOV A,D JMP PHLP ;-------------------------------------------------------------------- ;SEEK TO THE TRACK IN THE ACCM. ; 1) IF THERE ARE ANY ERRORS ENCOUNTERED THEN THEY ARE REPORTED ; TO THE CONSOLE AND THE ERROR_FLAG (THE CARRY BIT) IS SET. ; 2) IF THERE WERE NO ERRORS THEN THE ERROR_FLAG IS RESET. SEEK: STA RDTKTK ;START AT TRACK INDICATED BY A STA TRACK ;KEEP RECORD PUSH D ;SAVE DE PUSH H ;SAVE HL MOV C,A ;SAVE TRACK IN C LHLD LOGPNT ;GET LOG POINTER INX H ;ADVANCE LOG POINTER TO SIDES BYTE MOV A,M ;LOAD BYTE DCX H ;RETURN POINTER ANI 80H ;SEE IF DBLESIDED BIT IS ON JZ ONESID ;IF NOT, FORGET IT LDA RDTKSD ;ELSE LOAD SIDE BYTE XRI 80H ;TOGGLE IT ONESID: STA RDTKSD ;REPLACE IT STA SIDE ;SAVE IT MOV B,A ;SAVE SIDE BYTE IN B PUSH B ;SAVE BC SUB A ;ZERO A STA RTRSLT ;CLEAR RESULT BYTE OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT TO FINISH POP B ;RESTORE BC LDA RTRSLT ;CHECK THE RESULTS CPI GOOD ;NORMAL COMPLETION? POP H ;RESTORE HL POP D ;RESTORE DE JNZ GRAB1 ;IF ERROR = NO THEN STC CMC ; ERROR_FLAG:=NO RET ; RETURN GRAB1: DB TRAP ;ELSE (CONDITIONAL RST 7) CALL ERROR ; REPORT ERROR STC ; ERROR:=TRUE (CRY=SET) RET ; RETURN ;-------------------------------------------------------------------- ;REPORT AN ERROR ON THE CONSOLE ; 1) THIS ROUTINE IS USED BY THE SEEK TRACK ROUTINE (SEEK). ; 2) THIS ROUTINE IS ALSO USED BY THE LOG ON ACTIVE DRIVES ; ROUTINE (LOGIN) WHICH ENTERS AT LOGER2. LOGERR: PUSH PSW ;SAVE ERROR CODE GRAB5: DB TRAP ;CONDITIONAL RST 7 PUSH B ;SAVE DRIVE NUMBER IN B LXI D,DRVMSG ;DRIVE MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS POP B ;GET DRIVE NUMBER MOV A,B ;MOVE IT CALL BCDOUT ;SEND IT POP PSW ;RECOVER ERROR CODE LOGER2: CALL ERRFND ;LOADS DE TO ERR MSG INX D ;SKIP CRS & LF INX D INX D MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS RET ;==================================================================== ;BEGIN READ AND WRITE TEST ; 1) WRDRV AND RDDRV RETURN CARRY CLEAR FOR NO ERROR RDWRTS: LXI D,READNG ;ADDRESS OF READ/WRITE MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS CALL DRTYPE ;TRACK AND DRIVE NUMBER SUB A ;ZERO A STA PASS ;CLEAR PASS COUNTER CALL CLRTBL ;CLEARS COMMAND TABLE CALL TRKSZR ;PUTS SIZE OF TRACK AT TBYTES NOP TSTDAT: LXI H,WRTRAK ;WRITE TRACK COMMAND ADDRESS SHLD VECTOR ;TO GUIDE CONTROLLER CALL WRDRV ;WRITES ALL TRACKS RC ;IF ERROR = TRUE THEN RETURN LXI H,RDTRAK ;READ TRACK COMMAND ADDRESS SHLD VECTOR ;GUIDE CONTROLLER CALL RDDRV ;READS AND COMPARES ALL RC ;IF ERROR = TRUE THEN RETURN LDA PASS ;GET PASS COUNTER INR A ;INCREMENT IT STA PASS ;PUT IT BACK CPI 4 ;ONE TO MANY JNZ TSTDAT ;CONTINUE DATA TEST RET ;-------------------------------------------------------------------- ;FIGURE SIZE OF TRACK IN BYTES ; 1) THIS ROUTINE IS ONLY USED BY RDWRTS. TRKSZR: LHLD LOGPNT ;PICKUP LOG POINTER MVI B,0 ;ZERO B MOV A,M ;GET TRACKS IN A CPI 77 ;8 INCH? JNZ SKP ;DO NOT CHANGE MVI B,3 ;TO SKIP 5 INCH SKP: INX H ;ADVANCE POINTER TO 2ND LOG ENTRY MOV A,M ;LOAD SECTOR SIZE & SIDES ANI 7 ;MASK SIZE ONLY ADD B ;COVERS 5 OR 8 INCH DRIVES LXI H,TKSIZ5 ;INITIALIZE POINTER TO SIZES CALL ADJUST ;ADJUST M BY DOUBLE A MOV E,M ;LOAD LOW BYTE INX H ;ADVANCE POINTER MOV D,M ;LOAD HIGH BYTE XCHG ;PUT RESULT IN HL SHLD TBYTES ;STORE RESULT RET ;-------------------------------------------------------------------- ;WRITE ALL TRACKS ON A DRIVE ; 1) IF ANY ERRORS OCCURE THEN THE CARRY IS RETURNED SET ELSE ; ITS RETURNED CLEAR. WRDRV: LXI D,WRTMSG ;WRITING MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA PASS ;GET PASS NUMBER CALL BCDOUT ;SEND IT CALL CLRMAP ;CLEARS BADMAP TO ZEROS LXI H,BADMAP ;ADDRESS OF MAP SHLD MAPPNT ;INITIALIZES POINTER TO BADMAP LHLD LOGPNT ;PICKUP LOG POINTER MOV B,M ;NUMBER OF TRACKS SUB A ;ZERO A STA WRTKSD ;START WITH SIDE 0 STA SIDE ;STORE FOR ERROR MESSAGE TRKLP: PUSH B ;SAVE TRACK COUNTER PUSH H ;SAVE LOG POINTER MOV A,M ;NUMBER OF TRACKS SUB B ;TRACK COUNTER MOV C,A ;SAVE TRACK IN C STA WRTKTK ;CURRENT TRACK TO COMMAND STA TRACK ;AND RECORD CALL NEWPAT ;GET PATTERN FOR THIS TRACK CALL FILBUF ;WRITES IT TO DISK BUFFER WTTK: SUB A ;ZERO A STA WTRSLT ;CLEAR RESULT BYTE OUT STARTR ;STARTS CONTROLLER CALL WAIT1 ;WAIT FOR IT TO FINISH LDA WRTKSD ;GET THE SIDE BYTE MOV B,A ;SAVE IT IN B LDA WTRSLT ;LOAD RESULT BYTE CPI GOOD ;ORDINARY COMPLETION JZ UPDATE ;GIVES NORMAL RETURN GRAB2: DB TRAP ;CONDITIONAL RST 7 CPI NOTRDY ;IF DRIVE = NOT_READY THEN JNZ MOD115 POP H ; RESTORE STACK POP B STC ; ERROR = YES (CRY=SET) RET ; RETURN MOD115: LHLD MAPPNT ;PICKUP POINTER TO BADMAP MOV M,A ;STORE ERROR CODE INX H ;ADVANCE POINTER SHLD MAPPNT ;STORE POINTER CALL ERROR ;REPORT AND CONTINUE JMP ASWAS ;NORMAL COMPLETION UPDATE: CALL CKTBL ;CHECK SECTOR RESULTS TABLE LHLD MAPPNT ;PICKUP POINTER TO BADMAP INX H ;ADVANCE IT SHLD MAPPNT ;STORE IT ASWAS: LHLD LOGPNT ;GET LOG POINTER INX H ;ADVANCE TO SIDE BYTE MOV A,M ;LOAD IT ANI 80H ;CHECK SIDES BIT JZ CNTDWN ;IF SINGLE-SIDED, FORGET IT LDA WRTKSD ;LOAD COMMAND SIDE BYTE ANI 80H ;CHECK SIDE BIT JNZ RESET ;ALREADY DONE MVI A,80H ;SET IT STA WRTKSD ;STORE IN COMMAND STA SIDE ;AND STORE IT JMP WTTK RESET: SUB A ;RESET SIDE BIT FOR NEXT TRACK STA WRTKSD ;STORE IN COMMAND STA SIDE ;AND STORE IT CNTDWN: POP H ;RESTORE POINTER POP B ;RESTORE BC DCR B ;COUNT DOWN THE TRACKS JNZ TRKLP ;DO ANOTHER TRACK STC CMC ;ERROR = FALSE (CRY=CLEAR) RET ;PASS COMPLETE ;-------------------------------------------------------------------- ;CLEAR BAD MAP ; 1) THIS ROUTINE IS ONLY USED BY THE WRITE A TRACK ROUTINE ; (WRDRV). CLRMAP: MVI C,MAPSIZ ;SIZE OF BADMAP LXI H,BADMAP ;ADDRESS OF MAP SUB A ;ZERO A MAPLP: MOV M,A ;PUT ZERO IN MAP INX H ;ADVANCE DCR C ;COUNT-DOWN JNZ MAPLP ;UNTIL DONE RET ;-------------------------------------------------------------------- ;FILL THE DISK BUFFER ; 1) THIS ROUTINE IS ONLY USED BY THE WRITE A TRACK ROUTINE ; (WRDRV). FILBUF: PUSH H ;SAVE HL LHLD TBYTES ;TRACK SIZE XCHG ;PUTS SIZE IN DE LXI H,DSKBUF ;POINTS M AT DISK BUFFER BUFLP: MOV M,B ;STORES B IN BUFFER INX H ;STEPS M DCX D ;DECREMENT COUNTER MOV A,E ;TO CHECK FOR ZERO ORA D JNZ BUFLP ;LOOP TILL DONE POP H ;RESTORE HL RET ;-------------------------------------------------------------------- ;READ ALL THE TRACKS ON A DRIVE ; 1) IF THERE ARE ANY ERRORS THEN THE CARRY IS RETURNED SET ; ELSE THE CARRY IS RETURNED CLEARED. RDDRV: LXI D,RDNMSG ;READING MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA PASS ;GET PASS CALL BCDOUT ;SEND IT SUB A ;ZERO A STA RDTKSD ;START WITH SIDE 0 STA SIDE ;AND SAVE RECORD LXI H,BADMAP ;INITIALIZE POINTER DCX H ;TO ONE LESS SHLD MAPPNT ;AND STORE IT LHLD LOGPNT ;GET LOG POINTER MOV B,M ;LOADS # OF TRACKS TO B TRKLP2: PUSH B ;SAVE TRACK COUNTER PUSH H ;SAVE LOG POINTER MOV A,M ;GET NUMBER OF TRACKS SUB B ;TRACK COUNTER MOV C,A ;SAVE TRACK IN C STA RDTKTK ;STORE IN COMMAND STA TRACK ;TRACK RECORD RD: LHLD MAPPNT ;PICKUP BADMAP POINTER INX H ;ADVANCE IT SHLD MAPPNT ;PUT IT BACK MOV A,M ;LOAD IT ANI 0FFH ;SEE IF ITS CLEAR JNZ NXTRK ;SKIP TRACK IF NOT SUB A ;ZERO A STA RTRSLT ;CLEAR RESULT BYTE OUT STARTR ;START CONTROLLER CALL WAIT1 ;WAIT FOR IT TO FINISH LDA RDTKSD ;GET SIDE BYTE MOV B,A ;SAVE IT IN B LDA RTRSLT ;GET RESULT BYTE CPI GOOD ;COMPARE JZ OKAY ;GIVES NORMAL RETURN GRAB3: DB TRAP ;CONDITIONAL RST 7 CPI NOTRDY ;DRIVE GONE AWAY? JNZ MOD255 ;IF DRIVE = NOT_READY THEN POP H ; RESTORE STACK POP B STC ; ERROR = YES (CRY=SET) RET ; RETURN MOD255: CALL ERROR ;REPORT AND CONTINUE OKAY: PUSH B ;SAVE BC CALL CKTBL ;CHECK SECTOR RESULTS TABLE POP B ;RESTORE BC CALL NEWPAT ;GET TEST PATTERN CALL VERIFY ;READ AND COMPARE DATA NXTRK: LHLD LOGPNT ;GET LOG POINTER INX H ;ADVANCE TO SIDE BYTE MOV A,M ;LOAD IT ANI 80H ;CHECK SIDES BIT JZ IGNOR ;IF SINGLE-SIDED, FORGET IT LDA RDTKSD ;LOAD COMMAND SIDE BYTE ANI 80H ;CHECK SIDE BIT JNZ RESET2 ;ALREADY DONE MVI A,80H ;SET IT STA RDTKSD ;STORE IN COMMAND STA SIDE ;SAVE RECORD JMP RD ;DO OTHER SIDE RESET2: SUB A ;RESET SIDE BIT FOR NEXT TRACK STA RDTKSD ;STORE IN COMMAND STA SIDE ;SAVE RECORD IGNOR: POP H ;RESTORE POINTER POP B ;RECOVER COUNTER DCR B ;COUNT DOWN TRACKS JNZ TRKLP2 ;DO NEXT TRACK STC CMC ;ERROR = NO (CRY=CLEARED) RET ;FINISH ;-------------------------------------------------------------------- ;VERIFY THAT DATA WAS CORRECTLY READ ; 1) THIS ROUTINE IS ONLY USED BY THE READ A TRACK ROUTINE ; (RDDRV). VERIFY: LXI D,0 ;ZERO DE PUSH D ;SAVE DE LHLD TBYTES ;LOAD TRACK SIZE XCHG ;MOVE TO DE LXI H,DSKBUF ;SET M TO DISK BUFFER VERLP: MOV A,M ;PICK UP MEMORY CMP B ;WHAT IT SHOULD BE JZ CNTINU ;IF CORRECT XTHL ;SAVE HL & GET ERROR COUNT INX H ;INCREMENT ERROR COUNT XTHL ;RESTORE & SAVE CNTINU: INX H ;INCREMENT M DCX D ;DECREMENT SIZE COUNTER MOV A,E ;CHECK FOR ZERO ORA D JNZ VERLP ;CONTINUE IF NOT POP H ;GET ERROR COUNT MOV A,L ;PUT L IN A ORA H ;ZERO? RZ PUSH H ;OR REPORT LXI D,CRLF ;CARRIAGE RETURN & LINE FEED MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS POP H ;GET ERROR COUNT PUSH H MOV A,H CALL BCDOUT ;PRINT THE HI-BYTE ERROR COUNT POP H MOV A,L CALL BCDOUT ;PRINT THE LO-BYTE ERROR COUNT LXI D,CMPERR ;COMPARE ERROR MSG MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA RDTKTK ;GET TRACK NUMBER CALL BCDOUT ;SEND IT LXI D,SDMS ;SIDE MSG MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA RDTKSD ;LOAD SIDE BIT ANI SD2BIT ;GET SIDE BIT RLC ;PUT IT IN LOWEST BIT CALL BCDOUT ;SEND IT RET ;-------------------------------------------------------------------- ;CHECK SECTOR TABLE ; 1) THIS ROUINE IS USED BY BOTH THE READ AND THE WRITE A TRACK ; ROUTINES(WRTDRV,RDDRV). CKTBL: CALL GETSCS ;RETURNS # OF SECTORS IN C MOV B,C ;SAVE # IN B LXI H,TRKTBL ;TRACK R/W RESULT TABLE CKLP: MOV A,M ;LOAD M CPI GOOD ;NORMAL COMPLETION CNZ SECERR ;REPORT ERROR INX H ;ADVANCE DCR C ;DECREMENT COUNTER JNZ CKLP ;REPEAT TILL DONE SUB A ;ZERO A FOR CLRTBL CALL CLRTBL ;CLEAR TABLE AND RETURN RET ;-------------------------------------------------------------------- ;RETURN NUMBER OF SECTORS ON DISK IN REGISTER C ; 1) THIS ROUTINE IS ONLY REFERENCED BY THE CHECK THE SECTOR ; TABLE ROUTINE (CKTBL). GETSCS: LHLD LOGPNT ;GET DRIVE LOG POINTER MOV A,M ;GET # OF TRACKS CPI 77 ;IF 8 INCH JZ NOT5 ;SKIP 5 INCH MVI C,0AH ;10 SECTORS FOR FIVE INCH RET NOT5: LDA TRACK ;LOAD CURRENT TRACK CPI 0 ;SEE IF ITS TRACK 0 JNZ NOT0 ;SKIP IF ITS NOT MVI C,26 ;ELSE ITS 26 SECTORS RET NOT0: INX H ;ADVANCE TO SECTOR SIZE MOV A,M ;LOAD SECTOR SIZE BYTE ANI 7 ;LOW BITS ONLY MOV B,A ;SAVE IN B LXI H,SCTRS ;POINT M AT TABLE MOV A,L ;ADJUST M BY B ADD B JNC NOTOVR ;IN CASE OF CARRY INR H NOTOVR: MOV L,A ;M NOW ADJUSTED MOV C,M ;PUT NUMBER OF SECTORS IN C RET ;-------------------------------------------------------------------- ;REPORT SECTOR ERROR ; 1) THIS ROUTINE IS ONLY USED BY THE CHECK SECTOR TABLE ; ROUTINE (CKTBL). SECERR: PUSH H ;SAVE HL GRAB6: DB TRAP ;CONDITIONAL RST 7 PUSH B ;AND BC CALL ERRFND ;LOADS DE WITH ERR MSG MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LXI D,TRKMSG ;TRACK MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA TRACK ;GET TRACK NUMBER CALL BCDOUT ;SEND IT LXI D,SIDEMS ;SIDE MSG MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA SIDE ;GET CURRENT SIDE RLC ;MOVE SIDE BIT TO DATA 0 CALL BCDOUT ;SEND IT LXI D,SECMSG ;SECTOR MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS POP B ;RECOVER BC PUSH B ;AND RE-SAVE MOV A,B ;NUMBER OF SECTORS SUB C ;COUNTER CALL BCDOUT ;SEND IT AND RETURN POP B ;RESTORE BC POP H ;RESTORE HL RET ;-------------------------------------------------------------------- ;GET A NEW TEST PATTERN NEWPAT: PUSH H ;SAVE HL LXI H,PATBLE ;SET M TO TEST PATTERNS LDA PASS ;LOAD PASS COUNTER ADD L ;ADJUST LOW BYTE OF ADDRESS JNC NOCARY ;COVER OVERFLOW POSSIBILITY INR H NOCARY: MOV L,A ;BRINGS M TO CURRENT PATTERN LDA TRACK ;GET CURRENT TRACK NUMBER RAR ;CHECK FOR EVEN OR ODD MOV A,M ;LOAD TEST PATTERN JNC EVEN ;SKIP ON ALTERNATE TRACKS CMA ;COMPLEMENT TEST PATTERN EVEN: POP H ;RESTORE HL MOV B,A ;SAVE IN B RET ;-------------------------------------------------------------------- ;WAIT FOR CONTROLLER TO FINISH ITS OPERATION WAIT1: PUSH D ;SAVE DE LXI D,0A000H ;LOAD AS TIMER-COUNTER WTLOOP: DCX D ;START COUNTDOWN MOV A,D ORA E ;CHECK IT FOR 0 JZ RESTRT ;REPORT TO TERMINAL & WBOOT SKIP: PUSH D CALL CKABRT ;CHECK FOR KEYBOARD INTERRUPT POP D ;RECOVER LOCAL COUNTERS LDA HLTED ;UNIVERSAL HALT RESULT CPI 0 ;DONE YET? JZ WTLOOP ;WAIT FOR IT ANI GOOD ;NORMAL COMPLETION? JZ RESTRT ;ABORT IF NOT SUB A ;ZERO A STA HLTED ;CLEAR RESULT BYTE POP D ;RECOVER DE RET RESTRT: LXI D,EIGHTN ;NO RESPONSE MESSAGE GRAB4: DB TRAP ;CONDITIONAL RST 7 MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS JMP START ;RE-START TEST ;-------------------------------------------------------------------- ;ABORT OPERATION IF ESCAPE ENTERED AT CONSOLE ; 1) THIS ROUTINE IS ONLY USED BY THE WAIT FOR CONTROLLER TO ; FINISH ROUTINE (WAIT1). CKABRT: PUSH B ;SAVE BC PUSH H ;SAVE HL PUSH D ;SAVE DE MVI C,CONSTA ;ASKS FOR CONSOLE STATUS CALL BDOS DCR A ;0FFH MEANS DATA READY POP D ;RECOVER DE POP H ;RECOVER HL POP B ;RECOVER BC RNZ ;NO ABORT MVI C,CONIN ;GET THE CHARACTER CALL BDOS CPI ESC ;ESCAPE CHARACTER RNZ ;IGNORE ANYTHING ELSE RST 7 ;RETURN TO DDT RET ;-------------------------------------------------------------------- ;CLEAR SECTOR TABLE CLRTBL: MVI C,TBLSZ ;SIZE OF TABLE LXI H,TRKTBL ;COMMAND RESULT TABLE TBLP: MOV M,A ;FILL IT WITH A INX H ;INCREMENT MEMORY POINTER DCR C JNZ TBLP RET ;-------------------------------------------------------------------- ;REPORT AN ERROR TO THE CONSOLE ERROR: PUSH D PUSH H PUSH B ;SAVE REGISTER PAIRS CALL ERRFND ;LOADS DE WITH ERROR MSG MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LXI D,TKMSG ;TRACK MESSAGE MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA TRACK ;GET CURRENT TRACK CALL BCDOUT ;AND SEND IT LXI D,SDMS ;SIDE MSG MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS POP B MOV A,B ;GET SIDES RLC ;MOVE SIDE BIT TO DATA 0 CALL BCDOUT ;SEND IT RESUME: POP H ;RECOVER REGISTER PAIRS POP D RET ;-------------------------------------------------------------------- ;GET THE BASE ADDRESS OF AN ERROR STRING ERRFND: ANI 1FH ;MASK OFF ERROR VALUE LXI H,ERRTBL ;PICKUP ADDRESS OF MSG TABLE CALL ADJUST ;ADJUST M BY TWICE A MOV E,M ;LOAD LOW ADDRESS INX H ;INCREMENT POINTER MOV D,M ;LOAD HIGH ADDRESS RET ;-------------------------------------------------------------------- ;DOUBLE THE ACCM. AND THEN ADD IT TO THE HL PAIR. ADJUST: MOV B,A ;SAVE A IN B MOV A,L ;PICKUP POINTER LOW BYTE ADD B ;ADJUST TO B JNC SKPNC ;IF NO OVERFLOW INR H ;ADJUST H SKPNC: ADD B ;FOR HIGH BYTE JNC SKPNC2 ;IF NO OVERFLOW INR H ;ADJUST H SKPNC2: MOV L,A ;PUT IN L RET ;POINTER IS ADJUSTED BY A ;-------------------------------------------------------------------- ;PRINT THE DRIVE TYPE AND NUMBER ; 1) THIS ROUTINE IS USED BY BOTH SEEKS AND RDWRTS IN THEIR ; OPENING MESSAGES. DRTYPE: LHLD LOGPNT ;PICK UP LOG POINTER MOV A,M ;GET NUMBER OF TRACKS CPI 77 ;SEE IF EIGHT INCH LXI D,EIGHMS ;EIGHT INCH DRIVE MESSAGE JZ EIGHTR ;FOR EIGHT INCH MESSAGE LXI D,FIVEMS ;FIVE INCH DRIVE MESSAGE EIGHTR: MVI C,WRSTRN ;CPM_FUNCTION:=WRITE_STRING CALL BDOS LDA RDTKDR ;GET NUMBER OF DRIVE CALL BCDOUT ;SEND TO TERMINAL RET ;-------------------------------------------------------------------- ;PUTDC PRINTS THE ASCII DECIMAL EQUIVALENT OF THE NUMBER IN HL * ; 1) PRINT THE ACCM. AS ONE BCD DIGIT. BCDOUT: MOV L,A MVI H,0 PUTDC: LXI B,-10 PHL: PUSH D MOV D,B MOV E,B PHLLP: DAD B INX D JC PHLLP XTHL XCHG MOV A,H ORA L CNZ PHL POP H MVI A,'0' ADD L SUB C PCHAR: PUSH H PUSH B PUSH D PUSH PSW MOV E,A MVI C,2 CALL BDOS POP PSW POP D POP B POP H RET ;-------------------------------------------------------------------- ;REPORT TRACK ERROR ; 1) THIS ROUTINE IS CURRENTLY UNUSED BADTRK: PUSH PSW ;SAVE ERROR CODE CALL ERROR ;REPORT FAULT LHLD MAPPNT ;PICKUP BADMAP POINTER POP PSW ;RECOVER ERROR CODE MOV M,A ;STORE IT IN MAP INX H ;ADVANCE POINTER SHLD MAPPNT ;STORE IT RET ;-------------------------------------------------------------------- ;BEGIN CHANNEL COMMANDS SNSTAT: DB SNSTA ;SENSE STATUS COMMAND SNSDRV: DB 0 ;PHYSICAL DRIVE NUMBER DSTAT1: DB 0 ;DSTAT 1 DSTAT2: DB 0 ;DSTAT 2 DSTAT3: DB 0 ;DSTAT 3 SNSRLT: DB 0 ;COMMAND RESULT BRANCH: DB BRNCH ;BRANCH COMMAND DW COMHLT DB 0 ;EXTENDED ADDRESS SETDMA: DB SETMA ;SET DMA FOR SEEKS DW DSKBUF ;ALL PURPOSE BUFFER (EIGHTK-8192 BYTES) DB 0 ;EXTENDED ADDRESS BYTE DB BRNCH ;BRANCH COMMAND DW COMHLT DB 0 ;EXTENDED ADDRESS WRTRAK: DB WRTRK ;WRITE TRACK COMMAND WRTKTK: DB 0 ; WRTKSD: DB 0 ; WRTKDR: DB 0 ; WRTABL: DW TRKTBL ; DB 0 WTRSLT: DB 0 DB BRNCH ;BRANCH COMMAND DW COMHLT DB 0 ;EXTENDED ADDRESS RDTRAK: DB RDTRK ;READ TRACK COMMAND RDTKTK: DB 0 ; RDTKSD: DB 0 ; RDTKDR: DB 0 ; RDSCTB: DW TRKTBL ; DB 0 RTRSLT: DB 0 DB BRNCH ;BRANCH COMMAND DW COMHLT DB 0 ;EXTENDED ADDRESS RETRYS: DB STRTRY ;COMMAND TO SET # OF RETRIES DB RETRIES ;NUMBER OF RETRIES DB BRNCH ;BRANCH COMMAND DW COMHLT ;STANDARD HALT DB 0 COMHLT: DB CONHLT ;UNIVERSAL HALT COMMAND HLTED: DB 0 ;RESULT BYTE ;-------------------------------------------------------------------- ;VARIABLE STORAGE TRKTBL: DS TBLSZ ;TABLE USED BY WRITE TRACK COMMAND PATBLE: DB 0 ;TEST PATTERNS DB 0FFH DB 0AAH DB 55H TKSIZ5: DW 0 ;NO EQUIVALENT ON 5 IN DW 2560 ;5 INCH SINGLE DENSITY DW 5120 ;5 INCH DOUBLE DENSITY TKSIZ8: DW 3328 ;8 INCH SINGLE DENSITY DW 6656 ;8 INCH 256 BYTE SECTORS DW 7680 ;DITTO 512 DW 8192 ;DITTO 1024 SCTRS: DB 26 ;SINGLE DENSITY 8 INCH DB 26 ;DOUBLE DENSITY 256 BYTE SECTORS DB 15 ;512 BYTE SECTORS DB 8 ;1024 BYTE SECTORS TBYTES: DW 0 ;CURRENT TRACK SIZE TRACK: DB 0 ;CURRENT TRACK SIDE: DB 0 ;CURRENT SIDE PASS: DB 0 ;CURRENT PASS LOGPNT: DW DRVLOG ;POINTER TO DRVLOG DRVLOG: DS 16 ;DRIVE LOG (TRKS, SIDES & SECTOR SIZES) ;-------------------------------------------------------------------- ;MESSAGE STRINGS SEEKNG: DB LF,LF,CR,CR DB 'TESTING SEEKS ON$' READNG: DB LF,CR,CR DB 'TESTING READ/WRITES ON$' TRKMSG: DB ' TRACK $' SIDEMS: DB ' SIDE $' SECMSG: DB ' SECTOR $' CRLF: DB LF,CR,CR DB '$' CMPERR: DB ' COMPARE ERROR(S) ON TRACK $' DRVMSG: DB LF,CR,CR DB 'PHYSICAL $' FIVEMS: DB ' 5 INCH PHYSICAL $' EIGHMS: DB ' 8 INCH PHYSICAL $' WRPRMS: DB ' WRITE PROTECTED$' DBLMSG: DB ' DOUBLE-SIDED DRIVE$' NODRVS: DB LF,CR,CR DB 'NO DRIVES ARE READY$' SIDESQ: DB ': HOW MANY SIDES ON THIS DRIVE? $' ZERO: DB LF,CR,CR DB ' IMPROPER COMMAND CODE$' ONE: DB LF,CR,CR DB ' IMPROPER DISK DRIVE VALUE$' TWO: DB LF,CR,CR DB ' DISK DRIVE NOT READY$' THREE: DB LF,CR,CR DB ' IMPROPER TRACK VALUE$' FOUR: DB LF,CR,CR DB ' UNREADABLE MEDIA$' FIVE: DB LF,CR,CR DB ' IMPROPER SECTOR HEADER - NO SYNC BYTE(S)$' SIX: DB LF,CR,CR DB ' CRC ERROR IN SECTOR HEADER SCAN$' SEVEN: DB LF,CR,CR DB ' SEEK ERROR$' EIGHT: DB LF,CR,CR DB ' COMPARE ERROR IN SECTOR HEADER SCAN$' FOURTN: DB LF,CR,CR DB ' CRC ERROR IN DATA FIELD$' FIFTN: DB LF,CR,CR DB ' IMPROPER SECTOR VALUE$' SIXTN: DB LF,CR,CR DB ' MEDIA WRITE PROTECTED$' SEVNTN: DB LF,CR,CR DB ' LOST DATA - DMA CHANNEL DID NOT RESPOND$' EIGHTN: DB LF,CR,CR DB ' LOST COMMAND - CHANNEL DID NOT RESPOND$' TKMSG: DB ' TRACK $' SDMS: DB ' SIDE $' SD1MS: DB ' SIDE ONE$' SD2MS: DB ' SIDE TWO$' WRTMSG: DB LF,CR,CR DB 'WRITING ALL TRACKS PASS $' RDNMSG: DB LF,CR,CR DB 'VERIFYING ALL TRACKS WRITTEN ON PASS $' ONMS: DB LF,LF,CR,CR DB 'TO ABORT TEST HIT "ESC". TYPE G100 FOR RE-RUN.' DB LF,LF,CR,CR,'$' ;-------------------------------------------------------------------- ;MISC RESERVES ERRTBL: DW ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT DW EIGHT,EIGHT,EIGHT,EIGHT,EIGHT,FOURTN DW FIFTN,SIXTN,SEVNTN,EIGHTN DS 50 STACK EQU $ MAPPNT: DW 0 ;POINTER TO BADMAP BADMAP: DS 152 ;76 TRKS TIMES 2 SIDES DSKBUF: DS 8192 ;8K DISK BUFFER END