NAM HDFORMAT OPT PAG PAG * HDFORMAT PROGRAM FOR SK*DOS 68K * SUPPORTS THE PERIPHERAL TECH PT-68K-2 COMPUTER WINCHESTER * USING THE WD1002A-WX1 HARD DISK CONTROLLER * COPYRIGHT (C) 1986, 1987 BY PETER A. STARK * FOR STAR-K SOFTWARE SYSTEMS CORP. * MOD 9-27-87 TO DEFAULT TO 34 SEC/TRK AND NOT ASK * AND NEW FOR THIS CONTROLLER VERSION * MOD 12-25-87 TO FIX PROBLEM WITH SLOW DRIVES * AND ALLOW JUST ONE HEAD * MOD 5-17-88 TO FLUSH TYPEAHEAD BUFFER * MOD 11-5-88 TO PERMIT CHOICE OF INTERLEAVE * MOD 2-21-89 TO FIX PROBLEMS WITH DRIVE B * SK*DOS EQUATES LIB SKEQUATE WINTAB EQU $200 OFFSET FOR DOS'S WINTAB HARDWE EQU $FF0C0D HUMBUG HARDWARE BYTE WXDATA EQU $FA0641 DATA REGISTER WXCOMM EQU WXDATA COMMAND REGISTER WXSTAT EQU WXDATA+2 STATUS REGISTER WXRESE EQU WXDATA+2 RESET REGISTER WXSELE EQU WXDATA+4 SELECT REGISTER WDAROM EQU $D90000 CONTROLLER ROM SPACE START BRA.S START1 DC.W $0106 VERSION * FIRST, TEST WHETHER THERE IS A CONTROLLER START1 MOVE.B WDAROM+1,D7 GET FIRST BYTE CMP.B WDAROM+3,D7 COMPARE WITH SECOND BEQ.L NOCONT NO WD1002 THERE * INITIALIZE THE CONTROLLER MOVE.B #0,WXRESE RESET IT BSR.L CHBUSY WAIT FOR WD1002 NOT BUSY LEA WX1TAB(PC),A4 POINT TO WX1 COMMAND TABLE MOVE.W #$0100,0(A4) CLR.L 2(A4) COMMAND TO RESTORE DRIVE BSR.L GIVE6 GIVE TO CONTROLLER BSR.L CFWAIT WAIT FOR COMPLETION CODE BNE.L FERROR ERROR IF TIMEOUT MOVE.B WXDATA,D7 CHECK THE CODE BEQ.L INITAL IF OK FOR DRIVE 1 MOVE.W #$0120,0(A4) IF DRIVE 1 NG, TRY DRV 2 BSR.L GIVE6 GIVE TO CONTROLLER BSR.L CFWAIT WAIT FOR COMPLETION CODE BNE.L FERROR ERROR IF TIMEOUT MOVE.B WXDATA,D7 CHECK THE CODE AND.B #$DF,D7 DELETE DRIVE BIT BNE.L FERROR ERROR IF NOT ZERO * NOW INITIALIZE EVERYTHING INITAL LEA OURWIN(PC),A0 POINT TO OUR WIN TABLE MOVE.W #15,D0 CLRTAB MOVE.L #$FFFFFFFF,(A0)+ CLEAR 4 BYTES DBRA D0,CLRTAB REPEAT UNTIL FULL OF FF'S * FIRST, FIND OUT WHICH DRIVE TO INITIALIZE > PHDRIV (B) GETDRV LEA DRVMSG(PC),A4 DC PSTRNG ASK "WHICH DRIVE- A OR B?" DC GETCH GET ANSWER AND.B #$DF,D5 CMP.B #$41,D5 A? BEQ.S DRVOK CMP.B #$42,D5 B? BNE.S GETDRV WRONG DRVOK SUB.B #$40,D5 A=1, B=2 LEA PHDRIV(PC),A4 MOVE.B D5,(A4) AND STORE PHYSICAL DRIVE NUMB * GET NUMBER OF PHYSICAL CYLINDERS ON THIS DRIVE > PHCYLS (W) GETCYL LEA PHTMSG(PC),A4 "HOW MANY CYLINDERS " MESSAGE DC PSTRNG DC INLINE GO GET INPUT DC DECIN CMP.L #1000,D5 CHECK IT BHI.S GETCYL REPEAT IF >1000 CMP.L #5,D5 BCS.S GETCYL LEA PHCYLS(PC),A0 WHERE TO PUT IT MOVE.W D5,(A0) * GET NUMBER OF CYLINDER TO PARK ON > PARKCY (W) GETPAR LEA PRKMSG(PC),A4 "WHERE TO PARK " MESSAGE DC PSTRNG DC INLINE GO GET INPUT DC DECIN CMP.L #1000,D5 CHECK IT BHI.S GETPAR REPEAT IF >1000 LEA PARKCY(PC),A0 WHERE TO PUT IT MOVE.W D5,(A0) * GET PRECOMPENSATION CYLINDER NUMBER > PRECOM (W) GETPRE LEA PREMSG(PC),A4 "WHERE TO PRECOMP " MESSAGE DC PSTRNG DC INLINE GO GET INPUT DC DECIN CMP.L #1023,D5 CHECK IT BHI.S GETPRE REPEAT IF >1000 CMP.L #5,D5 BCS.S GETPRE LEA PRECOM(PC),A0 WHERE TO PUT IT MOVE.W D5,(A0) * GET NUMBER OF HEADS > HEADS (B) GETHDS LEA HDSMSG(PC),A4 "HOW MANY HEADS " MESSAGE DC PSTRNG DC INLINE GO GET INPUT DC DECIN CMP.L #16,D5 CHECK IT BHI.S GETHDS REPEAT IF >16 CMP.L #1,D5 ALLOW 1 HEAD BCS.S GETHDS LEA HEADS(PC),A0 WHERE TO PUT IT MOVE.B D5,(A0) * DEFAULT NUMBER OF SECTORS PER TRACK > SECPT (B) GETSEC LEA SPTMSG(PC),A4 "HOW MANY SEC/TR" MESSAGE DC PSTRNG LEA SECPT(PC),A0 WHERE TO PUT IT MOVE.B #34,(A0) * GET DRIVE STEP SPEED > STEPRT (B) GETSEK LEA SEKMSG(PC),A4 "SELECT STEP RATE" MESSAGE DC PSTRNG DC INLINE GO GET INPUT DC DECIN CMP.L #7,D5 CHECK IT BHI.S GETSEK REPEAT IF >7 LEA STEPRT(PC),A0 WHERE TO PUT IT MOVE.B D5,(A0) * GET DESIRED INTERLEAVE > INTLVE (B) GETILV LEA ILVMSG(PC),A4 "INTERLEAVE? " MESSAGE DC PSTRNG DC INLINE GO GET INPUT DC DECIN CMP.L #15,D5 CHECK IT BHI.S GETILV REPEAT IF >15 LEA INTLVE(PC),A0 WHERE TO PUT IT MOVE.B D5,(A0) * CALCULATE AND PRINT TOTAL DISK CAPACITY CLR.L D0 CLR.L D7 MOVE.B HEADS(PC),D0 MOVE.B SECPT(PC),D7 MULU D7,D0 SECTORS PER CYLINDER MOVE.W PHCYLS(PC),D7 MULU D7,D0 SECTORS PER DRIVE MOVE.L D0,D4 LSR.L #2,D4 DIVIDE BY 4 LEA CAPMSG(PC),A4 DC PSTRNG PRINT "DISK CAP IS" CLR.L D5 NO SPACES DC OUT5D OUTPUT SIZE IN K LEA CA2MSG(PC),A4 DC PNSTRN PRINT "K" CLR.W D0 WILL BECOME LEFT HALF SWAP D0 MOVE OVERFLOW INTO B CMP.W #3,D0 CHECK IF >3 BLS.S NOTGT3 NO MOVE.B #3,D0 CHANGE >3 TO 3 NOTGT3 TST.B D0 CHECK WHETHER PART'S NEEDED BEQ.S NOPART NO MUSPAR LEA MUSMSG(PC),A4 DC PSTRNG PRINT "YOU MUST HAVE" CLR.L D4 MOVE.B D0,D4 ADD.B #1,D4 REQ'D NUMBER OF CLR.L D5 NO SPACES DC OUT5D PRINT MINIMUM NUMBER LEA PARMSG(PC),A4 DC PNSTRN PRINT "PARTITIONS" NOPART LEA WOUMSG(PC),A4 DC PSTRNG ASK "WANT TO PARTITION?" DC GETCH AND.B #$DF,D5 CMP.B #$59,D5 Y? BEQ.L YESPAR YES, GO PARTITION CMP.B #$4E,D5 N? BNE.S NOPART WRONG, ASK AGAIN TST.B D0 CHECK IF PARTITIONS NEEDED BNE.S NOPART YES, MUST PARTITION * COME HERE IF NO PARTITIONING IS NEEDED, DISK IS ONE BIG PART LEA OURWIN(PC),A0 POINT TO WIN TABLE MOVE.B #0,(A0) 0 INTO OURWIN MOVE.W PHCYLS(PC),6(A0) NUMBER OF CYLINDERS MOVE.W #0,8(A0) FIRST CYLINDER USED BSR.S SETLOG SET LOGICAL TRACK/SECTOR NOS BRA.L CHEKIT GO CHECK IF OK TO PROCEED * CONVERT INTO NUMBER OF TRACKS AND SCTRS ON LOG DRIVE. ENTER * WITH 6(A0) = CYLINDERS ON THIS LOGICAL DRIVE, AND A0 POINTING * TO OURWIN ENTRY TO PUT DATA INTO. ALSO SET 1(A0)-5(A0). SETLOG MOVE.B STEPRT(PC),1(A0) SEEK SPEED CODE CLR.L D6 CLR.L D7 MOVE.B SECPT(PC),D6 MOVE.B D6,2(A0) SECT PER TRACK MOVE.B HEADS(PC),D7 MOVE.B D7,3(A0) NUMB OF HEADS MULU D6,D7 SECTORS PER CYLINDER MOVE.W D7,4(A0) MOVE.W 6(A0),D6 CYLINDERS ON THIS LOG DRIVE MULU D6,D7 TOTAL SECTORS / LOG DRIVE MOVE.L D7,D6 CMP.L #$FFFF,D7 >65535 SECTORS ON DRIVE? BLS.S SETLOW NO; CONTINUE TO CALCULATE MOVE.B #255,D6 YES, USE 256 SECTORS/TRACK MOVE.B #255,D7 AND 256 TRACKS BRA.S SETLO2 SETLOW LSR.W #8,D6 GET LEFT BYTE ADD.W #1,D6 NUMBER OF SECTORS ON LOGICAL SETLOO CMP.W #$1F,D6 32 OR MORE? BHI.S SETLO1 WANT AT LEAST 32 SECTORS LSL.W #1,D6 BRA.S SETLOO REPEAT UNTIL AT LEAST 32 SETLO1 DIVU D6,D7 GIVES NUMBER OF TRACKS SUB.W #1,D6 LAST SECTOR SUB.W #1,D7 LAST TRACK SETLO2 MOVE.B D7,10(A0) LAST TRACK INTO OURWIN MOVE.B D6,11(A0) LAST SECTOR INTO OURWIN MOVE.W PARKCY(PC),12(A0) PARK CYLINDER MOVE.W PRECOM(PC),14(A0) PRECOMP CYLINDER RTS * YESPAR - YES, WE WANT TO (OR HAVE TO) PARTITION. LET'S * GET INFO ON HOW. ENTER WITH D0 = MINIMUM NUMBER - 1 OF PARTS YESPAR ADD.B #1,D0 D0 = MINIMUM OF PARTS NEEDED MOVE.L D0,A3 SAVE IN A3 CMP.B #1,D0 EXCEPT 1 IS NG BNE.S MORET1 ADD.B #1,D0 SO CHANGE 1 TO 2 MOVE.L D0,A3 SAVE IN A3 MORET1 MOVE.L A3,D0 RESTORE MINIMUM NO OF PARTS LEA OURWIN(PC),A0 POINT TO DRIVE TABLE LEA NUMMSG(PC),A4 DC PSTRNG ASK "HOW MANY?" DC INLINE DC DECIN GET ANSWER CMP.L D0,D5 CHECK AGAINST MINIMUM BCS.S MORET1 TOO SMALL CMP.B #4,D5 BHI.S MORET1 TOO BIG MOVE.L D5,D0 SAVE LEA PARTS(PC),A4 MOVE.B D5,(A4) SAVE NUMBER OF PARTITIONS LEA PA1MSG(PC),A4 DC PSTRNG PRINT "YOU WILL PART.." * CALCULATE MAXIMUM NUMBER OF CYLINDERS ALLOWED MOVE.L #65536,D1 MAX NO OF SECTRS / DRIVE CLR.W D2 MOVE.B HEADS(PC),D2 CLR.W D7 MOVE.B SECPT(PC),D7 MULU D7,D2 SECTORS PER CYLINDER DIVU D2,D1 DIV BY SECT/CYLINDER=C/LD MOVE.W D1,D3 MULU D0,D3 X NUMBER OF PARTITIONS CMP.W PHCYLS(PC),D3 COMPARE WITH ACTUAL BLS.S MCOK IF MAX IS LESS THAN ACTUAL MOVE.W PHCYLS(PC),D3 ELSE USE ACTUAL MAXIMUM MCOK CLR.L D4 MOVE.W D3,D4 CLR.L D5 NO SPACES DC OUT5D PRINT MAX CYLINDERS PER PHYS LEA PA2MSG(PC),A4 DC PSTRNG PRINT "MAX CYL PER PART'N" CLR.W D5 MOVE.B PARTS(PC),D5 NUMBER OF PARTITIONS SUB.W #1,D5 LESS ONE MOVE.W #5,D4 EACH ONE MINIMUM 5 CYLINDERS MULU D4,D5 MINIMUM NUMBER NEEDED MOVE.W PHCYLS(PC),D4 ACTUAL NUMBER OF CYLS SUB.W D5,D4 MAX SIZE OF ONE PARTITION IN CYL BMI.S MAXNOG NG IF NUMBER NEGATIVE CMP.W #5,D4 BCC MAXOK OK IF >=5 CYLINDERS MAXNOG LEA P2AMSG(PC),A4 IF NEGATIVE OR <5, DC PSTRNG ..PRINT "NOT ENOUGH CYLS" BRA.L MORET1 TRY IT AGAIN MAXOK CMP.W D1,D4 CHECK AGAINST NUMBER AVAILABLE BCS.S PRTMAX MOVE.W D1,D4 PRTMAX CLR.L D5 NO SPACES DC OUT5D PRINT MAX CYL PER LOGICAL LEA PA3MSG(PC),A4 DC PSTRNG PRINT "DECIDE AND ENTER" * NOW LOOP FOR EACH OF THE PARTITIONS MOVE.L #0,D2 LOOP COUNTER LEA OURWIN(PC),A0 POINT TO TABLE CLR.W D7 MOVE.B PHDRIV(PC),D7 PH DRIVE 1=A, 2=B SUB.B #1,D7 0=A, 1=B LSL.B #2,D7 0=A, 4=B ADD.B #$30,D7 30=A, 34=B MOVE.W D7,A1 SAVE IN A1 MOVE.L #0,A2 TO BE USED FOR TOTAL CYLS PARLOO LEA PA4MSG(PC),A4 DC PSTRNG PRINT "FOR PARTITION H" MOVE.W A1,D4 READY TO PRINT ADD.B D2,D4 DC PUTCH OUTPUT NUMBER LEA PA5MSG(PC),A4 DC PNSTRN PRINT " ? " DC INLINE DC DECIN INPUT NUMBER CMP.L D1,D5 CHECK AGAINST LARGEST PART BLS.S PAROK1 NOT TOO BIG LEA PTBMSG(PC),A4 DC PSTRNG PRINT "TOO BIG" BRA.S PARLOO PAROK1 CMP.L #5,D5 NO SMALLER THAN 5 BCC.S PAROK2 IF OK LEA PTSMSG(PC),A4 DC PSTRNG PRINT "TOO SMALL" BRA.S PARLOO PAROK2 MOVE.W A2,8(A0) PART STARTS AT PREV TOTAL MOVE.W D5,6(A0) AND HAS THIS MANY TRACKS ADD.W A2,D5 ADD CURRENT TO TOTAL MOVE.W D5,A2 AND RESTORE TOTAL ADD.L #16,A0 NEXT ENTRY IN OURWIN ADD.B #1,D2 COUNTER CMP.B D2,D0 CHECK DESIRED PARTITIONS BNE.S PARLOO GET NEXT PARTITION DATA CMP.W D5,D3 CHECK AGAINST MAX TOTAL NUMBER BEQ.S TOTLOK TOTAL IS OK LEA PA6MSG(PC),A4 DC PSTRNG PRINT "TOTAL DOESN'T ADD" BRA.L MORET1 AND REPEAT ALL OVER. * TOTAL IS OK, SO SET PARAMETERS IN OURWIN TOTLOK LEA OURWIN(PC),A0 POINT TO TABLE CLR.L D2 COUNTER TOTLOO MOVE.B D2,(A0) PUT DRIVE NUMB IN OURWIN BSR.L SETLOG SET LOGICAL TRACKS & SECTORS ADD.L #16,A0 NEXT ENTRY IN OURWIN ADD.B #1,D2 COUNTER CMP.B D0,D2 CHECK COUNTER BNE.S TOTLOO REPEAT UNTIL ALL SET * CHEKIT - CHECK THAT USER REALLY WANTS TO FORMAT CHEKIT DC PCRLF LEA CHKMSG(PC),A4 PRINT CHKMSG DC PSTRNG MOVE.B PHDRIV(PC),D4 ADD.B #$40,D4 CVT 1 TO A, 2 TO B DC PUTCH LEA RUSMSG(PC),A4 PRINT "ARE YOU SURE?" DC PSTRNG DC FLUSHT FLUSH TYPEAHEAD DC GETCH GET REPLY AND.B #$DF,D5 CVT TO UPPER CMP.B #$59,D5 BEQ.S WXINIT GO INITIALIZE THE DRIVE LEA NOTMSG(PC),A4 DC PSTRNG PRINT "ABORTING" DC WARMST * INITIALIZE THE DRIVE PARAMS AND GET READY FOR FORMATTING WXINIT LEA WX1TAB(PC),A4 POINT TO COMMAND TABLE CLR.W D7 MOVE.B PHDRIV(PC),D7 DRIVE A=1 SUB.B #1,D7 A=0 LSL.B #5,D7 BIT 5 = DRIVE ADD.W #$0C00,D7 INIT PARAM COMMAND MOVE.W D7,0(A4) CLR.L 2(A4) REST IS ZEROES BSR.L GIVE6 GIVE TO CONTROLLER BSR.L C9WAIT WAIT FOR BUSY AND REQ ONLY BNE.L FERROR ERROR IF TIMEOUT LEA WXDATA,A5 MOVE.B PHCYLS(PC),(A5) BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B PHCYLS+1(PC),(A5) NUMBER OF CYLINDERS BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B HEADS(PC),(A5) NUMBER OF HEADS BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B #0,(A5) BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B #128,(A5) REDUCE WRITE CUR AT 128 BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B PRECOM(PC),(A5) BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B PRECOM+1(PC),(A5) WRITE PRECOMP CYLINDER BSR.L C9WAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B #5,(A5) ECC BURST LENGTH OF 5 BSR.L CFWAIT WAIT FOR COMPLETION CODE BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A5),D7 CHECK THE CODE AND.B #$DF,D7 IGNORE DRIVE BIT BNE.L FERROR ERROR IF NOT ZERO * NEXT DO LOW LEVEL FORMAT DC PCRLF START ON NEW LINE LEA LLFMSG(PC),A4 DC PNSTRN PRINT "HDWE FOR'ING' LEA WX1TAB(PC),A4 POINT TO COMMAND TABLE CLR.W D7 MOVE.B PHDRIV(PC),D7 DRIVE A=1 SUB.B #1,D7 A=0 LSL.B #5,D7 BIT 5 = DRIVE ADD.W #$0400,D7 FORMAT DRIVE COMMAND MOVE.W D7,0(A4) CLR.L D7 MOVE.B INTLVE(PC),D7 ASL.L #8,D7 INTERLEAVE, ALL ELSE 0 ADD.B STEPRT(PC),D7 PUT IN STEP RATE MOVE.L D7,2(A4) PUT IN COMMAND BLOCK BSR.L GIVE6 GIVE TO CONTROLLER SKIPCC MOVE.B WXSTAT,D7 CHECK STATUS AND.B #$0F,D7 CMP.B #$0C,D7 WAITS FOR A CC REPLY BEQ.S SKIPCC WAIT WHILE FORMATTTING BSR.L CFWAIT THEN COMPLETION CODE BNE.L FERROR ERROR IF TIMEOUT MOVE.B WXDATA,D7 CHECK ERROR CODE AND.B #$DF,D7 IGNORE DRIVE BIT BNE.L FERROR * LOW LEVEL FORMAT COMPLETE. NOW CHECK EACH SECTOR, AND * WRITE LINKS IN EACH PARTITION BSR.L CLRBUF CLEAR THE BUFFER LEA OURWIN(PC),A0 POINT TO TABLE LPALOO MOVE.B 0(A0),D4 CHECK PARTITION NUMBER BMI.L DONE NONE LEFT TO DO LEA FLNMSG(PC),A4 DC PSTRNG PRINT "FORMAT PAR'N' ADD.B #$30,D4 DC PUTCH PRINT PARTITION NUMBER DC PCRLF LEA PRTNUM(PC),A6 PREV TRACK NUM FOR PRINTING CLR.B (A6) CLEAR IT CLR.L D0 CLR.L D1 MOVE.B 10(A0),D0 LAST LOG TRACK MOVE.B 11(A0),D1 LAST LOG SECTOR ADD.W #1,D1 NUMBER OF LOGICAL SECTORS MULU D0,D1 NUMBER OF FREE SECTORS LSL.W #8,D0 MOVE.B 11(A0),D0 COMBINE LOG TR & SECT MOVE.L #0,A2 INITIALIZE FIRST FREE PTR MOVE.L A2,A3 INITIALIZE LAST FREE PTR MOVE.L A2,A1 INITIALIZE PREV OK LEA CHFLAG(PC),A4 MOVE.B #1,(A4) LAST PTR WAS OK CHLOOP CLR.L D4 MOVE.W D0,D4 CURRENT LOG TR-SEC LSR.W #8,D4 TRACK INTO BYTE CMP.B PRTNUM(PC),D4 SAME AS PREVIOUS? BEQ.S CHLOO1 YES, JUST GO ON LEA PRTNUM(PC),A4 MOVE.B D4,(A4) NO, STORE THE NEW LEA FLTMSG(PC),A4 DC PNSTRN PRINT 'LOG TRK NUM" CLR.L D5 NO SPACES DC OUT5D PRINT THE NUMBER MOVE.B #$20,D4 DC PUTCH SPACE CHLOO1 BSR.L LPCONV CONV LOG TO PHYSICAL TR/SEC BSR.L CLRBUF CLEAR THE BUFFER LEA BUFFER(PC),A4 POINT TO BUFFER MOVE.W A1,(A4) PUT IN LINK TO PREV OK BSR.L HWRITE WRITE IT TO DISK BNE.S CHWRNG IF ERROR BSR.L HREAD READ CURRENT SECTOR BEQ.S CHROK IF NO ERROR * IF SECTOR COULDN'T BE READ, DELETE IT CHWRNG SUB.L #1,D1 SUBTRACT 1 FROM FREE LEA CHFLAG(PC),A4 CLR.B (A4) AND MARK IT DEFECTIVE LEA BDSMSG(PC),A4 PRINT "DEFECTIVE SECTOR AT" DC PSTRNG MOVE.L D0,D4 LSR.W #8,D4 TRACK NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT TRACK NUMBER MOVE.B #$2D,D4 DC PUTCH OUTPUT DASH MOVE.B D0,D4 SECTOR NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT SECTOR NUMBER DC PCRLF BRA.S CHNEXT AND THEN CONTINUE * SECTOR READ WAS OK CHROK MOVE.W A3,D7 CHECK LAST FREE BNE.S CHROK1 NON-ZERO MEANS THIS IS NOT LAST MOVE.L D0,A3 ELSE CURR TR-SEC IS LAST FREE CHROK1 MOVE.B CHFLAG(PC),D7 WAS PREVIOUS OK TOO? BEQ.S CHPRNG NO, SO UPDATE PTR MOVE.L D0,A1 SAVE CURRENT TRACK-SECTOR BRA.S CHNEXT AND GO TO NEXT SECTOR * THIS SECTOR OK, BUT PREVIOUS ONE OR MORE NG CHPRNG BSR.L CLRBUF CLEAR THE BUFFER MOVE.W A1,(A4) PUT NEW PTR INTO SECTOR BSR.L HWRITE WRITE SECTOR BACK BNE.L CHWRNG WRITE WAS NG, SAME AS A NG READ MOVE.W D0,A1 SAVE CURRENT TRACK-SECTOR LEA CHFLAG(PC),A4 MOVE.B #1,(A4) MARK THIS SECTOR AS OK * THEN STEP TO NEXT PREVIOUS SECTOR CHNEXT SUB.B #01,D0 STEP BACK ONE SECTOR BCC.L CHLOOP OK IF NOT < ZERO MOVE.B 11(A0),D0 LAST SECTOR ON PREVIOUS TRACK MOVE.W D0,D7 CURRENT TR-SEC CLR.B D7 SECTOR = 0 SUB.W #$0100,D7 GO BACK ONE TRACK CMP.W #$FF00,D7 FINISHED TRACK 0? BEQ.S DOSIS YES, FINISHED DISK MOVE.W D7,D6 MOVE.B D0,D6 RECOMBINE TRACK AND SECTOR MOVE.W D6,D0 AND BACK INTO D0 TST.W D7 ENTERING TRACK 0? BNE.L CHLOOP NO, OK TO CONTINUE MOVE.W A1,A2 YES, SAVE PREV TR-SECT AS FIRST FREE MOVE.L D1,D3 SAVE NUMBER OF FREE SECTORS BRA.L CHLOOP AND REPEAT AGAIN MOVE.L D0,A2 THAT IS NOW NEW FIRST FREE * FINISHED WHEN WE FINISH TRACK 0; NEXT DO SIS DOSIS BSR.L CLRBUF CLEAR THE BUFFER DC VPOINT MOVE.W #$0003,D0 TRACK 0 SECTOR 3 BSR.L LPCONV CONV LOG TO PHYSICAL TR/SEC LEA BUFFER+16(PC),A5 POINT TO NAME AREA OF SIS MOVE.B #$48,(A5)+ H MOVE.B #$44,(A5)+ D MOVE.B #$3A,(A5)+ : MOVE.B PHDRIV(PC),D6 ADD.B #$40,D6 CVT TO A OR B MOVE.B D6,(A5)+ LETTER A OR B MOVE.B #$20,(A5)+ SPACE MOVE.B #$50,(A5)+ P MOVE.B #$3A,(A5)+ : MOVE.B 0(A0),D6 PARTITION NUMBER ADD.B #$30,D6 CVT TO ASCII MOVE.B D6,(A5)+ DIGIT 0 THROUGH 3 CLR.B (A5)+ NO EXTENSION CLR.B (A5)+ " CLR.B (A5)+ " CLR.B (A5)+ NO VOLUME NUMBER CLR.B (A5)+ " MOVE.W A2,D6 FIRST FREE MOVE.W D6,D7 LSR.W #8,D7 MOVE.B D7,(A5)+ FIRST FREE TRACK MOVE.B D6,(A5)+ FIRST FREE SECTOR MOVE.W A3,D6 LAST FREE MOVE.W D6,D7 LSR.W #8,D7 MOVE.B D7,(A5)+ LAST FREE TRACK MOVE.B D6,(A5)+ LAST FREE SECTOR MOVE.W D3,D7 LSR.W #8,D7 MOVE.B D7,(A5)+ NUMBER FREE (MSB) MOVE.B D3,(A5)+ NUMBER FREE (LSB) MOVE.B CMONTH(A6),(A5)+ MOVE.B CDAY(A6),(A5)+ TODAY'S DATE MOVE.B CYEAR(A6),(A5)+ MOVE.B 10(A0),(A5)+ LAST TRACK MOVE.B 11(A0),(A5)+ LAST SECTOR BSR.L HWRITE BNE.L FERROR FATAL ERROR * NOW END OF DIRECTORY LEA BUFFER(PC),A4 POINT TO BUFFER MOVE.W #$0005,D0 TRACK 0 SECTOR 5 DODIR1 BSR.L LPCONV CONV LOG TO PHYSICAL TR/SEC BSR.L HREAD READ DIRECTORY SECTOR BNE.L FERROR FATAL ERROR IF UNREADABLE TST.B (A4) TEST TRACK POINTER BNE.S DODIR2 MEANS LAST SECTOR ON THIS TRACK MOVE.W (A4),D0 ELSE SETUP TO READ NEXT BRA.S DODIR1 GO DO IT DODIR2 BSR.L CLRBUF CLEAR THE BUFFER BSR.L HWRITE WRITE EMPTY BUFFER BACK BNE.L FERROR IF FATAL ERROR * STORE NUMBER OF NEXT FREE CYLINDER LEA OURWIN(PC),A1 POINT TO BEG OF TABLE MOVE.L 54(A1),D6 4TH PARTITION DATA MOVE.B 48(A1),D7 IS THERE A 4TH PARTITION? BPL.S ISTHER YES MOVE.L 38(A1),D6 3RD PARTITION DATA MOVE.B 32(A1),D7 IS THERE A 3RD PARTITION? BPL.S ISTHER YES MOVE.L 22(A1),D6 2ND PARTITION DATA MOVE.B 16(A1),D7 IS THERE A 2ND PARTITION? BPL.S ISTHER YES MOVE.L 6(A1),D6 1ST PARTITION DATA ISTHER MOVE.W D6,D7 FIRST CYL NUMBER IN LAST PARTITION SWAP D6 NUM OF CYLS IN LAST PARTITION ADD.W D6,D7 NEXT CYL AFTER LAST PARTITION LEA NEXCYL(PC),A1 WHERE TO PUT IT MOVE.W D7,(A1) STORE NUMBER OF NEXT FREE CYL * WRITE OURWIN TABLE INTO TRACK 0 SECTOR 0 CLR.L D0 TR 0 SEC 0 BSR.L LPCONV CONV LOG TO PHYSICAL TR/SEC BSR.L HREAD READ IT BNE.L FERROR FATAL ERROR IF UNREADABLE BSR.L CLRBUF CLEAR THE BUFFER LEA OURWIN(PC),A1 POINT TO BEG OF TABLE LEA BUFFER(PC),A2 AND SECTOR BUFFER MOVE.B #16,D7 COUNTER = 64/4 WINLOO MOVE.L (A1)+,(A2)+ SUB.B #1,D7 BNE.S WINLOO REPEAT UNTIL MOVED IN MOVE.W NEXCYL(PC),(A2)+ NEXT FREE CYLINDER GOES AT END BSR.L HWRITE WRITE BACK TO DISK BNE.S FERROR FATAL ERROR * ENTIRE PARTITION HAS BEEN INITIALIZED; GO DO THE NEXT ONE ADD.L #16,A0 POINT TO NEXT OURWIN ENTRY BRA.L LPALOO REPEAT FOR NEXT PARTITION * DISK IS FINALLY FINISHED, WRITE OURWIN TABLE INTO SK*DOS'S * WINTAB SO SK*DOS CAN IMMEDIATELY USE IT DONE LEA OURWIN(PC),A4 POINT TO OUR TABLE DC VPOINT MOVE.L DOSORG(A6),A5 POINT TO BEGINNING OF DOS LEA WINTAB(A5),A5 POINT TO DOS'S WINTAB MOVE.B #16,D7 COUNTER = 64/4 MOVE.B PHDRIV(PC),D6 CHECK PHYSICAL DRIVE NUMBER SUB.B #1,D6 DRIVE A? BEQ.S DONELO YES, USE ADDRESS AS IS ADD.L #64,A5 NO, POINT TO DRIVE B PORTION DONELO MOVE.L (A4)+,(A5)+ MOVE FOUR BYTES SUB.B #1,D7 BNE.S DONELO REPEAT FOR 64 BYTES SUB.L #64,A5 POINT BACK TO BEGINNING OF WINTAB LSL.B #2,D6 A=0, B=4 ADD.B #$20,D6 A=20, B=24 OR.B D6,(A5) UPDATE 0 TO 20 OR 24, ETC. OR.B D6,16(A5) OR.B D6,32(A5) OR.B D6,48(A5) * FINALLY FINISHED ... EXIT BSET #4,HARDWE SIGNAL WX1 INSTALLED LEA DONMSG(PC),A4 DC PSTRNG PRINT "DONE" DC WARMST AND QUIT * FATAL ERROR ROUTINE FERROR LEA FERMSG(PC),A4 DC PSTRNG PRINT "FATAL ERROR" DC WARMST * CLRBUF - CLEAR SECTOR BUFFER CLRBUF MOVEM.L A4/D7,-(A7) LEA BUFFER(PC),A4 POINT TO BUFFER MOVE.B #256/4,D7 256 BYTES TO CLEAR CLRLOO CLR.L (A4)+ CLEAR BUFFER SUB.B #1,D7 BNE.S CLRLOO MOVEM.L (A7)+,A4/D7 RTS * LPCONV - CONVERT A LOGICAL TRACK AND SECTOR NUMBER (IN D0 * AS 0000TRSE) INTO PHYSICAL TRACK, HEAD, AND SECTOR NUMBERS AND * PUT INTO WD REGS, USING INFO IN OURWIN ENTRY POINTED TO BY A0 LPCONV MOVE.W D0,D6 LSR.W #8,D6 LOGICAL TRACK CLR.L D7 MOVE.B 11(A0),D7 LOG SECT/TRACK ADD.W #1,D7 NUMBER PER TRACK MULU D7,D6 SECT BEFORE THIS TRACK CLR.L D7 MOVE.B D0,D7 LOG SECTOR ADD.W D7,D6 BLOCK NUMBER MOVE.W 4(A0),D7 SECT/CYL ON HARD DISK DIVU D7,D6 REMAINDER | TRACK NUMBER ADD.W 8(A0),D6 PLUS START OF PARTITION LEA WX1CYL(PC),A6 MOVE.W D6,(A6) SAVE CYLINDER NUMBER LSR.L #8,D6 LSR.L #8,D6 REMAINDER IN RIGHT HALF CLR.L D7 MOVE.B 2(A0),D7 SECTORS PER TRACK DIVU D7,D6 SECTOR | HEAD LEA WX1HD(PC),A6 MOVE.B D6,(A6) HEAD NUMBER SWAP D6 MOVE SECTOR RIGHT LEA WX1SEC(PC),A6 MOVE.B D6,(A6) SAVE SECTOR NUMBER (256-BYTE) RTS * HWRITE - WRITE A SECTOR TO DISK FROM BUFFER POINTED TO BY A4 * USING DATA IN WX1CYL, WX1HD, AND WX1SEC HWRITE MOVEM.L A4-A4,-(A7) STACK BUFFER POINTER MOVE.L WX1CYL(PC),D7 DESIRED CYL/HD/SEC LSR.B #1,D7 CVT TO WX1 PHYS SCTR CMP.L OLDCYL(PC),D7 ALREADY IN WX1BUF? BEQ.S HWRYES YES, ALREADY THERE BSR.S PREAD NO, SO READ AND UPDATE OLD BNE.S HWREXI EXIT ON ERROR HWRYES LEA WX1BUF(PC),A6 POINT TO EVEN SECTOR BTST #0,WX1SEC(PC) CHECK IF EVEN OR ODD DESIRED BEQ.S HWREVN EVEN OK ADD.L #256,A6 NO, POINT TO ODD HWREVN MOVE.W #255,D7 COUNTER = 256 MOVE.L (A7),A4 RESTORE A4 POINTER HWRLOO MOVE.B (A4)+,(A6)+ READ A BYTE DBRA D7,HWRLOO REPEAT FOR 256 BYTES BSR.L PWRITE NOW WRITE SECTOR TO DISK HWREXI MOVEM.L (A7)+,A4-A4 PULL RTS EXIT * HREAD - READ A SECTOR FROM DISK INTO BUFFER POINTED TO BY A4 * USING DATA IN WX1CYL, WX1HD, AND WX1SEC HREAD MOVEM.L A4-A4,-(A7) STACK BUFFER POINTER MOVE.L WX1CYL(PC),D7 DESIRED CYL/HD/SEC LSR.B #1,D7 CVT TO WX1 PHYS SCTR CMP.L OLDCYL(PC),D7 ALREADY IN WX1BUF? BEQ.S HRDYES YES, ALREADY THERE BSR.S PREAD NO, SO READ AND UPDATE OLD BNE.S HRDEXI EXIT ON ERROR HRDYES LEA WX1BUF(PC),A6 POINT TO EVEN SECTOR BTST #0,WX1SEC(PC) CHECK IF EVEN OR ODD DESIRED BEQ.S HRDEVN EVEN OK ADD.L #256,A6 NO, POINT TO ODD HRDEVN MOVE.W #255,D7 COUNTER = 256 MOVE.L (A7),A4 RESTORE A4 POINTER HRDLOO MOVE.B (A6)+,(A4)+ READ A BYTE DBRA D7,HRDLOO REPEAT FOR 256 BYTES OR.B #$04,CCR ZERO TO SIGNAL NO ERROR HRDEXI MOVEM.L (A7)+,A4-A4 PULL RTS EXIT * PREAD - PHYSICAL READ OF A 512-BYTE SECTOR INTO WX1BUF, * RETURNS NON-ZERO IF ERROR, AND USES DATA IN WX1CYL, * WX1HD, AND WX1SEC PREAD BSR.L CHBUSY WAIT FOR NOT BUSY LEA WX1TAB(PC),A4 POINT TO COMMAND TABLE MOVE.B #8,0(A4) READ SECTOR COMMAND MOVE.B PHDRIV(PC),D7 DRIVE A=1 SUB.B #1,D7 DRIVE A=0 LSL.B #5,D7 MOVE INTO BIT 5 ADD.B WX1HD(PC),D7 COMBINE WITH HEAD NUMBER MOVE.B D7,1(A4) INTO TABLE MOVE.W WX1CYL(PC),D7 CYLINDER LSR.W #1,D7 MSB IN BITS 7-8 AND.B #$80,D7 ONLY BITS 7-8 ADD.B WX1SEC(PC),D7 COMBINE WITH SECTOR LSR.W #1,D7 DIVIDE BY 2 MOVE.B D7,2(A4) MSB OF CYL AND SECTOR MOVE.B WX1CYL+1(PC),D7 MOVE.B D7,3(A4) LSB OF CYL MOVE.B #1,4(A4) 1 SECTOR MOVE.B STEPRT(PC),D7 MOVE.B D7,5(A4) STEPRATE BSR.L GIVE6 BSR.L CBWAIT WAIT FOR CB BNE.S RDERR EXIT ON TIMEOUT LEA WX1BUF(PC),A4 POINT TO WX1 BUFFER MOVE.W #510,D7 COUNTER FOR 511 BYTES WXRDLP MOVE.B WXDATA,(A4)+ MOVE A BYTE MOVE.B WXSTAT,D6 CHECK STATUS AND.B #$0F,D6 CMP.B #$0B,D6 CHECK IF STILL WAITING BNE.S RDERR NO, ERROR DBRA D7,WXRDLP YES, CONTINUE MOVE.B WXDATA,(A4)+ GET THE LAST BYTE LEA OLDCYL(PC),A4 POINT TO OLD CYL/HD/SEC MOVE.L WX1CYL(PC),D7 NEW CYL/HD/SEC LSR.B #1,D7 CVT TO 512-BYTE NUMBER MOVE.L D7,(A4) MOVE TO OLDSEC RDERR BSR.L CFWAIT WAIT FOR COMPLETION MOVE.B WXDATA,D7 GET COMPLETION CODE AND.B #$DF,D7 IGNORE DRIVE BIT BEQ.S RDRTS OK IF ZERO MOVE.B #$FF,2(A4) ELSE ERASE HD NUMBER ON ERROR RDRTS RTS * PWRITE - PHYSICAL WRITE OF A 512-BYTE SECTOR FROM WX1BUF, * RETURNS NON-ZERO IF ERROR, AND USES DATA IN WX1CYL, * WX1HD, AND WX1SEC PWRITE BSR.L CHBUSY WAIT FOR NOT BUSY LEA WX1TAB(PC),A4 POINT TO COMMAND TABLE MOVE.B #$0A,0(A4) WRITE SECTOR COMMAND MOVE.B PHDRIV(PC),D7 DRIVE A=1 SUB.B #1,D7 DRIVE A=0 LSL.B #5,D7 MOVE INTO BIT 5 ADD.B WX1HD(PC),D7 COMBINE WITH HEAD NUMBER MOVE.B D7,1(A4) INTO TABLE MOVE.W WX1CYL(PC),D7 CYLINDER LSR.W #1,D7 MSB IN BITS 7-8 AND.B #$80,D7 ONLY BITS 7-8 ADD.B WX1SEC(PC),D7 COMBINE WITH SECTOR LSR.W #1,D7 DIVIDE BY 2 MOVE.B D7,2(A4) MSB OF CYL AND SECTOR MOVE.B WX1CYL+1(PC),D7 MOVE.B D7,3(A4) LSB OF CYL MOVE.B #1,4(A4) 1 SECTOR MOVE.B STEPRT(PC),D7 MOVE.B D7,5(A4) STEPRATE BSR.L GIVE6 BSR.L C9WAIT WAIT FOR C9 BNE.S WRERR EXIT ON TIMEOUT LEA WX1BUF(PC),A4 POINT TO WX1 BUFFER MOVE.W #510,D7 COUNTER FOR 511 BYTES WXWRLP MOVE.B (A4)+,WXDATA MOVE A BYTE MOVE.B WXSTAT,D6 CHECK STATUS AND.B #$0F,D6 CMP.B #$09,D6 CHECK IF STILL WAITING BNE.S WRERR NO, ERROR DBRA D7,WXWRLP YES, CONTINUE MOVE.B (A4)+,WXDATA MOVE THE LAST BYTE WRERR BSR.L CFWAIT WAIT FOR COMPLETION MOVE.B WXDATA,D7 GET COMPLETION CODE AND.B #$DF,D7 IGNORE DRIVE BIT WRRTS RTS * CHBUSY - WAIT FOR CONTROLLER NOT BUSY BUT ABORT IF IT TAKES * TOO LONG. ACTUALLY LOOKS FOR $C0 (NOT BUSY, DATA, WRITE, AND * NOT REQ) RATHER THAN JUST NOT BUSY * USES D6 AND D7 CHBUSY MOVE.L #$100000,D7 SET UP COUNTER CHBUS1 SUB.L #1,D7 DEC COUNTER BEQ.L TOSLOW ERROR IF TOOK TOO LONG MOVE.B WXSTAT,D6 GET STATUS AND.B #$0F,D6 DELETE THE $C BNE.S CHBUS1 REPEAT IF STILL BUSY RTS * GIVE6 - ROUTINE TO PASS A 6-BYTE CONTROL BLOCK FROM (A4)-> * TO THE CONTROLLER GIVE6 BSR.S CHBUSY WAIT FOR NOT BUSY MOVE.B #0,WXSELE SELECT THE CONTROLLER BSR.S CDWAIT WAIT FOR COMMAND REQUEST BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A4)+,WXCOMM GIVE FIRST BYTE BSR.S CDWAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A4)+,WXCOMM BSR.S CDWAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A4)+,WXCOMM BSR.S CDWAIT GIVE REMAINING BYTES BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A4)+,WXCOMM BSR.S CDWAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A4)+,WXCOMM BSR.S CDWAIT BNE.L FERROR ERROR IF TIMEOUT MOVE.B (A4)+,WXCOMM RTS * CDWAIT - WAIT FOR CONTROLLER READY TO RECEIVE A COMMAND BYTE * (STATUS RETURNS A $CD AS SIGNAL = BUSY COMMAND WRITE REQ) * USES D6 AND D7 CDWAIT MOVE.L #$100000,D7 SET UP COUNTER CDLOOP SUB.L #1,D7 DEC COUNTER BEQ.S WERROR ERROR IF TOOK TOO LONG MOVE.B WXSTAT,D6 GET STATUS REGISTER AND.B #$0F,D6 KEEP RIGHT 4 BITS CMP.B #$0D,D6 CHECK BUSY, COM, WRITE, REQ BNE.S CDLOOP WAIT FOR IT RTS WERROR AND.B #$FB,CCR NOT ZERO IF ERROR RTS * CFWAIT - WAIT FOR CONTROLLER READY TO RETURN COMPLETION CODE * (STATUS RETURNS A $CF AS SIGNAL = BUSY COMMAND READ REQUEST) * USES D6 AND D7 CFWAIT MOVE.L #$100000,D7 SET UP COUNTER CFLOOP SUB.L #1,D7 DEC COUNTER BEQ.S WERROR ERROR IF TOOK TOO LONG MOVE.B WXSTAT,D6 GET STATUS REGISTER AND.B #$0F,D6 KEEP RIGHT 4 BITS CMP.B #$0F,D6 CHECK BUSY, COM, READ, REQ BNE.S CFLOOP WAIT FOR IT RTS * C9WAIT - WAIT FOR CONTROLLER READY TO RETURN COMPLETION CODE * (STATUS RETURNS A $C9 AS SIGNAL = BUSY DATA WRITE REQUEST) * USES D6 AND D7 C9WAIT MOVE.L #$100000,D7 SET UP COUNTER C9LOOP SUB.L #1,D7 DEC COUNTER BEQ.S WERROR ERROR IF TOOK TOO LONG MOVE.B WXSTAT,D6 GET STATUS REGISTER AND.B #$0F,D6 KEEP RIGHT 4 BITS CMP.B #$09,D6 CHECK BUSY, DATA, WRITE, REQ BNE.S C9LOOP WAIT FOR IT RTS * CBWAIT - WAIT FOR CONTROLLER READY TO RETURN COMPLETION CODE * (STATUS RETURNS A $CB AS SIGNAL = BUSY DATA READ REQUEST) * USES D6 AND D7 CBWAIT MOVE.L #$100000,D7 SET UP COUNTER CBLOOP SUB.L #1,D7 DEC COUNTER BEQ.S WERROR ERROR IF TOOK TOO LONG MOVE.B WXSTAT,D6 GET STATUS REGISTER AND.B #$0F,D6 KEEP RIGHT 4 BITS CMP.B #$0B,D6 CHECK BUSY, DATA, WRITE, REQ BNE.S CBLOOP WAIT FOR IT RTS * ERROR PROCESSING TOSLOW LEA RESMSG(PC),A4 DC PSTRNG PRINT "HARDWARE PROBLEM - SLOW DC WARMST AND QUIT NOCONT LEA NOCMSG(PC),A4 DC PSTRNG PRINT "NO CONTROLLER DC WARMST AND QUIT * TEXT STRINGS DRVMSG FCC 'Which drive - A or B? ',4 PHTMSG FCC 'Number of cylinders (Tracks/Side) to use on drive? ',4 PRKMSG FCC 'Which cylinder should the drive be parked on? ',4 PREMSG FCC 'Which cylinder to start precompensation? ',4 ILVMSG FCC 'Enter desired interleave (6 if unsure): ',4 HDSMSG FCC 'How many heads on the drive? ',4 SPTMSG FCC '(There are 34 sectors per track/side.)',4 SEKMSG FCB $D,$A FCC 'Enter the required code (0-7) for drive step rate -' FCB $D,$A FCC 'consult the controller manual for the required value, or' FCB $D,$A FCC 'use 5 if unsure: ',4 CAPMSG FCB $D,$A FCC 'Total disk capacity is ',4 CA2MSG FCC ' K.',4 MUSMSG FCB $D,$A FCC 'THIS EXCEEDS THE MAXIMUM LOGICAL DRIVE CAPACITY; you must' FCB $D,$A FCC 'therefore partition the disk into ',4 PARMSG FCC ' to 4 partitions.',4 WOUMSG FCC 'Would you like to partition the disk (Y/N)? ',4 NUMMSG FCC 'How many partitions would you like? ',4 PA1MSG FCB $D,$A FCC 'You will now partition the disk by Cylinders (Tracks). The' FCB $0D,$0A FCC 'TOTAL number of usable cylinders on this drive is ',4 PA2MSG FCB $D,$A FCC 'The MAXIMUM number of cylinders allowed in any one' FCB $0D,$0A FCC ' partition is ',4 P2AMSG FCB $D,$A FCC 'Oops ... not enough cylinders for this many partitions - try again.',4 PA3MSG FCB $D,$A FCC 'The MINIMUM number of cylinders allowed in any one' FCB $0D,$0A FCC ' partition is 5.' FCB $0D,$0A FCC 'Decide how you would like to split up the TOTAL number of' FCB $0D,$0A FCC ' cylinders and enter the counts:',4 PA4MSG FCC 'Cylinders for Partition H',4 PA5MSG FCC '? ',4 PTBMSG FCC 'Partition too big ... Try it again.',4 PTSMSG FCC 'Partition too small ... Try it again.',4 PA6MSG FCC "TOTAL Cylinders don't add up correctly. Try again.",4 CHKMSG FCC 'READY TO FORMAT HARD DRIVE ',4 RUSMSG FCC 'ARE YOU SURE YOU WANT TO GO AHEAD? ',4 NOCMSG FCC 'No WX-type controller exists - ' NOTMSG FCC 'Formatting aborted.',4 LLFMSG FCB $0D,$0A FCC 'Low level format - Please wait...',4 FLNMSG FCC 'Formatting and verifying partition ',4 FLTMSG FCB $0D CR ONLY, NO LF FCC ' Logical track ',4 DONMSG FCB $0D,$0A FCC 'Formatting completed. To make this a bootable disk,' FCB $0D,$0A FCC 'copy SK*DOS.SYS to partition 0 as soon as possible.',4 RESMSG FCC 'Hardware problem - BUSY too long - Aborting Format.',4 BDSMSG FCC 'DEFECTIVE SECTOR AT LOGICAL TRACK/SECTOR ',4 FERMSG FCC 'FATAL ERROR - FORMATTING ABORTED.',4 * DATA AREA FOR FORMAT HEADS DC.B 0 NUMBER OF HEADS SDHMEM DC.B 0 S-D-H MEMORY CHFLAG DC.B 0 0=LAST WAS AN ERROR, 1=OK PHDRIV DC.B 0 PHYSICAL DRIVE A=1, B=2 SECPT DC.B 0 SECTORS PER TRACK OR SIDE PARTS DC.B 0 NUMBER OF PARTITIONS ON DISK STEPRT DC.B 0 STEPRATE CODE FOR SDH REG PRTNUM DC.B 0 PREVIOUS TRACK NUMBER INTLVE DC.B 0 DESIRED INTERLEAVE EVEN PRECOM DC.W 0 PRECOMPENSATION START CYL PARKCY DC.W 0 CYLINDER TO PARK DRIVE ON OURWIN DS.B 64 WINCHESTER CONFIG TABLE DC.W $FFFF *** END MARKER FOR ABOVE *** NEXCYL DC.W 0 NEXT FREE CYLINDER PHCYLS DC.W 0 NUMBER OF CYLINDERS ON DRIVE WX1TAB DC.W 0,0,0 6 BYTE COMMAND BLOCK FOR WX1 WX1CYL DS.W 1 CYLINDER NUMBER TO USE WX1HD DS.B 1 HEAD NUMBER TO USE WX1SEC DS.B 1 SECTOR NUMBER TO USE IF 256 OLDCYL DC.W 0 OLD CYLINDER NOW IN WX1BUF OLDHD DC.B 255 OLD HEAD OLDSEC DC.B 0 OLD WX1 SECTOR NUMBER EVEN BUFFER DS.B 256 SECTOR BUFFER FOR DATA WX1BUF DS.B 512 WX1 512-BYTE SECTOR BUFFER END START