textfiles/apple/ANATOMY/t.dos.bd00.bfff.txt

979 lines
27 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

*=================================
* 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
* CHECK DRIVE STATUS.
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.
* COMMAND WAS WRITE
WASWRITE JSR PRENIBL ;CONVERT 256 MEMORY BYTES TO 342
;6-BIT NIBBLES NEEDED FOR WRITING.
* COMMON TO READ OR WRITE.
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.
* GOT A GOOD READ.
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#.
* GOT A VOLUME MISMATCH.
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.
* USING A TWO-PHASE DRIVE.
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.
* FORMAT THE NEXT TRACK.
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.
* INTIALIZE COUNTERS.
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.
* REDUCE THE SIZE OF GAP3.
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) *
**********************************