NAM FORMAT-DC4 OPT PAG PAG * FORMAT PROGRAM FOR STAR-DOS LEVEL I * SUPPORTS ONLY DC-4 - STYLE CONTROLLERS * COPYRIGHT (C) 1984 BY PETER A. STARK * FOR STAR-KITS SOFTWARE SYSTEMS CORP. * STAR-DOS EQUATES USRFCB EQU $C840 MONTH EQU $CC0E YEAR EQU $CC10 MEMEND EQU $CC2B MAXDRV EQU $CC5F WARMST EQU $CD03 GETCH EQU $CD15 PUTCH EQU $CD18 INLINE EQU $CD1B PSTRNG EQU $CD1E PCRLF EQU $CD24 GETNAM EQU $CD2D OUT5D EQU $CD39 OUT2H EQU $CD3C DECIN EQU $CD48 FCS EQU $D406 RESTOR EQU $DE09 DISK DRIVER - RESTORE DSEEK EQU $DE1B DISK DRIVER - SEEK DLATCH EQU $E014 DRIVE SELECT LATCH CMDREG EQU $E018 FDC COMMAND REGISTER STAREG EQU CMDREG FDC STATUS REGISTER TRKREG EQU $E019 FDC TRACK REGISTER SECREG EQU $E01A FDC SECTOR REGISTER DATREG EQU $E01B FDC DATA REGISTER ORG $0200 START BRA START1 VER FCB 1 VERSION START1 LDX MEMEND CHECK IF ENOUGH MEMORY EXISTS CMPX #$4000 MINIMUM 16K NEEDED BHS MEMEOK OK IF OVER 16K LDX #MEMMSG ELSE PRINT "NOT ENOUGH RAM" JSR PSTRNG JMP WARMST MEMEOK BSR GETDRV GO GET DRIVE NUMBER BSR ASKTRK GET NUMBER OF TRACKS TO FORMAT JSR ASKSID GET NUMBER OF SIDES JSR ASKDEN GET DENSITY JSR GETNAN GET NAME AND NUMBER JSR CHEKIT CHECK IF OK TO PROCEED JSR PCRLF LDA DRIVE GET DRIVE NUMBER STA DLATCH SELECT DRIVE LDA #$D0 STA CMDREG RESET FDC AND START MOTOR LDX #0 WAITM LEAX -1,X BNE WAITM JSR SETUPS SETUP BUFFER WITH SD TEMPLATE FOR TRACK 0 JSR FORMAT GO WRITE EVERY TRACK JSR CHKSEC GO CHECK ALL SECTORS JSR DOBOOT PUT ON BOOT JSR DOSIS DO SYSTEM INFO RECORD JSR DODIR DO DIRECTORY JSR REPORT REPORT ON RESULTS JMP WARMST AND QUIT * GET DRIVE NUMBER GETDRV JSR DECIN GET DRIVE NUMBER BCS DRNONG IF DRIVE NUMBER IS BAD TST B BNE DRNOK IF VALID NUMBER WAS FOUND DRNONG LDX #DRNMSG INVALID DRIVE NUMBER JSR PSTRNG JMP WARMST DRNOK TFR X,D CMPB MAXDRV CHECK VALID NUMBER BHI DRNONG INVALID IF >9 TST A BNE DRNONG MUST BE ZERO STB DRIVE SAVE NUMBER RTS * ASKTRK - GET NUMBER OF TRACKS DESIRED ASKTRK JSR PCRLF LDX #GTTMSG ASK FOR NUMBER OF TRACKS JSR PSTRNG JSR INLINE GET INPUT JSR DECIN GET NUMBER BCS ASKTRK ASK AGAIN IF NOTHING TFR X,D CMPD #2 CHECK NUMBER OF TRACKS BHS TRKSOK >1 SEEMS OK TRKSNG LDX #TNGMSG ELSE NUMBER OF TRACKS IS NG JSR PSTRNG BRA ASKTRK AND ASK AGAIN TRKSOK CMPD #80 BHI TRKSNG ABOVE 81 ALSO NG STB TRACKS STORE IT RTS AND RETURN * ASKSID - GET NUMBER OF SIDES ASKSID LDX #SIDMSG JSR PSTRNG PRINT "SINGLE OR DOUBLE SIDED?" JSR GETCH ANDA #$DF CVT TO UPPER CASE CMPA #'S S? BEQ SINSID SINGLE CMPA #'D D? BNE ASKSID IF INVALID LDA #1 DOUBLE SIDED STA SIDES RTS SINSID CLR SIDES SINGLE SIDED RTS * ASKDEN - GET DESIRED DENSITY ASKDEN LDX #DENMSG JSR PSTRNG PRINT "SINGLE OR DOUBLE DENSITY?" JSR GETCH ANDA #$DF CVT TO UPPER CASE CMPA #'S S? BEQ SINDEN SINGLE CMPA #'D D? BNE ASKDEN IF INVALID LDA #18 18 SEC/TR IN DOUBLE DENSITY STA DIDENS RTS SINDEN CLR DIDENS SINGLE DENSITY RTS * GETNAN - GET DISK NAME AND NUMBER GETNAN LDX #NAMMSG ASK FOR NAME JSR PSTRNG JSR INLINE GET THE NAME LDX #NAME-4 POINT BEFORE NAME JSR GETNAM GO GET THE NAME BCS GETNAN ASK AGAIN FOR A VALID NAME TST EXT CHECK EXTENSION BNE GETNUM EXTENSION IS OK LDA #'S LDB #'- STD EXT ELSE FORCE .S-D EXTENSION LDA #'D STA EXT+2 GETNUM LDX #NUMMSG ASK FOR NUMBER JSR PSTRNG JSR INLINE JSR DECIN GET THE NUMBER BCS GETNUM IF NO NUMBER STX NUMBER ELSE STORE IT RTS AND RETURN * CHEKIT - CHECK THAT USER REALLY WANTS TO FORMAT * AND MAKE SURE DISK IS NOT WRITE PROTECTED CHEKIT JSR PCRLF LDX #CHKMSG PRINT CHKMSG JSR PSTRNG LDA DRIVE ADDA #$30 CVT TO ASCII JSR PUTCH LDX #RUSMSG PRINT "ARE YOU SURE?" JSR PSTRNG JSR GETCH GET REPLY ANDA #$DF CVT TO UPPER CMPA #'Y BNE ABORT LDX #USRFCB LDA DRIVE STA 3,X PUT IN DRIVE NUMBER JSR RESTOR SELECT DRIVE AND RESTORE IT LDB STAREG GET FDC STATUS ANDB #$D1 CHECK NR, WP, SEEK, BUSY BNE CHEKNG IF ERROR RTS ELSE JUST RETURN CHEKNG BITB #$40 CHECK WRITE PROTECT BIT BNE CHEKWP IF WRITE PROTECTED LDX #DERMSG JSR PSTRNG UNSPECIFIED ERROR MESSAGE BRA ABORT CHEKWP LDX #WPMSG JSR PSTRNG DISK WRITE PROTECTED ABORT LDX #NOTMSG JSR PSTRNG PRINT "ABORTING" JMP WARMST * SETUP - SET UP A TRACK DATA TEMPLATE WHICH WILL * LATER BE FILLED IN WITH TRACK AND SECTOR DATA * AND POINTERS FOR EACH ACTUAL TRACK * HAS TWO ENTRY POINTS: SETUPS FOR SINGLE DENSITY, * AND SETUPD FOR DOUBLE DENSITY SETUPS CLR TRDENS THIS TRACK IS SINGLE LDU #SDTABL POINT TO SINGLE DENSITY SETUP TABLE LDD 0,U++ GET NUMBERS OF SECTORS STA SECTR0 NO OF SECTORS ON TRACK 0 STB SECTRS NO OF SECTORS ON OTHER TRACKS BRA SETUP1 THEN CONTINUE SETUPD INC TRDENS THIS TRACK IS DOUBLE LDU #DDTABL POINT TO DOUBLE DENSITY SETUP TABLE LDD 0,U++ GET NUMBERS OF SECTORS STB SECTRS NO OF SECTORS ON REMAINING TRACKS SETUP1 LDY #BUFFER POINT TO BUFFER LDD 0,U++ JSR PUTBNY PRE-INDEX GAP LDD 0,U++ JSR PUTBNY SYNC BYTES BEFORE INDEX MARK LDD 0,U++ JSR PUTBNY 3 BYTES OF C2 IN DD ONLY LDD 0,U++ JSR PUTBNY INDEX MARK LDD 0,U++ JSR PUTBNY DO GAP 1 STY S1BEG SECTOR 1 BEGINNING LDX #0 POINTER/COUNTER LDD 0,U++ JSR PUTBNY SYNC BYTES LDD 0,U++ BSR PUTBNY 3 BYTES OF A1 IN DD ONLY LDD 0,U++ BSR PUTBNY ID ADDRESS MARK STX TRKPTR X-> TRACK NUMBER WITHIN GROSS SECTOR LDD 0,U++ BSR PUTBNY TRACK BYTE LDD 0,U++ BSR PUTBNY DENSITY BYTE STX SECPTR X-> SEC NUMBER WITHIN GROSS SECTOR LDD 0,U++ BSR PUTBNY SECTOR BYTE LDD 0,U++ BSR PUTBNY SECTOR LENGTH LDD 0,U++ BSR PUTBNY CRC LDD 0,U++ BSR PUTBNY GAP 2 LDD 0,U++ BSR PUTBNY SYNC LDD 0,U++ BSR PUTBNY 3 BYTES OF A1 IN DD ONLY LDD 0,U++ BSR PUTBNY DATA ADDRESS MARK STX DATAPT X-> TO DATA WITHIN GROSS SECTOR LDD 0,U++ BSR PUTBNY 128 ZEROES IN SECTOR LDD 0,U++ BSR PUTBNY PLUS 128 MORE = 256 LDD 0,U++ BSR PUTBNY CRC LDD 0,U++ BSR PUTBNY GAP 3 LDD 0,U++ STD PREIND PRE-INDEX (END OF TRACK) INFO STU INTADR INTERLEAVE TABLE ADDRESS STX GRSIZE SIZE OF SECTOR * HAVING SETUP THE FIRST SECTOR, COPY IT INTO ALL THE * FOLLOWING SECTORS LDB SECTRS NUMBER OF SECTORS PER SIDE ON CURRENT TRACK CLRA EXTEND TO 16 BITS TFR D,X MOVE INTO X CLR A CLR B SECALC ADDD GRSIZE ADD SIZE LEAX -1,X DECREMENT COUNTER BNE SECALC ADDD S1BEG ADD TO BEGINNING OF SECTOR 1 STD BUFEND END OF BUFFER LDX S1BEG POINT TO BEGINNING OF SECTOR 1 SECOPY LDA 0,X+ STA 0,Y+ CMPY BUFEND FINISHED? BNE SECOPY NO, KEEP COPYING LDD PREIND ADD PRE-INDEX GAP BSR PUTBNY LDD PREIND BSR PUTBNY STY BUFEND REAL BUFFER END RTS FINALLY EXIT WHEN ENTIRE TRACK IS SET UP * PUTBNY - PUT C(B) INTO THE C(A) BYTES OF * MEMORY BEGINNING AT C(Y), EXIT WITH Y POINTING * TO FIRST EMPTY BYTE PUTBNY TST A BEQ PUTRTS DO NOTHING IF 0 PUTAN2 STB 0,Y+ PUT IN THE BYTE LEAX 1,X INCREMENT X DECA DECR COUNTER BNE PUTAN2 REPEAT UNTIL DONE PUTRTS RTS THEN RETURN * FORMAT - GO FILL IN DATA INTO TRACK TEMPLATE AND WRITE IT * FOR TRACK = 0 TO TRACKS-1 FORMAT CLR TRACK START WITH TRACK 0 LDA #'1 STA TRCHAR INDICATOR STARTS WITH A 1 * DO TRACK TRLOOP LDA TRACK LDB #1 TO FORCE SIDE A JSR DSEEK SEEK TO SECTOR (A) LDA TRCHAR JSR PUTCH PRINT TRACK INDICATOR DIGIT INC TRCHAR INCREMENT IT LDA TRCHAR CMPA #'9 PAST 9? BLS FORSID NO, STILL OK LDA #'0 YES, CHANGE BACK TO 0 STA TRCHAR * FOR SIDE = 0 TO SIDES FORSID CLR SIDE * DO SIDE SILOOP BSR FMTMEM FORMAT MEMORY FOR TRACK JSR WRITRK GO WRITE THE TRACK ONTO DISK * NEXT SIDE INC SIDE GO TO NEXT SIDE LDA SIDE CMPA SIDES CHECK IT BLS SILOOP REPEAT FOR SECOND SIDE * NEXT TRACK INC TRACK INCREMENT TRACK LDA DIDENS CHECK DISK DENSITY CMPA TRDENS CHECK WITH CURRENT TRACK BEQ DENSOK IF SAME JSR SETUPD ELSE SWITCH FOR DOUBLE IF DIFFERENT DENSOK LDA TRACK GET TRACK NUMBER CMPA TRACKS CHECK FOR MAXIMUM TRACK BNE TRLOOP REPEAT UNTIL DONE RTS THEN EXIT * FMTMEM FILL IN TRACK AND SECTOR DATA IN TEMPLATE FMTMEM LDX S1BEG POINT TO FIRST SECTOR LDY INTADR POINT TO INTERLEAVE TABLE LEAY -1,Y ACTUALLY, JUST BEFORE IT LDB #1 PHYSICAL SECTOR NUMBER STB PHYSEC FMTSEC LDA TRACK LDB TRKPTR+1 WHERE TO PUT TRACK NUMBER STA B,X PUT IN TRACK NUMBER LDB DATAPT+1 WHERE TO PUT LINK TO NEXT TRACK STA B,X TEMP ASSUME LINK TO CURRENT TRACK LDB PHYSEC GET PHYSICAL SECTOR NUMBER LDA B,Y GET LOGICAL SECTOR NUMBER TST SIDE WHICH SIDE? BEQ SIDE0 OK IF FIRST SIDE ADDA SECTRS ON SECOND SIDE CHANGE SECTOR NUMBER SIDE0 LDB SECPTR+1 WHERE TO PUT IT STA B,X PUT IN SECTOR NUMBER INCA POINTER TO NEXT LDB DATAPT+1 POINT TO DATA AREA INCB WHERE TO PUT LINK TO NEXT SECTOR STA B,X TEMP ASSUME LINK IS TO NEXT SECTOR * NOW CHECK IF AT END OF CYLINDER PSHS A TEMP SAVE LINK TO NEXT SECTOR LDA SECTRS SECTORS PER SIDE ASLA *2 GIVES LAST SECTOR ON SECOND SIDE CMPA 0,S CHECK AGAINST CURRENT SECTOR POINTER PULS A AND RESTORE LINK INTO A BLO FMTSNG CHANGE LINK IF PAST SIDE 2 DECA DECREMENT CURRENT LINK CMPA SECTRS DID LINK POINT JUST PAST SIDE 1? BNE FMTSOK NO, OK TO LEAVE AS IS TST SIDES YES, BUT IS DISK TWO-SIDED? BNE FMTSOK YES, SO LEAVE POINTING TO SIDE 2 * LINK POINTS PAST CYLINDER, SO CHANGE IT FMTSNG LDA #1 ELSE GO TO SEC 1 ON NEXT TRACK STA B,X TEMP PUT IT IN DECB POINT BACK TO TRACK LINK INC B,X AND TEMP STEP TO NEXT TRACK LDA B,X NOW GET NEXT TRACK CMPA TRACKS CHECK IF PAST LAST TRACK BLO FMTSOK IF STILL NOT DONE CLR B,X ELSE PUT IN A POINTER OF 00-00 INCB POINT TO SECTOR LINK CLR B,X FMTSOK LDD GRSIZE GROSS SIZE OF SECTOR LEAX D,X STEP TO NEXT SECTOR'S DATA INC PHYSEC GO TO NEXT PHYSICAL SECTOR LDB PHYSEC LOOK AT IT CMPB SECTRS CHECK WITH MAX NUMBER OF SECTORS ON 1 SIDE BLS FMTSEC REPEAT UNTIL ALL SECTORS ARE DONE RTS THEN RETURN * WRITRK - WRITE AN ENTIRE TRACK TO DISK WRITRK TST SIDE SIDE 1? BNE WRITE0 YES, SKIP WAIT JSR WABUSY NO, WAIT FOR FDC TO FINISH SEEK WRITE0 TST SIDES DOUBLE SIDED DISK? BEQ WRITE1 NO, DON'T SWITCH SIDE LDA SIDE YES, SELECT NEW SIDE ASLA ASLA ASLA SHIFT INTO SIDE SELECT BIT 6 ASLA ASLA ASLA ORA DRIVE ADD DRIVE BITS STA DLATCH SELECT DRIVE AND SIDE JSR WAIT WRITE1 PSHS CC SAVE CONDITIONS ORCC #$50 DISABLE INTERRUPTS TST TRDENS CHECK DENSITY OF CURRENT TRACK BNE WRITED GO DO DOUBLE DENSITY * ON SINGLE DENSITY WRITE: WRITES LDX #BUFFER POINT TO BUFFER LDA #$F4 WRITE TRACK COMMAND STA CMDREG START IT JSR WAIT WAIT FOR CMDREG TO SETTLE WRITS1 LDA STAREG GET FDC STATUS BITA #2 DRQ? BNE WRITS2 YES, GO GIVE IT BITA #1 BUSY? BNE WRITS1 YES, SO WAIT SOME MORE PULS CC RTS ELSE EXIT WHEN FINISHED WRITS2 LDA 0,X+ GET NEXT DATA BYTE STA DATREG GIVE TO FDC CMPX BUFEND FINISHED DATA? BNE WRITS1 NO, SO KEEP GOING BSR WABUSY WAIT AS LONG AS FDC IS BUSY PULS CC RTS AND EXIT * ON DOUBLE DENSITY: WRITED NOP NOP NOP LDD BUFEND SUBD #BUFFER LENGTH OF BUFFER TFR D,X X BECOMES A COUNTER LDY #BUFFER LDU #DLATCH POINT TO I/O LDA #$F6 WRITE TRACK COMMAND WITH DDEN STA CMDREG JSR WAIT WRITD1 LDA 0,Y+ GET NEXT BYTE WRITD2 LDB 0,U BMI WRITD3 STORE DATA ON DRQ BEQ WRITD2 ELSE WAIT FOR INTERRUPT LDA STAREG ON INTERRUPT, WE'RE DONE SO CLEAR IT PULS CC RESTORE INTERRUPTS RTS WRITD3 STA DATREG LEAX -1,X DECR COUNTER BNE WRITD1 DO MORE IF NOT DONE BSR WABUSY ELSE WAIT AS LONG AS FDC IS BUSY PULS CC RESTORE INTERRUPTS RTS AND EXIT * WABUSY - WAIT WHILE FDC IS BUSY WABUSY LDA STAREG GET FDC STATUS BITA #1 CHECK BUSY BIT BNE WABUSY WAIT WHILE STILL BUSY RTS THEN EXIT * CHKSEC CHECK ALL SECTORS TO REMOVE DEFECTIVE ONES CHKSEC LDX #USRFCB POINT TO FCB LDA DRIVE STA 3,X DRIVE NUMBER LDA TRACKS NUMBER OF TRACKS DECA LDB SECTRS NUMBER OF SECTORS ON ONE SIDE TST SIDES DOUBLE SIDED? BEQ CHKS1 NO, USE AS IS ASLB YES, DOUBLE THE NUMBER CHKS1 STD 30,X CURRENT TRACK & SEC NOS. STA CHFLAG LAST POINTER WAS OK MUL GET NUMBER OF FREE SECTORS TFR D,U AND INTO U LDY #0 LAST POINTER POINTS TO 00-00 STY FIFREE INITIALIZE FIRST FREE POINTER STY LAFREE INITIALIZE LAST FREE POINTER * LOOP TO GO BACKWARD THROUGH FREE CHAIN CHLOOP LDA #9 READY TO READ STA 0,X JSR FCS READ CURRENT SECTOR BEQ CHROK IF SECTOR READ OK * IF SECTOR COULDN'T BE READ, DELETE IT CHWRNG LEAU -1,U SUBTRACT 1 FROM FREE CLR CHFLAG AND MARK IT DEFECTIVE PSHS X,D SAVE X AND MAKE ROOM LDX #BDSMSG PRINT "DEFECTIVE SECTOR AT" JSR PSTRNG CLR 0,S MSB=0 LDA USRFCB+30 TRACK NUMBER STA 1,S PUT ON STACK TFR S,X POINT TO IT CLRB SUPPRESS SPACES JSR OUT5D OUTPUT TRACK NUMBER LDA #'- JSR PUTCH OUTPUT DASH LDA USRFCB+31 SECTOR NUMBER STA 1,S TFR S,X POINT TO IT CLRB SUPPRESS SPACES JSR OUT5D OUTPUT SECTOR NUMBER JSR PCRLF LDB USRFCB+30 CHECK CURRENT TRACK INCB SO TRACK 0 IS A 1 LDA #'1 ASCII 1 TRPLOO BEQ TRKPFI FINISHED WHEN ON TRACK 0 JSR PUTCH INCA CMPA #'9 IS IT PAST 9? BLS NPAST9 NOT YET LDA #'0 YES, RESTORE TO 0 NPAST9 DECB DECREMENT TRACK COUNTER BRA TRPLOO AND REPEAT TRKPFI PULS D,X RESTORE REGISTERS BRA CHNEXT AND THEN CONTINUE * SECTOR READ WAS OK CHROK LDD LAFREE CHECK LAST FREE BNE CHROK1 NON-ZERO MEANS THIS IS NOT LAST LDD 30,X ELSE GET CURRENT TRACK-SECTOR STD LAFREE SAVE AS LAST FREE CHROK1 TST CHFLAG WAS PREVIOUS OK TOO? BEQ CHPRNG NO, SO UPDATE POINTER LDY 30,X SAVE CURRENT TRACK-SECTOR BRA CHNEXT AND GO TO NEXT SECTOR * THIS SECTOR OK, BUT PREVIOUS ONE OR MORE NG CHPRNG STY 64,X PUT NEW POINTER INTO SECTOR LDA #10 STA 0,X READY TO WRITE BACK JSR FCS WRITE SECTOR BACK BNE CHWRNG WRITE WAS NG, SAME AS A NG READ LDY 30,X SAVE CURRENT TRACK-SECTOR INC CHFLAG MARK THIS SECTOR AS OK * THEN STEP TO NEXT PREVIOUS SECTOR CHNEXT LDD 30,X GET CURRENT TRACK-SECTOR DECB STEP BACK ONE SECTOR BNE CHNEX1 OK IF NOT ZERO PSHS A IF 0, SAVE CURRENT TRACK NO AND GO BACK A TRACK LDA #$08 ON NEW TRACK ERASE TRACK INDICATOR DIGIT JSR PUTCH LDA #$20 JSR PUTCH LDA #$08 JSR PUTCH LDB SECTRS LAST SECTOR ON PREVIOUS TRACK TST SIDES TWO-SIDED DISK? BEQ CHNEX0 NO, USE AS IS ASLB YES, DOUBLE IT CHNEX0 PULS A CURRENT TRACK DECA GO BACK ONE CMPA #$FF FINISHED TRACK 0? BEQ CHFINI YES, FINISHED DISK TSTA ENTERING TRACK 0? BNE CHNEX1 NO, OK TO CONTINUE STY FIFREE YES, SAVE PREVIOUS TRACK-SECTOR AS FIRST FREE STU FREE SAVE NUMBER OF FREE SECTORS LDB SECTR0 SECTORS ON TRACK 0 TST SIDES DOUBLE-SIDED? BEQ CHNEX1 NO, USE AS IS ASLB YES, DOUBLE IT STB SECTR0 SAVE CORRECT NUMBER FOR TRACK 0 CHNEX1 STD 30,X NEW CURRENT TRACK-SECTOR JMP CHLOOP AND REPEAT AGAIN * FINISHED WHEN WE REACH TRACK 0 CHFINI RTS AND RETURN * DOBOOT - PUT BOOT ON DISK TR 0 SEC 1 AND 2 DOBOOT LDX #BOOT POINT TO SUPER BOOT'S FIRST SECTOR LDY #USRFCB+64 AND FCB CLRB COUNTER DOBOO1 LDA 0,X+ GET BYTE STA 0,Y+ PUT IT IN DECB DECR COUNTER BNE DOBOO1 REPEAT 256 TIMES LDX #USRFCB POINT TO FCB LDA #10 STA 0,X WRITE CODE LDD #0001 STD 30,X TR 0 SEC 1 JSR FCS GO WRITE IT BNE SYSERR ERROR PUTTING BOOT THERE LDX #BOOT+256 POINT TO SUPER BOOT'S SECOND SECTOR LDY #USRFCB+64 AND FCB CLRB COUNTER DOBOO2 LDA 0,X+ GET BYTE STA 0,Y+ PUT IT IN DECB DECR COUNTER BNE DOBOO2 REPEAT 256 TIMES LDX #USRFCB POINT TO FCB LDB #02 STB 31,X TR 0 SEC 2 JSR FCS GO WRITE IT BNE SYSERR ERROR PUTTING BOOT THERE RTS ELSE RETURN * SYSERR - SYSTEM ERROR ON TRACK 0 SYSERR LDX #TR0MSG PRINT "ERROR ON TRACK 0" JSR PSTRNG JMP WARMST AND STOP * DOSIS - WRITE SIS TO DISK DOSIS LDX #USRFCB LDA #10 STA 0,X WRITE SECTOR CODE LDD #$0003 TRACK 0 SEC 3 STD 30,X SAVE INTO FCB LEAY 64,X POINT Y TO DATA AREA CLR B COUNTER ERASIS CLR 0,Y+ ERASE NEXT DECB DECR COUNTER BNE ERASIS ERASE 256 BYTES LDD FIFREE FIRST FREE STD 93,X LDD LAFREE LAST FREE STD 95,X LDD FREE NUMBER FREE STD 97,X LDD MONTH MONTH AND DAY STD 99,X LDA YEAR YEAR STA 101,X LDA TRACKS NUMBER OF TRACKS DECA STARTS WITH 0 LDB SECTRS NUMBER OF SECTORS ON ONE SIDE TST SIDES HOW MANY SIDES? BEQ SISLAS USE AS IS IF SS ASLB ELSE *2 FOR DS SISLAS STD 102,X LDY #NAME POINT TO NAME LEAX 80,X POINT TO NAME LOCATION LDB #13 NAME+EXT+NUMBER MOVNAM LDA 0,Y+ GET CHAR STA 0,X+ PUT INTO SIS DECB DECREMENT COUNTER BNE MOVNAM MOVE 13 BYTES LDX #USRFCB RESET POINTER JSR FCS GO WRITE SECTOR BACK BNE SYSERR REPORT ERROR RTS THEN RETURN * DODIR - PUT AN END ON DIRECTORY DODIR LDX #USRFCB LDD #$0005 TRACK 0 SEC 5 STD 30,X LDA #9 STA 0,X READ CODE DODIR1 JSR FCS GO READ SECTOR BNE SYSERR ERROR IF CAN'T READ LDD 64,X GET NEXT POINTER TST A CHECK TRACK BNE DODIR2 MEANS LAST SECTOR ON THIS TRACK STD 30,X ELSE SETUP TO READ NEXT BRA DODIR1 GO DO IT DODIR2 CLR 64,X CLR 65,X MARK END OF DIRECTORY INC 0,X CHANGE 9 (READ) TO 10 (WRITE) JSR FCS GO REWRITE SECTOR LBNE SYSERR RTS AND QUIT * REPORT - REPORT THAT FORMATTING IS DONE REPORT LDX #FCMMSG PRINT "FORMATTING COMPLETE." JSR PSTRNG LDX #FREE CLRB JSR OUT5D PRINT NUMBER OF FREE SECTORS RTS AND RETURN * TEXT STRINGS MEMMSG FCC 'MINIMUM 16K OF RAM IS NEEDED.',4 DRNMSG FCC 'INVALID DRIVE NUMBER.',4 CHKMSG FCC 'ABOUT TO FORMAT DRIVE NUMBER ',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 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 ',4 TR0MSG FCC 'ERROR ON TRACK 0 - FORMATTING ABORTED.',4 * DISK FORMAT TABLES SDTABL FCB 10,10 SECTORS/TRACK (TRACK 0 AND OTHER TRACKS) FCB 12,$FF PRE-INDEX GAP FCB 6,0 SYNC BYTES BEFORE INDEX MARK FCB 0,0 NOT USED IN SINGLE DENSITY FCB 1,$FC INDEX MARK FCB 8,$FF GAP 1 (POST INDEX) FCB 6,0 SYNC BYTES BEFORE ID FIELD FCB 0,0 NOT USED IN SINGLE DENSITY FCB 1,$FE ID ADDRESS MARK FCB 1,0 TRACK NUMBER BYTE FCB 1,0 SINGLE DENSITY FCB 1,0 SECTOR NUMBER BYTE FCB 1,1 SECTOR LENGTH (1=256 BYTES) FCB 1,$F7 CRC FCB 11,$FF GAP 2 FCB 6,0 SYNC BYTES BEFORE DATA FIELD FCB 0,0 NOT USED IN SINGLE DENSITY FCB 1,$FB DATA ADDRESS MARK FCB 128,0,128,0 128+128=256 BYTES OF DATA FCB 1,$F7 CRC FCB 14,$FF GAP 3 FCB 75,$FF PRE-INDEX GAP FCB 1,4,7,10,3,6,9,2,5,8 INTERLEAVE TABLE DDTABL FCB 10,18 SECTORS/TRACK (TRACK 0 AND OTHER TRACKS) FCB 24,$4E PRE-INDEX GAP FCB 12,0 SYNC BYTES BEFORE INDEX MARK FCB 3,$F6 C2 IN DOUBLE DENSITY ONLY FCB 1,$FC INDEX MARK FCB 16,$4E GAP 1 (POST INDEX) FCB 12,0 SYNC BYTES BEFORE ID FIELD FCB 3,$F5 A1 IN DOUBLE DENSITY ONLY FCB 1,$FE ID ADDRESS MARK FCB 1,0 TRACK NUMBER BYTE FCB 1,1 DOUBLE DENSITY FCB 1,0 SECTOR NUMBER BYTE FCB 1,1 SECTOR LENGTH (1=256 BYTES) FCB 1,$F7 CRC FCB 22,$4E GAP 2 FCB 12,0 SYNC BYTES BEFORE DATA FIELD FCB 3,$F5 A1 IN DOUBLE DENSITY ONLY FCB 1,$FB DATA ADDRESS MARK FCB 128,0,128,0 128+128=256 BYTES OF DATA FCB 1,$F7 CRC FCB 16,$4E GAP 3 FCB 168,$4E PRE-INDEX GAP FCB 1,3,5,7,9,11,13,15,17,2,4,6,8,10,12,14,16,18 INTERLEAVE TABLE * THE FOLLOWING SUPER-BOOT PROGRAM IS PUT ON * TRACK 0 SECTORS 1 AND 2 OF DISK * SUPER-BOOT FOR DC-4 - TYPE CONTROLLERS * POSITION-INDEPENDENT CODE FOR STAR-DOS * (C) 1984 BY PETER A. STARK * EXPLANATION OF DLATCH OPERATION: * ON WRITE: BITS 0 AND 1 SELECT DRIVE 0-3 * BIT 6 SELECTS SIDE (0=SIDE A) * BIT 7 DISABLES DRIVE SELECT IF 1 * ON READ: BIT 6 SAME AS FDC INTRQ OUTPUT PIN * BIT 7 SAME AS FDC DRQ OUTPUT PIN * SUPER BOOT EQUATES INCHE EQU $F806 MONITOR INPUT CHARACTER WITH ECHO MPSTRN EQU $F810 MONITOR PSTRNG ROUTINE MONITR EQU $F814 MONITOR RE-ENTRY POINT BOOT BRA BOOT1 FCC 'DC4' FOR DC-4 CONTROLLER FIRSTS FDB 0 FIRST TRACK-SECTOR OF DOS DIDENS FCB 0 0=SD DISK; ELSE NUM OF SCTRS ON OTHER TRKS DUBLFL FCB 0 0=SINGLE-STEPPING DRIVE SECSID FCB 10 SECTORS PER SIDE (DEFAULT 10 FOR SD) BOOT1 LDS #$C980 SET STACK POINTER CLR DLATCH FORCE DRIVE 0, SS, AND SD LDA #$0B STA CMDREG RESTORE, LOAD HEAD, SLOW STEP LBSR WNBUSY PAUSE AND WAIT FOR NOT BUSY LEAX BOOT+256,PCR STX BUFFAD,PCR SAVE ADDRESS OF 2ND 256 BYTES LDD #$0002 TRACK 0 SECT 2 STD TRSEC,PCR BSR GETSEC READ SECOND HALF OF SUPER BOOT BNE BOOT1 IMMEDIATELY RETRY ON ERROR LDA DIDENS,PCR CHECK DISK DENSITY BEQ DISKSD ZERO MEANS DISK IS SINGLE DENSITY STA SECSID,PCR ELSE UPDATE SECTORS PER SIDE DISKSD LEAX SBBUFF,PCR STX BUFFAD,PCR USE SBBUF FROM NOW ON LDD FIRSTS,PCR FIRST TRACK-SECTOR IS NOW ... STD TRSEC,PCR NEXT TRACK-SECTOR LBEQ LNKERR IF NOT LINKED CLR DATPTR,PCR CLEAR DATA POINTER LDX #$FFFF STX TRADDR,PCR ERASE TRANSFER ADDRESS LBRA MLOOP CONTINUE WITH MAIN LOOP * GET THE NEXT SECTOR GETSEC LDD TRSEC,PCR NEXT TRACK-SECTOR LBEQ DONE NEXT IS 00-00 SO END STB SECREG GIVE SECTOR TO FDC CMPB SECSID,PCR COMPARE WITH SECTORS PER SIDE BLS SIDEA IF SIDE A LDB #$40 STB DLATCH ELSE SWITCH TO SIDE B BRA SIDEOK SIDEA CLR DLATCH IF SIDE A SIDEOK CMPA TRKREG ALREADY ON RIGHT TRACK? BEQ TRKOK YES TST DUBLFL,PCR CHECK IF WE'RE DOUBLE-STEPPING BEQ GOSEEK NO, SEEK NORMALLY ASL TRKREG MAKE BELIEVE FDC ON TRACK * 2 ASLA AND DESIRED TRACK IS ALSO * 2 GOSEEK STA DATREG NO, GIVE TRACK TO FDC LDA #$1B STA CMDREG SEEK, LOAD, SLOW STEP RATE BSR WNBUSY WAIT FOR COMPLETION TST DUBLFL,PCR CHECK IF DOUBLE-STEPPING BEQ TRKOK IF NOT, THEN TRAK REG IS OK LSR TRKREG ELSE UNFOOL FDC TRKOK ORCC #$50 DISABLE INTERRUPTS TST TRSEC,PCR CHECK TRACK NUMBER BEQ READSD READ TRACK 0 AS SINGLE DENSITY TST DIDENS,PCR CHECK REST OF DISK LBNE READDD <>0 MEANS DOUBLE DENSITY * SINGLE DENSITY READ ROUTINE READSD CLRB COUNTER = 256 LDX BUFFAD,PCR POINT TO BUFFER LDA #$8C STA CMDREG READ COMMAND BSR WAIT SDLOOP LDA STAREG BITA #2 DRQ? BNE SDGETD YES, GET THE DATA BITA #1 BUSY? BNE SDLOOP YES, WAIT FOR IT SDFINI BSR WNBUSY WAIT FOR READY BITB #$1C RNF, CRC, LD ERRORS RTS AND QUIT SDGETD LDA DATREG GET DATA STA 0,X+ SAVE IT DECB DECREMENT COUNTER BNE SDLOOP REPEAT UNTIL DONE BRA SDFINI * WAIT LOOP TO STABILIZE COMMAND REGISTER WAIT BSR WAIT1 WAIT1 BSR WAIT2 WAIT2 BSR WAIT3 WAIT3 RTS * WNBUSY - WAIT FOR NOT BUSY WNBUSY BSR WAIT LDB STAREG CHECK STATUS BITB #1 CHECK BUSY FLAG BNE WNBUSY WAIT IF STILL BUSY RTS ELSE RETURN WITH B=STATUS **** PREVIOUS PART MUST BE ON FIRST SECTOR **** * MAIN READ LOOP MLOOP BSR GETBYT GET A BYTE CMPA #2 DATA FOLLOWS? BEQ RDDATA YES, GO READ IT CMPA #$16 ADDRESS FOLLOWS? BEQ RDADDR YES, GO GET IT BRA MLOOP ELSE REPEAT * GETBYT ROUTINE - GET NEXT BYTE FROM FILE GETBYT LDB DATPTR,PCR GET DATA POINTER BNE GETBY1 OK TO CONTINUE IF NOT 0 LBSR GETSEC ELSE GET SECTOR BEQ BYTEOK IF NO ERROR BITB #$10 ON ERROR, CHECK IF RECORD NOT FOUND LBEQ ERROR ANYTHING ELSE IS AN ERROR COM DUBLFL,PCR COMPLEMENT DOUBLE FLAG LDA #$0B STA CMDREG RESTORE, LOAD HEAD, SLOW STEP BSR WNBUSY WAIT FOR COMPLETION LBSR GETSEC AND TRY AGAIN BNE ERROR QUIT ON ANY ERRORS BYTEOK LDB #4 STB DATPTR,PCR NEXT BYTE IS BYTE 4 GETBY1 LEAX SBBUFF,PCR POINT TO SBBUFF ABX POINT TO BYTE INC DATPTR,PCR BUMP POINTER LDA 0,X GET BYTE RTS RETURN WITH BYTE IN A AND CC SET * RDDATA - READ DATA FROM SECTOR RDDATA BSR GETBYT PSHS A BSR GETBYT TFR A,B PULS A GET LOAD ADDRESS TFR D,Y INTO Y REG BSR GETBYT GET COUNT BEQ ERROR IF COUNT = 0 TFR A,B RDMEM PSHS B SAVE COUNTER BSR GETBYT GET NEXT BYTE PULS B STA 0,Y+ SAVE IT DECB DECREMENT COUNTER BNE RDMEM REPEAT UNTIL DONE BRA MLOOP GO LOOK FOR MORE * RDADDR - READ ADDRESS FROM SECTOR RDADDR BSR GETBYT STA TRADDR,PCR BSR GETBYT STA TRADDR+1,PCR BRA MLOOP GO GET MORE * WHEN DONE, CHECK TRANSFER ADDR AND GO DO IF OK DONE LEAS 4,S REMOVE TWO RETURN ADDRESSES FROM STACK LDX TRADDR,PCR GET TRANSFER ADDRESS CMPX #$FFFF ANYTHING THERE? BEQ ERROR NO JMP 0,X ELSE GO TO PROGRAM * DOUBLE DENSITY READ ROUTINE READDD LDA #$E0 POINT DP TO I/O PAGE TFR A,DP LDX BUFFAD,PCR POINT TO BUFFER CLRB COUNTER = 256 LDA #$8E READ DD COMMAND STA