💾 Archived View for mirrors.apple2.org.za › archive › www.textfiles.com › apple › ANATOMY › t.dos.bd… captured on 2023-01-29 at 11:41:58.
View Raw
More Information
-=-=-=-=-=-=-
- =================================
- READ/WRITE TRACK/SECTOR (RWTS).
- (ENTER WITH (Y)/(A) POINTING AT
- RWTS'S INPUT/OUTPUT BLOCK (IOB).
- =================================
RWTS STY PTR2IOB ;SET UP A Z-PG PTR 2 RWTS'S IOB.
STA PTR2IOB+1
LDY #2 ;INITIALIZE CNTR FOR MAXIMUM
STY RECLBCNT ;NUMBER OF RECALIBRATION TRIES.
LDY #4 ;INITIALIZE COUNTER FOR MAXIMUM
STY RSEEKCNT ;# OF RE-SEEKS BTW'N RECALIBS.
LDY #1 ;(Y) = INDEX TO RWTS'S IOB.
LDA (PTR2IOB),Y ;GET SLOT*16 FROM IOB IN (X), SO
TAX ;CAN USE IT TO INDEX BASE ADRS
;FOR DRIVE FUNCTIONS.
- CHK IF WANTED SLOT*16 = LAST SLOT*16?
LDY #15 ;INDEX 4 VAL OF LAST SLOT USED.
CMP (PTR2IOB),Y ;WANTED*16 VS LAST*16.
BEQ SAMESLOT ;SLOT WANTED=SLOT LAST ACCESSED.
- WANT TO USE A DIFFERENT SLOT SO
- RESET (X) BACK TO INDEX OLD SLOT
- SO CAN TEST OLD MOTOR.
TXA ;SAVE SLOT*16 WANTED ON STK.
PHA
LDA (PTR2IOB),Y ;GET OLD SLOT*16 BACK.
TAX ;PUT IT IN (X) 2 INDEX BASE ADRS.
PLA ;PUT SLOT*16 WANTED IN (A) AND
PHA ;KEEP IT SAVED ON STK.
STA (PTR2IOB),Y ;UPDATE LAST-USED SLOT*16 FOR
;NEXT TIME AROUND.
- CHECK TO SEE IF LAST-USED DRIVE
- ASSOC WITH LAST-USED SLOT IS
- STILL SPINNING. IF IT IS, WAIT
- FOR IT TO STOP.
LDA Q7L,X ;PREP LATCH FOR INPUT.
CKSPIN LDY #8 ;SET CNTR 2 INSURE AT LEAST 8 CKS
LDA Q6L,X ;STROBE LATCH TO READ.
CHKCHNG CMP Q6L,X ;READ AGAIN & CMP TO LAST READ.
BNE CKSPIN ;DATA CHANGED, SO STILL SPINNING.
DEY ;NO CHANGE, SO CHK WITH SOME
BNE CHKCHNG ;DELAYS JUST TO MAKE SURE.
- GET INDEX FOR SLOT WANTED.
PLA ;GET SLOT*16 BAK OFF STK & PUT IT
TAX ;IN (X) SO WE CAN NDX BASE ADRS.
- CHECK TO SEE IF A DRIVE ASSOC
- WITH SLOT WANTED IS STILL
- SPINNING. (AS SOON AS GET A
- CHANGE, KNOW IT IS SPINNING.
- IF NO CHANGE, CHK AT LEAST 8
- TIMES TO BE CERTAIN IT IS OFF.)
SAMESLOT LDA Q7L,X ;SET READ MODE.
LDA Q6L,X ;STROBE LATCH TO READ.
LDY #8 ;SET CNTR FOR 8 CHKS IF NEEDED.
STRBAGN LDA Q6L,X ;STROBE LATCH AGAIN.
PHA ;DELAY 14 MACHINE CYCLES.
PLA
PHA
PLA
STX SLOTPG5 ;SAVE SLOT*16 WANTED IN PAGE5.
CMP Q6L,X ;HAS DATA CHANGED YET?
BNE DONETEST ;YES - DATA CHANGED, SO SPINNING.
DEY ;NO - NO CHANGE, SEE IF CHKD
;ENOUGH TIMES YET.
BNE STRBAGN ;CHK AT LEAST 8 TIMES.
DONETEST PHP ;SAVE TEST RESULTS ON STK SO CAN
;LATER CHK IF NEED EXTRA DELAY
;OR NOT.
- TURN MOTOR ON IN A DRIVE ASSOC
- WITH SLOT WANTED (JUST IN CASE
- IT WASN'T ALREADY SPINNING).
- NOTE: THIS USES DRIVE WITH SAME
- # AS LAST DRIVE USED. THIS MAY
- OR MAY NOT BE THE SPECIFIC DRIVE
- # WE WANT. HOWEVER, WE MUST USE
- THIS INSTRUC TO SEND POWER VIA
- THE CONTROLLER. ONCE SWITCH IS
- THROWN, WE CAN LATER RE-ROUTE
- THAT POWER TO WHICHEVER DRIVE WE
- WANT BY THROWING ANOTHER SWITCH
- TO SELECT DRIVE1 OR DRIVE2.
LDA MTRON,X ;TURN MOTOR ON.
- ESTABLISH Z-PAGE POINTERS TO
- DEVICE CHARACTERISTIC TABLE &
- RWTS'S I/O BUFFER (SO WE CAN
- USE Z-PAGE INDIRECT ADDRESSING):
- IBDCTP --> PTR2DCT (3C,3D).
- IBBUFP --> PTR2BUF (3E,3F).
LDY #6
MOVPTRS LDA (PTR2IOB),Y ;GET PTRS FROM RWTS'S IOB.
STA: PTR2DCT-6,Y ;PUT THEM IN Z-PAGE. (":" USED
INY ;2 FORCE A 3-BYTE ZERO-PAGE ADR.)
CPY #10 ;4 BYTES TO COPY (6 TO 9).
BNE MOVPTRS
LDY #3 ;SAVE HI BYTE OF MOTOR-ON-TIME
LDA (PTR2DCT),Y ;COUNT IN Z-PAGE.
STA MTRTIME+1
LDY #2 ;GET DRIVE # WANTED.
LDA (PTR2IOB),Y
LDY #16 ;SET (Y) = INDEX 2 LAST-USED DRV.
CMP (PTR2IOB),Y ;DRV# WANTED VS DRV# LAST USED.
BEQ SAMEDRV
STA (PTR2IOB),Y ;DESIGNATE DRV# WANTED AS LAST-
;USED DRV# FOR NEXT TIME AROUND.
PLP ;GET STATUS BACK OFF STK.
LDY #0 ;RESET STATUS (Z-FLAG OFF) TO
;SIGNAL THAT SPECIFIC DRV # WE
;WANT IN SPECIFIC SLOT WANTED WAS
;NOT ORIGINALLY SPINNING.
PHP ;PUSH UPDATED STATUS BACK ON STK.
SAMEDRV ROR ;PUT LOW BIT OF DRV WNTED IN (C).
BCC USEDRV2 ;BRANCH IF WANT DRIVE 2.
LDA SELDRV1,X ;ROUTE POWER TO SELECT DRIVE 1.
BCS USEDRV1 ;ALWAYS.
USEDRV2 LDA SELDRV2,X ;ROUTE POWER TO SELECT DRIVE 2.
USEDRV1 ROR DRVZPG ;PUT SIGN BIT FOR WHICH DRIVE
;USING IN Z-PAGE: NEG = DRIVE1.
; POS = DRIVE2.
- CHK TO SEE IF A SPECIFIC DRIVE
- WANTED IN SPECIFIC SLOT WANTED
- WAS ORIGINALLY ON OR NOT.
PLP ;GET PREVIOUS TEST RESULT.
PHP ;PUT IT BACK ON STK 4 LATER USE.
BNE WASON ;ORIG DRV IN ORIG SLOT WAS ON.
- SPECIFIC DRIVE WANTED IN SPECIFIC
- SLOT WANTED WAS ORIGINALLY OFF,
- SO DELAY A BIT TO AVOID POS'NING
- HEAD DURING THE PERIOD OF HEAVY
- CURRENT FLOW THAT OCCURS WHEN
- MOTOR IS TURNED ON. (THAT IS,
- GIVE LINE/CAPACITOR TIME TO BLEED
- DOWN CAUSE MOTOR ON/OFF SWITCH
- REQUIRES MORE CURRENT THAN THE
- STEPPER MOTOR.)
-
- (AMOUNT OF DELAY IS NOT CONSTANT
- CAUSE IT DEPENDS ON WHAT IS IN
- ACCUMULATOR & WE DON'T KNOW
- CAUSE WE WERE JUST ACCESSING
- HARDWARE.)
LDY #7
WAIT4MTR JSR DELAY ;STALL.
DEY
BNE WAIT4MTR ;GO STALL SOME MORE.
LDX SLOTPG5 ;RESTORE (X) = SLOT*16.
WASON LDY #4 ;GET TRK WANTED.
LDA (PTR2IOB),Y
JSR SEEKTRK ;GO MOVE ARM TO CORRECT TRK.
- CHECK TO SEE IF MOTOR WAS
- ORIGINALLY ON.
PLP ;GET EARLIER RESULT OF MOTOR TEST
BNE BEGINCMD ;BRANCH IF DRV WAS ORIGINALLY ON.
LDY MTRTIME+1 ;MOTOR WASN'T ORIGNALLY ON.
;HOWEVER, WE HAVE SINCE TURNED IT
;ON. NOW CHECK IF IT HAS BEEN ON
;LONG ENOUGH.
BPL BEGINCMD ;YES -NO NEED TO WAIT ANY LONGER.
- ALTHOUGH MOTOR IS TURNED ON, IT
- HASN'T BEEN ON LONG ENOUGH TO DO
- ACCURATE READING OF BYTES. THERE4
- DELAY UNTIL MOTOR ON TIME IS ONE
- SECOND (AT WHICH TIME MTRTIME
- COUNT IS 0). (PART OF TIME WAS
- TAKEN UP TO SEEK TRACK.)
TIME1 LDY #18
TIME2 DEY
BNE TIME2
INC MTRTIME
BNE TIME1
INC MTRTIME+1
BNE TIME1
- =================================
- MOTOR IS UP TO SPEED SO NOW
- PROCESS COMMAND (SEEK=00,
- READ=01, WRITE=02, FORMAT=04).
- ---------------------------------
- USE THE FOLLOWING COUNTERS:
- READCNTR = ALLOW UP TO 48 TIMES
- TO FIND CORRECT ADR
- PROLOGUE BETWEEN
- RE-SEEKING.
- RSEEKCNT = ALLOW UP TO 4 RE-SEEKS
- BTWN RECALIBRATIONS.
- RECLBCNT = ALLOW UP TO 2 RECALIBRATIONS.
-
- (THERE4, IF NECESSARY, ALLOW UP
- TO 384 ATTEMPTS TO FIND CORRECT
- PROLOGUE ADDR.)
- BEGIN RWTS COMMAND PROCESSING.
BEGINCMD LDY #12 ;GET CMD FROM IOB.
LDA (PTR2IOB),Y
BEQ WASEEK ;BRANCH IF CMD WAS "SEEK".
CMP #4 ;WAS CMD "FORMAT"?
BEQ FORMDSK ;BRANCH IF CMD WAS "FORMAT".
- ---------------------------------
- COMMAND WAS READ OR WRITE
- (OPCODES $01 OR $02)
- ---------------------------------
ROR ;(C)=1 IF READ (OPCODE %00000001)
;(C)=0 IF WRIT (OPCODE %00000010)
PHP ;SAVE (C) DENOTING CMD ON STK.
BCS RESETCNT ;READING - SO SKIP PRENIBBLING.
WASWRITE JSR PRENIBL ;CONVERT 256 MEMORY BYTES TO 342
;6-BIT NIBBLES NEEDED FOR WRITING.
RESETCNT LDY #48 ;INIT COUNT TO READ ADR HEADER.
STY READCNTR
SETXSLT LDX SLOTPG5 ;SET (X)=SLOT*16.
JSR RDADDR ;GO READ ADDR HEADER TO FIND SEC
;THAT WE WANT TO READ OR WRITE.
BCC RDRIGHT ;ADDR READ WAS GOOD.
- BAD ADDRESS (OR DATA) READ.
REDUCERD DEC READCNTR ;REDUCE READ COUNT.
BPL SETXSLT ;TRY AGAIN.
- DO A RECALIBRATION CAUSE WE HAVE
- EXHAUSTED ALL ATTEMPTS TO GET A
- GOOD READ.
DORECALB LDA PRESTRK ;SAVE TRK WANTED ON STK.
PHA
LDA #96 ;PRETEND PRESENTLY ON TRK #96 SO
;WE FORCE HEAD AGAIN STOP.
;(REPEATEDLY BANGING HEAD AGAINST
;STOP = FAMILIAR DISK CLATTER.)
JSR SETTRK ;GO SELECT DRV & PUT TRK WANTED
;IN MEM LOCATION SPECIFIC 2 DRV.
DEC RECLBCNT ;REDUCE RECALIBRATION COUNTER.
BEQ DRVERR ;ERROR -EXHAUSTED RECALIBRATIONS.
LDA #4 ;INDICATE 4 CHANCES TO RESEEK TRK
STA RSEEKCNT ;BETWEEN RECALIBRATIONS.
LDA #0 ;SEEK TRACK 0.
JSR SEEKTRK ;GO MOVE ARM TO TRK 0.
PLA ;GET TRK WANTED FROM STK.
RESEEK JSR SEEKTRK ;NOW, MOVING OUT FROM TRK 0, TRY
;TO LOCATE TRK WANTED.
JMP RESETCNT ;GO BACK & TRY TO DO READ AGAIN.
RDRIGHT LDY TRKDSK ;(Y) = TRK# FOUND IN HEADER.
CPY PRESTRK ;TRK FOUND = TRK WANTED?
BEQ RTTRK ;YES - SEEEKED TO CORRECT TRK.
- BAD SEEK (OR ELSE SOME KIND
- OF PROTECTION SCHEME) CAUSE
- TRK WANTED < > TRK FOUND.
LDA PRESTRK ;SAVE TRK WANTED ON STK.
PHA
TYA ;SET (A) =PRESENT TRK =TRK FOUND.
JSR SETTRK ;GO SELECT DRV & PUT TRK WANTED N
;MEMORY LOCATION SPECIFIC TO DRV.
PLA ;GET TRK WANTED BACK OFF STACK.
DEC RSEEKCNT ;ALLOW 4 ATTEMPTS TO FIND CORRECT
;TRK BETWEEN RECALIBRATIONS.
BNE RESEEK ;MORE ATTEMPTS LEFT TO FIND TRK.
BEQ DORECALB
- ---------------------------------
- GOT A DRIVE ERROR.
- ---------------------------------
DRVERR PLA
LDA #$40 ;ERROR CODE FOR BAD DRIVE.
TOERRWTS PLP
JMP RWTSERR
- ---------------------------------
- RWTS COMMAND WAS SEEK (NULL).
- ---------------------------------
WASEEK BEQ RWTSEXIT ;IF CMD WAS SEEK, THEN GO EXIT
;RWTS CAUSE JUST COMPLETED MOVE.
- ---------------------------------
- RWTS COMMAND WAS FORMAT ($04).
- ---------------------------------
FORMDSK JMP FORMAT ;GO DO THE FORMAT.
- ---------------------------------
- FOUND CORRECT TRK FOR RWTS'S
- READ OR WRITE COMMANDS.
- ---------------------------------
RTTRK LDY #3 ;GET VOL WANTED FROM IOB.
LDA (PTR2IOB),Y
PHA ;SAVE IT ON THE STACK.
LDA VOLDSK ;GET VOL FOUND AND SAV IT IN IOB.
LDY #14
STA (PTR2IOB),Y
PLA ;RETRIEVE VOL WANTED OFF STK.
BEQ CRCTVOL ;VOLUME 0 GOOD FOR ALL.
CMP VOLDSK ;VOL WANTED = VOL FOUND?
BEQ CRCTVOL ;YES - GOT CORRECT VOL#.
LDA #$20 ;SET CODE FOR VOL MISMATCH.
BNE TOERRWTS ;ALWAYS.
- FOUND CORRECT VOLUME SO NOW CHK
- IF THE SECTOR IS ALSO CORRECT.
CRCTVOL LDY #5 ;GET LOGICAL SECTOR # WANTED.
LDA (PTR2IOB),Y
TAY ;SET (Y) = LOGICAL SECTOR# WANTED.
LDA PHYSECTR,Y ;(A) = PHYSICAL SECTOR # WANTED.
CMP SECDSK ;PHYS SEC WANTED=PHYS SEC FOUND?
BNE REDUCERD ;NO - GO TRY AGAIN.
PLP ;GET TYPE OF OPERATION FROM STK:
; (C)=0=WRITE, (C)=1=READ.
BCC WRITE ;BRANCH IF RWTS OPCODE WAS WRITE.
- READ DATA SEC INTO RWTS'S BUFFERS.
JSR READATA ;GO READ A SECTOR.
PHP ;SAVE STATUS OF READ ON STACK JUST
;IN CASE WE NEED TO RE-READ.
BCS REDUCERD ;BAD READ - GO TRY AGAIN. LEAVE
;SET (C) ON STK 2 DENOTE READING.
;(WE PREVIOUSLY PULLED THE SAVED
;STATUS OFF THE STK. THERE4, WE
;BETTER PUT A SET (C) BACK ON STK
;CAUSE WE ARE READING AND WE ARE
;ABOUT 2 BRANCH BACK 2 A ROUTINE
;THAT EXPECTS THE READ (C=1) OR
;WRITE (C=0) FLAG ON THE STACK.
PLP ;GOOD READ -NOT BRANCHING BACK SO
;NO NEED TO PRESERVE FLAG ON STK.
- POSTNIBBLE DATA & SHUT DOWN.
LDX #0
STX PROSCRTH
JSR POSTNB16 ;CONVERT 6- & 2-ENCODED BYTES IN
;RWTS BUFS TO NORMAL MEMORY BYTES
;(USUALLY PLACED IN DOS DATA
;SECTOR BUFFER).
LDX SLOTPG5 ;SET (X) = SLOT*16 FROM PAGE 5.
- ----------------------------------
- SIGNAL SUCCESS OR FAILURE
- AND THEN SHUT DOWN.
- ----------------------------------
- SEVERAL REFERENCES ERRONEOUSLY
- STATE THAT THE RETURN CODE IS
- ZERO IF NO ERRORS OCCURRED.
- HOWEVER, A LONE SEEK OPERATION
- ALWAYS SETS THE RTN CODE TO ZERO.
- EVEN IF A READ OR WRITE OPERATION
- WAS SUCCESSFUL, THE IOB RTN CODE
- WILL ACQUIRE A RANDOM VALUE (AS
- A RESULT OF ACCESSING A HARDWARE
- SWITCH PRIOR TO ENTERING THIS
- ROUTINE). THERE4, THE RTN CODE
- IS ONLY RELEVANT IF AN ERROR IS
- DENOTED (CARRY SET).
RWTSEXIT CLC ;(C)=0, SIGNL SUCCESSFUL OPERAT'N
HEX 24 ;"BIT $38" 2 IGNORE "SEC" INSTRUC
RWTSERR SEC ;(C)=1, SIGNL UNSUCCESSFUL OPER'N
LDY #13 ;STORE RETURN CODE IN IOB.
STA (PTR2IOB),Y
LDA MTROFF,X ;TURN MOTOR OFF.
RTS
- ---------------------------------
- WRITE SECTOR.
- ---------------------------------
WRITE JSR WRITESEC ;WRITE SYNC GAP AFTR ADR EPILOGUE
;& THEN WRITE DATA PROLOGUE, DATA
;PROPER AND DATA EPILOGUE.
BCC RWTSEXIT ;GOOD WRITE - GO EXIT.
LDA #$10 ;WRITE PROTECT ERROR CODE.
BCS RWTSERR ;BAD WRITE - HANDLE THE ERROR.
- =================================
- DETERMINE DRIVE TYPE & MOVE
- DISK ARM TO DESIRED TRK.
- =================================
SEEKTRK PHA ;SAVE # OF TRK WANTED ON STK.
LDY #1 ;GET DRIVE TYPE (EVEN VAL=2PHASE,
LDA (PTR2DCT),Y ;ODD VAL=1PHASE) FROM DCT.
;(PS. THE "II" IN THE "DISK II"
;LOGO STAMPED ON APPLE'S DISK
;DRIVE DENOTES A 2-PHASE MOTOR.)
ROR ;PUT LOW BYTE OF DRV TYPE IN (C).
PLA ;GET TRK# WANTED BACK IN (A).
BCC SEEKIT ;NOT USING STANDARD DRIVE II,
;USING A ONE-PHASE DRIVE INSTEAD,
;THERE4 SKIP DOUBLING OF TRK# AND
;USE SEEKIT AS PART OF ROUTINE
;INSTEAD OF AS A SEPERATE SUBRTN.
ASL ;2*TRK# WANTED=1/2TRACK# WANTED.
JSR SEEKIT ;MOVE THE DISK ARM 2 DESIRED TRK.
LSR PRESTRK ;CONVERT HALFTRACK VALUE BACK TO
RTS ;WHOLE TRACK VALUE.
- =====================================
- ROUTINE/SUBROUTINE TO MOVE DRIVE
- ARM TO A SPECIFIC TRK POS'N.
- =====================================
- USED AS A SUBROUTINE WHEN USING
- APPLE'S DISK DRIVE II. NOTE WHEN
- SEEKIT IS USED AS A SUBROUTINE,
- DESTRK, PRESTRK, TRK4DRV1, TRK4DR2,
- STPSDONE AND HOLDPRES ARE ALL
- EXPRESSED IN TERMS OF HALFTRACKS:
- DESTRK = DESTINATION HALF-TRACK POS'N.
- PRESTRK = PRESENT HALF-TRACK POS'N.
- HOLDPRES = PRESENT HALF-TRACK POS'N.
- TRK4DRV1 = BASE ADR (INDEXED BY SLOT*16)
- TO POINT TO THE ADR THAT
- CONTAINS THE LAST HALF-
- TRACK # THAT DRIVE1 WAS
- ALIGNED ONE.
- TRK4DRV2 = BASE ADR (INDEXED BY SLOT*16)
- TO POINT TO THE ADR THAT
- CONTAINS THE LAST HALF-
- TRACK # THAT DRIVE2 WAS
- ALIGNED ON.
- STPSDONE = NUMBER OF HALFTRACKS
- MOVED SO FAR.
- (NOTE: IF NOT USING A II-PHASE
- DRIVE, CHANGE ALL THE COMMENTS
- BELOW THAT REFER TO HALFTRACKS
- TO REFER TO FULLTRACKS INSTEAD.)
SEEKIT STA DESTRK ;(A) = HALFTRACK# WANTED.
JSR SLOTX2Y ;CONVERT (X)=SLOT*16-->(Y)=SLOT.
LDA TRK4DRV1,Y ;PRES HALFTRK # ASSOC WITH DRV1.
BIT DRVZPG ;CONTAINS: NEG=DRV1, POS=DRV2.
BMI SETPRSTK ;BRANCH IF USING DRIVE1.
LDA TRK4DRV2,Y ;USING DRIVE2 SO GET PRESENT
;HALFTRACK # ASSOC WITH DRIVE 2.
SETPRSTK STA PRESTRK ;SAVE PRESENT HALFTRK#.
- DESIGNATE HALFTRK WE ARE ABOUT
- TO SEEK AS PRESENT HALFTRK FOR
- NEXT TIME AROUND. (PUT HALFTRK
- INFO IN SLOT-DEPENDENT LOCATIONS.)
LDA DESTRK ;HALFTRK WANTED.
BIT DRVZPG ;CHK WHICH DRIVE WE'RE USING.
BMI DRV1USG ;BRANCH IF USING DRIVE 1.
STA TRK4DRV2,Y ;USING DRIVE2 -STORE HALFTRK INFO
;FOR NEXT TIME AROUND.
BPL DRV2USG ;ALWAYS.
DRV1USG STA TRK4DRV1,Y ;USING DRIVE1. STORE HALFTRK INFO
;FOR NEXT TIME AROUND.
DRV2USG JMP SEEKABS ;GO MOVE DRIVE ARM.
- ===================================
- TRANSLATE (X)=SLOT*16 TO (Y)=SLOT.
- ===================================
SLOTX2Y TXA ;GET SLOT*16 FROM (X).
LSR ;DIVIDE IT BY 16.
LSR
LSR
LSR
TAY ;PUT SLOT# IN (Y).
RTS
- =================================
- GO SELECT DRIVE AND PUT TRACK #
- WANTED IN MEMORY LOCATION ASSOC
- WITH THE # OF THE DRIVE WE'RE
- USING.
- =================================
SETTRK PHA ;SAVE PRESENT TRK # ON STK.
LDY #2 ;GET DRV # WANTED FROM IOB.
LDA (PTR2IOB),Y
ROR ;CONDITION CARRY:
; (C)=0=DRV1, (C)=1=DRV2.
ROR DRVZPG ;CONDITION ZERO-PAGE LOCATION:
; NEG=DRV1, POS=DRV2.
JSR SLOTX2Y ;USE (X)=SLOT*16 TO GET (Y)=SLOT.
PLA ;GET TRK # WANTED OFF STK.
ASL ;TIMES TWO FOR 1/2TRACK # WANTED.
BIT DRVZPG ;CHK WHICH DRIVE TO USE.
BMI STORDRV1 ;BRANCH IF USING DRIVE 1.
STA TRK4DRV2,Y ;SAV HALFTRK # WANTED FOR DRIVE2.
BPL RTNSETRK ;ALWAYS.
STORDRV1 STA TRK4DRV1,Y ;SAVE HALFTRK # WANTED 4 DRIVE1.
RTNSETRK RTS
- =================================
- RWTS'S FORMAT COMMAND.
- =================================
- INITIALIZE ZERO-PAGE LOCATIONS.
FORMAT LDY #3 ;GET VOL FRM IOB, STORE IN Z-PAGE.
LDA (PTR2IOB),Y
STA FRMTVOL
LDA #$AA ;STORE "AA" AS CONSTANT IN Z-PAGE.
STA HOLDAA
LDY #$56 ;INITIALIZE INDEX TO BUFFER.
LDA #0 ;INITIALIZE TRK COUNTER.
STA FRMTKCTR ;NOTE: ALWAYS BEGIN FORMATTING
;WITH TRACK $00.
- ZERO OUT THE RWTS BUFFERS.
- (NOTE: WHEN FORMATTING, THESE
- "$00" BUFFER BYTES WILL LATER BE
- TRANSLATED AND WRITTEN TO THE
- DISK AS "$96" DISK BYTES.)
- ZERO OUT RWTS BUFFER THAT NORMALLY
- CONTAINS 2-ENCODED NIBBLES.
- (RWTSBUF2, $BC00 <--- $BC55.)
ZBUF2 STA RWTSBUF1+$FF,Y ;($BC55 --> $BC00.)
DEY
BNE ZBUF2
- ZERO OUT RWTS BUFFER THAT NORMALLY
- CONTAINS 6-ENCODED NIBBLES.
- (RWTSBUF1, $BB00 ---> $BBFF.)
ZBUF1 STA RWTSBUF1,Y
DEY
BNE ZBUF1
- PREPARE TO DO A RECALIBRATION.
LDA #80 ;PRETEND WE'RE ON TRK #80.
JSR SETTRK ;GO SELECT DRV & PUT HALFTRACK #
;WANTED IN MEMORY LOCATION ASSOC
;WITH THE # OF DRV BEING USED.
LDA #40 ;SET UP FOR 40 SYNCS BTWN SECS
STA SYNCNTR ;ON TRK0. NOTE THAT THIS # WILL
;LATER BE REDUCED AS WE WRITE
;SUBSEQUENT TRKS.(HIGHER NUMBERED
;TRKS ARE CLOSER TO THE CENTER OF
;THE DSK & THERE4 ARE REPRESENTED
;BY SMALLER CIRCLES. WE CAN CROWD
;ALL THE SECS INTO A SMALLER
;CIRCUMFERENCE BY REDUCING THE #
;OF SYNC BYTES BETWEEN SECS.
FRMNXTRK LDA FRMTKCTR ;USE TRK COUNTER AS TRK TO SEEK.
JSR SEEKTRK ;POS'N ARM OVER CORRECT TRK.
- GO FORMAT A SPECIFIC TRACK.
JSR FORMATRK ;FORMAT A TRACK.
LDA #8 ;SET (A) AS DEFAULT VALUE IN CASE
;COULDN'T FORMAT. NOTE THAT ANY
;TYPE OF ERROR ENCOUNTERED WHEN
;FORMATTING YEILDS AN I/O-ERROR
;MESSAGE.
BCS ERRFRMT ;BRANCH IF COULDN'T FORMAT.
- DO A READ CHK OF TRK JUST FORMATTED.
- (EVENTHOUGH TRACK VERIFIED, READ
- IT AGAIN UNTIL LOCATE TRK0.
- (PRESUMABLY, THIS (PARTIALLY)
- DOUBLE CHECKS VERIFICATION AND
- KEEPS SECTORS IN DIFFERENT TRACKS
- SOMEWHAT ADJACENT?)
LDA #48 ;SET 48 ATTEMPTS TO READ.
STA READCNTR
RDAGAIN SEC ;DEFAULT (C)=1 TO SIGNAL ERROR.
DEC READCNTR ;REDUCE CHANCES TO READ.
BEQ ERRFRMT ;EXHAUSTED ALL CHANCES.
JSR RDADDR ;GO READ ADDR HEADER TO FIND SEC
;THAT WE WANT TO READ OR WRITE.
BCS RDAGAIN ;BAD READ - TRY AGAIN.
LDA SECDSK ;WAS IT SECTOR 0?
BNE RDAGAIN ;NO - TRY AGAIN.
JSR READATA ;LAST CHANCE TO READ DATA.
BCS RDAGAIN ;LAST CHANCE BOMBED OUT!!!
INC FRMTKCTR ;KICK UP TRK COUNTER.
LDA FRMTKCTR ;SET (A) FOR NEXT TRK COUNT.
CMP #$23 ;DONE ALL TRACKS YET (#0 TO #34)?
BCC FRMNXTRK ;NO - GO FORMAT THE NEXT TRACK.
CLC ;SIGNAL FINISHED ALL TRACKS.
BCC DONEFRMT ;ALWAYS - ONLY GOOD EXIT.
- NOTE: NO MATTER WHAT KIND OF ERROR
- WE MIGHT HAVE ENCOUNTERED WHEN
- FORMATTING, THE IOB ERROR CODE IS
- SET TO $08. THIS IS LATER TRANSLATED
- TO AN FM ERROR CODE (ALSO $08) WHICH
- DOS DISPLAYS AS AN I/O ERROR MSG.
- (THIS IS WHY TRYING TO FORMAT A
- WRITE-PROTECTED DISK RESULTS IN AN
- I/O ERROR MSG INSTEAD OF A DISK-
- WRITE-PROTECTED MSG.)
- IF NO ERROR OCCURRED, THE IOB RETURN
- CODE WILL BE SET TO SOME RANDOM
- NUMBER (FROM REFERENCING A HARD-
- WARE SWITCH ADDRESS).
ERRFRMT LDY #13 ;INDEX TO RETURN CODE IN IOB.
STA (PTR2IOB),Y ;STORE RETURN CODE.
SEC ;SIGNAL THAT AN ERROR OCCURRED.
DONEFRMT LDA MTROFF,X ;TURN THE MOTOR OFF, XIT WITH (C)
RTS ;DENOTING SUCCESS STATUS.
- ------------------------------------
- SUBROUTINE 2 FORMAT A SPECIFIC TRK.
- ------------------------------------
- SECTORS ARE WRITTEN IN ASCENDING
- ORDER FROM SEC $00 TO SEC $0F.
- (NOTE THAT THE FORMAT ROUTINE ONLY
- DEALS WITH PHYSICAL SECTOR NUMBERS.)
FORMATRK LDA #0 ;ALWAYS START WITH SEC $00.
STA FRMTSEC
LDY #128 ;USE 128 SYNC BYTS BEFORE SEC$00.
;NOTE: THIS GAP WILL BE PARTIALLY
;OVERWRITTEN BY SEC $0F.
BNE DOADDR ;ALWAYS.
FRMTASEC LDY SYNCNTR ;SET (Y)= # OF 40-CYCLE SELF-SYNC
;BYTES TO BE WRITTEN BTWN SECS.
;(THIS # VARIES DEPENDING ON THE
;SPEED OF THE SPECIFIC DRV BEING
;USED & THE # OF THE TRK BEING
;WRITTEN.)
DOADDR JSR WRITADR ;WRITE SYNC BYTES & ADDR HEADER.
BCS VRFYRTN ;ERROR -DISK WAS WRITE PROTECTED.
JSR WRITESEC ;WRITE SYNC GAP BTWN ADDR & DATA
;FIELDS, WRT DATA & WRITE A SYNC
;BYTE AFTER DATA EPILOGUE.
BCS VRFYRTN ;IRRELEVANT - NEVER TAKEN BECAUSE
;WE ALREADY CHECKED THE WRITE-
;PROTECT SWTCH WHEN WE WROTE ADR.
INC FRMTSEC ;INCREASE SEC #.
LDA FRMTSEC
CMP #$10 ;DONE ALL 16 SECS YET?
BCC FRMTASEC ;NO - GO DO SOME MORE.
- ......................................
- VERIFY A SINGLE TRACK.
- ......................................
- NOTE WE JUST FINISHED FORMATTING
- SEC $0F. BECAUSE SEC $0F SHOULDN'T
- OVERWRITE TOO MUCH OF OF THE SYNC GAP
- (ORIGINALLY 128 SYNC LONG) THAT WAS
- WAS WRITTEN PRIOR TO SEC $00, AND BECAUSE
- WE DON'T WASTE TOO MUCH TIME BETWEEN
- WRITING THE LAST BYTE OF SEC $0F AND
- LOOKING FOR THE NEXT ADDR HEADER,
- WE EXPECT TO BEGIN OUR VERIFICATION
- WITH SEC $00.
LDY #$0F ;SET COUNTER 4 # OF SECS VERIFIED
STY FRMTSEC
LDA #48 ;SET COUNTER FOR # OF ATTEMPTS.
STA READCNTR
- FILL SECTOR MAP WITH POSITIVE NUMBERS.
FILSECMP STA SECFLGS,Y
DEY
BPL FILSECMP
- DELAY TO LET SOME SYNCS PASS BY.
LDY SYNCNTR ;INITIALIZE (Y).
BYPSYNCS JSR VRFYRTN ;(12 CYC)
JSR VRFYRTN ;(12 CYC)
JSR VRFYRTN ;(12 CYC)
PHA ;(3 CYC)
PLA ;(4 CYC)
NOP ;(2 CYC)
DEY ;(2 CYC)
BNE BYPSYNCS ;(3 CYC ON BRNCH, 2 ON FALL THRU)
- READ ADDRESS OF FIRST SEC ENCOUNTERED.
- (THIS BETTER BE SEC $00!!!! IF IT
- ISN'T, OUR DRIVE IS TOO FAST & WE
- WILL EVENTUALLY HAVE TO REFORMAT
- THE TRACK.)
JSR RDADDR ;READ ADR OF 1RST SEC ENCOUNTERED
BCS REREADDR ;BAD READ, TRY AGAIN.
LDA SECDSK ;WAS SEC READ = SEC00?
BEQ RDNXTDAT ;YES - GO READ NEXT DATA SEC.
- DIDN'T FIND SECTOR $00 WHEN EXPECTED!!!!
- DRIVE MUST BE FASTER THAN ANTICIPATED
- CAUSE SEC $0F OVERLAID TOO MUCH OF
- THE LONG SYNC GAP (GAP1) THAT WAS
- ORIGINALLY WRITTEN BEFORE SEC $00.
- WE WILL EVENTUALLY HAVE TO REFORMAT
- THIS TRK USING 128 SELF-SYNCS BEFORE
- SEC $00 (GAP1) AND LESS SYNC BYTES
- BETWEEN OTHER SECS (GAP3). THIS
- WILL INSURE THAT LESS GAP-1 SYNCS
- WILL BE OVERWRITTEN BY SEC $OF.
- NOTE THAT DEPENDING ON JUST HOW
- MUCH TOO FAST THE DRIVE IS, WE MAY
- HAVE TO REFORMAT THIS TRK SEVERAL
- TIMES BEFORE WE GET IT RIGHT. EACH
- TIME WE REFORMAT, WE REDUCE THE #
- OF GAP-3 SYNCS. IF THE SYNC COUNTER
- IS > = 16, WE WRITE 2 LESS SYNCS.
- IF THE COUNTER IS < 16, WE ONLY REDUCE
- GAP-3 BY ONE SYNC. IN ORDER TO GIVE
- THE MACHINE TIME TO DECODE INFO, WE
- WON'T ALLOW A GAP LESS THAN 5 SYNCS
- LONG. (NOTE THAT WE WON'T REFORMAT
- THE TRACK UNTIL WE FIND THE ADR HEADER
- FOR SEC $0F. THIS PRESUMABLY KEEPS
- LIKE-NUMBERED SECS IN ADJACENT TRKS
- IN SOME SEMBLANCE OF ORDER.)
LDA #16
CMP SYNCNTR ;CONDITION CARRY.
LDA SYNCNTR ;IF SYNC COUNT < 16, SUBTRACT 1,
SBC #1 ;ELSE SUBTRACT 2.
STA SYNCNTR
CMP #5 ;DO WE HAVE AT LEAST 5 SYNCS?
BCS REREADDR ;YES.
SEC ;NO - SIGNAL ERROR CAUSE NEED AT
RTS ;LEAST 5 SYNCS. DRIVE IS SO FAST
- === ;THAT IT IS USELESS. WE CAN'T
;EVEN COMPENSATE 4 IT BY REDUCING
;THE NUMBER OF GAP-3 SYNCS.
- READ THE SEC ADDR & DATA PROPER.
RDNXTADR JSR RDADDR ;READ THE ADDR HEADER.
BCS BADREAD ;BRANCH IF BAD ADDRESS READ.
RDNXTDAT JSR READATA ;READ THE DATA PROPER.
BCC CKSECMAP ;READ WAS GOOD -SO GO CHK IF THIS
;SEC HAS ALREADY BEEN READ.
BADREAD DEC READCNTR ;EITHER GOT A BAD READ OR ELSE
;WE ALREADY VERIFIED THIS SEC.
;REDUCE THE # OF CHANCES LEFT.
BNE RDNXTADR ;MORE CHANCES LEFT -GO TRY AGAIN.
- DOING A RE-READ. WILL DEFINITELY
- HAVE TO REFORMAT.
REREADDR JSR RDADDR ;READ AN ADDR HEADER.
BCS NOTLAST ;GOT A BAD READ.
- WE WILL REFORMAT BUT WE DON'T WANT
- TO DO SO UNTIL WE READ SEC $0F.
- HAVE WE FOUND SEC $0F YET?
LDA SECDSK ;GET PHYS # OF SEC JUST READ.
CMP #$0F ;WAS IT SEC 15?
BNE NOTLAST ;NO, SO GO LOOK SOME MORE.
JSR READATA ;YES - READ THE DATA IN SEC $0F.
BCC FORMATRK ;GOOD READ ON SEC15 SO NOW TIMING
;IS RIGHT TO GO REFORMAT THIS TRK
NOTLAST DEC READCNTR ;BAD READ, CK IF MORE CHANCES LFT
BNE REREADDR ;YES - GO TRY AGAIN.
SEC ;EXHAUSTED ALL CHANCES, SO SET
VRFYRTN RTS ;(C) AS ERROR FLAG & EXIT.
- CHECK IF THIS SEC WAS PREVIOUSLY
- VERIFIED. IF NOT, UPDATE SECTOR
- VERIFICATION MAP. (IF TIMING IS
- RIGHT, SHOULD NEVER ENCOUNTER AN
- ALREADY VERIFIED SEC BEFORE FRMTSEC
- DECREMENTS FROM $0F DOWN TO $FF.)
CKSECMAP LDY SECDSK ;USE # OF SEC FOUND AS INDEX TO
;THE VERIFICATION MAP.
LDA SECFLGS,Y ;GET MAP BYT (NEG=PREV VERIFIED).
BMI BADREAD ;OH!OH! ALREADY VERIFIED THIS ONE
LDA #$FF ;SET BYTE IN MAP TO SIGNAL THAT
STA SECFLGS,Y ;THIS SEC WAS JUST VERIFIED.
DEC FRMTSEC ;ANY SECS LEFT TO VERIFY?
BPL RDNXTADR ;YES - GO DO SOME MORE.
- ALL SECS VERIFIED, SO CHECK
- IF WE JUST DID TRACK $00.
LDA FRMTKCTR ;WAS TRK JUST FORMATTED =TRK $00?
BNE NOTRK0 ;NO - SO EXIT CLEANLY.
- JUST FORMATTED & VERIFIED TRK $00.
- TRK $00 IS THE OUTSIDE TRK AND THERE4
- HAS THE LARGEST LENGTH IN WHICH TO
- WRITE BYTES. BECAUSE SUBSEQUENT
- TRKS HAVE A SMALLER CIRCUMFERENCE,
- WE MUST REDUCE THE NUMBER OF SYNCS
- TO WRITE BETWEEN SECS (GAP3) SO WE
- CAN GET ALL THE NEEDED INFO INTO
- A SMALLER SPACE.
LDA SYNCNTR ;CHECK SYNC COUNT.
CMP #16 ;LESS THAN 16 SYNCS?
BCC VRFYRTN ;YES - EXIT CLEANLY.
;DON'T WANT TO START OFF WITH A
;SMALLER GAP SO SKIP CODE BELOW.
DEC SYNCNTR ;GAP > = 16 SYNCS LONG, SO CAN
DEC SYNCNTR ;AFFORD 2 REDUCE IT BY 2 IN ORDER
NOTRK0 CLC ;TO ACCOMMODATE A TIGHTER TRACK.
RTS ;EXIT CLENALY.
- =================================
- FLAGS FOR SECTOR VERIFICATION.
- ($BFA8 - $BFB7)
- - NEG VAL = SECTOR VERIFIED.
- - TABLE IS INDEXED BY (Y),
- WHERE (Y) = SECTOR NUMBER.
- =================================
SECFLGS HEX FFFFFFFFFFFFFFFF ;SECS $00 TO $07.
HEX FFFFFFFFFFFFFFFF ;SECS $08 TO $0F.
- =================================
- PHYSICAL SECTOR NUMBERS
- ($BFB8 - $BFC7)
- - LISTED IN LOGICAL ORDER.
- =================================
;CORRESPONDING LOGICAL SECTOR#.
PHYSECTR HEX 00 ; 00
HEX 0D ; 01
HEX 0B ; 02
HEX 09 ; 03
HEX 07 ; 04
HEX 05 ; 05
HEX 03 ; 06
HEX 01 ; 07
HEX 0E ; 08
HEX 0C ; 09
HEX 0A ; 0A
HEX 08 ; 0B
HEX 06 ; 0C
HEX 04 ; 0D
HEX 02 ; 0E
HEX 0F ; 0F
- =================================
- CLOBBER THE LANGUAGE CARD.
- ($BFD9 - $BFDB)
- - PATCH CALLED BY BOOT2.
- =================================
CLOBCARD JSR SETVID ;SIMULATE A "PR#0" STATEMENT.
LDA $C081 ;WRITE ENABLE RAM CARD.
LDA $C081 ;(READ MOTHER/WRITE CARD BANK2.)
LDA #0 ;SET LANGUAGE IDENTIFYING BYTE ON
STA BASICCLD ;CARD TO $00 SO IF CARD IS TESTED
;(DURING AN "FP" CMD), THE
;MACHINE WILL BE FORCED TO USE
;MOTHERBOARD VERSION OF FP.
JSR CONTCLOB ;NOW CLOBBER THE 80-COLUMN CARD.
JMP BK2BOOT2 ;RTN TO ORIGINAL PART OF BOOT2.
- ===================================
- PATCH TO ZERO ADDED STORAGE BYTES.
- ($BFDC - $BFE5)
- ===================================
ZEROPTCH STA TEMPBYT
STA BYTPRSD
STA BYTPRSD+1
RTS
- =================================
- PATCH TO SET CONDITION 0 AND
- CLEAR THE RUN INTERRUPT FLAG.
- ($BFE6 - $BFEC)
- =================================
RESTATIN JSR RESTAT0 ;ZERO OUT CONDNFLG & OPUTCOND.
STY RUNTRUPT ;CLR THE RUN INTERRUPT FLAG.
RTS
- =================================
- DISK-FULL ERROR PATCH.
- ($BFED - $BFFF)
- =================================
FULLPTCH JSR CPYFMWA ;COPY FM WRK AREA--->FM WRK BUF.
LDX STKSAV ;RESTORE STACK POINTER.
TXS
JSR CLOSEALL ;CLOSE ALL FILES.
TSX
STX STKSAV ;SAVE STACK POINTER.
LDA #9 ;EXIT WITH DISK-FULL ERROR CODE.
JMP BADFMXIT
- *********************************
- END OF DOS ($BFFF) *
- *********************************