V*d6X* ATARI 1050 DISK DRIVE OPERATING SYSTEM -- part 3nX*xX* verify a sectorX*VERIFYQ>;assume error PERROR VERSEK;verify sectorHVERIFY1;br on error&Q>;otherwise, indicate 'no error' PERROR :;done!VERIFY1"COUNT;another retry?HVERIFY;br if so:;otherwise errorX* X* verifyX*VERSEK$>;set timeoutQ>" TIMEOUT,,Q>;'READ SECTOR' command for controller6 PFCNTRL@$VERSE1*DRA;IRQ from controller?JJVERSE2;errorT IVERSE1;DRQ from controller?^QDATREG;yes, read bytehN>;invertrRSEKBUF9;and check|HVERSE3;br on error!QTIM64;othersine, reset timer2;next byteIVERSE1;until end of bufferQ>,VERSE4*FCNTRL;wait for controller ready HVERSE4QFCNTRL;mask status bitsM>, :;doneVERSE2QFCNTRL;errorM>;controller ready?FVERSE5;br if so"Q>;otherwise, another timeout TIMEOUTHVERSE1;and continueVERSE3QTIM64;reset timer&&ERRADR;mark error address0 FORCE;interrupt controller:QDATREG;reset IRQDVERSE5QTIM64;reset timerNQFCNTRL;read statusXM>;lost data?bHVERSEK;try again, if solQ>;otherwise, return errorv:X* X* read status -- command 'S'X* RSTAT FORCE;stop controllerQDRAM> ;enhanced density?FRSTAT1;br if so"Q>;otherwise, reset bit 7,6,5 MSTATUS !RSTAT2%RSTAT1Q>;set bit 7 for enhanced LSTATUS2RSTAT2*FCNTRL;test for 'write protected' disk JRSTAT3 L>;set bit 3 if soHRSTAT4;br always %RSTAT3M>;otherwise, reset bit 3*"RSTAT4$>;put diskette status4PBUFFER9;to send buffer>2HQCSTAT;controller statusRN>;invert\PBUFFER9;put alsof2pQ>;3.byte E0z PBUFFER92Q>;4.byte 00 PBUFFER9PERROR;indicate 'no error' SCONT;send 'C'$>;and also 4 status bytes &COUNT $>BUFFER;from address BUFFER SENDQFCNTRL;update status PCSTAT :;doneX**X* format single density -- command $21X*SFORM SDF;do formatting$FORMVER*ERROR;error?.GSFORM1;br if so8 VERIFO;verify formattingBSFORM1QTIM64;reset timerL QUITT;return resultV!Q>;write FF to format buffer`$>jSFORM2PSEKBUF9;write FFt2~ISFORM2;until end of buffer#*ERROR;formatted without error?ISFORM3;br if soQ>;otherwise, reset#PSEKBUF;first 2 bytes in bufferPSEKBUF SFORM3!SNDSEK;sector to CPUX*X* single density formattingX* SDF BSEKT;build up a sectorQ>;start with track 0PSEKBUF;set address infoQDRA;set for single density L> PDRASDF1*FCNTRL;drive ready?(GSDF2;br if not2KSDF2;br if 'write protect'<ISDF3;br alwaysFSDF2Q>;indicate errorP PERRORZ :;doned#SDF3 SEEK;goto track to formatnQ>;try always 2 timesx PCOUNT F1T;format one track$>Җ&T1024I;set timer*ERROR;error?ISDF4;no, next track:;yes, breakSDF4#TRACK;incr track #FTNRQ>(;all 40 tracks? RTRACKHSDF1;no, continue:;yes, formatting doneX*X* write a trackX* F1T%>".QSKEWTB8;mark first sector from SKEW table, PFSNR6+Q>;'write track' command to controller@ PFCNTRLJQ>;for timeoutT$F1T1*DRA;write 1 byte 00 at DRQ^ IF1T1h 'DATREGrF1T2*DRA;another byte 00| IF1T2 'DATREGPT1024I;start timerQ>;write 00$>;172 timesF1T3*DRA;wait for DRQJF1T4;error, IRQ IF1T3PDATREG;write data byte 0;zero?HF1T3;no, continueQ>;write FC F1T5*DRA JF1T4 IF1T5 PDATREGQ>&$>;16 times 000 F1T6*DRA: JF1T4D IF1T6N PDATREGX0b HF1T6lFF1T7;br alwaysvF1T4!F1T8;error F1T7Q>$>;write 6 times 00 F1T9*DRA JF1T4 IF1T9 PDATREG0 HF1T9+$>;write 5 bytes from address $85 downF1T10QFDATA9F1T11*DRA JF1T4 IF1T11 PDATREG 0 IF1T10 Q>*$>;write 17 times 004F1T12*DRA> JF1T4H IF1T12R PDATREG\0f HF1T12p3$>;write sector, including track & sector addrzF1T13QSEKBUF9F1T14*DRA JF1T4 IF1T14 PDATREG0 HF1T133;SKEW table ends at 9)> ;for single density HF1T15%> ;now the even sectorsF1T15)>;ends at 16 FF1T16+QSKEWTB8;otherwise, continue formatting PFSNR Q>;write 11 times 00 $> $ F1T17*DRA. JF1T48 IF1T17B PDATREGL 0V HF1T17` !F1T7j "F1T16Q>;all tracks formattedt !$>;wait for controller ready~ F1T18MFCNTRL FF1T19;IRQ from controller *DRA IF1T18 &DATREG;continue to write 00 !F1T18 "F1T19QFCNTRL;controller ready M>;lost data? HF1T8;br if error Q>;o.k. !F1T20PERROR;set error status QTIM64;reset timer QFCNTRL;indicate status PCSTAT :;done !F1T8 FORCE;interrupt command "COUNT;another try?( GF1T21;br if not2 Q>;yes, set timer< PT1024IF !F1T;try againP F1T21Q>;indicate errorZ !F1T20d X*n ,X* format enhanced density -- command $22x X* 3DFORM DDF;build up a track in enhanced density !FORMVER;and format X* !X* enhanced density formatting X* DDF BSEKT;build up sector Q> PSEKBUF QDRA M>;set to enhanced density PDRA DDF1*FCNTRL GDDF2;IRQ? KDDF2;or DRQ? IDDF3;no, everything fine DDF2Q>;indicate error" PERROR, :6 (DDF3 SEEK;goto track without verify@ Q>;two triesJ PCOUNTT  F1TD;write one track^ $>h &T1024I;set timeoutr *ERROR;error?| IDDF4 : DDF4#TRACK;next track #FTNR Q>(;all tracks done? RTRACK HDDF1;no, continue : X* (X* format a track in enhanced density X* F1TD%> #QSKEWTB8;to start of SKEW table PFSNR;first sector number $>N;write 4E 'Q>;but first 'write track' command PFCNTRL& (F1TD1*DRA;wait for controller ready0 IF1TD1: &DATREGD A;write another 4EN $>;timeout valueX F1TD2*DRAb IF1TD2l PDATREGv &T1024I;start timer "$>;write another 144 times 4E F1TD3*DRA JF1TD4 IF1TD3 PDATREG 0 HF1TD3 )F1TD5*DRA;write another 256 times 4E JF1TD4 IF1TD5 PDATREG 0 HF1TD5 Q> $> ;write 12 times 00 F1TD6*DRA JF1TD4* IF1TD64 PDATREG> 0H HF1TD6R Q>\ $>;write 3 times F6f F1TD7*DRAp JF1TD4z IF1TD7 PDATREG 0 HF1TD7 Q>;write FC F1TD8*DRA JF1TD4 IF1TD8 PDATREG Q>N $>2;write 50 times 4E F1TD9*DRA JF1TD4 IF1TD9 PDATREG0 HF1TD9$ FF1TD10.F1TD4!F1TD118F1TD10Q>B$> ;write 12 times 00LF1TD12*DRAV JF1TD4` IF1TD12j PDATREGt0~ HF1TD12Q>$>;write 3 times F5F1TD13*DRA JF1TD4 IF1TD13 PDATREG0 HF1TD13&$>;write 5 bytes from address $85F1TD14QFDATA9F1TD15*DRA JF1TD4 IF1TD15  PDATREG0 IF1TD14(Q>N2$>;write 22 times 4E<F1TD16*DRAF JF1TD4P IF1TD16Z PDATREGd0n HF1TD16xQ>$> ;write 12 times 00F1TD17*DRA JF1TD4 IF1TD17 PDATREG0 HF1TD17Q>$>;write 3 times F5F1TD18*DRA JF1TD4 IF1TD18 PDATREG0 HF1TD18*$>;write sector + track§or number"F1TD19QSEKBUF9,F1TD20*DRA6 JF1TD4@ IF1TD20J PDATREGT0^ HF1TD19h3;next sector from tabler QSKEWTB8|GF1TD21;end of table? PFSNR;noQ>;continue formatting$>;write 17 times 00F1TD22*DRA JF1TD11 IF1TD22 PDATREG0 HF1TD22Q>N$> ;write 32 times 4EF1TD23*DRA JF1TD11 IF1TD23 PDATREG0& HF1TD230 !F1TD10:X*DF1TD21$>NNQ>XF1TD24MFCNTRLb FF1TD25l*DRAv IF1TD24&DATREG;write 4E !F1TD24F1TD25QFCNTRLM>;lost data? HF1TD11 Q>;noF1TD26PERROR;no errorQTIM64;reset timer QFCNTRL%PCSTAT;indicate controller status :;done#F1TD11 FORCE;interrupt command"COUNT;another try? GF1TD27;no, formatting error Q>;yes, set timer PT1024I !F1TD;try again*X*4F1TD27Q>;indicate error> !F1TD26HX*RX* sector skew table\9X* this table contains the sector numbers in the orderf&X* they are written to the diskettepX*z1SKEWTB ==== = = ======* ==== = ======= ;end of tableX*3X* build up a sector incl. addr info & SYNCBYTESX*BSEKT MOTON;start motor RESTORE;to track 0Q>PTRACK;start with track 0$>;clear sector bufferQ>BSEKT1PSEKBUF92 IBSEKT1)Q>;set SYNCBYTES, address marks etc. PRSEKH$Q>.PSEKBUF8 PFDATABQ>L$>VBSEKT2PFDATA9`0j HBSEKT2tQ>~ PFTNRQ>PT1024I;set timer:X*2X* read tracks from 39 down to check formattingX*'VERIFOQ>';track 39 is the last one PTRACKQDRAM> ;single density?T?PSBUF;if so, $40 to SBUF"VERIFO1Q>;read until track 0  PSBUFPERROR;no error, up to nowQ>;two tries( PCOUNT2 SEEK;goto track<VERIFO2%SBUFF *SBUFPJVERIFO3;single density?Z,)> ;yes, go until sector 9 in SKEW tabledHVERIFO4;more to don*%> ;otherwise, continue with number 13x$'SBUF;the even sector numbers0VERIFO4)>;whole table for enhanced density FVERIFO5&VERIFO3QSKEWTB8;get sector numberGVERIFO5;end of table?PSEKTOR;put sector numberPSEKREG;also to controller RDSEKTOR;and read sectorHVERIFO6;read error?,#SBUF;no, incr. pointer to SKEW tableIVERIFO2;br always VERIFO6"COUNT;error, retry?FVERIFO7;no more retries+ RDSEKTOR;otherwise, read one more timeHVERIFO6;another error?)Q>;no, set 2 retries for next sector PCOUNT"#SBUF;next sector,IVERIFO2;br always6VERIFO7Q>;error@(VERIFO8PERROR;indicate error statusJ&QFCNTRL;indicate controller statusT PCSTAT^:;verify donehVERIFO5"TRACK;next trackrIVERIFO1;until track 0|Q>;done, no error FVERIFO8X*X* motor off, wait, motor onX*MOTONOF MOTOFF;motor off$> DELAY2$>n DELAY2 TMOTON:X*2X* command $23, floppy test, does several testsAX* the command byte is followed by the test number, <2,2,3,4,5X*TEST TMOTON;motor on&QSEKBUF;get test number0R>;test number 2?: HTEST1D RESTORE;yes, to track 0NQ>XPTRACK;mark track 0b9QSEKBUF;second byte after command is sector numberlPSEKTOR;mark sectorv) TSTEPR;test step rate for all tracksETEST2;error? DTESTE;no, done & return 'C' TEST1GTEST3;test number <2?R>HTEST4;if not TSTEP;yes, make a step1!TESTE;direction in second byte after commandTEST4R>;test number 4?HTEST5;if not TESTE;otherwise return 'C'!FPTEST;and do floppy testTEST5R>;test number 5?HTEST2;no, error TSEEK;SEEK on track 4DTESTE;track number in second byte after command"TEST2QERROR;wrong test number L>;or test error*HTEST6;br always4,TEST3PFLAG;store test number <2 in FLAG>TESTEQERRORHM>;clear errorRTEST6PERROR;test done\#!QUITT;return 'C' or 'E' to CPU