;----------------------------------------------------- ; ; MICRO/SYS, INC. ; ; NULL PROGRAM TO REFORMAT CRASHED DISKS ; ; 10/2/79 ; 4/15/81 - SPECIFY COMMAND ADDED ; ;----------------------------------------------------- FBASE: EQU 0C0H ;SB8500 BASE ADDRESS FDSTAT: EQU FBASE ;SB8500 STATUS REGISTER FDDATA: EQU FBASE+1 ;SB8500 DATA REGISTER FDTC: EQU FBASE+2 ;SB8500 TERM COUNT PORT FDREQ: EQU FDTC ;SB8500 INT, DRQ PORT FDCBSY: EQU 10H ;SB8500 BUSY BIT ; BDOS: EQU 5 ;CP/M ENTRY ; NOTRKS: EQU 77 ;NUMBER OF TRACKS TO FORMAT ; XN: EQU 0 ;BYTES/SECTOR CODE XEOT: EQU 26 ;SECTORS/TRACK XGPL: EQU 7 ;GAP LENGTH XDTL: EQU 128 ;128 BYTES/SECTOR XGPL3: EQU 27 ;FORMAT GAP LENGTH XBSIZE: EQU XDTL ;BUFFER SIZE ; XRECAL: EQU 7 ;HOME COMMAND XSEEK: EQU 15 ;SEEK COMMAND XFRMTK: EQU 13 ;FORMAT TRACK COMMAND XSNSIS: EQU 8 ;SENSE INTR COMMAND XSPCFY: EQU 3 ;SPECIFY COMMAND ; ; ORG 100H NULL: LXI SP,STACK;USE OURS LXI H,MSG ;POINT TO MESSAGE CALL MESSG ;PRINT IT START: LXI H,READY ;NEXT MESSAGE CALL MESSG ;PRINT IT MVI C,1 ;BDOS INPUT CHAR CALL BDOS ;GET ONE CPI 'Y' ;Y? JNZ EXIT ;NO, EXIT LXI H,FDCBS ;POINT TO SPECIFY MVI B,3 ;3 BYTE FDCB CALL FCMDX ;SEND TO FDCB CALL HOME ;HOME DRIVE XRA A ;MAKE A 0 STA TRACK ;MAKE TRACK 0 NEXTRK: CALL SEEK ;GO TO TRACK CALL FORMAT ;FORMAT IT LDA TRACK ;GET TRACK INR A ;ADD 1 CPI NOTRKS ;CHECK FOR LAST TRACK STA TRACK ;PUT IT BACK JC NEXTRK ;DO NEXT TRACK JMP START ;DONE WITH THIS DISK ; ; EXIT: LXI H,EXITM ;POINT TO MESSAGE CALL MESSG ;PRINT IT MVI C,1 CALL BDOS ;GET INPUT FROM CONSOLE JMP 0 ;REBOOT SYSTEM ; ; HOME: LXI H,FDCB ;POINT TO FDCB MVI M,XRECAL;PUT HOME COMMAND MVI B,2 ;2 BYTE FDCB CALL FCMDX ;SEND TO FDC CALL INTWAIT ;WAIT FOR INTERRUPT RET ; ; SEEK: LXI H,FDCB ;POINT TO FDCB MVI M,XSEEK ;PUT SEEK COMMAND MVI B,3 CALL FCMDX ;SEND TO FDC CALL INTWAIT ;WAIT FOR INTERRUPT RET ; ; FORMAT: LDA TRACK ;GET TRACK MOV B,A ;TRACK IN B MVI C,0 ;HEAD IN C MVI D,1 ;RECORD IN D MVI E,XN ;BYTES/SECTOR CODE IN E MVI A,XEOT ;NUMBER OF SECTORS IN A LXI H,DBUFR ;POINT TO DATA BUFFER FORML: MOV M,B ;SET TRACK INX H MOV M,C ;SET HEAD INX H MOV M,D ;SET SECTOR INR D ;NEXT SECTOR INX H MOV M,E ;SET BYTES/SECTOR INX H DCR A ;DONE? JNZ FORML ;NO LXI H,DBUFR ;GET DATA ADDRESS PUSH H ;SAVE IT LXI H,FDCBF ;POINT TO FORMAT FDCB MVI B,6 ;6 BYTE FDCB CALL FCMDX ;SEND TO FDC POP H ;GET DBUFR BACK MVI B,XEOT*4;4 BYTES/SECTOR IN BUFFER FRQM: IN FDSTAT ;GET FDC STATUS ORA A ;CHECK FOR RQM JP FRQM ;NOT YET MOV A,M ;GET BYTE OUT FDDATA ;SEND TO FDC INX H ;NEXT BYTE DCR B ;COUNT BYTES JNZ FRQM ;MORE TO DO OUT FDTC ;END OF DATA CALL INTWAIT ;WAIT FOR INTERRUPT RET ; ; FCMDX: PUSH H ;SAVE FDCB ADDRESS DI ;NOT ALLOWED IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK BUSY JNZ ERROR ;YES. WHY? FDCCM: IN FDSTAT ;GET STATUS RLC ;RQM TO CARRY JNC FDCCM ;WAIT FOR RQM RLC ;DIO TO CARRY JC ERROR ;SHOULD BE 0 MOV A,M ;GET BYTE OUT FDDATA ;SEND TO FDC INX H ;NEXT BYTE DCR B ;COUNT BYTES JNZ FDCCM ;MORE TO DO POP H ;GET FDCB ADDRESS BACK RET ; ; INTWAIT:IN FDREQ ;GET FDC REQUESTS ORA A ;TEST INT REQ JP INTWAIT ;WAIT FOR IT IN FDSTAT ;GET STATUS ANI FDCBSY ;CHECK BUSY JNZ INTW1 ;HAS AUTOMATIC RESULT SENSRDY:IN FDSTAT ;GET STATUS RLC ;RQM TO CARRY JNC SENSRDY ;WAIT FOR IT MVI A,XSNSIS;SENSE INTERRUPT STATUS OUT FDDATA ;SEND COMMAND INTW1: CALL FSTAT ;GET RESULT BYTES RET ; ; FSTAT: LXI H,STAT0 ;POINT TO STATUS AREA FSTAT1: IN FDSTAT ;GET STATUS RLC ;RQM TO CARRY JNC FSTAT1 ;WAIT FOR IT RLC ;DIO TO CARRY JNC ERROR ;SHOULD BE HIGH IN FDDATA ;GET BYTE MOV M,A ;PUT IN BUFFER INX H ;NEXT LOCATION LDA 0 LDA 0 ;DELAY IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK STILL BUSY JNZ FSTAT1 ;YES, GET MORE LDA STAT0 ;GET STATUS REG 0 ANI 0C0H ;NORMAL TERMINATION? JNZ ERROR ;NO RET ;YES ; ; ERROR: LXI H,ERR ;POINT TO ERROR MESSAGE CALL MESSG ;PRINT IT MVI C,1 ;BDOS INPUT CHARACTER CALL BDOS ;WAIT FOR ONE JMP 0 ;REBOOT CP/M ; ; MESSG: MOV A,M ;GET CHAR ORA A ;CHECK FOR END RZ ;DONE CALL CONOUT ;PRINT CHAR INX H ;NEXT CHAR JMP MESSG ; ; CONOUT: PUSH H PUSH D PUSH B MOV E,A ;CHAR TO E MVI C,2 ;PRINT CHAR CALL CALL BDOS ;PRINT IT POP B POP D POP H RET ; ; MSG: DB 13,10,13,10,'MICRO/SYS DISK NULL PROGRAM' DB 13,10,13,10,'THIS WILL DESTROY ALL DATA' DB ' IN DRIVE A',13,10,0 READY: DB 13,10,'READY TO NULL DISK IN A (Y/N) ?',0 ERR: DB 13,10,'ERROR -' EXITM: DB 13,10,'PLACE SYSTEM DISK IN' DB ' A FOR REBOOT',0 ; ; FDCBF: DB XFRMTK ;FORMAT TRACK COMMAND DB 0 ;DRIVE 0 DB XN DB XEOT DB XGPL3 DB 0E5H ;DATA BYTE FOR FILL ; ; FDCBS: DB XSPCFY ;SPECIFY COMMAND DB 7FH ;9MS STEP, 240MS HD UNLOAD DB 25H ;36 MS HD LOAD, NON-DMA ; ; FDCB: EQU $ COMND: DB 0 ;COMMAND DRIVE: DB 0 ;DRIVE TRACK: DB 0 ;TRACK HEAD: DB 0 ;HEAD SECTOR: DB 1 ;SECTOR N: DB XN EOT: DB XEOT GPL: DB XGPL DTL: DB XDTL ; ; STAT0: DS 10 ;RESULT BYTES ; ; DBUFR: DS XBSIZE ;DATA BUFFER ; ; AREA: DS 50 ;STACK AREA STACK: EQU $ ; ; END NULL