;---------------------------------------------------- ; ; MICRO/SYS DISK READ TEST ; 11/28/79 ; 4/15/81 - SPECIFY COMMAND ADDED ; ;---------------------------------------------------- BDOS: EQU 5 ORG 100H DTEST: LXI SP,STACK ;SET SP LXI D,DRIVEM ;POINT TO SIGN ON MVI C,9 CALL BDOS ;PRINT IT DTESTR: XRA A STA NUMER ;CLEAR ERROR COUNTER MVI C,1 CALL BDOS ;GET DRIVE NAME CPI 3 JZ 0 ;CONTROL-C, REBOOT CPI 'E' JNC EXIT2 ;ILLEGAL DRIVE CPI 'A' JC EXIT2 ;ILLEGAL DRIVE ANI 7 ;STRIP JUNK DCR A ;MAKE 0-3 STA DRIVE ;PUT IN FDCB LXI H,FDCBS ;POINT TO SPECIFY MVI B,3 ;3 BYTE FDCB CALL FCMDX ;SEND TO FDC CALL HOME ;HOME DRIVE XRA A STA TRACK ;START WITH TRACK 0 MVI A,1 ;START WITH SECTOR 1 STA SECTOR ;STORE NEW SECTOR DTLOOP: CALL READ ;TRY TO READ IT JZ OK1 ;NO ERRORS IF ZERO FLAG LXI D,ERRM ;POINT TO ERROR MESSAGE MVI C,9 CALL BDOS ;PRINT IT LDA TRACK CALL OUTA ;PRINT TRACK NUMBER LXI D,SECTM MVI C,9 CALL BDOS LDA SECTOR CALL OUTA ;PRINT SECTOR NUMBER CALL CRLF ;CLEAN UP LDA NUMER INR A STA NUMER ;COUNT ERROR OK1: LDA SECTOR INR A STA SECTOR ;BUMP SECTOR CPI 27 ;TOO FAR? JC DTLOOP ;NO, GO READ IT MVI A,1 STA SECTOR ;RESET SECTOR TO 1 LDA TRACK INR A STA TRACK ;GO TO NEXT TRACK CPI 77 ;TOO FAR? JZ EXIT ;YES, EXIT MOV C,A CALL SETTRK ;SEEK TO NEW TRACK JMP DTLOOP ;AND CONTINUE TEST EXIT: CALL CRLF ;NEW LINE LXI D,ENDMSG;POINT TO END MESSAGE MVI C,9 CALL BDOS ;PRINT IT LDA NUMER ;GET ERRORS CALL OUTA ;PRINT THEM LXI D,ERRS MVI C,9 CALL BDOS ;PRINT 'ERRORS' EXIT2: LXI D,DRIVM2;POINT TO DRIVE REQUEST MVI C,9 CALL BDOS ;PRINT IT JMP DTESTR ;RESTART TEST OUTA: MVI E,0 ;CLEAR SECOND DIGIT OUTA1: SUI 10 JC OUTA2 INR E ;COUNT TENS JMP OUTA1 OUTA2: ADI 10+'0' ;REPLACE LAST 10, MAKE ASCII PUSH PSW ;SAVE SECOND DIGIT MVI C,2 MVI A,'0' ADD E ;MAKE FIRST DIGIT ASCII MOV E,A CALL BDOS ;PRINT IT POP PSW MOV E,A MVI C,2 CALL BDOS ;PRINT SECOND DIGIT RET CRLF: MVI E,13 MVI C,2 CALL BDOS ;CAR RET MVI E,10 MVI C,2 CALL BDOS ;LINE FEED RET ERRM: DB 13,10,'ERROR TRACK $' SECTM: DB ' SECTOR $' DRIVEM: DB 13,10,'MICRO/SYS DISK READ TEST' DRIVM2: DB 13,10,13,10,'WHICH DRIVE?$' FDBASE: EQU 0C0H ;SB8500 BASE ADDRESS FDSTAT: EQU FDBASE ;FDC STATUS PORT FDDATA: EQU FDBASE+1;FDC DATA PORT FDTC: EQU FDBASE+2;FDC TERMINAL COUNT PORT FDCREQ: EQU FDBASE+2;FDC INT, DRQ REQUEST PORT FDCBSY: EQU 10H ;FDC BUSY BIT FDCNDM: EQU 20H ;FDC NON-DMA EXECUTION BIT XN: EQU 0 ;BYTES/SECTOR CODE XEOT: EQU 26 ;SECTORS/TRACK XGPL: EQU 7 ;GAP LENGTH XDTL: EQU 128 ;DATA LENGTH XBSIZE: EQU 128 ;BUFFER SIZE XREAD: EQU 26H ;READ COMMAND XWRITE: EQU 25H ;WRITE COMMAND XSEEK: EQU 0FH ;SEEK COMMAND XRECAL: EQU 7 ;HOME COMMAND XSNSIS: EQU 8 ;SENSE INTERRUPT COMMAND XSPCFY: EQU 3 ;SPECIFY COMMAND ; ; RTCNT: EQU 10 ;RETRIES ON FDC ERROR ;---------------------------------------------------- ; ; SEND DRIVE TO TRACK 0 ; ;---------------------------------------------------- HOME: XRA A ;MAKE A 0 STA TRACK ;SET TRACK TO 0 MVI A,RTCNT ;RETRY COUNT FOR ERRORS HRETRY: STA SERCNT ;SET SEEK ERROR CNTR LXI H,FDCB ;POINT TO FDCB MVI M,XRECAL;PUT A HOME COMMAND MVI B,2 ;2 BYTE FDCB CALL FCMDX ;SEND TO FDC CALL INTWAIT ;WAIT FOR DONE INTERRUPT LDA STAT0 ;GET STATUS BYTE ANI 0C0H ;TOP 2 BITS RZ ;SUCCESSFUL COMPLETION LDA SERCNT ;GET ERROR COUNT DCR A ;COUNT ANOTHER JNZ HRETRY ;TRY AGAIN LXI H,HERMSG;POINT TO MESSAGE JMP ERROR ;------------------------------------------------------ ; ; SET TRACK NUMBER ACCORDING TO C AND SEEK ; ;------------------------------------------------------ SETTRK: MOV A,C ;GET DESIRED TRACK STA TRACK ;SELECT IT RSETRK: MVI A,RTCNT ;GET RETRY COUNT SRETRY: STA SERCNT ;SET ERROR COUNTER LXI H,FDCB ;POINT TO FDCB MVI M,XSEEK ;PUT SEEK COMMAND MVI B,3 ;3 BYTE FDCB CALL FCMDX ;SEND TO FDC CALL INTWAIT ;WAIT FOR DONE INTERRUPT LDA STAT0 ;GET STATUS BYTE ANI 0F8H ;CHECK TOP 5 BITS CPI 20H ;ERRORS? JNZ SKERR ;YES, GO HANDLE XRA A RET ;SUCCESSFUL COMPLETION SKERR: LDA SERCNT ;GET ERROR COUNTER DCR A ;COUNT ANOTHER JNZ SRETRY ;TRY AGAIN IF NOT OUT OF TRIES LXI H,SERMSG;POINT TO MESSAGE JMP ERROR ;---------------------------------------------------- ; ; READ SECTOR ESTABLISHED IN FDCB ; ;---------------------------------------------------- READ: LHLD DMAADD ;GET BUFFER ADDRESS PUSH H ;SAVE IT LXI H,FDCB ;POINT TO FDCB MVI M,XREAD ;PUT READ COMMAND CALL FCMD9 ;SEND TO FDC DI ;NO TIME FOR THEM NOW MVI B,XBSIZE;GET BUFFER SIZE POP H ;GET BUFFER ADDRESS RDRQM: IN FDSTAT ;GET FDC STATUS ORA A ;TEST RQM JP RDRQM ;NOT YET IN FDDATA ;GET BYTE MOV M,A ;PUT IN BUFFER INX H ;BUMP POINTER DCR B ;COUNT BYTES JNZ RDRQM ;MORE TO DO IN FDSTAT ;GET FDC STATUS OUT FDTC ;STOP FDC ANI FDCNDM ;PREMATURE EXIT? JNZ RDEND ;NO, SKIP NEXT CLRFDC: IN FDSTAT RLC ;RQM? JNC CLRFDC ;NO, WAIT FOR IT RLC ;DIO? JNC CLRFD1 ;NO, SHOULD BE CLEAR IN FDDATA ;GET INPUT DATA JMP CLRFDC CLRFD1: IN FDSTAT IN FDSTAT IN FDSTAT ;DELAY AND GET STATUS ANI 7FH ;MASK BUSY BITS JZ RDERR ;WE'RE CLEAR IF 0 LXI H,BUSYM ;FDC BUSY ERROR JMP ERROR RDEND: CALL INTWAIT ;WAIT FOR INT, GET RESULTS LDA STAT0 ;GET STATUS REGISTER 0 ANI 0C0H ;MASK TERMINATION BITS RZ ;ALL OK RDERR: MVI A,1 ORA A ;SET ERROR FLAG RET ;---------------------------------------------------- ; ; DISK CONTROLLER SUBROUTINES ; ;---------------------------------------------------- FCMD9: MVI B,9 ;FOR 9 BYTE FDCB'S FCMDX: PUSH H ;SAVE FDCB ADDRESS DI ;NOT NOW IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK IF BUSY JZ FDCCM ;NO, CONTINUE OUT FDTC ;STOP FDC EXECUTION CALL RESULT ;GET RESULT BYTES FDCCM: IN FDSTAT ;GET FDC STATUS RLC ;RQM TO CARRY JNC FDCCM ;WAIT FOR RQM RLC ;DIO TO CARRY JNC CMDOUT ;READY FOR COMMAND IN FDDATA ;GET UNKNOWN INPUT BYTE JMP FDCCM ;TRY AGAIN CMDOUT: MOV A,M ;GET FDCB BYTE OUT FDDATA ;SEND TO FDC INX H ;BUMP FDCB POINTER DCR B ;COUNT BYTES JNZ FDCCM ;MORE TO DO POP H ;RESTORE FDCB ADDRESS RET ; ;---------------------------------------------------------- ; INTWAIT:IN FDSTAT ;GET FDC STATUS ANI 1FH ;ANYTHING BUSY? JNZ INTW1 ;YES, WAIT FOR INT JMP RESULT INTW1: IN FDCREQ ;GET FDC REQUESTS ORA A ;TEST FOR INT REQUEST JP INTW1 ;WAIT FOR IT RESULT: IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK FDC BUSY JNZ INTW2 ;MUST BE READ OR WRITE (AUTO RESULT) SENSRDY:IN FDSTAT ;GET FDC STATUS RLC ;RQM TO CARRY JNC SENSRDY ;NOT READY FOR COMMAND MVI A,XSNSIS;SENSE INTERRUPT STATUS OUT FDDATA ;SEND TO FDC INTW2: CALL FSTAT ;GET RESULT BYTES RET ; ;----------------------------------------------------- ; FSTAT: LXI H,STAT0 ;POINT TO STATUS BUFFER FSTAT1: IN FDSTAT ;GET FDC STATUS RLC ;RQM TO CARRY JNC FSTAT1 ;NOT READY YET RLC ;DIO TO CARRY JC FSTAT2 ;READY TO INPUT RET FSTAT2: IN FDDATA ;GET RESULT BYTE MOV M,A ;PUT IN STATUS BUFFER INX H ;BUMP POINTER LDA 0 ;DELAY TO ALLOW FDC TO CLEAR LDA 0 ;BUSY BIT IF FINISHED IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK IF BUSY JNZ FSTAT1 ;YES, INPUT MORE RESULTS RET ; ;--------------------------------------------------- ; ERROR: XCHG ;PUT POINTER IN DE MVI C,9 CALL BDOS ;PRINT ERROR MESSAGE JMP 0 ;REBOOT ENDMSG: DB 13,10,'END OF TEST',13,10,'$' ERRS: DB ' ERRORS DETECTED',13,10,'$' HERMSG: DB 13,10,'HOME ERROR$' SERMSG: DB 13,10,'SEEK ERROR$' BUSYM: DB 13,10,'FDC BUSY ERROR$' NUMER: DS 1 ;READ ERROR COUNTER ERCNT: DS 1 ;ERROR COUNT FOR RETRIES SERCNT: DS 1 ;SEEK, HOME ERROR COUNT ; ;------------------------------------------------------ ; ; FLOPPY DISK CONTROL BLOCK (FDCB) ; ;------------------------------------------------------ FDCB: EQU $ COMND: DB 0 ;COMMAND DRIVE: DB 0 ;DRIVE SELECT TRACK: DB 0 ;TRACK SELECT HEAD: DB 0 ;HEAD SELECT SECTOR: DB 1 ;SECTOR SELECT N: DB XN ;BYTES/SECTOR CODE EOT: DB XEOT ;LAST SECTOR NUMBER GPL: DB XGPL ;GAP LENGTH DTL: DB XDTL ;DATA LENGTH DMAADD: DW 80H ;MEMORY ADDRESS OF DATA ; ; FDCBS: DB XSPCFY ;SPECIFY COMMAND DB 7FH ;9MS STEP, 240MS HD UNLOAD DB 25H ;36MS HD LOAD, NON-DMA ; ; STAT0: DS 1 ;STATUS REGISTER 0 STAT1: DS 1 ;STATUS REGISTER 1 STAT2: DS 1 ;STATUS REGISTER 2 STRK: DS 1 ;STATUS TRACK SHEAD: DS 1 ;STATUS HEAD SSECT: DS 1 ;STATUS SECTOR SN: DS 1 ;STATUS BYTE/SECTOR CODE ; ; STACK: EQU $+100H END DTEST