💾 Archived View for mirrors.apple2.org.za › archive › www.textfiles.com › apple › ANATOMY › t.dos.af… captured on 2023-01-29 at 11:41:53.

View Raw

More Information

-=-=-=-=-=-=-



READVTOC LDA #1 ;READ OPCODE FOR RWTS.
 BNE RDWRVTOC ;ALWAYS.




WRITVTOC LDA #2 ;WRITE OPCODE FOR RWTS.



RDWRVTOC LDY ADRVTOC ;GET ADR OF VTOC FRM FM CONSTANTS
 STY IBBUFP ;TABLE & DESIGNATE IT AS THE I/O
 LDY ADRVTOC+1 ;BUF IN RWTS'S IOB.
 STY IBBUFP+1
 LDX TRKWA ;ENTER RWTS DRIVER WITH (X)/(Y)
 LDY #0 ;EQUAL TO TRK/SEC VALS OF VTOC.
 JMP RWTSDRVR ;CALL DRIVER TO READ/WRITE VTOC.




RDDIRECT PHP ;SAVE (C) ON STK:
;   (C) = 0 = READ 1RST DIR SEC.
;   (C) = 1 = READ NEXT DIR SEC.

 JSR PT2DIRBF ;DESIGNATE DIR SEC BUF AS I/O BUF
;IN RWTS'S IOB.
 PLP ;CHK IF DEALING WITH 1RST DIR SEC
 BCS RDNXTDIR ;NO - GO READ NEXT DIR SEC.



RDFIRDIR LDY FIRDIRSC ;(Y)/(X)=TRK/SEC VALS OF 1RST
 LDX FIRDIRTK ;DIRECTORY SEC (FROM VTOC BUF).
 BNE DODIRRD ;ALWAYS - GO READ IN DIREC SEC.



RDNXTDIR LDX DIRLNKTK ;GET TRK OF NXT DIR SEC FROM LINK
;IN CURRENT DIRECTORY SECTOR.
 BNE GETDIRLK ;LINK NOT ZEROED OUT.
 SEC ;LINK ZEROED OUT -EXIT WITH (C)=1
 RTS ;TO SIGNAL NO MORE DIREC SECS.


GETDIRLK LDY DIRLNKSC ;GET SEC OF NEXT DIR SEC FRM LINK
;BYTES IN CURRENT DIRECTORY SEC.



DODIRRD STX CURDIRTK ;SAV TRK/SEC VALS OF DIRECTORY WE
 STY CURDIRSC ;ARE ABOUT 2 READ SO THEY WILL BE
;THE CURRENT DIRECTORY SEC VALS
;FOR THE NEXT TIME AROUND.
 LDA #1 ;READ OPCODE FOR RWTS.
 JSR RWTSDRVR ;CALL RWTS DRIVER TO DO THE READ.
 CLC ;LINK DIDN'T ZERO OUT SO SIGNAL
 RTS ;MORE DIREC SECS EXIST & THEN XIT




WRDIRECT JSR PT2DIRBF ;DESIGNATE DIREC SEC BUF AS I/O
;BUF IN RWTS'S IOB.
 LDX CURDIRTK ;ENTER RWTS DRIVER WITH (X)/(Y)
 LDY CURDIRSC ;EQUAL TO THE TRK/SEC VALS OF THE
;DIRECTORY SECTOR.
 LDA #2 ;WRITE OPCODE FOR RWTS.
 JMP RWTSDRVR ;CALL DRIVER TO WRITE DIREC SEC.




PT2DIRBF LDA ADRDIRBF ;GET ADDR OF DIREC SEC BUF FROM
 STA IBBUFP ;FM CONSTANTS TBL & DESIGNATE IT
 LDA ADRDIRBF+1 ;AS I/O BUFFER IN RWTS'S IOB.
 STA IBBUFP+1
 RTS




RWTSDRVR STX IBTRK ;ENTER WITH (X) = TRK WANTED.
 STY IBSECT ;           (Y) = SEC WANTED.
RWTSDRV1 STA IBCMD ;           (A) = OPCODE FOR RWTS
;RWTSDRV1 = ENTRY PT USED BY INIT
;FUNCTION HNDLR WHEN FORMATTING.
 CMP #2 ;IS CMD A WRITE?  NOTE: THE "CMP"
