BDOS: EQU 0005 ;BDOS ENTRY POINT DCOM EQU 010H ;DISK COMMAND PORT DSTAT EQU 010H ;DISK STATUS PORT TRACK EQU 011H ;DISK TRACK COMMAND SECTP EQU 012H ;DISK SECTOR PORT DDATA EQU 013H ;DISK DATA PORT SELECT EQU 0F6B1H ;MONITOR ENTRY TO SELECT DRIVE RESTOR EQU 0F6F1H ;MONITOR ENTRY TO GO TO TRK 00 ORG 0100H ;LOAD & EX HERE ; JMP START ;JUMP AROUND MESSAGES MSG1: DB 'BIG-BOARD DISK FORMATTING PROGRAM' DB ' VER. 1.6' DB 0DH,0AH,0DH,0AH DB 'DRIVE TO BE FORMATTED? (A,B,C,D) : $' MSG2: DB 0DH,0AH,'READY TO FORMAT IN DRIVE ' DISKNO: DS 1 DB 0DH,0AH,'IS BLANK DISK READY TO FORMAT (Y-N)? $' SELERR: DB 0DH,0AH,'INVALID DRIVE SELECTION' DB 0DH,0AH,'ENTER A,B,C OR D : $' MSG3: DB 0DH,0AH,'DRIVE ' DISKID: DS 1 DB ' NOT READY.',0DH,0AH,0AH DB 'PROGRAM RESTARTING ..........',0DH,0AH,0AH,'$' DISKTMP DB 0 FMTDSK: DS 1 ;HOLDS DISK # TO BE USED TEMP DS 1 SPSAV: DS 2 ;SAVE AREA FOR CP/M STACK PTR ; START: LDA 066H ;SET UP NMI VECTOR STA TEMP ;FOR IMMEDIATE RETURN MVI A,0C9H STA 066H LXI H,0 DAD SP SHLD SPSAV ;SAVE CP/M'S STACK PTR MVI C,25 ;INTERROGATE DRIVE NUMBER CALL BDOS STA DISKTMP ;SAVE COPY CURRENT DRIVE REQ: MVI C,9 ;GET CODE FOR PRINT LXI D,MSG1 ;GET ADDR OF MSG CALL BDOS RESP: MVI C,1 ;GET CONSOLE CHAR CALL BDOS ANI 0DFH ;CONVERT TO UPPER CASE STA DISKNO ;PUT IN MSG STA DISKID SBI 65 ;CONVERT TO BINARY STA FMTDSK ;SAVE VALUE FOR SELDSK CPI 4 ;CHECK FOR VALID RESPONSE JC NXTDSK ;JUMP IF VALID DRIVE # ERR: MVI C,9 LXI D,SELERR CALL BDOS JMP RESP ;ASK FOR DRIVE # AGAIN NXTDSK: MVI C,9 ;GET CODE FOR PRINT LXI D,MSG2 ;GET ADDR OF MSG CALL BDOS EI ;ENABLE INTERRUPTS MVI C,1 ;GET CONSOLE CHAR CALL BDOS CPI 'Y' ;WAS IT A YES JZ BEGIN ;START FORMATTING CPI 'Y'+20H ;CHECK FOR LOWER CASE 'Y' JZ BEGIN LDA TEMP STA 066H ;RESTORE NMI VECTOR LHLD SPSAV SPHL ;RESTORE CP/M STACK PTR LDA DISKTMP ;GET COPY OF ORIG LOGGED DISK SELDSK: MOV C,A JMP SELECT ; ; ; RESTORE DRIVE TO TRACK 00 ; BEGIN LDA FMTDSK ;DISK TO BE USED IN ACC CALL SELDSK ;SELECT DRIVE ORA A ;SET FLAGS JZ CONT ;JUMP IF SELECTION OK LXI D,MSG3 MVI C,9 CALL BDOS ;PRINT ERROR MSG JMP REQ ;START AGAIN CONT CALL RESTOR MVI C,0 ;SET TRACK NUMBER TO 0 MVI H,77 ;SET TOTAL TRACKS TO 77 NXTTRK MVI D,1 ;SECTOR NUMBER MVI E,26 ;SET MAX # SECTORS MVI B,40 ;GAP 4 PREINDEX 40 BYTES OF FF DI ;DISABLE INTERRUPTS MVI A,0F4H ;LOAD TRACK WRITE COMMAND OUT DCOM ;ISSUE TRACK WRITE XTHL XTHL ;WASTE SOME TIME ; WRITE PREINDEX FILL MVI A,0FFH PREIND HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK DCR B ;COUNT =COUNT - 1 JNZ PREIND ;GO BACK TILL B =0 MVI B,6 ;WRITE 6 BYTES OF ZEROES XRA A PREIN2 HLT ;WAIT FOR DRQ OUT DDATA DCR B JNZ PREIN2 ; ; WRITE ADDRESS MARK ON TRACK ; MVI A,0FCH ;LOAD ADDRESS MARK HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; POST INDEX GAP ; PID MVI B,26 ;SET # OF BYTES MVI A,0FFH ;LOAD FILL DATA POSTID HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK DCR B ;COUNT = COUNT - 1 JNZ POSTID ;IF NOT 0 GO BACK ; ; PRE ID SECTION ; ASECT MVI B,6 ;GET # OF BYTES XRA A ;LOAD ZEROES SECTOR HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON TRACK DCR B ;COUNT = COUNT=1 JNZ SECTOR ;JMP BACK IF NOT DONE ; ; WRITE ID ADDRESS MARK ; MVI A,0FEH ;LOAD ADDRESS MARK HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; WRITE TRACK NUMBER ON DISK ; MOV A,C ;GET TRACK NUMBER HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; WRITE ONE BYTE OF 00 ; XRA A HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; WRITE SECTOR # ON DISK ; MOV A,D ;GET SECTOR NUMBER HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; ONE MORE BYTE 0 ; XRA A HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK INR D ;BUMP SECT. # ; ; WRITE 2 CRC'S ON THIS SECTOR ; MVI A,0F7H ;GET CRC PATTERN HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; PRE DATA 17 BYTES ; MVI B,11 ;SET COUNT MVI A,0FFH PREDAT HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK DCR B ;REDUCE COUNT BY 1 JNZ PREDAT ;GO BACK IF NOT DONE MVI B,6 ;SET COUNT XRA A ;SET DATA TO ZERO PREDAT2 HLT ;WAIT FOR DRQ OUT DDATA ;DO IT DCR B ;DECREMENT COUNT JNZ PREDAT2 ; ; DATA ADDRESS MARK ; MVI A,0FBH ;GET DATA ADDRESS MARK HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; FILL DATA FIELD WITH E5 ; MVI B,128 ;SET FIELD LENGTH MVI A,0E5H ;GET FILL BYTE DFILL HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK DCR B ;DROP 1 FROM COUNT JNZ DFILL ;DO TILL 00 ; ; WRITE CRC'S ; MVI A,0F7H ;GET CRC BYTE HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK ; ; END OF SECTOR FILL ; DCR E ;REDUCE SECTOR COUNT JZ ENDTRK ;IF 0 DO END OF TRACK RTN MVI A,0FFH ;GET FILL CHAR. DATGAP HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK JMP PID ;GO BACK FOR MORE ; ; DO TRACK & SECTOR HOUSE KEEPING ; ENDTRK IN DSTAT ;LOOK AT STATUS ANI 3 ;CHECK FOR DRQ, BUSY JZ DONE MVI A,0FFH ;LOAD FILL CHAR. HLT ;WAIT FOR DRQ OUT DDATA ;WRITE IT ON DISK JMP ENDTRK ;DO UNTIL INTRQ ; ; DONE INR C ;BUMP TRACK # DCR H ;TRK COUNT =COUNT -1 JNZ BMPTRK ;IF NOT 0 THEN DO MORE JMP NXTDSK ;GO AGAIN BMPTRK MVI A,43H ;LOAD STEP IN OUT DCOM ;STEP IN XTHL XTHL ;DELAY LOOP IN DSTAT ;CHECK STATUS ANI 01 ;LOOK FOR BUSY JNZ LOOP JMP NXTTRK ; END 0100H