NAM FORMAT OPT PAG PAG * FORMAT PROGRAM FOR SK*DOS 68K * SUPPORTS THE PERIPHERAL TECH PT-68K-4 COMPUTER * COPYRIGHT (C) 1986 BY PETER A. STARK * FOR STAR-K SOFTWARE SYSTEMS CORP. * VER 1.4 MOD 10-10-86 TO SLOW DOWN STEP FOR 1772 * VER 1.5 10-18-86 TO UPDATE FOR DRUSED AND DRWPRO TABLES * VER 1.6 1-11-87 TO UPDATE HELP MESSAGE * VER 1.7 MOD >>A<< 3-25-87 TO SLOW DOWN STEP FOR 1772 * VER 1.8 MOD >>B<< 4-14-87 TO WRITE TO END OF TRACK, FIX PRINT * VER 1.8A MOD >>B1<< 4-19-87 FOR PT-68K-1A COMPUTER * VER 1.8B MOD >>B2<< 6-12-87 FOR PT-68K-2 COMPUTER * VER 1.9 MOD >>C<< 7-31-87 CHANGED INTERLEAVE AND LENGTHENED WAITF * VER 2.0 MOD >>D<< 8-3-87 TO VERIFY FORWARD * VER 2.1 MOD >>E<< 3-5-88 TO CHANGE A BNE.L TO BNE.S * VER 2.2 MOD >>F<< 8-20-88 1 RETRY DURING FORMAT VERIFY * VER 2.3 MOD >>G<< 10-6-88 FIX RETRY CHANGE * VER 2.4 MOD >>H<< 10-21-89 TO FIX PROBLEM WITH ADDR >8000 * VER 2.5 MOD >>I<< 6-27-90 FOR PT-68K-4 - INCREASE WAIT * VER 2.6 MOD >>J<< 7-16-90 FOR 37C65 CONTROLLER OF PT68K-4 * SK*DOS EQUATES LIB SKEQUATE DRUSED EQU $13C DRUSED TABLE OFFSET DRWPRO EQU $146 DR WR PROT TABLE OFFSET NRETRY EQU $150 NUMBER OF FLOPPY RETRIES >>F<< FL0D EQU $00FF0BEB HUMBUG'S CONTROLLER/DRIVE DATA >>J<< COMREG EQU $FE0101 FDC COMMAND REGISTER STAREG EQU COMREG FDC STATUS REGISTER TRKREG EQU COMREG+2 FDC TRACK REGISTER SECREG EQU COMREG+4 FDC SECTOR REGISTER DATREG EQU COMREG+6 FDC DATA REGISTER DLATCH EQU $FE00C1 DRIVE SELECT LATCH HOUTCH EQU $F800EA HUMBUG'S OUTEEE ROUTINE >>B2<< HCOLDS EQU $F800C0 HUMBUG'S REENTRY >>B2<< * EXPLANATION OF 1772 DLATCH OPERATION: * BITS 0 & 1 SELECT DRIVE 0-3 >>B1<< * BIT 5 SELECTS DENSITY (0 = DD) * BIT 6 SELECTS SIDE (0 - SIDE A) * BITS 2, 3, 4, 7 - NOT USED * 37C65 CONTROLLER EQUATES REGOPER EQU $FA07E5 OPERATIONS REGISTER REGSTAT EQU REGOPER+4 MAIN STATUS REGISTER REGDATA EQU REGOPER+6 DATA REGISTER REGCONT EQU REGOPER+10 CONTROL REGISTER START BRA.S START1 DC.W $0206 VERSION START1 BRA.L START2 * DATA AREA FOR FORMAT SIDES DC.B 0 NUMBER OF SIDES SIDE DC.B 0 CURRENT SIDE SECTRS DC.B 0 SECTORS ON CURRENT TRACK (ONE SIDE) * KEEP FOLLOWING 2 LINES IN ORDER SECTR0 DC.B 0 SECTORS ON TRACK 0 (ONE SIDE) SECTRA DC.B 0 SECTORS ON OTHER TRACKS TRDENS DC.B 0 DENSITY OF CURRENT TRACK * KEEP FOLLOWING 2 LINES IN ORDER TR0DEN DC.B 0 DENSITY OF TRACK 0 TRADEN DC.B 0 DENSITY OF OTHER TRACKS PREIND DC.W 0 PRE-INDEX GAP INFO FOR USE LATER S1BEG DC.L 0 BEG OF SECTOR 1 IN BUFFER GRSIZE DC.W 0 GROSS SIZE OF SECTOR (256+ALL ELSE) TRKPTR DC.L 0 LSB POINTS TO TRACK IN GROSS SECTOR DATAPT DC.L 0 POINTS TO DATA AREA IN GROSS FCB INTADR DC.L 0 ADDRESS OF INTERLEAVE TABLE BUFEND DC.L 0 POINT JUST PAST END OF BUFFER PHYSEC DC.B 0 PHYSICAL SECTOR NUMBER LOGDRV DC.B 0 LOGICAL DRIVE NUMBER TO FORMAT ON PHYDRV DC.B 0 PHYSICAL DRIVE NUMBER TO FORMAT ON TRACK DC.B 0 CURRENT TRACK LAGOOD DC.W 0 LAST GOOD TRACK-SECTOR CHFLAG DC.B 0 0=LAST WAS AN ERROR, 1=OK TRCHAR DC.B 0 TRACK INDICATOR TRACKS DC.B 0 NUMBER OF TRACKS TO FORMAT INTERL DC.B 0 INTERLEAVE CONSTANT >>C<< FREE DC.W 0 NUMBER OF FREE SECTOR FIFREE DC.W 0 FIRST FREE TRACK-SECTOR LAFREE DC.W 0 LAST FREE TRACK-SECTOR NUMBER DC.W 0 DISK NUMBER MLATCH DC.B 0 COPY OF DISK LATCH CTTYPE DC.B 0 TYPE OF CONTROLLER (17 OR 37) >>J<< CTDRNO DC.B 0 NUM OF DRIVE ON CONTROLLER >>J<< DRTYPE DC.B 0 DRIVE TYPE FROM FLxD >>J<< DSKTPT DC.L 0 POINTER TO DISK TYPE ENTRY IN TABLE * THE FOLLOWING FOUR LINES MUST STAY IN ORDER DUMMY DC.L 0 LEAVE THIS BEFORE NAME NAME DC.L 0,0 DISK NAME EXT DC.B 0,0,0 DISK EXTENSION DUMMY2 DC.B 0 LEAVE THIS AFTER EXTENSION T0ILTAB DS.B 34 INTERLEAVE TABLE FOR TRACK 0 TAILTAB DS.B 34 INTERLEAVE TABLE FOR OTHER TRACKS FLG128 DC.B 0 FLAG: 0=1772, <>0=37C65, $FF=128 BYTE SECTORS MTIMER DC.B 0 MOTOR ON TIMER COMMAND DS.B 9 COMMAND BUFFER ST0 DC.B 0 STATUS REGISTER 0 ST1 DC.B 0 STATUS REGISTER 1 ST2 DC.B 0 STATUS REGISTER 2 C DC.B 0 H DC.B 0 R DC.B 0 N DC.B 0 * DRIVE PARAMETER AREA. FOR EACH KIND OF DRIVE, WE STORE THE * FOLLOWING DATA: DN EQU 0 N DTL EQU 1 DTL DATA LENGTH DBPS EQU 2 BPS CODE FOR CONTROL REG D0MF EQU 3 MF BIT FOR TRACK 0 DAMF EQU 4 MF BIT FOR OTHER TRACKS D0SECT EQU 5 SECTORS PER TRACK 0 DASECT EQU 6 SECTORS ON OTHER TRACKS D0FGAP EQU 7 TRK 0 FMT GAP 3 DAFGAP EQU 8 OTHER TRK FORMAT GAP 3 D0GAP EQU 9 TRK 0 R/W GAP 3 DAGAP EQU 10 OTHER TRK R/W GAP 3 D0SIDB EQU 11 TRK 0 SEC NUM SUB FOR SIDE B DASIDB EQU 12 OTHER TRK SEC NUM SUB FOR B DDUBL EQU 13 DOUBLE-STEP FLAG DNTRKS EQU 14 NUMBER OF TRACKS ON DISK SEC128 EQU 15 128-BYTE SECTOR FLAG * THERE ARE 16 BYTES FOR EACH; THE LAST 2 ARE ZERO EVEN * 360K DRIVE 40-TRACK DRIVE TYPEB DC.B 1,$FF,2,1,1,18,18,12,12,10,10,00,00,0,40,0 DD ALL DC.B 1,$FF,2,0,0,10,10,14,14,08,08,00,00,0,40,0 SD ALL DC.B 1,$FF,2,0,1,10,18,14,12,08,10,00,00,0,40,0 0 SD, DD ALL * 720K 80-TRACK DRIVE TYPEC DC.B 1,$FF,2,1,1,18,18,12,12,10,10,00,00,0,80,0 80 TR DD DC.B 1,$FF,2,1,1,18,18,12,12,10,10,00,00,1,40,0 40 TR DD DC.B 1,$FF,2,0,0,10,10,14,14,08,08,00,00,1,40,0 40 TR SD * 1.1 MEG 5-1/4" DRIVE TYPED DC.B 1,$FF,0,1,1,28,28,40,40,20,20,28,28,0,80,0 80 TR HD DC.B 1,$FF,1,1,1,18,18,12,12,10,10,00,00,0,80,0 80 TR DD DC.B 1,$FF,1,1,1,18,18,12,12,10,10,00,00,1,40,0 40 TR DD * 1.4 MEG 3-1/2" DRIVE TYPEE DC.B 1,$FF,0,1,1,34,34,40,40,27,27,34,34,0,80,0 80 TR HD DC.B 1,$FF,2,1,1,18,18,12,12,10,10,00,00,0,80,0 80 TR DD * 8" 1 MEG DRIVE TYPEF DC.B 1,$FF,0,1,1,26,26,54,54,14,14,00,00,0,77,0 77 TR DD DC.B 1,$FF,0,0,0,15,15,42,42,14,14,00,00,0,77,0 77 TR SD DC.B 0,128,0,0,0,26,26,27,27,07,07,26,26,0,77,1 128 BYTE START2 DC VPOINT POINT TO VARIABLES LEA TRACKS(PC),A5 MOVE.B #80,(A5) NO MORE THAN 80 TRACKS ALLOWED MOVE.L MEMEND(A6),D7 CHECK IF ENOUGH MEMORY EXISTS LEA BUFFER(PC),A5 POINT TO END OF FORMAT SUB.L A5,D7 CMP.L #$4000,D7 MINIMUM 16K NEEDED BCC.S MEMEOK OK IF OVER 16K LEA MEMMSG(PC),A4 ELSE PRINT "NOT ENOUGH RAM" DC PSTRNG DC WARMST MEMEOK LEA MLATCH(PC),A6 CLR.B (A6) CLEAR MLATCH IN PREPARATION BSR.L GETDRV GO GET DRIVE NUMBER BSR.L GETINL GET INTERLEAVE CONSTANT >>C<< * DECIDE WHICH CONTROLLER, AND DO THINGS SLIGHTLY DIFFERENTLY MOVE.B CTTYPE(PC),D7 CMP.B #$17,D7 BEQ.S DO1772 IF 1772 CMP.B #$37,D7 BEQ.S DO3765 BRA.L DRNONG ELSE MUST BE AN ERROR * ROUTINE FOR 1772 CONTROLLER DO1772 BSR.L ASKTRK GET NUMBER OF TRACKS TO FORMAT BSR.L ASKSID GET NUMBER OF SIDES BSR.L ASKDEN GET DENSITY BSR.L ASKTR0 GET TRACK 0 DENSITY BSR.L GETNAN GET NAME AND NUMBER BSR.L CHEKIT CHECK IF OK TO PROCEED BSR.L STUP17 SET UP 1772 DC PCRLF MOVE.B #$D0,COMREG RESET FDC BSR.L SETUP0 SETUP BUFFER WITH TEMPLATE FOR TRK 0 BSR.L WAIT1S MOTOR ON AND WAIT BSR.L FORMAT GO WRITE EVERY TRACK BSR.L CHKS17 GO CHECK ALL SECTORS LEA FLG128(PC),A2 CLR.B (A2) SIGNAL 1772 CONTROLLER MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>FG<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>FG<< BSR.L DOBOOT PUT ON BOOT BSR.L DOSIS DO SYSTEM INFO RECORD BSR.L DODIR DO DIRECTORY BSR.L REPORT REPORT ON RESULTS DC WARMST AND QUIT DO3765 LEA SIDES(PC),A5 MOVE.B #1,(A5) ALL 37C65 STUFF IS DOUBLE-SIDED BSR.L ASKALL ASK FOR DISK TYPE BSR.L ASKTRK GET NUMBER OF TRACKS TO FORMAT BSR.L GETNAN GET NAME AND NUMBER BSR.L CHEKIT CHECK IF OK TO PROCEED BSR.L STUP37 SET UP 37C65 DC PCRLF BSR.L FORM37 GO WRITE EVERY TRACK BSR.L CHKS37 GO CHECK ALL SECTORS LEA FLG128(PC),A2 MOVE.B #1,(A2) SIGNAL 37C65 CONTROLLER MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>FG<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>FG<< BSR.L DOBOOT PUT ON BOOT BSR.L DOSIS DO SYSTEM INFO RECORD BSR.L REPORT REPORT ON RESULTS DC WARMST AND QUIT *----------------------------------------------------------------------* * ROUCOM - ROUTINES COMMON TO BOTH CONTROLLERS *----------------------------------------------------------------------* *********************** * GET DRIVE NUMBER *********************** GETDRV DC DECIN GET DRIVE NUMBER BCS.S DRNONG IF DRIVE NUMBER IS BAD TST.B D6 BNE.S DRNOK IF VALID NUMBER WAS FOUND DRNONG LEA HLPMSG(PC),A4 INVALID DRIVE NUMBER DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST DRNOK CLR.L D4 MOVE.B MAXDRV(A6),D4 EXTEND MXDRV TO LONG CMP.L D4,D5 CHECK VALID NUMBER BHI.S DRNONG INVALID IF > MAXIMUM LEA LOGDRV(PC),A5 MOVE.B D5,(A5) SAVE LOGICAL NUMBER MOVE.L DOSORG(A6),A4 POINT TO DOS ORG LEA DRUSED(A4),A5 POINT TO DRUSED TABLE MOVE.B 0(A5,D5),D6 GET PHYSICAL DRIVE ENTRY BTST.B #4,D6 CHECK FLOPPY BIT BEQ.S NOTFLO NOT FLOPPY AND.L #$0F,D6 KEEP ONLY PHYSICAL DRIVE NUM LEA DRWPRO(A4),A5 POINT TO DRWPRO TABLE TST.B 0(A5,D5) TEST WRITE PROTECT ENTRY BMI.S WRIPRO IS WRITE PROTECTED LEA PHYDRV(PC),A5 MOVE.B D6,(A5) SAVE PHYSICAL NUMBER LSL.B #2,D6 X4 >>J<< LEA FL0D,A5 POINT TO HUMBUG'S DR 0 ENTRY >>J<< MOVE.B 0(A5,D6),D7 GET NUMBER/DRIVE CODE >>J<< BEQ.S DRNONG >>J<< MOVE.B -2(A5,D6),D6 GET CONTROLLER TYPE CODE >>J<< BEQ.S DRNONG >>J<< LEA CTTYPE(PC),A5 >>J<< MOVE.B D6,(A5) SAVE CONTROLLER TYPE >>J<< MOVE.B D7,D6 >>J<< LSR.B #4,D6 PHYS NO OF DRV ON CTRLER >>J<< AND.B #$0F,D7 DRIVE TYPE >>J<< LEA CTDRNO(PC),A5 >>J<< MOVE.B D6,(A5) SAVE NO OF DRV ON CTRLER >>J<< LEA DRTYPE(PC),A5 >>J<< MOVE.B D7,(A5) SAVE DRIVE TYPE >>J<< RTS NOTFLO LEA NFLMSG(PC),A4 NOT FLOPPY DRIVE DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST WRIPRO LEA WPRMSG(PC),A4 DRIVE IS WRITE PROTECTED DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST ********************************************* * GETINL - GET INTERLEAVE CONSTANT >>C<< NEW ********************************************* GETINL DC DECIN GET NUMBER FROM COMMAND LEA INTERL(PC),A5 MOVE.B D5,(A5) HOPE IT'S VALID RTS **************************************** * ASKTRK - GET NUMBER OF TRACKS DESIRED **************************************** ASKTRK DC PCRLF LEA GTTMSG(PC),A4 ASK FOR NUMBER OF TRACKS DC PSTRNG DC INLINE GET INPUT DC DECIN GET NUMBER BCS.S ASKTRK ASK AGAIN IF NOTHING MOVE.B TRACKS(PC),D7 MAXIMUM ALLOWED CMP.B D7,D5 CHECK NUMBER OF TRACKS BHI.S TRKSNG 81 OR ABOVE IS NG CMP.B #2,D5 BCC.S TRKSOK >1 SEEMS OK TRKSNG LEA TNGMSG(PC),A4 ELSE NUMBER OF TRACKS IS NG DC PSTRNG BRA.S ASKTRK AND ASK AGAIN TRKSOK CMP.B #80,D5 BHI.S TRKSNG ABOVE 81 ALSO NG LEA TRACKS(PC),A4 MOVE.B D5,(A4) STORE IT RTS AND RETURN ************************************* * GETNAN - GET DISK NAME AND NUMBER ************************************* GETNAN LEA NAMMSG(PC),A4 ASK FOR NAME DC PSTRNG DC INLINE GET THE NAME LEA NAME-4(PC),A4 POINT BEFORE NAME DC GETNAM GO GET THE NAME BCS.S GETNAN ASK AGAIN FOR A VALID NAME LEA EXT(PC),A6 MOVE.B (A6),D7 CHECK EXTENSION BNE.S GETNUM EXTENSION IS OK MOVE.L #$534B2A00,(A6) ELSE FORCE .SK* EXTENSION GETNUM LEA NUMMSG(PC),A4 ASK FOR NUMBER DC PSTRNG DC INLINE DC DECIN GET THE NUMBER BCS.S GETNUM IF NO NUMBER LEA NUMBER(PC),A4 MOVE.W D5,(A4) ELSE STORE IT RTS AND RETURN ************************************* * CHEKIT - CHECK THAT USER REALLY WANTS TO FORMAT ************************************* CHEKIT DC PCRLF LEA CHKMSG(PC),A4 PRINT CHKMSG DC PSTRNG MOVE.B PHYDRV(PC),D4 ADD.B #$30,D4 CVT TO ASCII 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 BNE.L ABORT MOVE.L A6,A4 POINT TO USER FCB MOVE.B LOGDRV(PC),FCBDRV(A4) PUT IN DRIVE NUMBER RTS ************************************* * DOBOOT - PUT BOOT ON DISK TR 0 SEC 1 AND 2 ************************************* DOBOOT LEA BOOT(PC),A0 POINT TO SUPER BOOT'S FIRST SECTOR LEA FCBDAT(A6),A1 AND FCB MOVE.L #64,D1 COUNTER = 256/4 DOBOO1 MOVE.L (A0)+,(A1)+ MOVE FOUR BYTES SUB.B #01,D1 DECR COUNTER BNE.S DOBOO1 DO 64 TIMES MOVE.L A6,A4 POINT TO FCB MOVE.W #0001,FCBCTR(A4) TR 0 SEC 1 DC SWRITE GO WRITE IT BNE.S SYSERR ERROR PUTTING BOOT THERE LEA BOOT+256(PC),A0 POINT TO SUPER BOOT'S SECOND SECTOR LEA FCBDAT(A6),A1 AND FCB MOVE.L #64,D1 COUNTER = 256/4 DOBOO2 MOVE.L (A0)+,(A1)+ MOVE FOUR BYTES SUB.B #01,D1 DECR COUNTER BNE.S DOBOO2 DO 64 TIMES MOVE.B #02,FCBCSE(A4) TR 0 SEC 2 DC SWRITE GO WRITE IT BNE.S SYSERR ERROR PUTTING BOOT THERE RTS ELSE RETURN ************************************* * SYSERR - SYSTEM ERROR ON TRACK 0 ************************************* SYSERR LEA TR0MSG(PC),A4 PRINT "ERROR ON TRACK 0" DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST AND STOP ************************************* * FATERR - FATAL ERROR, PROBABLY SECOND FAILURE ON SAME SEC >>F<< ************************************* FATERR LEA FATMSG(PC),A4 PRINT "FATAL ERROR" DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST AND STOP *************************** * DOSIS - WRITE SIS TO DISK *************************** DOSIS MOVE.W #$0003,FCBCTR(A4) TRACK 0 SEC 3 LEA FCBDAT(A4),A1 POINT A1 TO DATA AREA MOVE.B #64,D1 COUNTER = 256/4 ERASIS CLR.L (A1)+ ERASE NEXT 4 BYTES SUB.B #01,D1 DECR COUNTER BNE.S ERASIS ERASE 256 BYTES MOVE.B FIFREE(PC),FCBDAT+29(A4) FIRST FREE MOVE.B FIFREE+1(PC),FCBDAT+30(A4) MOVE.B LAFREE(PC),FCBDAT+31(A4) LAST FREE MOVE.B LAFREE+1(PC),FCBDAT+32(A4) MOVE.B FREE(PC),FCBDAT+33(A4) NUMBER FREE MOVE.B FREE+1(PC),FCBDAT+34(A4) MOVE.B CMONTH(A6),FCBDAT+35(A4) MONTH MOVE.B CDAY(A6),FCBDAT+36(A4) DAY MOVE.B CYEAR(A6),FCBDAT+37(A4) YEAR MOVE.B TRACKS(PC),D0 NUMBER OF TRACKS SUB.B #01,D0 STARTS WITH 0 MOVE.B D0,FCBDAT+38(A4) LAST TRACK NUMBER MOVE.B SECTRS(PC),D1 NUMBER OF SECTORS ON ONE SIDE MOVE.B SIDES(PC),D7 HOW MANY SIDES? BEQ.S SIS128 USE AS IS IF SS LSL.B #1,D1 ELSE *2 FOR DS SIS128 MOVE.B FLG128(PC),D7 CHECK 128-BYTE FLAG BPL.S SISLAS LSR.B #1,D1 ELSE HALF AS MANY SECTORS SISLAS MOVE.B D1,FCBDAT+39(A4) LEA NAME(PC),A1 POINT TO NAME LEA FCBDAT+16(A4),A0 POINT TO NAME LOCATION MOVE.L (A1)+,(A0)+ MOVE.L (A1)+,(A0)+ MOVE 11 BYTES - NAME AND EXT MOVE.L (A1)+,(A0)+ (AND ONE EXTRA) MOVE.B NUMBER(PC),FCBDAT+27(A4) NUMBER MOVE.B NUMBER+1(PC),FCBDAT+28(A4) DC SWRITE GO WRITE SECTOR BACK BNE.L SYSERR REPORT ERROR RTS THEN RETURN *************************** * DODIR - PUT AN END ON DIRECTORY *************************** DODIR MOVE.W #$0005,FCBCTR(A4) TRACK 0 SEC 5 DODIR1 DC SREAD GO READ SECTOR BNE.L SYSERR ERROR IF CAN'T READ MOVE.B FCBDAT(A4),D0 GET NEXT TRACK POINTER MOVE.W FCBDAT(A4),D1 GET NEXT TRACK & SEC POINTER TST.B D0 CHECK TRACK BNE.S DODIR2 MEANS LAST SECTOR ON THIS TRACK MOVE.B D1,FCBCSE(A4) ELSE SETUP TO READ NEXT BRA.S DODIR1 GO DO IT DODIR2 CLR.W FCBDAT(A4) MARK END OF DIRECTORY DC SWRITE GO REWRITE SECTOR BNE.L SYSERR RTS RTS AND QUIT *************************** * REPORT - REPORT THAT FORMATTING IS DONE *************************** REPORT LEA FCMMSG(PC),A4 PRINT "FORMATTING COMPLETE." DC PSTRNG MOVE.W FREE(PC),D4 MOVE.L #0,D5 SUPPRESS SPACES DC OUT5D PRINT NUMBER OF FREE SECTORS RTS AND RETURN *************************** * TEST STRINGS *************************** HLPMSG DC.B 'FORMAT is used to initialize a blank diskette for use with' DC.B $0D,$0A DC.B 'SK*DOS. It may also be used to completely erase all data on a' DC.B $0D,$0A DC.B 'disk and initialize it as if it were brand new. The syntax is' DC.B $0D,$0A DC.B ' FORMAT ' >>C<< DC.B $0D,$0A DC.B 'The must be specified, and must apply to a' >>C<< DC.B $0D,$0A DC.B 'valid floppy drive. The , if' >>C<< DC.B $0D,$0A DC.B 'given, overrides the default interleave constant.' >>C<< DC.B $0D,$0A DC.B 'FORMAT will then ask for further information. Remember' >>C<< DC.B $0D,$0A DC.B 'that to be bootable, the disk must be double-density throughout.' DC.B $0D,$0A DC.B 'Caution: FORMAT does really erase everything on the diskette!',4 *************************** * TEXT STRINGS *************************** MEMMSG FCC 'Minimum 16K of RAM is needed.',4 NFLMSG FCC 'Specified logical drive is not a floppy.',4 CHKMSG FCC 'About to format physical floppy drive number F',4 WPRMSG FCC 'Drive is write-protected.',4 GTTMSG FCC 'How many tracks? ',4 TNGMSG FCC 'Invalid number of tracks.',4 SIDMSG FCC 'Single or double sided? ',4 DENMSG FCC 'Single or double density? ',4 T0DMSG FCC 'Single or double density track 0? ',4 NAMMSG FCC 'Enter disk name: ',4 NUMMSG FCC 'Enter disk number: ',4 RUSMSG FCC 'Are you sure you really want to? ',4 NOTMSG FCC 'No formatting done.',4 DERMSG FCC 'Disk error - cannot format.',4 WPMSG FCC 'Disk is write protected',4 FCMMSG FCC 'Disk is formatted; free sectors = ',4 BDSMSG FCC 'Defective sector at track-sector (decimal) ',4 TR0MSG FCC 'Error on track 0 - formatting aborted.',4 FATMSG FCC 'Marginal disk, fatal error. Formatting aborted.',4 >>F<< ILEMSG FCC 'Invalid interleave constant specified.',4 >>C<< FORMSG FCC 'Formatting:',$0D,$0A,4 >>D<< VERMSG FCC 'Verifying:',$0D,$0A,4 >>D<< *-----------------------------------------------------------------------* * ROU1772 - ROUTINES FOR 1772 CONTROLLER ONLY *-----------------------------------------------------------------------* **************************************** * ASKSID - GET NUMBER OF SIDES **************************************** ASKSID LEA SIDMSG(PC),A4 DC PSTRNG PRINT "SINGLE OR DOUBLE SIDED?" DC GETCH LEA SIDES(PC),A4 CLR.B (A4) INIT AT 0 AND.B #$DF,D5 CVT TO UPPER CASE CMP.B #$53,D5 S? BEQ.S SINSID SINGLE CMP.B #$44,D5 D? BNE.S ASKSID IF INVALID MOVE.B #1,(A4) DOUBLE SIDED RTS SINSID CLR.B (A4) SINGLE SIDED RTS **************************************** * ASKDEN - GET DESIRED DENSITY, AND COMPUTE INTERLEAVE * >>C<< ENTIRELY REVISED * TABLE IF NEEDED **************************************** ASKDEN LEA DENMSG(PC),A4 DC PSTRNG PRINT "SINGLE OR DOUBLE DENSITY?" DC GETCH LEA DIDENS(PC),A4 CLR.B (A4) ASSUME SINGLE DENSITY AND.B #$DF,D5 CVT TO UPPER CASE CMP.B #$53,D5 S? BEQ.S SINDEN SINGLE CMP.B #$44,D5 D? BNE.S ASKDEN IF INVALID MOVE.B #18,(A4) 18 SEC/TR IN DOUBLE DENSITY MOVE.W #18,D5 NUMBER OF SECTORS LEA DDILTB-1(PC),A4 POINT TO INTERLEAVE TBL BRA.S SINDE1 SINDEN CLR.B (A4) SINGLE DENSITY MOVE.W #10,D5 NUMBER OF SECTORS LEA SDILTB-1(PC),A4 POINT TO INTERLEAVE TBL SINDE1 CLR.L D7 MOVE.B INTERL(PC),D7 CHECK INTERLEAVE BEQ.S ASKDEX IGNORE IF NOT SPECIFIED CMP.B D5,D7 COMPARE WITH NUMBER BCC INTLER INTERLEAVE ERROR IF >SECT * FOR D6=1 TO D5 : T(D6)=0 : NEXT D6 MOVE.L #1,D6 ILVCLR CLR.B 0(A4,D6) ADD.B #1,D6 CMP.B D6,D5 BCC.S ILVCLR * D6=1 MOVE.B #1,D6 * D4=1-D7 MOVE.L #1,D4 SUB.B D7,D4 INIT SECTOR WILL BE 1 * D4=D4+D7 L300 ADD.B D7,D4 NEXT SECTOR (INIT 1) * IF D4>D5 THEN D4=D4-D5 L310 CMP.B D4,D5 BCC.S MILVOK OK IF NEXT <= MAX SUB.B D5,D4 ELSE START AGAIN * IF T(D4)<>0 THEN D4=D4+1 : GOTO L310 MILVOK TST.B 0(A4,D4) BEQ.S MILVO1 ADD.B #1,D4 BRA.S L310 * T(D4)=D6 MILVO1 MOVE.B D6,0(A4,D4) * D6=D6+1 : IF D6<=D5 THEN L300 ADD.B #1,D6 CMP.B D6,D5 BCC.S L300 ASKDEX RTS INTLER LEA ILEMSG(PC),A4 PRINT INTERLEAVE ERROR MSG DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST **************************************** * ASKTR0 - GET DESIRED DENSITY FOR TRACK 0 **************************************** ASKTR0 LEA TR0DEN(PC),A4 POINT TO TRACK 0 DENS FLAG MOVE.B DIDENS(PC),D7 CHECK DISK DENSITY BEQ.S SINTR0 IF DISK IS SD, SO IS TR 0 LEA T0DMSG(PC),A4 IF DISK IS DD, THEN ASK DC PSTRNG PRINT "SINGLE OR DOUBLE DENSITY?" DC GETCH LEA TR0DEN(PC),A4 AND.B #$DF,D5 CVT TO UPPER CASE CMP.B #$53,D5 S? BEQ.S SINTR0 SINGLE CMP.B #$44,D5 D? BNE.S ASKTR0 IF INVALID MOVE.B #18,(A4) IF DD ON TRACK 0 RTS SINTR0 CLR.B (A4) SINGLE DENSITY RTS ************************************** * STUP17 - SET UP 1772 TO GET IT READY * AND MAKE SURE DISK IS NOT WRITE PROTECTED ************************************** STUP17 DC DIREST SELECT DRIVE AND RESTORE IT MOVE.B STAREG,D1 GET FDC STATUS AND.B #$51,D1 CHECK NR, WP, SEEK, BUSY BNE.S CHEKNG IF ERROR RTS ELSE JUST RETURN CHEKNG BTST.B #6,D1 CHECK WRITE PROTECT BIT BNE.S CHEKWP IF WRITE PROTECTED LEA DERMSG(PC),A4 DC PSTRNG UNSPECIFIED ERROR MESSAGE BRA.S ABORT CHEKWP LEA WPMSG(PC),A4 DC PSTRNG DISK WRITE PROTECTED ABORT LEA NOTMSG(PC),A4 DC PSTRNG PRINT "ABORTING" MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST ************************************** * SETUP - SET UP A TRACK DATA TEMPLATE WHICH WILL * LATER BE FILLED IN WITH TRACK AND SECTOR DATA * AND PTRS FOR EACH ACTUAL TRACK * HAS TWO ENTRY POINTS: SETUP0 FOR TRACK 0, * AND SETUPD FOR DOUBLE DENSITY ************************************** SETUP0 MOVE.B TR0DEN(PC),D7 GET DENSITY OF TRACK 0 BNE.S SET0DD SET0DD IF DOUBLE DEN LEA TRDENS(PC),A2 ELSE ... CLR.B (A2) THIS TRACK IS SINGLE LEA SDTABL(PC),A2 POINT TO SINGLE DENSITY SETUP TABLE LEA SECTR0(PC),A5 MOVE.B (A2)+,(A5) NO OF SECTORS ON TRACK 0 LEA SECTRS(PC),A5 MOVE.B (A2)+,(A5) NO OF SECTORS ON OTHER TRACKS BRA.S SETUP1 THEN CONTINUE SET0DD LEA SECTR0(PC),A5 ON DD TRACK 0, SET NUMBER ... MOVE.B DDTABL(PC),(A5) ...OF SECT ON TRACK 0 FIRST SETUPD LEA TRDENS(PC),A2 MOVE.B #1,(A2) THIS TRACK IS DOUBLE LEA DDTABL(PC),A2 POINT TO DOUBLE DENSITY SETUP TABLE LEA SECTRS(PC),A5 LEA 1(A2),A2 LEAVE TRK 0 SECT UNCHANGED MOVE.B (A2)+,(A5) NO OF SECTORS ON REMAINING TRACKS SETUP1 LEA BUFFER(PC),A1 POINT TO BUFFER BSR.L PUTBNY PRE-INDEX GAP BSR.L PUTBNY SYNC BYTES BEFORE INDEX MARK BSR.L PUTBNY 3 BYTES OF C2 IN DD ONLY BSR.L PUTBNY INDEX MARK BSR.S PUTBNY DO GAP 1 LEA S1BEG(PC),A6 MOVE.L A1,(A6) SECTOR 1 BEGINNING MOVE.L #0,A0 PTR/COUNTER BSR.S PUTBNY SYNC BYTES BSR.S PUTBNY 3 BYTES OF A1 IN DD ONLY BSR.S PUTBNY ID ADDRESS MARK LEA TRKPTR(PC),A6 MOVE.L A0,(A6) A0-> TRACK NUMBER WITHIN GROSS SECTOR BSR.S PUTBNY TRACK BYTE BSR.S PUTBNY SIDE BYTE BSR.S PUTBNY SECTOR BYTE BSR.S PUTBNY SECTOR LENGTH BSR.S PUTBNY CRC BSR.S PUTBNY GAP 2 BSR.S PUTBNY SYNC BSR.S PUTBNY 3 BYTES OF A1 IN DD ONLY BSR.S PUTBNY DATA ADDRESS MARK LEA DATAPT(PC),A6 MOVE.L A0,(A6) A0-> TO DATA WITHIN GROSS SECTOR BSR.S PUTBNY 128 ZEROES IN SECTOR BSR.S PUTBNY PLUS 128 MORE = 256 BSR.S PUTBNY CRC BSR.S PUTBNY GAP 3 LEA PREIND(PC),A6 MOVE.B (A2)+,(A6)+ PRE-INDEX (END OF TRACK) INFO MOVE.B (A2)+,(A6) LEA INTADR(PC),A6 MOVE.L A2,(A6) INTERLEAVE TABLE ADDRESS LEA GRSIZE(PC),A6 MOVE.W A0,(A6) SIZE OF SECTOR * HAVING SETUP THE FIRST SECTOR, COPY IT INTO ALL THE * FOLLOWING SECTORS CLR.W D1 MOVE.B SECTRS(PC),D1 NUM OF SECT PER SIDE ON CURR TRK MOVE.W A0,D0 GROSS SIZE OF EACH SECTOR MULU D1,D0 TOTAL LENGTH OF ALL SECTORS ADD.L S1BEG(PC),D0 ADD TO BEG ADDR OF SECTOR 1 MOVE.L D0,A3 END OF BUFFER MOVE.L S1BEG(PC),A0 POINT TO BEGINNING OF SECTOR 1 SECOPY MOVE.B (A0)+,(A1)+ COPY A BYTE CMP.L A3,A1 FINISHED? BNE.S SECOPY NO, KEEP COPYING BSR.S PUTBNP BSR.S PUTBNP PRE-INDEX DATA LEA BUFEND(PC),A6 MOVE.L A1,(A6) REAL BUFFER END RTS EXIT WHEN ENTIRE TRACK IS SET UP ************************************** * PUTBNY & PUTBNP - PUT DATA INTO SECTOR BUFFER * HAS TWO ENTRY POINTS: * PUTBNY TAKES A AND B FROM (A2)+, AND PUTS * A BYTES OF B INTO (A1)+ * PUTBNP TAKES A AND B FROM PREIND * BOTH EXIT WITH A2 POINTING TO NEXT EMPTY BYTE ************************************** PUTBNP MOVE.B PREIND(PC),D0 COUNT MOVE.B PREIND+1(PC),D1 WHAT TO PUT BRA.S PUTAN2 THEN CONTINUE PUTBNY MOVE.B (A2)+,D0 COUNT A MOVE.B (A2)+,D1 WHAT TO PUT IN B TST.B D0 CHECK COUNT BEQ.S PUTRTS DO NOTHING IF 0 PUTAN2 MOVE.B D1,(A1)+ PUT IN THE BYTE ADD.L #1,A0 INCREMENT A0 SUB.B #1,D0 DECR COUNTER BNE.S PUTAN2 REPEAT UNTIL DONE PUTRTS RTS THEN RETURN ************************************** * FORMAT FOR 1772 - GO FILL IN DATA INTO TRACK TEMPLATE AND WRITE IT ************************************** * FOR TRACK = 0 TO TRACKS-1 FORMAT LEA FORMSG(PC),A4 >>D<< DC PSTRNG PRINT "FORMATTING" >>D<< LEA TRACK(PC),A6 >>D<< CLR.B (A6) START WITH TRACK 0 LEA TRCHAR(PC),A4 MOVE.B #$30,(A4) INDICATOR STARTS WITH ASCII 0 * DO TRACK TRLOOP MOVE.B TRCHAR(PC),D4 DC PUTCH PRINT TRACK INDICATOR DIGIT LEA TRCHAR(PC),A4 ADD.B #1,(A4) INCREMENT IT MOVE.B (A4),D7 CHECK IT CMP.B #$39,D7 PAST 9? BLS.S FORSID NO, STILL OK MOVE.B #$30,(A4) YES, CHANGE BACK TO 0 * FOR SIDE = 0 TO SIDES FORSID LEA SIDE(PC),A6 CLR.B (A6) CLEAR SIDE * DO SIDE SILOOP BSR.S FMTMEM FORMAT MEMORY FOR TRACK BSR.L WRITRK GO WRITE THE TRACK ONTO DISK * NEXT SIDE LEA SIDE(PC),A6 ADD.B #1,(A6) GO TO NEXT SIDE MOVE.B (A6),D0 CMP.B SIDES(PC),D0 CHECK IT BLS.S SILOOP REPEAT FOR SECOND SIDE * NEXT TRACK LEA TRACK(PC),A6 ADD.B #1,(A6) INCREMENT TRACK MOVE.B DIDENS(PC),D0 CHECK DISK DENSITY CMP.B TRDENS(PC),D0 COMP WITH CURRENT TRACK BEQ.S DENSOK IF SAME BSR.L SETUPD ELSE SWITCH FOR DOUBLE IF DIFFERENT DENSOK MOVE.B TRACK(PC),D0 GET TRACK NUMBER CMP.B TRACKS(PC),D0 CHECK FOR MAXIMUM TRACK BNE.S TRLOOP REPEAT UNTIL DONE RTS THEN EXIT ************************************** * FMTMEM FILL IN TRACK AND SECTOR DATA IN TEMPLATE ************************************** FMTMEM MOVE.L S1BEG(PC),A0 POINT TO FIRST SECTOR MOVE.L INTADR(PC),A1 POINT TO INTERLEAVE TABLE SUB.L #1,A1 ACTUALLY, JUST BEFORE IT LEA PHYSEC(PC),A6 MOVE.B #1,(A6) PHYSICAL SECTOR NUMBER FMTSEC MOVE.B TRACK(PC),D0 MOVE.L TRKPTR(PC),D1 WHERE TO PUT TRACK NUMBER MOVE.B D0,0(A0,D1) PUT IN TRACK NUMBER MOVE.B SIDE(PC),1(A0,D1) PUT IN SIDE NUMBER NEXT MOVE.L DATAPT(PC),D2 WHERE TO PUT LINK TO NEXT TRACK MOVE.B D0,0(A0,D2) TEMP ASSUME LINK TO CURRENT TRACK CLR.L D3 WE'RE GOING TO USE D3.W! MOVE.B PHYSEC(PC),D3 GET PHYSICAL SECTOR NUMBER MOVE.B 0(A1,D3),D0 GET LOGICAL SECTOR NUMBER MOVE.B SIDE(PC),D7 WHICH SIDE? BEQ.S SIDE0 OK IF FIRST SIDE ADD.B SECTRS(PC),D0 ON SECOND SIDE CHANGE SECTOR NUMBER SIDE0 MOVE.B D0,2(A0,D1) PUT IN SECTOR NUMBER ADD.B #01,D0 PTR TO NEXT SECTOR MOVE.B D0,1(A0,D2) TEMP ASSUME LINK IS TO NEXT SECTOR * NOW CHECK IF AT END OF CYLINDER MOVE.B SECTRS(PC),D3 SECTORS PER SIDE MOVE.B SIDES(PC),D7 IS DISK TWO SIDED? BEQ.S FMT1SI NO, JUST ONE ASL.B #1,D3 DOUBLE FOR TWO SIDES FMT1SI CMP.B D0,D3 CHECK AGAINST CURRENT SECTOR PTR BCC.S FMTSOK OK IF CURRENT LOWER OR SAME * LINK POINTS PAST CYLINDER, SO CHANGE IT FMTSNG MOVE.B #1,1(A0,D2) GO TO SEC 1 ON NEXT TRACK ADD.B #1,0(A0,D2) AND TEMP STEP TO NEXT TRACK MOVE.B 0(A0,D2),D0 NOW GET NEXT TRACK CMP.B TRACKS(PC),D0 CHECK IF PAST LAST TRACK BCS.S FMTSOK IF STILL NOT DONE CLR.B 0(A0,D2) ELSE PUT IN A PTR OF 00-00 CLR.B 1(A0,D2) FMTSOK CLR.L D1 MOVE.W GRSIZE(PC),D1 GROSS SIZE OF SECTOR ADD.L D1,A0 STEP TO NEXT SECTOR'S DATA LEA PHYSEC(PC),A6 ADD.B #1,(A6) GO TO NEXT PHYSICAL SECTOR MOVE.B (A6),D1 LOOK AT IT CMP.B SECTRS(PC),D1 CHECK W MAX NUMBER OF SECTORS ON 1 SIDE BLS.L FMTSEC REPEAT UNTIL ALL SECTORS ARE DONE RTS THEN RETURN ************************************** * WRITRK - WRITE AN ENTIRE TRACK TO DISK ************************************** WRITRK MOVE.B SIDE(PC),D7 SIDE A OR B? BNE.S DISINT SIDE B, SKIP SEEK BSR.L DSEEK SIDE A, SEEK TO NEW TRACK BNE.L ABORT ON ERROR * AT THIS POINT, WE WANT TO TURN OFF INTERRUPTS DISINT DC INTDIS CALL DOS TO TURN OFF INTERRUPTS * ACTUAL LOOP TO WRITE A TRACK LEA BUFFER(PC),A5 POINT TO BUFFER LEA STAREG,A6 POINT TO STATUS REGISTER LEA DATREG,A4 POINT TO DATA REGISTER MOVE.B SIDE(PC),D0 GET SIDE NUMBER LSL.B #6,D0 CVT SIDE B INTO A $40 ADD.B MLATCH(PC),D0 COMBINE WITH DENSITY AND DRIVE MOVE.B D0,DLATCH GIVE TO DISK LATCH MOVE.B #$F4,COMREG WRITE TRACK COMMAND BSR.L WAITF WAIT FOR COMREG TO SETTLE WRITS1 MOVE.B (A6),D6 GET FDC STATUS BTST.B #1,D6 DRQ? BNE.S WRITS2 YES, GO GIVE IT BTST.B #0,D6 BUSY? BNE.S WRITS1 YES, WAIT SOME MORE BRA.S WRITEX NO, FINISH UP WRITS2 MOVE.B (A5)+,(A4) WRITE DATA BYTE BRA.S WRITS1 KEEP GOING >>B<< WRITEX DC INTENA CALL DOS TO ENABLE INTERRUPTS BSR.S WABUSY WAIT AS LONG AS FDC IS BUSY RTS AND EXIT ************************************** * WAITF - WAIT FOR COMREG TO SETTLE - SHOULD BE ABOUT 28 OR 56 * USEC, DEPENDING ON SYSTEM ************************************** WAITF MOVE.B #32,D7 >>C<< >>I<< WAITF1 SUB.B #1,D7 BNE.S WAITF1 RTS ************************************** * WABUSY - WAIT WHILE FDC IS BUSY ************************************** WABUSY MOVE.B STAREG,D6 GET FDC STATUS BTST.B #0,D6 CHECK BUSY BIT BNE.S WABUSY WAIT WHILE STILL BUSY RTS THEN EXIT ************************************** * DSEEK - SEEK TO NEW TRACK AND SECTOR * THIS ROUTINE IS VERY SIMILAR TO THAT * IN THE BIOS ************************************** * * CALLED BY: WRITRK * INPUT: PHYDRV HAS F NUMBER, * CTDRNO HAS NUMBER OF DRIVE ON ITS CONTROLLER * TRACK(PC) HAS TRACK NUMBER * OUTPUT: RETURN ZERO IF NO ERROR; * ELSE D6 CONTAINS ANY FDC ERROR CODE DSEEK MOVE.B CTDRNO(PC),D6 GET DRIVE NUMBER * ADD.B #1,D6 CONVERT INTO DRIVE CODE >>B1<< MOVE.B TRACK(PC),D7 CHECK TRACK NUMBER BNE.S DSEEK1 CONTINUE IF NOT TRK 0 MOVE.B TR0DEN(PC),D7 ON TRK 0 CHECK ITS DENSITY BEQ.S DSEEK3 IF SINGLE DENSITY BRA.S DSEEK2 IF DOUBLE DENSITY DSEEK1 MOVE.B DIDENS(PC),D7 CHECK DENSITY BEQ.S DSEEK3 IF SINGLE DENSITY DSEEK2 OR.B #$20,D6 ELSE ADD DOUBLE DENSITY BIT DSEEK3 CMP.B MLATCH(PC),D6 CHECK IF SAME AS BEFORE BEQ.S NOD2 YES, LEAVE AS IS MOVE.B D6,DLATCH SELECT DRIVE, DENSITY (NO SIDE YET) LEA MLATCH(PC),A6 MOVE.B D6,(A6) SAVE MEMORY NOD2 MOVE.B TRACK(PC),D5 CMP.B TRKREG,D5 ALREADY ON DESIRED TRACK? BEQ.S ONTRK YES, WAIT AND EXIT MOVE.B D5,DATREG AND GIVE NEW TRACK TO FDC BSR WAIT * FOLLOWING IS 11 FOR 1772, 13 FOR OTHER WESTERN DIGITAL FDC'S MOVE.B #$11,COMREG SEEK COMMAND, SLOW (FOR 1772) MOVE.L #DLATCH,A2 (WNBUSY WANTS THIS) BSR WNBUSY WAIT FOR COMPLETION AND.B #$18,D0 CHECK NR,SK,CRC ERRORS RTS ONTRK BSR WAIT WAIT FOR COMPLETION MOVE.L #0,D0 IF NO ERROR RTS *********************************************************** * CHKS17 CHECK ALL SECTORS TO REMOVE DEFECTIVE ONES * TOTALLY REWRITTEN IN >>D<< TO VERIFY FORWARD CHKS17 LEA VERMSG(PC),A4 DC PSTRNG PRINT "VERIFYING" MOVE.B #'0',D4 DC PUTCH PRINT "0" MOVE.L A6,A4 POINT TO FCB MOVE.B LOGDRV(PC),FCBDRV(A4) LOGICAL DRIVE NUMBER MOVE.W #$0001,FCBCTR(A4) TR 0 SEC 1 DC SREAD READ IT BNE.L SYSERR FATAL ERROR MOVE.W #$0002,FCBCTR(A4) SEC 2 DC SREAD BNE.L SYSERR MOVE.W #$0003,FCBCTR(A4) SEC 3 DC SREAD BNE.L SYSERR MOVE.W #$0004,FCBCTR(A4) SEC 4 DC SREAD BNE.L SYSERR MOVE.W #$0005,FCBCTR(A4) SEC 5 DC SREAD CHECK IT BNE.L SYSERR MOVE.W #$0006,FCBCTR(A4) SEC 6 DC SREAD BNE.L SYSERR * NOW CHECK REST OF TRACK 0 MOVE.W #$0007,D3 NEXT DO TR 0 SEC 7 MOVE.W #$0006,D2 LAST GOOD MOVE.B TR0DEN(PC),D0 0=SD, $12=DD BNE.S T0ISDD IF DD MOVE.B #10,D0 ELSE USE 10 IF SD T0ISDD MOVE.B SIDES(PC),D7 DOUBLE SIDED? BEQ.S T0LOOP NO, USE AS IS ASL.B #1,D0 YES, DOUBLE THE NUMBER T0LOOP MOVE.W D3,FCBCTR(A4) DC SREAD READ NEXT DIR SECTOR BEQ.S RDIROK IF OK LEA BDSMSG(PC),A4 PRINT "DEFECTIVE SECTOR AT" DC PSTRNG CLR.L D4 MOVE.B FCBCTR(A6),D4 TRACK NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT TRACK NUMBER MOVE.B #$2D,D4 DC PUTCH OUTPUT DASH CLR.L D4 MOVE.B FCBCSE(A6),D4 SECTOR NUMBER CLR.L D5 CLRB SUPPRESS SPACES DC OUT5D OUTPUT SECTOR NUMBER DC PCRLF MOVE.B #'0',D4 DC PUTCH PRINT "0" AGAIN MOVE.L A6,A4 POINT BACK TO FCB CMP.B D0,D3 AT END? BCS.S MORE0 IF THERE'S MORE ON 0 MOVE.W #$0101,D3 ELSE POINT OFF TRACK 0 MORE0 MOVE.W D3,FCBDAT(A4) PUT IN POINTER MOVE.W D2,FCBCTR(A4) INTO LAST GOOD SECTOR DC SWRITE REWRITE OLD SECTOR BNE.L SYSERR ABORT IF ERROR CMP.W #$0101,D3 PAST END? BEQ.S CHREST YES BRA.S T0LOOP NO, CONTINUE RDIROK MOVE.W D3,D2 IF OK, LAST GOOD = CURRENT ADD.B #1,D3 TO NEXT SECTOR CMP.B D0,D3 END OF TRACK? BLS.S T0LOOP NO, CONTINUE * NOW CHECK REST OF DISK CHREST MOVE.B #'1',D4 ASCII TRACK INDICATOR DC PUTCH MOVE.B TRACKS(PC),D0 NUMBER OF TRACKS SUB.B #1,D0 LAST TRACK LSL.W #8,D0 INTO LEFT BYTE MOVE.B SECTRS(PC),D0 SECTORS MOVE.B SIDES(PC),D7 DOUBLE SIDED? BEQ.S CHKS1 NO, USE AS IS ASL.B #1,D0 YES, DOUBLE THE NUMBER CHKS1 MOVE.W #$0101,D2 LAST FREE = 0101 MOVE.W D2,FCBCTR(A4) DC SREAD READ IT BNE.L SYSERR ABORT IF 0101 NO GOOD MOVE.L #1,D1 COUNT 1 GOOD SECTOR MOVE.L DOSORG(A6),A0 POINT TO DOS ORG >>F<< MOVE.B #1,NRETRY(A0) SET UP FOR JUST 1 RETRY >>F<< LEA FIFREE(PC),A0 FIRST FREE MOVE.W D2,(A0) SAVE FIRST FREE MOVE.W #$0102,D3 NEXT CURRENT TDLOOP MOVE.W D3,FCBCTR(A4) MOVE.W D3,A1 TEMP SAVE IT ADD.L #1,D1 ASSUME IT'S OK DC SREAD NEXT SECTOR BEQ.S TDNEXT DO NEXT IF IT WAS OK SUB.L #1,D1 SUBTRACT IT FROM COUNT NEG.L D1 NEGATE COUNT TO SIGNAL ERROR MOVE.L D4,A3 TEMP SAVE TRACK INDICATOR LEA BDSMSG(PC),A4 PRINT "DEFECTIVE SECTOR AT" DC PSTRNG CLR.L D4 MOVE.B FCBCTR(A6),D4 TRACK NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT TRACK NUMBER MOVE.B #$2D,D4 DC PUTCH OUTPUT DASH CLR.L D4 MOVE.B FCBCSE(A6),D4 SECTOR NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT SECTOR NUMBER DC PCRLF MOVE.L A6,A4 POINT BACK TO FCB MOVE.L A3,D4 RESTORE TRACK INDICATOR * GO TO NEXT SECTOR TDNEXT ADD.B #1,D3 NEXT SECTOR CMP.B D0,D3 PAST END OF TRACK? BLS.S NOTFVE NO, SAME TRACK CLR.B D3 YES, RESET ADD.W #$0101,D3 SEC 1 ON NEXT TRACK CMP.W D0,D3 PAST LAST TRACK? BHI.S YESFVE YES, FINISHED VERIFYING ADD.B #01,D4 CMP.B #$39,D4 IS IT PAST 9? BLS.S NPAST9 NOT YET MOVE.B #$30,D4 YES, RESTORE TO 0 NPAST9 DC PUTCH NEXT TRACK INDICATOR BRA.S NOTFVE YESFVE CLR.L D3 YES, SO MARK US DONE NOTFVE TST.L D1 CHECK ERROR FLAG BPL.S TDISOK CONTINUE IF NO ERROR NEG.L D1 FIX ERROR FLAG MOVE.W D2,FCBCTR(A4) GO BACK TO REWRITE LAST GOOD MOVE.W D3,FCBDAT(A4) ...WITH POINTER TO HERE DC SWRITE BNE.L FATERR VERY BAD IF CAN'T DO SO >>F<< TST.L D3 DONE? BNE.S TDLOOP NO, SO TRY NEXT SECTOR TDISOK MOVE.W A1,D2 LAST FREE IS ONE WE JUST DID TST.L D3 DONE? BNE.L TDLOOP NO, SO TRY NEXT SECTOR LEA LAFREE(PC),A5 LAST FREE MOVE.W D2,(A5) LEA FREE(PC),A5 MOVE.W D1,(A5) NUMBER FREE RTS ********************************************* * DISK FORMAT TABLES - USED BY 1772 CODE ONLY ********************************************* SDTABL DC.B 10,10 SECTORS/TRACK (TRACK 0 AND OTHER TRACKS) DC.B 12,$FF PRE-INDEX GAP DC.B 6,0 SYNC BYTES BEFORE INDEX MARK DC.B 0,0 NOT USED IN SINGLE DENSITY DC.B 1,$FC INDEX MARK DC.B 8,$FF GAP 1 (POST INDEX) DC.B 6,0 SYNC BYTES BEFORE ID FIELD DC.B 0,0 NOT USED IN SINGLE DENSITY DC.B 1,$FE ID ADDRESS MARK DC.B 1,0 TRACK NUMBER BYTE DC.B 1,0 SIDE NUMBER BYTE DC.B 1,0 SECTOR NUMBER BYTE DC.B 1,1 SECTOR LENGTH (1=256 BYTES) DC.B 1,$F7 CRC DC.B 11,$FF GAP 2 DC.B 6,0 SYNC BYTES BEFORE DATA FIELD DC.B 0,0 NOT USED IN SINGLE DENSITY DC.B 1,$FB DATA ADDRESS MARK DC.B 128,0,128,0 128+128=256 BYTES OF DATA DC.B 1,$F7 CRC DC.B 14,$FF GAP 3 DC.B 75,$FF PRE-INDEX GAP SDILTB DC.B 10,1,4,7,2,5,8,3,6,9 INTERLEAVE TABLE >>C<< DDTABL DC.B 10,18 SECTORS/TRACK (TRACK 0 AND OTHER TRACKS) DC.B 24,$4E PRE-INDEX GAP DC.B 12,0 SYNC BYTES BEFORE INDEX MARK DC.B 3,$F6 C2 IN DOUBLE DENSITY ONLY DC.B 1,$FC INDEX MARK DC.B 16,$4E GAP 1 (POST INDEX) DC.B 12,0 SYNC BYTES BEFORE ID FIELD DC.B 3,$F5 A1 IN DOUBLE DENSITY ONLY DC.B 1,$FE ID ADDRESS MARK DC.B 1,0 TRACK NUMBER BYTE DC.B 1,0 SIDE NUMBER BYTE DC.B 1,0 SECTOR NUMBER BYTE DC.B 1,1 SECTOR LENGTH (1=256 BYTES) DC.B 1,$F7 CRC DC.B 22,$4E GAP 2 DC.B 12,0 SYNC BYTES BEFORE DATA FIELD DC.B 3,$F5 A1 IN DOUBLE DENSITY ONLY DC.B 1,$FB DATA ADDRESS MARK DC.B 128,0,128,0 128+128=256 BYTES OF DATA DC.B 1,$F7 CRC DC.B 16,$4E GAP 3 DC.B 168,$4E PRE-INDEX GAP DDILTB DC.B 1,7,13,2,8,14,3,9,15,4,10,16,5,11,17,6,12,18 INTERLEAVE TABLE >>C<< *-----------------------------------------------------------------------* * ROU3765 - ROUTINES FOR 37C65 CONTROLLER ONLY *-----------------------------------------------------------------------* *********************************************** * ASKALL - ASK FOR DISK TYPE IF 3765 CONTROLLER *********************************************** ASKALL CLR.L D7 MOVE.B DRTYPE(PC),D7 DRIVE TYPE BEQ.L DRNONG BETTER NOT BE 0! LSL #2,D7 X4 LEA DRTMSP(PC),A4 POINT TO DISK TYPE MESSAGE POINTER MOVE.L -4(A4,D7),D7 GET OFFSET TO MESSAGE LEA DTMSGB(PC),A4 POINT TO FIRST MESSAGE ADD.L D7,A4 ADD OFFSET TO IT DC PSTRNG PRINT IT MOVE.B -6(A4),D0 NUMBER OF ALLOWED CHOICES MOVE.L -4(A4),D7 TABLE OFFSET LEA TYPEB(PC),A4 POINT TO 1ST TABLE ENTRY LEA 0(A4,D7),A0 POINT TO ACTUAL TABLE ENTRY FOR DRIVE DC GETCH GET REPLY SUB.B #$30,D5 CVT FROM ASCII BEQ.S ASKALL DISALLOW ZERO CMP.B D5,D0 CHECK IF VALID BCS.S ASKALL ASK AGAIN IF INVALID AND.L #$F,D5 LSL.B #4,D5 X16 LEA -16(A0,D5),A0 POINT TO ACTUAL DISK TYPE ENTRY LEA DSKTPT(PC),A1 MOVE.L A0,(A1) SAVE IT MOVE.B DNTRKS(A0),D7 NUMBER OF TRACKS LEA TRACKS(PC),A4 MOVE.B D7,(A4) LEA SIDES(PC),A4 MOVE.B #1,(A4) DOUBLE-SIDED * CHECK DESIRED INTERLEAVE, AND COMPUTE INTERLEAVE TABLE MOVE.B INTERL(PC),D7 USER'S INTERLEAVE BNE.S USEINT USE HIS INTERLEAVE IF >0 MOVE.B #3,D7 ELSE DEFAULT TO 3 LEA INTERL(PC),A4 MOVE.B D7,(A4) SAVE INTERLEAVE USEINT LEA T0ILTAB-1(PC),A4 TRACK 0 INTERLEAVE TABLE CLR.L D0 TRACK 0 BSR.S SETINT COMPUTE INTERLEAVE FOR TRK 0 LEA TAILTAB-1(PC),A4 OTHER TRACK INTERLEAVE TABLE MOVE.B #1,D0 OTHER * AND FALL THROUGH TO DO FOR OTHER TRACKS SETINT MOVE.L DSKTPT(PC),A1 POINT TO DISK DATA TABLE MOVE.B D0SECT(A1,D0),D5 SECTORS/TRACK LEA SECTR0(PC),A2 MOVE.B D5,0(A2,D0) STORE SECTORS/TRACK CLR.L D7 MOVE.B INTERL(PC),D7 CHECK INTERLEAVE CMP.B D5,D7 COMPARE WITH NUMBER BCC INTLE3 INTERLEAVE ERROR IF >SECT * WHILE WE'RE AT IT, ALSO CALCULATE INTERLEAVE TABLE * FOR D6=1 TO D5 : T(D6)=0 : NEXT D6 MOVE.L #1,D6 IL3CLR CLR.B 0(A4,D6) ADD.B #1,D6 CMP.B D6,D5 BCC.S IL3CLR * D6=1 MOVE.B #1,D6 * D4=1-D7 MOVE.L #1,D4 SUB.B D7,D4 INIT SECTOR WILL BE 1 * D4=D4+D7 L3003 ADD.B D7,D4 NEXT SECTOR (INIT 1) * IF D4>D5 THEN D4=D4-D5 L3103 CMP.B D4,D5 BCC.S MILVO3 OK IF NEXT <= MAX SUB.B D5,D4 ELSE START AGAIN * IF T(D4)<>0 THEN D4=D4+1 : GOTO L3103 MILVO3 TST.B 0(A4,D4) BEQ.S MILV37 ADD.B #1,D4 BRA.S L3103 * T(D4)=D6 MILV37 MOVE.B D6,0(A4,D4) * D6=D6+1 : IF D6<=D5 THEN L3003 ADD.B #1,D6 CMP.B D6,D5 BCC.S L3003 RTS INTLE3 LEA ILEMSG(PC),A4 PRINT INTERLEAVE ERROR MSG DC PSTRNG MOVE.L DOSORG(A6),A2 POINT TO DOS ORG >>F<< MOVE.B #5,NRETRY(A2) RESTORE 5 RETRIES >>F<< DC WARMST DRTMSP DC.L DTMSGB-DTMSGB DC.L DTMSGC-DTMSGB POINTERS TO OFFSETS FOR 5 MSGS DC.L DTMSGD-DTMSGB DC.L DTMSGE-DTMSGB DC.L DTMSGF-DTMSGB EVEN DC.B 3 CHOICES DC.L TYPEB-TYPEB OFFSET DTMSGB DC.B 'For the 360K 40-track drive, you can format the following:' DC.B $0D,$0A DC.B ' 1. 40-track double-density disk' DC.B $0D,$0A DC.B ' 2. 40-track single-density disk' DC.B $0D,$0A DC.B ' 3. 40-track double-density disk, track 0 single density' DC.B $0D,$0A DC.B 'Choose 1, 2, or 3: ' DC.B $0D,$0A,4 EVEN DC.B 3 CHOICES DC.L TYPEC-TYPEB OFFSET DTMSGC DC.B 'For the 720K 80-track drive, you can format the following:' DC.B $0D,$0A DC.B ' 1. 80-track double-density disk' DC.B $0D,$0A DC.B ' 2. 40-track double-density disk (double-stepping)' DC.B $0D,$0A DC.B ' 3. 40-track single-density disk (double-stepping)' DC.B $0D,$0A DC.B 'Choose 1, 2, or 3: ' DC.B $0D,$0A,4 EVEN DC.B 3 CHOICES DC.L TYPED-TYPEB OFFSET DTMSGD DC.B 'For the 1.1 megabyte drive, you can format the following:' DC.B $0D,$0A DC.B ' 1. 80-track high-density disk' DC.B $0D,$0A DC.B ' 2. 80-track double-density disk' DC.B $0D,$0A DC.B ' 3. 40-track double-density disk (double-stepping)' DC.B $0D,$0A DC.B 'Choose 1, 2, or 3: ' DC.B $0D,$0A,4 EVEN DC.B 2 CHOICES DC.L TYPEE-TYPEB OFFSET DTMSGE DC.B 'For the 1.4 megabyte drive, you can format the following:' DC.B $0D,$0A DC.B ' 1. 80-track high-density disk' DC.B $0D,$0A DC.B ' 2. 80-track double-density disk' DC.B $0D,$0A DC.B 'Choose 1 or 2: ' DC.B 0,$0D,$0A,4 EVEN DC.B 3 CHOICES DC.L TYPEF-TYPEB DTMSGF DC.B 'For the 8-inch 77-track drive, you can format the following:' DC.B $0D,$0A DC.B ' 1. 77-track double-density disk' DC.B $0D,$0A DC.B ' 2. 77-track single-density disk' DC.B $0D,$0A DC.B ' 3. 77-track single-density disk (128-byte sectors)' DC.B $0D,$0A DC.B 'Choose 1, 2, or 3: ' DC.B 0,$0D,$0A,4 * STUP37 - SET UP 37C65 TO GET IT READY * FIRST, INITIALIZE THE CONTROLLER STUP37 MOVE.B #$34,D7 MOTORS ON, NO SOFT RESET: AT MODE ADD.B CTDRNO(PC),D7 ADD IN UNIT NUMBER MOVE.B D7,REGOPER BSR.L WAIT1S MOVE.B DBPS(A1),REGCONT SET CORRECT BPS RATE LEA COMMAND(PC),A6 MOVE.B #$03,(A6) SPECIFY COMMAND MOVE.B #$4F,1(A6) STEPRATE AND HEAD UNLOAD TIME MOVE.B #$7F,2(A6) HEAD LOAD=126, NON-DMA MODE MOVE.W #3,D5 THREE BYTES TO SEND MOVE.B #0,D4 DON'T TURN OFF IRQ BSR.L SENDIT SEND COMMAND TO 3765 RTS *********************************************************** * FORM37 - 37C65 FORMAT UTILITY *********************************************************** * FOR TRACK = 0 TO TRACKS-1 FORM37 LEA FORMSG(PC),A4 >>D<< DC PSTRNG PRINT "FORMATTING" >>D<< CLR.L D1 C = TRACK NUMBER CLR.L D0 0=TRK 0, 1=ELSEWHERE LEA TRCHAR(PC),A4 MOVE.B #$30,(A4) INDICATOR STARTS WITH ASCII 0 * DO TRACK T7LOOP MOVE.B TRCHAR(PC),D4 DC PUTCH PRINT TRACK INDICATOR DIGIT LEA TRCHAR(PC),A4 ADD.B #1,(A4) INCREMENT IT MOVE.B (A4),D7 CHECK IT CMP.B #$39,D7 PAST 9? BLS.S SEEK37 NO, STILL OK MOVE.B #$30,(A4) YES, CHANGE BACK TO 0 * SEEK TO THE DESIRED TRACK SEEK37 MOVE.B D1,D7 TEST TRACK NUMBER BEQ.S SEEKT0 OK IF TRACK 0 TST.B DDUBL(A1) DOUBLE-STEPPING? BEQ.S SEEKT0 NO LSL.B #1,D7 YES, DOUBLE IT SEEKT0 LEA COMMAND(PC),A6 MOVE.B D7,2(A6) THEN PUT INTO COMMAND BUFFER TST.B D7 STARTING AT TRACK 0? BNE.S SEEKGO NO, OK TO SEEK BSR.L RESTORE BNE.L CHEKNG EXIT IN ERROR * READY TO SEEK LEA COMMAND(PC),A6 SEEKGO MOVE.B #$0F,(A6) SEEK COMMAND MOVE.W #3,D5 THREE BYTES IN COMMAND MOVE.B #0,D4 DON'T TURN OFF IRQ BSR.L SENDIT SEND TO FDC BNE.L CHEKNG SOMETHING WRONG BSR.L SENSIN SENSE IRQ TO CLEAR MOVE.B D0SECT(A1,D0),D2 SECTORS PER TRACK LEA SECTRS(PC),A4 MOVE.B D2,(A4) STORE SECTORS FOR CHKSEC LATER LEA T0ILTAB(PC),A4 START WITH TRK 0 INTERLEAVE TST.B D1 CHECK TRACK NUMBER BEQ.S F37SID IF WE ARE DOING TRACK 0 LEA TAILTAB(PC),A4 ELSE POINT TO OTHER TABLE * FOR SIDE = 0 TO SIDES F37SID CLR.B D3 CLEAR SIDE * DO SIDE * PREPARE BUFFER, WRITE ONE TRACK S3LOOP MOVE.B #D0MF(A1,D0),D7 PICK UP APPROPRIATE MF BIT LSL.B #6,D7 INTO BIT 6 ADD.B #$0D,D7 INSERT FORMAT COMMAND LEA COMMAND(PC),A6 MOVE.B D7,(A6) FORMAT COMMAND MOVE.B D3,D7 SIDE 0 OR 1 LSL.B #2,D7 BIT 2 ADD.B CTDRNO(PC),D7 ADD UNIT NUMBER MOVE.B D7,1(A6) MOVE.B DN(A1),2(A6) N MOVE.B D2,3(A6) SC=SECTORS PER TRACK MOVE.B D0FGAP(A1,D0),4(A6) GPL GAP LENGTH MOVE.B #0,5(A6) FILL WITH ZEROES MOVE.W #6,D5 SIX BYTES TO SEND MOVE.B #1,D4 DO TURN OFF IRQ BSR.L SENDIT SEND TO FDC LEA REGSTAT,A2 POINT TO STATUS REG LEA REGDATA,A3 POINT TO DATA REGISTER MOVE.B (A5)+,D7 GET LAST BYTE OF COMMAND * LAST BYTE OF COMMAND HAS NOT BEEN SENT YET. IN THE MEANTIME, * SET UP THE LOOP TO DO EACH SECTOR IN THE TRACK * REGISTER USAGE (> MEANS ENTERING WITH): * >D0 = 0 ON TRACK 0, 1 ON OTHER TRACKS * >D1 = C = TRACK * >D2 = SECTORS PER TRACK ON THIS TRACK * >D3 = SIDE 0 OR 1 * >D4 = N - LENGTH CODE * D5 = SECTOR COUNTER * D6 = SECTOR OFFSET TO ADD FOR SIDE B * >D7 = LAST BYTE OF COMMAND * >A1 = POINTER TO DISK DATA * >A2 = POINTER TO REGSTAT * >A3 = POINTER TO REGDATA * >A4 = POINTER TO INTERLEAVE TABLE MOVE.L A4,A0 VARIABLE IL TABLE POINTER DC INTDIS DISABLE INTERRUPTS MOVE.B D2,D6 SUB.B D0SIDB(A1,D0),D6 SIDE B SECTOR OFFSET TO ADD TO IL LEA ST0(PC),A5 SET UP TEMPORARY BUFFER FOR CHRN MOVE.B D1,0(A5) C MOVE.B D3,1(A5) H BNE.S ISSIDB CLR.L D6 ISSIDB MOVE.B DN(A1),3(A5) N = LENGTH CODE MOVE.B #0,REGDATA SEND OUT LAST BYTE OF COMMAND BSR.L WAIT12 * TRACK FORMAT HAS BEEN STARTED; SUPPLY C H R N AS PROCESSOR ASKS FOR THEM FOMOVE LEA ST0(PC),A5 SET UP TEMPORARY BUFFER FOR CHRN MOVE.B (A0)+,D7 SECTOR NUMBER ADD.B D6,D7 ADD SECTOR OFFSET MOVE.B D7,2(A5) READY TO OUTPUT MOVE.W #4-1,D4 4 BYTES PER SECTOR FOMOV1 MOVE.B (A2),D7 STATUS REGISTER BPL.S FOMOV1 WAIT FOR RQM BTST #5,D7 CHECK IF STILL EXECUTING BEQ.S FODONE NO, SO FINISHED READING MOVE.B (A5)+,(A3) MOVE A BYTE DBRA D4,FOMOV1 OUTPUT 4 BYTES PER SECTOR BRA.S FOMOVE THEN DO NEXT 4 BYTES FODONE DC INTENA RESTORE INTERRUPTS LEA ST0(PC),A5 POINT TO RESULTS BUFFER FORESU BSR.L WAIT12 MOVE.B REGSTAT,D7 GET STATUS REGISTER AND.B #$C0,D7 LOOK AT DIO AND RQM ONLY CMP.B #$80,D7 10 MEANS WE'RE FINISHED BEQ.S FINRES CMP.B #$C0,D7 NEED 11 TO CONTINUE READING BNE.S FORESU MOVE.B REGDATA,(A5)+ BRA.S FORESU * FINISHED READING AND TRANSFERRING; CHECK FOR ERRORS FINRES MOVE.B ST0(PC),D7 CHECK STATUS REG 0 AND.B #$D8,D7 CHECK BITS 3,4,6,7 BEQ.L FOISOK * FOLLOWING FOUR LINES CORRECT FOR ANOTHER 37C65 BUG CMP.B #$40,D7 CHECK FOR NON-COMPLETION BNE.S FO7ERR MUST BE SOMETHING ELSE MOVE.B ST1(PC),D7 CMP.B #$80,D7 END OF CYLINDER? BOOBOO! BEQ.L FOISOK YES, NOT REALLY AN ERROR * CHECK FOR WRITE PROTECT ERROR? FO7ERR MOVE.B ST1(PC),D7 CHECK STATUS REG 1 BTST.B #1,D7 WRITE PROTECT ERROR? BNE.L CHEKWP WP ERROR * NEXT SIDE FOISOK ADD.B #1,D3 GO TO NEXT SIDE CMP.B SIDES(PC),D3 CHECK IT BLS.L S3LOOP REPEAT FOR SECOND SIDE * NEXT TRACK ADD.B #1,D1 INCREMENT TRACK CMP.B TRACKS(PC),D1 CHECK FOR MAXIMUM TRACK BNE.L T7LOOP REPEAT UNTIL DONE RTS THEN EXIT ********************************** * SENDIT ROUTINE: SEND (D5) BYTES TO 765 FROM COMMAND BUFFER * THE CALLING ROUTINE SETS D4=1 IF IT WANTS IRQ DISABLED, 0 IF NOT * IF D4=1, THEN SENDIT DOESN'T SEND THE VERY LAST BYTE OF * THE COMMAND, LETTING THE CALLING PROGRAM DO IT ********************************** SENDIT MOVE.W #$FFFF,D6 REPEAT MANY TIMES SEND10 MOVE.B REGSTAT,D7 BTST #7,D7 CHECK DRQ BIT BEQ.S SEND20 WAIT IF NOT READY BTST #6,D7 DIO MUST BE 0 FOR WRITE BEQ.S SEND40 OK MOVE.B REGDATA,D7 ELSE READ DATA TO CLEAR SEND20 BSR.L WAIT12 WAIT 12 MICROSECONDS SENDER DBRA D6,SEND10 MOVE.B #1,D7 BNE MEANS ERROR RTS SEND40 BTST #4,REGSTAT CHECK BUSY BIT BNE.S SENDER IF STILL BUSY, THEN REAL BAD MOVE.B REGSTAT,D7 AND.L #$0F,D7 CHECK 4 SEEK BITS BEQ.S SEND50 OK IF NONE BSR.L SENSIN EXECUTE SENSE INTERRUPT * PRESUMABLY 765 IS NOW READY FOR COMMAND, SO GO! AT THIS POINT, * D5 CONTAINS NUMBER OF BYTES TO SEND FROM COMMAND BUFFER SEND50 LEA COMMAND(PC),A5 POINT TO COMMAND BUFFER SUB.W #1,D5 SEND ALL BYTES, EXCEPT ... SUB.B D4,D5 OMIT LAST IF D4=1 SEND60 BSR.L WAITRQ WAIT FOR OK TO WRITE MOVE.B (A5)+,D7 MOVE.B D7,REGDATA OUTPUT A COMMAND DBRA D5,SEND60 REPEAT FOR ALL BUT LAST BSR.S WAITRQ WAIT FOR OK TO WRITE, RET BEQ SENDND BSR.S WAIT12 SENDEX RTS AND RETURN WITH BEQ ********************************** * RESTORE SUBROUTINE ********************************** RESTORE LEA COMMAND(PC),A6 MOVE.B #7,(A6) RESTORE COMMAND MOVE.B CTDRNO(PC),D7 DRIVE NO ON CONTROLLER MOVE.B D7,1(A6) PUT IN US ONLY MOVE.W #2,D5 TWO BYTES IN COMMAND MOVE.B #0,D4 DON'T TURN OFF IRQ BSR.L SENDIT SEND TO FDC BNE.S RESTNG SOMETHING WRONG BSR.L SENSIN SENSE IRQ TO CLEAR TST.B D7 CHECK PRESENT TRACK NO BNE.S RESTNG ERROR IF NOT 0 RTS RESTNG MOVE.B #1,D7 RETURN NON-ZERO ON ERROR RTS ********************************** * SENSE INTERRUPT COMMAND - TO CLEAR IRQ AFTER SEEK OR RESTORE * RETURNS STATUS REG 0 IN D6, CYLINDER IN 7 ********************************** SENSIN MOVE.W #$7FFF,D7 SENSIN1 SUB.W #1,D7 WAIT FOR BOOBOO BNE.S SENSIN1 MOVE.B #$08,REGDATA SENSE INTERRUPT STATUS CMD BSR.S WAITRQ MOVE.B REGDATA,D6 RETURN STATUS REG 0 CMP.B #$80,D6 INVALID OP CODE, ALL ELSE OK? BEQ.S SENSIN YES, REPEAT AGAIN BSR.S WAITRQ MOVE.B REGDATA,D7 GET CYLINDER NUMBER BTST #5,D6 SEEK END? BEQ.S SENSIN NO, SO WAIT SOME MORE RTS ********************************** * WAIT 12 MICROSECONDS TO KEEP 765 HAPPY ********************************** WAIT12 MOVE.B #50,D7 WAIT12A SUB.B #1,D7 BNE.S WAIT12A RTS ********************************** * WAIT FOR STATUS REG RQM REQUEST SIGNAL ********************************** WAITRQ BSR.S WAIT12 WAITRQ1 MOVE.B REGSTAT,D7 CHECK STATUS BPL.S WAITRQ1 WAIT FOR RQM=1 RTS ********************************** * WAIT 1 SECOND ROUTINE FOR MOTOR TO COME ON ********************************** WAIT1S MOVE.L #1000000,D7 WAIT0S SUB.L #1,D7 WAIT 1 SECOND FOR MOTOR BNE.S WAIT0S RTS *********************************************************** * CHKS37 CHECK ALL SECTORS TO REMOVE DEFECTIVE ONES * TOTALLY REWRITTEN IN >>D<< TO VERIFY FORWARD * 37C65 VERSION NEEDS TO DO MORE, SINCE IT DID * NOT PUT IN SECTOR LINKS, SO WE HAVE TO WRITE THOSE TOO. *********************************************************** CHKS37 LEA VERMSG(PC),A4 DC PSTRNG PRINT "VERIFYING" MOVE.B #'0',D4 DC PUTCH PRINT "0" MOVE.L A6,A4 POINT TO FCB * ZERO OUT SECTOR BUFFER IN PREPARATION FOR WRITING LINKS LEA FCBDAT(A4),A5 MOVE.W #512/4-1,D4 CHKZLO CLR.L (A5)+ ZERO OUT 4 BYTES DBRA D4,CHKZLO MOVE.B LOGDRV(PC),FCBDRV(A4) LOGICAL DRIVE NUMBER * FIRST, CHECK BEGINNING OF TRACK 0 MOVE.W #$0001,FCBCTR(A4) TR 0 SEC 1 DC SREAD READ IT BNE.L SYSERR FATAL ERROR MOVE.W #$0002,FCBCTR(A4) SEC 2 DC SREAD BNE.L SYSERR MOVE.W #$0003,FCBCTR(A4) SEC 3 DC SREAD BNE.L SYSERR MOVE.W #$0004,FCBCTR(A4) SEC 4 DC SREAD BNE.L SYSERR MOVE.W #$0005,FCBCTR(A4) SEC 5 MOVE.W #$0006,FCBDAT(A4) LINK TO SECTOR 00-06 DC SWRITE WRITE IT BNE.L SYSERR DC SREAD CHECK IT BNE.L SYSERR MOVE.W #$0006,FCBCTR(A4) SEC 6 MOVE.W #$0007,FCBDAT(A4) LINK TO SECTOR 00-07 DC SWRITE WRITE IT BNE.L SYSERR DC SREAD BNE.L SYSERR * NOW CHECK REST OF TRACK 0 MOVE.W #$0007,D3 NEXT DO TR 0 SEC 7 MOVE.W #$0006,D2 LAST GOOD MOVE.L DSKTPT(PC),A1 MOVE.B D0SECT(A1),D0 SECTORS ON TRACK 0 MOVE.B SIDES(PC),D7 DOUBLE SIDED? BEQ.S T3C128 NO, USE AS IS ASL.B #1,D0 YES, DOUBLE THE NUMBER T3C128 TST.B SEC128(A1) CHECK IF SPECIAL 128-BYTE DISK BEQ.S T3LOOP NO, OK TO PROCEED LSR.B #1,D0 YES, THERE ARE HALF AS MANY MOVEM.L A0-A0,-(A7) PUSH LEA FLG128(PC),A0 MOVE.B #$FF,(A0) SET 128-BYTE FLAG MOVEM.L (A7)+,A0-A0 T3LOOP MOVE.W D3,FCBCTR(A4) ADD.B #1,D3 NEXT SECTOR FOR POINTER MOVE.W D3,FCBDAT(A4) SUB.B #1,D3 RESTORE D3 DC SWRITE WRITE THE POINTER BNE.S T3SENG DC SREAD READ NEXT DIR SECTOR BEQ.S RDIRO3 IF OK T3SENG LEA BDSMSG(PC),A4 PRINT "DEFECTIVE SECTOR AT" DC PSTRNG CLR.L D4 MOVE.B FCBCTR(A6),D4 TRACK NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT TRACK NUMBER MOVE.B #'-',D4 DC PUTCH OUTPUT DASH CLR.L D4 MOVE.B FCBCSE(A6),D4 SECTOR NUMBER CLR.L D5 CLRB SUPPRESS SPACES DC OUT5D OUTPUT SECTOR NUMBER DC PCRLF MOVE.B #'0',D4 DC PUTCH PRINT "0" AGAIN MOVE.L A6,A4 POINT BACK TO FCB CMP.B D0,D3 AT END? BCS.S MORE03 IF THERE'S MORE ON 0 MOVE.W #$0000,D3 ELSE SIGNAL END OF TRACK MORE03 MOVE.W D3,FCBDAT(A4) PUT IN POINTER MOVE.W D2,FCBCTR(A4) INTO LAST GOOD SECTOR DC SWRITE REWRITE OLD SECTOR BNE.L SYSERR ABORT IF ERROR CMP.W #$0000,D3 PAST END? BEQ.S CHRES3 YES BRA.S T3LOOP NO, CONTINUE RDIRO3 MOVE.W D3,D2 IF OK, LAST GOOD = CURRENT ADD.B #1,D3 TO NEXT SECTOR CMP.B D0,D3 END OF TRACK? BLS.S T3LOOP NO, CONTINUE MOVE.W #0,FCBDAT(A4) ELSE CHANGE LAST POINTER DC SWRITE REWRITE OLD SECTOR BNE.L T3SENG IF ERROR * FORCE SREAD INTO DOUBLE-STEPPING IF REQUIRED MOVE.W #$0201,FCBCTR(A4) ASK TO READ TRACK 2 DC SREAD IGNORE ERRORS * NOW CHECK REST OF DISK, ONE TRACK AT A TIME CHRES3 MOVE.B #'1',D4 ASCII TRACK INDICATOR DC PUTCH MOVE.B TRACKS(PC),D0 NUMBER OF TRACKS SUB.B #1,D0 LAST TRACK LSL.W #8,D0 INTO LEFT BYTE MOVE.B SECTRS(PC),D0 SECTORS MOVE.B SIDES(PC),D7 DOUBLE SIDED? BEQ.S CHKS3A NO, USE AS IS LSL.B #1,D0 YES, DOUBLE THE NUMBER CHKS3A TST.B SEC128(A1) SPECIAL 128-BYTE SECTORS? BEQ.S CHKS3 NO, CONTINUE LSR.B #1,D0 YES, HALF AS MANY SCTRS CHKS3 MOVE.W #$0101,D2 LAST FREE = 0101 MOVE.W D2,FCBCTR(A4) MOVE.W #$0102,FCBDAT(A4) POINTER TO NEXT DC SWRITE WRITE POINTER BNE.L SYSERR ABORT IF 0101 IS NO GOOD DC SREAD READ IT BNE.L SYSERR ABORT IF 0101 NO GOOD MOVE.L #1,D1 COUNT 1 GOOD SECTOR MOVE.L DOSORG(A6),A0 POINT TO DOS ORG >>F<< MOVE.B #1,NRETRY(A0) SET UP FOR JUST 1 RETRY >>F<< LEA FIFREE(PC),A0 FIRST FREE MOVE.W D2,(A0) SAVE FIRST FREE MOVE.W #$0102,D3 NEXT CURRENT * START TRACK LOOP BY WRITING POINTERS TO ENTIRE TRACK, IGNORING ERRORS U4LOOP MOVE.W D3,A1 TEMP SAVE D3 T4LOOP MOVE.W D3,FCBCTR(A4) FIRST TR-SEC TO DO ADD.B #1,D3 BUMP SECTOR MOVE.W D3,FCBDAT(A4) POINTER TO NEXT CMP.B D0,D3 CHECK IF PTR POINTS PAST END BLS.S TDNOTL NO, OK TO USE AS IS ADD.B #1,FCBDAT(A4) YES, SO POINT TO NEXT TRACK MOVE.B #1,FCBDAT+1(A4) AND SECTOR 1 CMP.W FCBDAT(A4),D0 PAST LAST TRACK? BHI.S TDNOTL NO, OK TO USE AS IS MOVE.W #0,FCBDAT(A4) YES, SO END THE CHAIN TDNOTL DC SWRITE WRITE, IGNORE ERRORS CMP.B D0,D3 CHECK IF WE'RE PAST END OF TRACK BLS.S T4LOOP NO, SO GO BACK TO DO NEXT SECTOR MOVE.W A1,D3 RESTORE D3 POINTER * NOW FINALLY GO READ THE TRACK AND VERIFY T5LOOP MOVE.W D3,FCBCTR(A4) MOVE.W D3,A1 TEMP SAVE IT ADD.L #1,D1 ASSUME IT'S OK DC SREAD NEXT SECTOR BEQ.S TDNEX3 DO NEXT IF IT WAS OK SUB.L #1,D1 SUBTRACT IT FROM COUNT NEG.L D1 NEGATE COUNT TO SIGNAL ERROR MOVE.L D4,A3 TEMP SAVE TRACK INDICATOR LEA BDSMSG(PC),A4 PRINT "DEFECTIVE SECTOR AT" DC PSTRNG CLR.L D4 MOVE.B FCBCTR(A6),D4 TRACK NUMBER CLR.L D5 SUPPRESS SPACES DC OUT5D OUTPUT TRACK NUMBER MOVE.B #$2D,D4 DC PUTCH OUTPUT DASH CLR.L D4 MOVE.B FCBCSE(A6),D4 SECTOR NUMBER CLR.L D5 CLRB SUPPRESS SPACES DC OUT5D OUTPUT SECTOR NUMBER DC PCRLF MOVE.L A6,A4 POINT BACK TO FCB MOVE.L A3,D4 RESTORE TRACK INDICATOR * GO TO NEXT SECTOR TDNEX3 ADD.B #1,D3 NEXT SECTOR CMP.B D0,D3 PAST END OF TRACK? BLS.S NOTFV NO, SAME TRACK CLR.B D3 YES, RESET ADD.W #$0101,D3 SEC 1 ON NEXT TRACK CMP.W D0,D3 PAST LAST TRACK? BHI.S YESFV YES, FINISHED VERIFYING ADD.B #01,D4 CMP.B #$39,D4 IS IT PAST 9? BLS.S NPAS39 NOT YET MOVE.B #$30,D4 YES, RESTORE TO 0 NPAS39 DC PUTCH NEXT TRACK INDICATOR BRA.S NOTFV YESFV CLR.L D3 YES, SO MARK US DONE NOTFV TST.L D1 CHECK ERROR FLAG BPL.S TDISO3 CONTINUE IF NO ERROR NEG.L D1 FIX ERROR FLAG MOVE.W D2,FCBCTR(A4) GO BACK TO REWRITE LAST GOOD MOVE.W D3,FCBDAT(A4) ...WITH POINTER TO HERE DC SWRITE BNE.L FATERR VERY BAD IF CAN'T DO SO >>F<< TST.L D3 DONE? BNE.L T5LOOP NO, SO TRY NEXT SECTOR TDISO3 MOVE.W A1,D2 LAST FREE IS ONE WE JUST DID TST.L D3 DONE? BEQ.S TVFINI YES, VERIFICATION FINISHED CMP.B #$01,D3 ABOUT TO START A NEW TRACK? BEQ.L U4LOOP YES, SO PUT IN LINKS FIRST BRA.L T5LOOP NO, SO TRY NEXT SECTOR TVFINI LEA LAFREE(PC),A5 LAST FREE MOVE.W D2,(A5) LEA FREE(PC),A5 MOVE.W D1,(A5) NUMBER FREE RTS ******************************************************** * THE FOLLOWING SUPER-BOOT PROGRAM IS PUT ON * TRACK 0 SECTORS 1 AND 2 OF DISK - NEEDED ONLY FOR 1772 * SUPER-BOOT FOR PTA-2/4 COMPUTERS * POSITION-INDEPENDENT CODE FOR SK*DOS * (C) 1987 BY PETER A. STARK ******************************************************** BOOT BRA.S BOOT1 SBBUFF EQU *+$0200 SECTOR BUFFER GOES AFTER BOOT TYPE DC.B 'PT4' TYPE OF BOOT FIRSTS DC.B 0,0 FIRST TRACK-SECTOR OF DOS DIDENS DC.B 0 0=SD DISK; ELSE NUM OF SCTRS ON OTHER TRKS SECSID DC.B 10 SECTORS PER SIDE (DEFAULT 10 FOR SD) BOOT1 MOVE.L #DLATCH,A2 POINT A2 TO DLATCH LEA BOOT(PC),A4 POINT TO THIS BOOT MOVE.B #$20,(A2) FORCE DRIVE 0, DD, SIDE A * FOLLOWING IS 01 FOR 1772, 03 FOR OTHER WESTERN DIGITAL FDC'S >>A<< MOVE.B #$01,COMREG-DLATCH(A2) RESTORE, LOAD HEAD, SLOW STEP >>A<< CLR.B D4 DOUBLE-STEP FLAG BSR.L WNBUSY PAUSE AND WAIT FOR NOT BUSY LEA BOOT+256(PC),A3 ADDRESS OF 2ND 256 BYTES MOVE.W #$0002,SBBUFF-BOOT(A4) MAKE PTR TO TR 0 SEC 02 BSR.S GETSEC READ SECOND HALF OF SUPER BOOT BNE.S BOOT1 IMMEDIATELY RETRY ON ERROR MOVE.B DIDENS(PC),D0 CHECK DISK DENSITY BEQ.S DISKSD ZERO MEANS DISK IS SINGLE DENSITY MOVE.B D0,SECSID-BOOT(A4) ELSE UPDATE SECTORS PER SIDE DISKSD MOVE.B FIRSTS(PC),SBBUFF-BOOT(A4) FIRST TR-S IS NOW NEXT MOVE.B FIRSTS+1(PC),SBBUFF+1-BOOT(A4) BEQ.L LNKERR IF NOT LINKED CLR.L D3 CLEAR DATA POINTER MOVE.L #-1,A5 ERASE TRANSFER ADDRESS BRA.L MLOOP CONTINUE WITH MAIN LOOP * GET THE NEXT SECTOR GETSEC MOVE.W SBBUFF(PC),D7 GET NEXT TR-SEC BEQ.L DONE NEXT IS 00-00 SO END MOVE.B D7,SECREG-DLATCH(A2) GIVE SECTOR TO FDC CLR.B D5 ASSUME SIDE 0 CMP.B SECSID(PC),D7 COMPARE WITH SECTORS PER SIDE BLS.S SIDEA IF SIDE A MOVE.B #$40,D5 ELSE GET SIDE B BIT SIDEA ASR.W #8,D7 MOVE TRACK TO RIGHT BYTE CMP.B TRKREG-DLATCH(A2),D7 ALREADY ON RIGHT TRACK? BEQ.S TRKOK YES TST.B D4 CHECK IF WE'RE DOUBLE-STEPPING BEQ.S GOSEEK NO, SEEK NORMALLY MOVE.B TRKREG-DLATCH(A2),D0 LSL.B #1,D0 MAKE BELIEVE FDC ON TRACK * 2 MOVE.B D0,TRKREG-DLATCH(A2) LSL.B #1,D7 AND DESIRED TRACK IS ALSO * 2 GOSEEK MOVE.B D7,DATREG-DLATCH(A2) NO, GIVE TRACK TO FDC * FOLLOWING IS 11 FOR 1772, 13 FOR OTHER WESTERN DIGITAL FDC'S >>A<< MOVE.B #$11,COMREG-DLATCH(A2) SEEK, LOAD, SLOW STEP >>A<< BSR.S WNBUSY WAIT FOR COMPLETION TST.B D4 CHECK IF DOUBLE-STEPPING BEQ.S TRKOK IF NOT, THEN TRACK REG IS OK MOVE.B TRKREG-DLATCH(A2),D0 LSR.B #1,D0 ELSE UNFOOL FDC MOVE.B D0,TRKREG-DLATCH(A2) TRKOK MOVE.B #$20,D0 SWITCH TO DD ON DRIVE 0 * READ SECTOR ROUTINE * ASSUME INTERRUPTS ARE ALREADY OFF READ ADD.B D5,D0 COMBINE WITH SIDE BIT MOVE.B D0,(A2) SELECT DENSITY, SIDE, DR 0 LEA DATREG-DLATCH(A2),A0 POINT A0 TO DATA REG LEA STAREG-DLATCH(A2),A1 POINT A1 TO STATUS REG MOVE.B #$84,COMREG-DLATCH(A2) READ COMMAND BSR.S WAIT SDLOOP MOVE.B (A1),D0 CHECK STATUS BTST #1,D0 DRQ? BNE.S SDGETD YES, GET THE DATA BTST #0,D0 BUSY? BNE.S SDLOOP YES, WAIT FOR IT SDFINI BSR.S WNBUSY WAIT FOR READY AND.B #$1C,D0 RNF, CRC, LD ERRORS RTS AND QUIT SDGETD MOVE.B (A0),(A3)+ GET AND PUT DATA BRA.S SDLOOP REPEAT UNTIL DONE * WAIT LOOP TO STABILIZE COMMAND REGISTER. SHOULD BE * EITHER 28 OR 56 USED, DEPENDING ON SYSTEM, BUT IT * DOESN'T HURT TO MAKE IT LONGER, WHICH TAKES LESS CODE. WAIT CLR.B D7 WAIT1 SUB.B #1,D7 BNE.S WAIT1 RTS * WNBUSY - WAIT FOR NOT BUSY WNBUSY BSR.S WAIT MOVE.B STAREG-DLATCH(A2),D0 CHECK STATUS BTST.B #0,D0 CHECK BUSY FLAG BNE.S WNBUSY WAIT IF STILL BUSY RTS ELSE RETURN WITH B=STATUS **** PREVIOUS PART MUST BE ON FIRST SECTOR **** * MAIN READ LOOP MLOOP BSR.S GETBYT GET A BYTE CMP.B #2,D0 DATA FOLLOWS? BEQ.S R2DATA YES, GO READ IT CMP.B #3,D0 DATA FOLLOWS? BEQ.S R3DATA YES, GO READ IT CMP.B #$16,D0 ADDRESS FOLLOWS? BEQ.S R6ADDR YES, GO GET IT CMP.B #$17,D0 ADDRESS FOLLOWS? BEQ.S R7ADDR YES, GO GET IT BRA.S MLOOP ELSE REPEAT * GETBYT ROUTINE - GET NEXT BYTE FROM FILE GETBYT TST.B D3 CHECK DATA POINTER BNE.S GETBY1 OK TO CONTINUE IF NOT 0 LEA SBBUFF(PC),A3 READ INTO SBBUFF BSR.L GETSEC ELSE GET SECTOR BEQ.S BYTEOK IF NO ERROR BTST.B #4,D0 ON ERROR, CHECK IF RECORD NOT FOUND BEQ.L ERROR ANYTHING ELSE IS AN ERROR EOR.B #$FF,D4 COMPLEMENT DOUBLE FLAG * FOLLOWING IS 01 FOR 1772, 03 FOR OTHER WESTERN DIGITAL FDC'S >>A<< MOVE.B #$01,COMREG-DLATCH(A2) RESTORE, LOAD, SLOW >>A<< BSR.S WNBUSY WAIT FOR COMPLETION LEA SBBUFF(PC),A3 READ INTO SBBUFF BSR.L GETSEC AND TRY AGAIN BNE.S ERROR QUIT ON ANY ERRORS BYTEOK MOVE.B #4,D3 NEXT BYTE IS BYTE 4 GETBY1 LEA SBBUFF(PC),A0 POINT TO SECTOR BUFFER CLR.L D0 MOVE.B 0(A0,D3),D0 GET NEXT BYTE OF DATA ADD.B #1,D3 BUMP POINTER RTS RETURN WITH BYTE IN D0 * GETWRD - GET A PAIR OF BYTES INTO D0; USES D1 FOR TEMP GETWRD BSR.S GETBYT GET MSB BYTE MOVE.L D0,D1 SAVE IN D1 LSL.W #8,D1 MOVE INTO SECOND BYTE BSR.S GETBYT GET LSB BYTE ADD.W D1,D0 COMBINE INTO D0 RTS AND RETURN * R2DATA - READ DATA FROM SECTOR IN SHORT FORMAT R2DATA BSR.S GETWRD GET 2-BYTE LOAD ADDRESS MOVE.L D0,A6 MOVE INTO A6 BSR.S GETBYT GET COUNT R23DAT MOVE.L D0,D2 COUNTER RDMEM BSR.S GETBYT GET NEXT BYTE MOVE.B D0,(A6)+ SAVE IT SUB.W #01,D2 DECREMENT COUNTER BNE.S RDMEM REPEAT UNTIL DONE BRA.S MLOOP GO LOOK FOR MORE * R3DATA - READ DATA FROM SECTOR IN LONG FORMAT R3DATA BSR.S GETWRD GET LEFT BYTE OF ADDRESS SWAP D0 MOVE INTO LEFT HALF MOVE.L D0,A6 MOVE INTO A6 BSR.S GETWRD GET RIGHT HALF OF ADDRESS ADD.L A6,D0 >>H<< MOVE.L D0,A6 COMBINE WITH LEFT >>H<< BSR.S GETWRD GET COUNT BRA.S R23DAT REJOIN OTHER ROUTINE * R6ADDR - READ 16-BIT ADDRESS FROM SECTOR R6ADDR BSR.S GETWRD GO GET LOAD ADDRESS MOVE.L D0,A5 SAVE INTO A5 BRA.L MLOOP GO GET MORE * R7ADDR - READ 32-BIT ADDRESS FROM SECTOR R7ADDR BSR.S GETWRD GO GET MSB OF LOAD ADDRESS SWAP D0 MOVE INTO LEFT HALF MOVE.L D0,A5 SAVE INTO A5 BSR.S GETWRD GET LSB OF ADDRESS ADD.L A5,D0 >>H<< MOVE.L D0,A5 COMBINE WITH MSB >>H<< BRA.L MLOOP GO GET MORE * WHEN DONE, CHECK TRANSFER ADDR AND GO DO IF OK DONE ADD.L #8,A7 REMOVE TWO RETURN ADDRESSES FROM STACK CMP.L #-1,A5 VALID TRANSFER ADDRESS? BEQ.S ERROR NO JMP (A5) ELSE GO TO PROGRAM * ERROR ROUTINES LNKERR LEA LNKMSG(PC),A0 PRINT "DISK NOT LINKED" BRA.S PRINT ERROR LEA ERRMSG(PC),A0 PRINT "ERROR - TRY AGAIN?" PRINT MOVE.B (A0)+,D4 GET NEXT CHAR >>B<< CMP.B #4,D4 END OF STRING? BEQ.S QUIT JSR.L HOUTCH OUTPUT CHARACTER BRA.S PRINT QUIT JMP.L HCOLDS THEN RETURN TO HUMBUG LNKMSG DC.B $0D,$0A FCC 'DISK NOT LINKED ',4 ERRMSG DC.B $0D,$0A FCC 'ERROR - TRY AGAIN? ',4 * END OF SUPERBOOT PROGRAM * TRACK BUFFER BEGINS HERE BUFFER EQU * TRACK BUFFER END START