NAM HDFORMAT OPT PAG PAG * HDFORMAT PROGRAM FOR SK*DOS 68K * SUPPORTS THE PERIPHERAL TECH PT68K-1 COMPUTER WINCHESTER * USING THE WD1002 HARD DISK CONTROLLER * COPYRIGHT (C) 1986 BY PETER A. STARK * FOR STAR-K SOFTWARE SYSTEMS CORP. * MOD 9-26-87 TO DEFAULT TO 32 SEC/TRK AND NOT ASK * SK*DOS EQUATES LIB SKEQUATE WINTAB EQU $200 OFFSET FOR DOS'S WINTAB WDREAD EQU $E0020 READ DATA REGISTER WDWRIT EQU WDREAD WRITE DATA REGISTER WDERRO EQU $E0024 ERROR REGISTER WDWPRE EQU WDERRO WRITE PRECOMP REGISTER WDSCNT EQU $E0028 SECTOR COUNT REGISTER WDSNUM EQU $E002C SECTOR NUMBER WDCYLO EQU $E0030 CYLINDER NUMBER - LOW ORDER BYTE WDCYHI EQU $E0034 CYLINDER NUMBER - HIGH ORDER BYTE WDSDHR EQU $E0038 SIZE,DRIVE,HEAD REGISTER WDSTAT EQU $E003C STATUS REG - READ ONLY WDCOMA EQU WDSTAT COMMAND REG - WRITE ONLY START BRA.S START1 DC.W $0102 VERSION * INITIALIZE EVERYTHING START1 LEA OURWIN(PC),A0 POINT TO OUR WIN TABLE MOVE.B #16,D0 CLRTAB MOVE.L #$FFFFFFFF,(A0)+ CLEAR 4 BYTES SUB.B #1,D0 DEC COUNTER BNE.S 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 > PHTRKS (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 (B) 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 LSR.L #2,D5 WD1002 WANTS IT DIVIDED BY 4 LEA PRECOM(PC),A0 WHERE TO PUT IT MOVE.B 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 #2,D5 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 #32,(A0) DEFAULT TO 32 SEC/TRK * 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 #15,D5 CHECK IT BHI.S GETSEK REPEAT IF >15 LEA STEPRT(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.B PRECOM(PC),14(A0) PRECOMP CYLINDER/4 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 GETCH GET REPLY AND.B #$DF,D5 CVT TO UPPER CMP.B #$59,D5 BEQ.S INTLVE GO INITIALIZE THE DRIVE LEA NOTMSG(PC),A4 DC PSTRNG PRINT "ABORTING" DC WARMST * CALCULATE INTERLEAVE TABLE INTLVE MOVE.L #20,D5 USE INTERLEAVE = 20 CLR.L D7 MOVE.B SECPT(PC),D7 SECTORS PER TRACK LEA BUFFER(PC),A3 POINT TO BUFFER ERASIL MOVE.B #$FF,(A3)+ ERASE ENTRY SUB.B #1,D7 SUBTRACT FROM COUNTER BNE.S ERASIL ERASE ENTIRE SEC TABLE CLR.B D7 RESET COUNTER CLR.B D6 RESET INTERLEAVE STEP LEA BUFFER(PC),A3 POINT TO BUFFER INTLV CMP.B SECPT(PC),D6 STEPPED PAST NUM OF SEC/TR? BCS.S INTLV1 NO SUB.B SECPT(PC),D6 YES, DO MODULO SEC/TR INTLV1 CMP.B #$FF,0(A3,D6.W) CHECK NEXT ENTRY IN TABLE BNE.S INTLV2 IF ALREADY SET MOVE.B D7,0(A3,D6.W) ELSE SET IT IF NOT YET BRA.S INTLV3 INTLV2 ADD.B #1,D6 ENTRY ALREADY SET, GO TO NEXT BRA.S INTLV INTLV3 ADD.B D5,D6 STEP TO NEXT ADD.B #1,D7 BUMP COUNTER CMP.B SECPT(PC),D7 CHECK WHETHER ALL DONE BNE.S INTLV NO * INITIALIZE THE DRIVE AND GET READY FOR FORMATTING MOVE.B PHDRIV(PC),D0 DRIVE NUMBER (1 OR 2) LSL.B #3,D0 INTO BITS 3 AND 4 OR.B #$80,D0 SELECT ECC BIT LEA SDHMEM(PC),A4 MOVE.B D0,(A4) SAVE INTO SDH MEMORY MOVE.B D0,WDSDHR ECC,SEC=256,DRIVE N,HEAD 0 MOVE.B PRECOM(PC),WDWPRE SET PRECOMP MOVE.B #$10,D0 RESTORE COMMAND CODE ADD.B STEPRT(PC),D0 ADD IN STEP RATE CODE MOVE.B D0,WDCOMA DO A SLOW RESTORE AT 2.0 MSEC BSR.L CHBUSY WAIT FOR WD1002 NOT BUSY * NEXT LOOP FOR EACH TRACK AND HEAD TO DO LOW LEVEL FORMAT DC PCRLF START ON NEW LINE CLR.L D0 TRACK COUNTER MOVE.B PHDRIV(PC),D2 DRIVE NUMBER LSL.B #3,D2 MOVE INTO BITS 4&3 OR.B #$80,D2 OR IN ECC BIT FOR SDH REG FTRLOO BSR.L CHBUSY CHECK THAT WD IS NOT BUSY LEA LLFMSG(PC),A4 DC PNSTRN PRINT "HDWE FOR'ING' MOVE.W D0,D4 CLR.L D5 NO SPACES DC OUT5D AND OUTPUT TRACK NUMBER MOVE.L D0,D7 TRACK NUMBER MOVE.B D7,WDCYLO TO WD 1002 LSR.W #8,D7 MOVE.B D7,WDCYHI DITTO CLR.L D1 HEAD COUNTER FHDLOO MOVE D2,D7 ECC AND DRIVE BITS ADD.B D1,D7 PLUS HEAD NUMBER MOVE.B D7,WDSDHR TO SIDE-DRV-HD REGISTER MOVE.B SECPT(PC),WDSCNT SECTOR COUNT REGISTER MOVE.B #$50,WDCOMA SEND WRITE TRACK COMMAND BSR.L CHBUSY JUST IN CASE LEA BUFFER(PC),A5 POINT TO BUFFER MOVE.B #128,D7 256/2 BYTES TO OUTPUT FBYLOO MOVE.B #0,WDWRIT 00 = THIS SECTOR OK MOVE.B (A5)+,WDWRIT FOLLOWED BY SECTOR NUMBER SUB.B #1,D7 DEC BYTE COUNTER BNE FBYLOO OUTPUT 256 BYTES (INCL GARBAGE) BSR.L CHBUSY WAIT FOR COMPLETION ADD.B #1,D1 INC HEAD COUNTER CMP.B HEADS(PC),D1 CHECK IF DONE BNE.S FHDLOO DO MORE HEADS ADD.W #1,D0 INC TRACK COUNTER CMP.W PHCYLS(PC),D0 CHECK IF DONE BNE.S FTRLOO DO MORE TRACKS * 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 BNE.S CHWRNG IF DEFINITE ERROR BTST #2,D7 CHECK CORRECTED BIT BEQ.S CHROK IF NO CORRECTION REQUIRED BSR.L HREAD AFTER CORRECTION, TRY READ AGAIN BNE.S CHWRNG IF DEFINITE ERROR BTST #2,D7 CHECK CORRECTED BIT BEQ.S CHROK IF NO CORRECTION REQUIRED * 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.S 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 CLR.B WDSDHR DESELECT DRIVE LEA DONMSG(PC),A4 DC PSTRNG PRINT "DONE" DC WARMST AND QUIT * FATAL ERROR ROUTINE FERROR CLR.B WDSDHR DESELECT DRIVE 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 MOVE.B D6,WDCYLO LSR.L #8,D6 MOVE.B D6,WDCYHI CYLINDER NUMBER TO WD1002 LSR.L #8,D6 REMAINDER IN RIGHT HALF CLR.L D7 MOVE.B 2(A0),D7 SECTORS PER TRACK DIVU D7,D6 SECTOR | HEAD ADD.B SDHMEM(PC),D6 COMBINE WITH OTHER SDH BITS MOVE.B D6,WDSDHR PUT INTO SDH REGISTER SWAP D6 MOVE SECTOR RIGHT MOVE.B D6,WDSNUM SECTOR NUMBER TO WD1002 RTS * HWRITE - WRITE A SECTOR TO DISK FROM BUFFER POINTED TO BY A4 HWRITE MOVE.B #1,WDSCNT SECTOR COUNT = 1 MOVE.L A4,A6 POINT TO BUFFER MOVE.B #$30,WDCOMA SEND WRITE COMMAND MOVE.B #64,D7 COUNTER = 256/4 HWRLOO MOVE.L (A6)+,WDWRIT OUTPUT 4 BYTES SUB.B #1,D7 DECREMENT COUNTER BNE.S HWRLOO REPEAT FOR 256 BYTES BSR.S CHBUSY WAIT FOR COMPLETION MOVE.B WDSTAT,D7 GET WD STATUS BYTE BTST.B #0,D7 CHECK ERROR BIT RTS EXIT WITH ZERO IF NO ERROR * HREAD - READ A SECTOR FROM DISK INTO BUFFER POINTED TO BY A4 HREAD MOVE.B #1,WDSCNT SECTOR COUNT = 1 MOVE.B #$20,WDCOMA SEND READ COMMAND BSR.S CHBUSY WAIT FOR COMPLETION MOVE.L A4,A6 POINT TO BUFFER MOVE.B #64,D7 COUNTER = 256/4 HRDLOO MOVE.L WDREAD,(A6)+ READ 4 BYTES SUB.B #1,D7 DECREMENT COUNTER BNE.S HRDLOO REPEAT FOR 256 BYTES BSR.S CHBUSY WAIT FOR COMPLETION MOVE.B WDSTAT,D7 GET WD STATUS BYTE BTST.B #0,D7 CHECK ERROR BIT RTS EXIT WITH ZERO IF NO ERROR * CHBUSY - WAIT IF BUSY, BUT ABORT IF IT TAKES TOO LONG CHBUSY MOVEM.L D6-D6,-(A7) MOVE.L #$100000,D6 TIMEOUT COUNTER CHBUS1 SUB.L #1,D6 DROP TIMEOUT COUNT BEQ.S CHBUS2 SOMETHING WRONG? TST.B WDSTAT CHECK WD1002 STATUS BMI.S CHBUS1 WAIT UNTIL NOT BUSY MOVEM.L (A7)+,D6-D6 RTS CHBUS2 CLR.B WDSDHR DESELECT DRIVE LEA RESMSG(PC),A4 DC PSTRNG PRINT "HARDWARE PROBLEM - SLOW DC WARMST AND QUIT 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 HDSMSG FCC 'How many heads on the drive? ',4 SPTMSG FCC '(There are 32 sectors per track/side.)',4 SEKMSG FCB $D,$A FCC 'Enter the required code for drive step rate -' FCB $D,$A FCC '0 if buffered, 1 to 15 for 0.5 to 7.5 msec respectively: ',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 NOTMSG FCC 'Formatting aborted.',4 LLFMSG FCB $0D CR ONLY, NO LF FCC 'Low level format - Physical cylinder ',4 FLNMSG FCC 'Formatting and verifying partition ',4 FLTMSG FCB $0D CR ONLY, NO LF FCC ' Logical track ',4 DONMSG FCC 'Formatting completed.',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 PRECOM DC.B 0 PRECOMPENSATION START CYL EVEN 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 BUFFER DS.B 256 SECTOR BUFFER FOR DATA END START