;CONDITIONS THE CARRY AS FOLLOWS:
;(C)=0 =SEEK ($00) OR READ ($01)
;(C)=1 =WRITE($02) OR FORMAT($03)
 BNE SKPWRSET ;BRANCH IF NOT WRITING.
 ORA UPDATFLG ;CONDITION UPDATE FLG 2 DESIGNATE
 STA UPDATFLG ;LAST OPERATION WAS A WRITE (FOR
;NEXT TIME AROUND).



SKPWRSET LDA VOLWA ;PUT COMPLEMENTED VOL IN IOB.
 EOR #$FF
 STA IBVOL
 LDA SLOT16WA ;PUT SLOT*16 IN IOB.
 STA IBSLOT
 LDA DRVWA ;PUT DRIVE # IN IOB.
 STA IBDRVN
 LDA SECSIZWA ;PUT SEC LENGTH IN IOB  (STANDARD
 STA IBSECSZ ;SIZE OF #256 OR $0100 BYTES).
 LDA SECSIZWA+1
 STA IBSECSZ+1
 LDA #1
 STA IBTYPE
 LDY ADRIOB ;SET (Y) & (A) TO POINT AT
 LDA ADRIOB+1 ;RWTS'S IOB.




 JSR ENTERWTS ;SAV STATUS,SET INTERRUPT DISABLE
;FLAG & CALL RWTS TO PERFORM TASK
;(SEEK, READ, WRITE, FORMAT).
 LDA IBSMOD ;GET VOL FOUND (FRM IOB) & PUT IT
 STA VOLFM ;IN THE FM PARAMETER LIST.
 LDA #$FF ;PUT VOL WANTED IN IOB.
 STA IBVOL ;(USE 255 AS DEFAULT VAL FOR NEXT
;TIME.  ACTUALLY USING 0 CAUSE
;#$FF EOR #$FF = $00).
 BCS ERRWTSDR ;OPERATION WAS UNSUCCESSFUL.
 RTS ;ABOVE BRANCH NEVER TAKEN WHEN
;USING SEEK CMD, CAUSE NO ERROR
;CHKING ROUTINES ARE ENCOUNTERED
;BY A LONE SEEK OPERATION.




ERRWTSDR LDA IBSTAT ;GET RWTS'S ERROR CODE.



 LDY #7 ;SET (Y) FOR FM ERROR CODE.
 CMP #$20 ;VOL MISMATCH?
 BEQ SETFMERR ;YES.
 LDY #4 ;NO.
 CMP #$10 ;WRITE PROTECTED?
 BEQ SETFMERR ;YES.
 LDY #8 ;NO - MUST HAVE BEEN OTHER SO
SETFMERR TYA ;DESIGNATE IT AS GENERAL I/O ERR.
 JMP BADFMXIT ;GO HANDLE ERROR.
;ANY ERR ENCOUNTERED WHEN FORMAT-
;TING IS TREATED AS AN I/O ERROR.








NXTDATRD LDA FILPTSEC ;LAST SEC USED VS CUR SEC WNTD.
 CMP RELPREV
 BNE CKWCURDA ;NOT SAME - WILL EVENTUALLY HAVE
;TO READ NEW DATA SEC IN.
 LDA FILPTSEC+1 ;MAYBE SAME - CHK HI BYTES.
 CMP RELPREV+1
 BEQ XITNXDAT ;SAME SO GO EXIT.






CKWCURDA JSR CKDATUP ;CHK UPDATE FLG 2 SEE IF DATA SEC
;BUF HAS CHANGED SINCE LAST R/W.
;IF IT HAS, WRITE DATA BUF 2 DSK.





CKCURTS LDA FILPTSEC+1 ;SEC OFFSET INTO FILE ASSOCIATED
 CMP RELFIRST+1 ;WITH THE PRESENT DATA SECTOR
;VERSUS THE RELATIVE SEC# OF THE
;FIRST DATA SEC DESCRIBED IN THE
;PRESENT T/S LIST.
 BCC NEEDNXTS ;DATA SEC WANTED REPRESENTS A
;SMALLER OFFSET INTO FILE SO NEED
;A DIFFERENT T/S LIST.
  BNE CKCURTS1 ;SEC OFFSET OF WANTED DATA SEC IS
;LARGER THAN THAT OF THE 1RST DAT
;SEC THAT CAN BE DESCRIBED IN THE
;PRESENT T/S LIST SO IT MAY STILL
;BELONG TO THIS T/S LIST.
 LDA FILPTSEC ;HI BYTES SAME -SO CMP LOW BYTES.
 CMP RELFIRST
 BCC NEEDNXTS ;SEC OFFSET OF WNTD FILE IS LESS
;SO READ IN A DIFFERENT T/S LIST.
;(START BY READING THE FILE'S
;FIRST T/S LIST.)



CKCURTS1 LDA FILPTSEC+1 ;SEC OFFSET OF DATA SEC WANTED
 CMP RELASTP1+1 ;VS RELATIVE SEC # OF THE LAST
;DATA SEC THAT CAN POSSIBLY BE
;DESCRIBED IN THE PRES T/S LIST.
 BCC GETDATPR ;SEC OFFSET ASSOC WITH DATA SEC
;WANTED IS DESCRIBED IN THE
;PRESENT T/S LIST.
 BNE NEEDNXTS ;SEC OFFSET OF PRESENT DATA SEC
;IS LARGER THAN THAT OF THE LAST
;DATA SECTOR (PLUS 1) THAT CAN
;POSSIBLY BE DESCRIBED IN THE
;PRESENT T/S LIST, SO WE NEED A
;NEW T/S LIST SECTOR.
 LDA FILPTSEC ;HI BYTES SAME -SO CMP LOW BYTES.
 CMP RELASTP1
 BCC GETDATPR ;SEC OFFSET ASSOCIATED WITH THE
;DATA SECTOR WE WANT IS LESS THAN
;THE RELATIVE SEC # (PLUS 1) OF
;THE LAST DATA SECTOR THAT CAN
;POSSIBLY BE LISTD IN THE PRESENT
;T/S LIST.  (THERE4, THE WANTED
;DATA SEC SHOULD BE DESCRIBED IN
;THE PRESENT T/S LIST.)



NEEDNXTS JSR READTS ;READ IN THE NEXT (OR FIRST) T/S
;LIST.  HOWEVER, FIRST CHECK THE
;UPDATE FLAG TO SEE IF THE T/S
;LST PRESENTLY IN MEMORY REQUIRES
;UPDATING BEFORE WE READ IN THE
;NEXT (OR FIRST) T/S LIST SECTOR.
;IF UPDATING IS REQUIRED, WRITE
;THE PRESENT T/S LIST.
 BCC CKCURTS ;GO BACK & CHK IF THIS IS CORRECT
;T/S LIST.
 RTS ;RTN WITH (C)=1 TO SIGNAL THAT WE

;READING  OR TO DO GOOD EXIT IF
;RAN OUT OF DATA WHILE VERIFYING
;OR 2 SIGNAL POSSIBLE ERROR WHILE
;APPENDING.



GETDATPR SEC ;CALC OFFSET TO DATA PAIR:
 LDA FILPTSEC ;SEC OFFSET OF DATA SEC INTO FILE
 SBC RELFIRST ;MINUS REL INDEX OF 1RST DATA SEC
;DESCRIBED IN PRES T/S LIST.
 ASL  ;TIMES 2 CAUSE 2 BYTES USED TO
;DESCRIBE A DATA PAIR.
 ADC #12 ;ADD 12 CAUSE 1RST DATA PAIR IS
 TAY  ;ALWAYS LISTED 12 BYTES FROM THE
;START OF THE T/S LIST BUFFER.
 JSR SELTSBUF ;POINT A4L/H AT THE T/S LIST BUF.
 LDA (A4L),Y ;GET TRK # OF DATA SEC PAIR.
 BNE RDDATSEC ;GO READ IN THE DATA SECTOR.



 LDA OPCODEFM ;CHECK TO SEE IF WRITING OR NOT.
 CMP #4 ;OPCODE FOR WRITE.
 BEQ NEWPAIR ;BRANCH IF WRITING.
 SEC ;NOT WRITING & RAN OUT OF DATA
 RTS ;SECTOR PAIRS DESCRIBED IN THE

;CARRY SET 2 SIGNAL NO MORE DATA.



NEWPAIR JSR NWDATKSC ;ADD NEW DATA SEC PR TO T/S LIST,
;ZERO OUT DATA SEC BUF & SET
;UPDATE FLAG TO SIGNAL THAT BOTH
;T/S LIST SEC & DATA SEC REQUIRE
;UPDATING.
 JMP SETPREV ;NOTE:  IF YOU FOLLOW THIS JUMP

;TIMES WE EVENTUALLY EXIT THE
;PRESENT FUNCTION WITHOUT WRITING
;THE T/S LIST AND DATA SEC BUFS
;BACK TO THE DISK. HOWEVER, AFTER
;THE SUBFUNCTIONS ARE EXITED, THE
;CLOSE FUNCTION EVENTUALLY TESTS
;THE STATUS OF THE UPDATE FLAG
;(UPDATFLG, $B5D5) & THEN WRITES
;THE T/S LIST & DAT SEC BUFS BACK
;TO THE DISK.



RDDATSEC STA CURDATRK ;SAVE TRK/SEC VALS OF CURRENT DATA
 INY ;SECTOR IN THE WORK AREA.
 LDA (A4L),Y ;SEC# OF CURRENT DATA SEC.
 STA CURDATSC
 JSR READDATA ;GO READ IN THE DATA SECTOR.



SETPREV LDA FILPTSEC ;CURRENT SEC OFFSET INTO FILE.
 STA RELPREV ;OFFSET IN FILE OF LAST DAT READ.
 LDA FILPTSEC+1
 STA RELPREV+1



XITNXDAT JSR SELDABUF ;POINT A4L/H AT DATA SEC BUF.
 LDY FILPTBYT ;(Y)=BYT OFFSET IN2 CUR DATA SEC.
 CLC  ;EXIT CLEANLY.
 RTS




NWDATKSC STY SCRNSRCH ;SAVE OFFSET 2 DAT PR IN T/S LST.
 JSR ASGNTKSC ;FIND & DESIGNATE AN AVAIL SEC.
 LDY SCRNSRCH ;RETRIEVE OFFSET TO DATA PAIR.
 INY
 STA (A4L),Y ;PUT NEW SEC# IN THE T/S LIST AND
 STA CURDATSC ;WORK AREA.
 DEY
 LDA ASIGNTRK ;PUT TRK# IN T/S LST & WORK AREA.
 STA (A4L),Y
 STA CURDATRK
 JSR SELDABUF ;POINT A4L/H AT DATA SEC BUF.
ZOUTDAT JSR ZCURBUF ;ZERO OUT DATA SEC BUF.
 LDA #%11000000 ;SET BOTH BITS 6 & 7 IN FLAG TO
 ORA UPDATFLG ;SIGNAL THAT BOTH DATA & T/S LIST
 STA UPDATFLG ;SECTORS REQUIRE UPDATING.
 RTS








INCREC LDX RECNMBWA ;CURRENT RECORD #.
 STX RECNMBFM ;RECORD # IN PARAMETER LIST.
 LDX RECNMBWA+1
 STX RECNMBFM+1



 LDX BYTOFFWA ;GET OFFSET IN2 RECORD (WRK AREA)
 LDY BYTOFFWA+1
 STX BYTOFFFM ;STORE IT IN FM PARAMETER LIST.
 STY BYTOFFFM+1



 INX
 BNE BYTVSREC
 INY
BYTVSREC CPY RECLENWA+1 ;FIXED VAL VIA OPEN CMD, ELSE
;L-PARM VIA SAVE OR BSAVE CMD
;(FROM WORK AREA).
KIKOFF1 BNE SETBYTOF
 CPX RECLENWA
KIKOFF2 BNE SETBYTOF
 LDX #0 ;OFFSET INTO RECORD WAS SAME AS
 LDY #0 ;RECORD LENGTH SO PREP TO RESET
;OFFSET INTO RECORD TO ZERO.
 INC RECNMBWA
NOKIKOFF BNE SETBYTOF
 INC RECNMBWA+1



SETBYTOF STX BYTOFFWA
 STY BYTOFFWA+1
 RTS




INCFILPT INC FILPTBYT ;KICK UP OFFSET INTO THE SECTOR.
 BNE INCPTRTN ;NOT AT END OF CURRENT SECTOR.

 INC FILPTSEC ;OFFSET INTO SEC WRAPPED AROUND,
 BNE INCPTRTN ;SO AT END OF SEC, SO KICK UP THE
;OFFSET INTO THE ENTIRE FILE.
 INC FILPTSEC+1 ;INC HI BYTE IF NECESSARY.
INCPTRTN RTS




INCIOBUF LDY CURIOBUF ;GET ADR OF DEST'N/SOURCE LOC'N
 LDX CURIOBUF+1 ;FROM FM PARM LIST.
 STY A4L ;POINT A4L/H AT TARGET.
 STX A4L+1
 INC CURIOBUF ;KICK UP ADR OF DEST'N/SOURCE LOC
 BNE INCIORTN
 INC CURIOBUF+1
INCIORTN RTS




DECRWLEN LDY LEN2RDWR ;LENGTH TO READ OR LENGTH-1 TO
;WRITE (FROM FM PARM LIST).
 BNE DECLENRW ;MORE BYTES TO READ OR WRITE.
 LDX LEN2RDWR+1 ;LOW BYTE WAS 0, CHK HI BYTE.
 BEQ RWLEN0 ;COUNTER = 0 SO DONE READ/WRITE.
 DEC LEN2RDWR+1
DECLENRW DEC LEN2RDWR ;REDUCE COUNTER.
 RTS

RWLEN0 JMP GOODFMXT ;DONE READ/WRITE, EXIT FM.




GETFNTRY JSR READVTOC ;READ IN VTOC SO CAN GET LINK TO
;TRKMAPS & LINK TO 1RST DIR SEC.



 LDA FNAMBUFM ;GET ADR OF NAME BUF FROM THE
 STA A4L ;FM PARM LIST & PUT IT IN A4L/H.
 LDA FNAMBUFM+1
 STA A4L+1




 LDA #1 ;INIT SRCH COUNTER (SCRNSRCH), IN
SETSRCH STA SCRNSRCH ;FM SCRATCH SPACE FOR 2 SEARCHES
;(1 = SEARCH1, 0 = SEARCH2).
 LDA #0 ;INIT OFFSET OF FILE DESCRIP FROM
 STA SECNXD1R ;THE VERY 1RST DIRECTORY SEC.
 CLC ;(C)=0=SIGNAL TO RD 1RST DIR SEC.
GETDIRSC INC SECNXD1R ;KICK UP OFFSET FROM 1RST DIR.
;(ON FIRST ENTRY:  $00 ---> $01.)
 JSR RDDIRECT ;GO READ  DIREC SEC IN2 DIREC BUF
 BCS CHNGSRCH ;LNK ZEROED OUT, NO MORE DIRECT
;SECTORS, SO GO SWITCH SEARCHES.
 LDX #0
CKDIRTRK STX CURDIRNX ;OFFSET OF FILE DESCRIP INTO THE
;CURRRENT DIRECTORY SECTOR.
 LDA FIL1TSTK,X ;GET TRK# OF 1RST T/S LIST SEC
;FOR A PARTICULAR FILE FROM THE
;FILE DESCRIP ENTRY IN DIR SEC.
 BEQ CHRSRCHA ;IF TRK#=0, NO MORE FILES IN THIS
;DIRECTORY SECTOR.
 BMI CHRSRCHB ;SKIP DELETED FILE.  (WHEN A FILE
;IS DELETED, #$FF IS PUT IN BYTE
;WHERE TRK# OF 1RST T/S LIST IS
;USUALLY KEPT.)



 LDY #0 ;INIT INDEX TO NAME BUFFER.
 INX ;POINT (X) AT 1RST CHAR POS'N IN
 INX ;NAME FIELD OF DESCRIP ENTRY.
CMPNAMES INX
 LDA (A4L),Y ;GET CHAR OF NAME WANTED FROM THE
;PRIMARY FILENAME BUFFER.
 CMP FIL1TSTK,X ;CHAR OF NAME WANTED VS CHAR IN
;DESCRIPTION ENTRY OF DIREC SEC.
 BNE DONTMTCH ;CHARS (IE., NAMES) DON'T MATCH.
 INY
 CPY #30 ;DONE ALL CHARS YET (0 TO 29)?
 BNE CMPNAMES ;CHRS MTCH, BRANCH IF MORE 2 CHK.
 LDX CURDIRNX ;ALL CHARS MTCHD, SO NAMES MTCHD.
 CLC ;RTN WITH (X) = INDEX TO FILE
 RTS ;DESCRIP IN CURRENT DIRECTORY AND

;CORRECT FILE DESCRIP WAS FOUND.



DONTMTCH JSR NXPLUS35 ;NAMES DIDN'T MATCH, SO ADD 35 TO
;INDEX TO POINT IT AT NEXT ENTRY.
;(CHK TO MAKE SURE DON'T INDEX
;RIGHT OFF END OF DIRECTORY SEC.)
 BCC CKDIRTRK ;MORE POTENTIAL FILE DESCRIPS TO
;CHK IN THIS DIRECTORY SECTOR.
 BCS GETDIRSC ;GO GET NEXT DIRECTORY SECTOR.




CHRSRCHA LDY SCRNSRCH ;(1=SEARCH1, 0=SEARCH2)
 BNE SETSRCH ;GO SWITCH TO SECOND SEARCH.



CHRSRCHB LDY SCRNSRCH ;(1=SEARCH1, 0=SEARCH2)
 BNE DONTMTCH



NWDESCRP LDY #0 ;INIT INDEX TO PRIMARY NAME BUF.
 INX ;SET INDEX TO 1RST CHAR POS'N IN
 INX ;THE NAME FIELD OF FILE DESCRIP
SETNWNAM INX ;ENTRY SPACE N THE DIRECTORY SEC.
 LDA (A4L),Y ;COPY CHAR FROM PRIMARY NAME BUF
 STA FIL1TSTK,X ;TO DIREC DESCRIP ENTRY AREA.
 INY
 CPY #30 ;30 CHARS IN NAME (0 TO 29).
 BNE SETNWNAM ;BRANCH IF MORE CHARS TO COPY.
 LDX CURDIRNX ;RTN WITH INDEX TO FILE DESCRIP
 SEC ;IN CURRENT DIRECTORY SECTOR AND
 RTS ;WITH (C)=1 TO SIGNAL A NEW ENTRY
;WAS JUST CREATED.




NXPLUS35 CLC ;ADD 35 TO THE INDEX.  (EACH FILE
 LDA CURDIRNX ;DESCRIPTION IS 35 BYTES LONG.)
 ADC #35
 TAX ;CHK IF MORE SPACE FOR ENTRIES IN
 CPX #245 ;CURRENT DIRECTORY.
 RTS ;EXIT WITH (C) CONDITIONED:
; (C)=0=MORE SPACE IN DIRECTORY.
; (C)=1=RAN OFF END OF DIRECTORY.




CHNGSRCH LDA #0 ;SET (A) = 0 SO WE CAN RESET
;SCRNSRCH IF WE HAVE 2 GO BACK 2
;DO A SECOND SEARCH.
 LDY SCRNSRCH ;(1=SEARCH1, 0=SEARCH2.)
 BNE SETSRCH ;JUST DID FIRST SEARCH, SO NOW GO
;BACK TO START SECOND SEARCH.
 JMP DISKFULL ;EVEN THE SECOND SEARCH WAS
;UNSUCCESSFUL, SO GO HANDLE A
;DISK-FULL ERROR.









ASGNTKSC LDA ASIGNTRK
 BEQ PRPNWTRK ;BRANCH IF NO TRK ASSIGNED YET.
;(ALWAYS TAKEN 1RST TIME "JSR" TO
;HERE FRM CREATNEW. HOWEVER, WHEN
;WE LATER JSR TO HERE, ASIGNTRK
;EQUALS THE TRK # FOR T/S LIST.)



ANYAVAIL DEC ASIGNSEC ;NEXT SECTOR BE ASSIGNED.
 BMI ASGNWTRK ;IF DEC FROM $00 ==> #$FF, THEN
;NO MORE FREE SECS ON THIS TRK.



 CLC ;ROLL BITS IN THE 4-BYTES OF
 LDX #4 ;ASIGNMAP AS AS UNIT - ROLL THEM
;BACK TO STANDARD POSITION.
ADJSTMAP ROL ASIGNMAP-1,X ;IF C=1, SEC ASSOC WITH ROLLED
 DEX ;BIT POS'N IS FREE TO BE ASSIGNED
 BNE ADJSTMAP ;TO A NEW FILE.
 BCC ANYAVAIL ;SEC NOT FREE - GO GET NEXT ONE.



 INC FILENSEC ;SEC WAS FREE, SO KICK FILE SIZE
 BNE XWITHFRE ;UP BY 1 & RTN WITH FREE SEC# IN
 INC FILENSEC+1 ;(A) SO IT CAN LATER BE USED FOR
XWITHFRE LDA ASIGNSEC ;THE T/S LIST SECTOR.
 RTS ;(ACTUALLY ONLY GOOD EXIT AVAIL.)




ASGNWTRK LDA #0 ;SET SIGNAL TO ASSIGN NEW TRK.
 STA ASIGNTRK



PRPNWTRK LDA #0
 STA TRK0YET ;SIGNAL NOT ALL TRKS CHECKED YET.
 JSR READVTOC ;READ IN THE VTOC TO FIND NEXT
;TRK TO USE.



GETNWTRK CLC
 LDA NXTRKUSE ;GET NEXT TRK# TO ASSIGN.
 ADC DRECTION ;DIRECTION (+1/-1) OF ASSIGNMENT.
 BEQ CKIFFULL ;IF 0, GO SEE IF CHKD ALL TRKS.



 CMP TKPERDSK ;# OF TRKS ON DISK (FROM VTOC).
 BCC CHK4FREE ;BRANCH IF TRK # IS VALID.



 LDA #$FF ;(A) = -1.
 BNE SRCH4TRK ;ALWAYS.



CKIFFULL LDA TRK0YET
 BNE TODSKFUL ;2ND TIME = DISK FULL.



 LDA #1 ;SET FLAG TO INDICATE THAT THE
 STA TRK0YET ;PENDING SEARCH WILL BE 2ND ONE.



SRCH4TRK STA DRECTION ;SET THE SEARCH DIRECTION.
 CLC ;BEGIN THE SEARCH ONE TRACK AWAY
 ADC #$11 ;FROM THE CATALOG TRK.



CHK4FREE STA NXTRKUSE
 STA ASIGNTRK
 TAY ;IRRELEVANT.
 ASL ;TRK*4 CAUSE 4BYTES/TRK N TRKMAP.
 ASL
 TAY ;INDEX FROM LAST BYTE OF TRKMAP0.
 LDX #4 ;INDEX TO THE ASIGNMAP.
 CLC ;(C)=0, ASSUME NO FREE SEC AVAIL.
CPYTKMAP LDA TRKMAP0+3,Y ;COPY BYTE FROM TRKMAP TO THE
 STA ASIGNMAP-1,X ;ASSIGNMENT MAP.
 BEQ NXMAPBYT ;0 = SEC USED.



 SEC ;(C) = 1 = FREE SECTOR FOUND.
 LDA #0 ;PUT 0 IN TRKMAP 2 REASSIGN ALL 8
 STA TRKMAP0+3,Y;SECS REPRESENTED BY THIS BYTE.
;(REMEMBER ONLY 2 BYTES OF TRKMAP
;ACTUALLY REPRESENT SECS.  THE
;OTHER 2 BYTES ARE DUDS.)
NXMAPBYT DEY ;REDUCE INDICES TO MAPS.
 DEX
 BNE CPYTKMAP ;NOT DONE TRANSFERRING ALL BYTES
;FROM TRKMAP TO ASIGNMAP YET.



 BCC GETNWTRK ;IF (C)=0,THEN NO FREE SECS FOUND
;YET SO GO BACK TO GET A NEW TRK.
 JSR WRITVTOC ;UPDATE THE VTOC ON THE DISK.
 LDA SECPERTK ;RESET ASIGNSEC WITH # SECS/TRK.
 STA ASIGNSEC (IE 1 GREATER THAN HIGHEST SEC#.)
 BNE ANYAVAIL ;ALWAYS.




TODSKFUL JMP DISKFULL ;GO HANDLE ERROR.
I