💾 Archived View for mirrors.apple2.org.za › archive › www.textfiles.com › apple › ANATOMY › fndelete… captured on 2024-08-19 at 03:02:11.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

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




(AD2B)
FNDELETE JSR COMNOPEN ;Locate a file with the same name & open it.

                      *** NOTE ***
                      * Not all of the common open routine is
                      * listed below because not all of it
                      * applies to the DELETE function.

                      * Common open routine.
                      (AB28)
                      COMNOPEN JSR ZWRKAREA ;Initialize the work area.

                                            * Zero out the FM work area so it can be customized
                                            * in accordance with the calling function.
                                            * (Although some work bytes may not be subsequently
                                            * alterd, don't be lulled into thinking that they
                                            * are not important.  Zero values are just as relevant
                                            * as non-zero values.)
                                            * (P.S.  Don't confuse the FM work area with its image
                                            * (FM work buffer) that is housed in the chain of
                                            * DOS buffers.)
                                            (ABDC)
                                            ZWRKAREA LDA #0
                                                     TAX          ;Initialize the x-index.
                                            ZEROWRKA STA FMWKAREA,X ;Put a $00 byte in work area.
                                                     INX
                                                     CPX #45      ;Work area is 45 bytes long.
                                            (ABE5)  BNE ZEROWRKA

                                            * Begin customizing the work area.
                                            * Get volume, drive, slot  & catalog track
                                            * values from the FM parameter list.  Put
                                            * drive, slot*16, catalog track and
                                            * complemented volume number in the work area.
                                            (ABE7)   LDA VOLFM    ;Volume number.
                                                     EOR #$FF     ;Calculate 1's complement of volume #.
                                                     STA VOLWA
                                                     LDA DRVFM    ;Drive #.
                                                     STA DRVWA
                                                     LDA SLOTFM   ;Get slot #.
                                                     ASL          ;Calculate slot * 16.
                                                     ASL
                                                     ASL
                                                     ASL
                                                     TAX          ;Set (x) = slot * 16.
                                                     STX SLOT16WA
                                                     LDA #$11     ;Normal catalog trk = #17.
                                                     STA TRKWA
                                            (AC05)   RTS

                      (AB2B)   LDA #1      ;Describe sector length as 256 bytes
                      (AB2D)   STA SECSIZWA+1 ;(in the FM work area).

                      * Get record length from the FM parameter
                      * list & put it in the FM work area.
                      * (Don't allow a zero length.  If zero,
                      * change it to one.)
                      (AB30)   LDX RECLENFM+1
                               LDA RECLENFM
                               BNE STRECLEN ;Non-zero record length is ok.
                               CPX #0
                               BNE STRECLEN
                               INX          ;Was zero, make it one instead.
                      STRECLEN STA RECLENWA ;Put length in FM work area.
                               STX RECLENWA+1
                      (AB43)   JSR GETFNTRY ;Try to find a directory sector for the file.

                                            * Locate or create a file entry in the
                                            * directory buffer.
                                            * Make two searches if necessary:
                                            *    - Search1 - try to locate entry with same name as file wanted.
                                            *    - Search2 - couldn't locate entry corresponding to file
                                            *                wanted so create a new entry in first available
                                            *                space in the directory sector.
                                            (B1C9)
                                            GETFNTRY JSR READVTOC ;Read in the VTOC so we can get the link to
                                                                  ;TRKMAPS & to the first directory sector.

                                                                  * Read the Volume Table of Contents (VTOC).
                                                                  (AFF7)
                                                                  READVTOC LDA #1       ;Read opcode for RWTS.
                                                                  (AFF9)   BNE RDWRVTOC ;ALWAYS.

                                                                  * Code common to read/write VTOC.
                                                                  (AFFD)
                                                                  RDWRVTOC LDY ADRVTOC  ;Get address of VTOC from the
                                                                           STY IBBUFP   ;FM constants table & designate it
                                                                           LDY ADRVTOC+1 ;as the I/O buffer in RWTS's IOB.
                                                                           STY IBBUFP+1
                                                                           LDX TRKWA    ;Enter RWTS driver with (x)/(y) equal
                                                                           LDY #0       ;to the trk/sec values of the VTOC.
                                                                  (B00E)   JMP RWTSDRVR ;Call driver to read/write the VTOC.
                                                                           ------------

                                                                  * Read/Write Track/Sector driver.
                                                                  (B052)
                                                                  RWTSDRVR .
                                                                           .
                                                                  (See dism'bly of RWTS driver using READ.)
                                                                           .
                                                                           .
                                                                           (RTS)

                                            * Point A4L/H at the primary file name buffer.
                                            (B1CC)   LDA FNAMBUFM ;Get address of the name buffer from the
                                                     STA A4L       ;FM parameter list & put it in the  A4L/H
                                                     LDA FNAMBUFM+1 ;pointer.
                                            (B1D4)   STA A4L+1

                                            * Try to find the directory sector with the
                                            * wanted file name & read it into the directory
                                            * sector buffer.  Make two searches if necessary.
                                            * On the first search, try to find a matching name.
                                            * If that doesn't work, do a second search to store
                                            * the description in the first available file
                                            * description field in a directory sector.
                                            (B1D6)   LDA #1       ;Initialize the search counter (SCRNSRCH)
                                            SETSRCH  STA SCRNSRCH ;in the FM scratch space for two searches.
                                            (B1D8)                ;(1 = search1, 0 = search2)
                                            (B1DB)   LDA #0       ;Initialize offset of file description from
                                                     STA SECNXDIR ;the very first directory sector.
                                                     CLC          ;(c)=0=signal to read first directory sec.
                                            GETDIRSC INC SECNXDIR ;Kick up offset from first directory.
                                            (B1E4)   JSR RDDIRECT ;Go read directory sector into buffer.

                                                                  * Read a directory sector.
                                                                  (B011)
                                                                  RDDIRECT PHP          ;Save (c) on stack:
                                                                                        ;  (c) = 0 = read 1rst directory sector.
                                                                                        ;  (c) = 1 = read next directory sector.
                                                                  (B012)   JSR PT2DIRBF

                                                                                        * Designate the directory sector buffer
                                                                                        * as I/O buffer in RWTS's IOB.
                                                                                        (B045)
                                                                                        PT2DIRBF LDA ADRDIRBF ;Get addr of direc
                                                                                                 STA IBBUFP   ;sec buf from the
                                                                                                 LDA ADRDIRBF+1 ;FM constants tbl
                                                                                                 STA IBBUFP+1 ;& designate it as
                                                                                        (B051)   RTS          ;as the I/O buffer.

                                                                  (B015)   PLP          ;Check if 1rst directory sec or not.
                                                                  (B016)   BCS RDNXTDIR ;Go read next directory sector.

                                                                  * Read the first directory sector.
                                                                  * (Carry = 0.)
                                                                  (B018)
                                                                  RDFIRDIR LDY FIRDIRSC ;(y)/(x) = trk/sec vals of first directory
                                                                           LDX FIRDIRTK ;sector (from the VTOC buffer).
                                                                  (B01E)   BNE DODIRRD  ;ALWAYS - go read in directory sector.

                                                                  * Read the next directory sector.
                                                                  * (Carry = 1.)
                                                                  (B020)
                                                                  RDNXTDIR LDX DIRLNKTK ;Get track of next directory sec from the
                                                                                        ;link in the current directory sector.
                                                                  (B023)   BNE GETDIRLK ;Link not zeroed out.
                                                                           SEC          ;Link zeroed out - exit with (c) = 1 to
                                                                  (B026)   RTS          ;signal there are no more directory secs.
                                                                           ============

                                                                  (B027)
                                                                  GETDIRLK LDY DIRLNKSC ;Get sector of next directory sec from the
                                                                                        ;link in the current directory sector.

                                                                  * Call to read in the directory sector.
                                                                  (B02A)
                                                                  DODIRRD  STX CURDIRTK ;Save trk/sec vals of directory sec that
                                                                  (B02D)   STY CURDIRSC ;we are about to read so they will be
                                                                                        ;the current directory sec values for the
                                                                                        ;next time around.
                                                                  (B030)   LDA #1       ;Read opcode for RWTS.
                                                                  (B032)   JSR RWTSDRVR ;Call RWTS driver to do the read.

                                                                                        * Read/Write Track/Sector driver.
                                                                                        (B052)
                                                                                        RWTSDRVR .
                                                                                                 .
                                                                                        (See dis'mbly of RWTS driver using READ.)
                                                                                                 .
                                                                                                 .
                                                                                                 (RTS)

                                                                  (B035)   CLC          ;Link didn't zero out so signal that there
                                                                  (B036)   RTS          ;are more directory secs to read & exit.
                                                                           ============

                                            (B1E7)   BCS CHNGSRCH ;Link zeroed out, no more directory secs,
                                                                  ;so go switch searches.
                                            (B1E9)   LDX #0
                                            CKDIRTRK STX CURDIRNX ;Offset of file description into the current
                                            (B1EB)                ;directory sector.
                                            (B1EE)   LDA FIL1TSTK,X ;Get track number of first T/S list
                                                                  ;for a particular file from the file
                                                                  ;description entry in the directory sector.
                                            (B1F1)   BEQ CHRSRCHA ;If trk=0, no more files in this direc sec.
                                            (B1F3)   BMI CHRSRCHB ;Skip deleted file.  (When a file is
                                                                  ;deleted, #$FF is put in byte where trk #
                                                                  ;of first T/S list is usually kept.

                                            * Compare the name found in the file
                                            * description entry portion of the
                                            * directory sector with the file name
                                            * wanted.  (On entry, A4L/H points at
                                            * the primary file name buffer.)
                                            (B1F5)   LDY #0       ;Initialize index to file name buffer.
                                                     INX          ;Point (x) at the first char position
                                                     INX          ;in the name field of description entry.
                                            CMPNAMES INX
                                                     LDA (A4L),Y  ;Get char of name from primary.
                                                     CMP FIL1TSTRK,X ;Compare to char in name of description.
                                                     BNE DONTMTCH ;Chars (and therefore names) don't match.
                                                     INY
                                                     CPY #30      ;Done all chars yet (0 to 29)?
                                                     BNE CMPNAMES ;Chars matched, branch if more to check.
                                                     LDX CURDIRNX ;All chars matched, so names matched.
                                                     CLC          ;Return with (x) = index to file
                                            (B20A)   RTS          ;description in current directory sector
                                                     ============ ;and with (c) = 0 to signal that the
                                                                  ;correct file description was found.

                                            * Advance index to point at the next
                                            * potential file description entry.
                                            (B20B)
                                            DONTMTCH JSR NXPLUS35 ;Names didn't match, so adjust index
                                                                  ;to point at the next entry.

                                                                  * Add 35 to the offset to point the index
                                                                  * at the next file description entry.
                                                                  * (Check to make sure that we don't index
                                                                  * right off the end of the directory sec.)
                                                                  (B230)
                                                                  NXPLUS35 CLC
                                                                           LDA CURDIRNX
                                                                  (B234)   ADC #35      ;Add 35 to index. (Each file description
                                                                                        ;entry is 35 bytes long.)
                                                                  (B236)   TAX          ;Check if there is more space for entries
                                                                           CPX #245     ;in the current directory sector.
                                                                  (B239)   RTS          ;Exit with (c) conditioned:
                                                                                        ; (c) = 0 = more space in directory.
                                                                                        ; (c) = 1 = ran off end of directory.

                                            (B20E)   BCC CKDIRTRK ;More potential file descriptions to check
                                                                  ;in this directory sector.
                                            (B210)   BCS GETDIRSC ;Go get next directory sector.
                                                     ------------

                                            * If we just completed the first search,
                                            * go back to do the second search.
                                            (B212)
                                            CHRSRCHA LDY SCRNSRCH ;(1 = search1, 0 = search2)
                                            (B215)   BNE SETSRCH  ;Go switch to second search.

                                            * If first search, skip deleted files.
                                            * If second search, fall through to store
                                            * the description in the first unused
                                            * space in the directory.
                                            (B217)
                                            CHRSRCHB LDY SCRNSRCH ;(1 = search1, 0 = search2)
                                            (B21A)   BNE DONTMTCH

                                            * Couldn't locate the named file in the
                                            * directory description entries, so begin
                                            * creating a new description in the first available
                                            * space in a directory (in case command can
                                            * legally create a new file).
                                            (B21C)
                                            NWDESCRP LDY #0       ;Initialize index to primary file name buffer.
                                                     INX          ;Set index to first char position in the
                                                     INX          ;name field of the file description entry
                                            SETNWNAM INX          ;space in the directory sector.
                                                     LDA (A4L),Y  ;Copy char from primary file name buffer
                                                     STA FIL1TSTK,X ;to the directory description space.
                                                     INY
                                                     CPY #30      ;30 chars in name (0 to 29).
                                                     BNE SETNWNAM ;Branch if more chars to copy.
                                                     LDX CURDIRNX ;Return with (x) = index to file
                                                     SEC          ;description space in current directory
                                            (B22F)   RTS          ;sector & with (c)=1 to signal new entry
                                                     ============ ;was just created.

                                            * If first search, switch to second search.
                                            * If second search, link zeroed out because
                                            * there isn't enough room left on the
                                            * disk for a new entry.  Therefore,
                                            * exit with a disk-full error message.
                                            (B23A)
                                            CHNGSRCH LDA #0       ;Used to reset search counter if
                                                                  ;go back to start second search.
                                            (B23C)   LDY SCRNSRCH ;(1 = search1, 0 = search2)
                                            (B23F)   BNE SETSRCH  ;Just did first search, so go start
                                                                  ;the second search.
                                            (B241)   JMP DISKFULL ;Even second search was unsuccesful
                                                     ------------ ;so go handle a disk-full error.

                      (AB46)   BCC FILLINWA ;Branch if found a directory sector with
                                            ;name wanted in the file description entry.

                      * Named file wasn't found in directory,
                      * so prepare a new file entry in case
                      * command can legally create a new file.
                      (AB48)   STX CURDIRNX ;Offset to new description entry in
                                            ;case want to create a new file.

                      * Check to  see if command can
                      * legally create a new file.
                      (AB4B)   LDX NDX2CMD  ;(x) = index representing command.
                      (AB4E)   LDA CMDATTRB,X ;Get first byte containing description
                                            ;of the given command's attributes.
                      (AB51)   LDX CURDIRNX ;(x) = index for new file description
                                            ;entry into the directory sector.
                      (AB54)   LSR          ;(c) = bit 0 of 1rst attribute byte.
                      (AB55)   BCS CREATNEW ;If (c) = 1, command can create a new file.
                                            ;ALWAYS FALL THRU FOR DELETE FUNCTION (cause (c) = 0).

                      * Command can't create a new file.
                      * See which language we are using and
                      * exit with the appropriate error msg.
                      (AB57)
                      NEWILLGL LDA CONDNFLG ;$00=warmstart, $01=reading, $40=A(RAM),
                                            ;$80=coldstart & $C0=integer.
                      (AB5A)   CMP #$C0     ;Integer in ROM?
                               BNE TOFILNOT ;No.
                      (AB5E)   JMP LNGNOTAV ;Yes - handle language-not-available error.
                               -------------

                      TOFILNOT JMP FILENOT  ;Handle file-not-found error.
                      (AB61)   ------------

                      * Fill in the FM work area buffer.
                      * (Routine common to opening a new
                      * or pre-existing file.)
                      (ABA6)
                      FILLINWA LDA FIL1TSTK,X ;T/S list trk val (from directory sec).
                               STA FIRSTSTK
                               LDA FIL1TSSC,X ;T/S list sec val (from directory sec).
                               STA FIRTSSEC
                               LDA FIL1TYPE,X ;File type (from directory sec).
                               STA FILTYPFM
                               STA FILTYPWA
                               LDA FIL1SIZE,X ;File size (from directory sec).
                               STA FILENSEC
                               LDA FIL1SIZE+1,X
                               STA FILENSEC+1
                               STX BYTNXDIR ;Index into directory sec to description.
                               LDA #$FF     ;Pretend that the last data sector used had
                               STX RELPREV  ;a relative sector number (in relation to
                      (ABCF)   STA RELPREV+1 ;the entire file) of #$FFFF.  NOTE:  This
                                            ;value is later used to trick the read and
                                            ;write subfunctions into ignoring the data
                                            ;sector currently in memory.
                      (ABD2)   LDA MXIN1TSL ;Dictate that a T/S list can only describe $7A
                      (ABD5)   STA MXSCURTS ;(#122) data sectors.  Note:  This value is later
                                            ;used by the read and write subfunctions to decide
                                            ;whether or not the T/S list currently in memory
                                            ;should be used.

                      * Read first T/S list sector
                      * to the T/S list buffer.
                      (ABD8)   CLC          ;(c) = 0 = signal 1rst T/S list sector.
                      (ABD9)   JMP READTS   ;Go read in the T/S list sector.
                               ------------
     
                      * Read T/S list sector.
                      (AF5E)
                      READTS   PHP          ;Save (c) denoting if 1rst T/S list or not.
                                            ;(c) = 0 = read 1rst T/S list sec.
                                            ;(c) = 1 = read next T/S list sec.
                      (AF5F)   JSR CKTSUPDT ;Write T/S list sec buf if updating is
                                            ;required.  (If T/S list buf has changed
                                            ;since last read or write, then write it
                                            ;back to the disk so don't overwrite buf
                                            ;and lose information when read the new
                                            ;T/S list sector.)

                                            * Check if T/S list requires updating.
                                            * (ie. Has T/S list buf changed since
                                            * the last read or write?)
                                            (AF34)
                                            CKTSUPDT LDA UPDATFLG
                                                     BMI WRITETS  ;If bit 7 set, updating is required.
                                            (AF39)   RTS          ;NOT APPLICABLE TO THE DELETE FUNCTION.
                                                     ============

                      (AF62)   JSR SETTSIOB ;Prepare RWTS's IOB for READING a T/S list.

                                            * Prepare RWTS's IOB for reading
                                            * or writing the T/S list sector.
                                            (AF4B)
                                            SETTSIOB LDA TSBUFFM  ;Get adr of the T/S list buf from the FM
                                                     STA IBBUFP   ;parameter list & designate T/S list buf
                                                     LDA TSBUFFM+1 ;as the I/O buffer in RWTS's IOB.
                                                     STA IBBUFP+1
                                                     LDX CURTSTRK ;Set (x)/(y) = trk/sec of current T/S list.
                                                     LDY CURTSSEC
                                            (AF5D)   RTS

                      (AF65)   JSR SELTSBUF ;Select the T/S list buffer.

                                            * Point A4L/H at the T/S list sector buffer.
                                            (AF0C)
                                            SELTSBUF LDX #2       ;Index for T/S list buf.
                                            (AF0E)   BNE PT2FMBUF ;ALWAYS.

                                            (AF12)
                                            PT2FMBUF LDA WRKBUFFM,X ;Get address of the desired buffer from
                                                     STA A4L      ;the FM parameter list & put it in the
                                                     LDA WRKBUFFM+1,X ;A4L/H pointer.
                                                     STA A4L+1
                                            (AF1C)   RTS

                      (AF68)   PLP          ;Get saved (c) back from stack.
                      (AF69)   BCS RDNXTTS  ;If (c) = 1, already read first T/S list
                                            ;sec, so go read next one.
                                            ;(Not applicable at this point in time cause (c) = 0.)

                      * Read first T/S list sector.
                      * (Carry was clear.)
                      (AF6B)
                      RDFIRSTS LDX FIRSTSTK ;Set (x)/(y)=trk/sec of first T/S list sec.
                               LDY FIRTSSEC
                      (AF71)   JMP RDTSLST  ;Go read T/S list sector into buffer.
                               ------------

                      * Subroutine to read/write T/S list sector.
                      (AFB5)
                      RDTSLST  LDA #1       ;Read opcode for RWTS.

                      * Code common to read/write T/S list.
                      (AFB7)
                      RDWRTS   STX CURTSTRK ;New T/S list sector trk/sec values (x)/(y)
                               STY CURTSSEC ;become current T/S list trk/sec values.
                      (AFBD)   JSR RWTSDRVR ;Call RWTS driver to read/write current T/S list.

                                            * Read or write the current T/S list.
                                            (B052)
                                            RWTSDRVR .
                                                     .
                                            (See dis'mbly of RWTS driver using READ.)
                                                     .
                                                     .
                                                     (RTS)

                      * Update the FM work area
                      * (not in DOS buffer chain).
                      (AFC0)   LDY  #5      ;Offset into current T/S list buffer.
                               LDA (A4L),Y  ;Get & save the relative sector number of
                      (AFC4)   STA RELFIRST ;the first data sector described in this
                                            ;T/S list.
                      (AFC7)   CLC          ;Add maximum # of data secs that can be described
                               ADC MXSCURTS ;in this T/S list ($7A or #122).
                               STA RELASTP1 ;Store relative sector number (plus 1) of
                               INY          ;the last data sector that can be described in list.
                               LDA (A4L),Y
                               STA REFIRST+1
                               ADC MXSCURTS+1
                               STA RELASTP1+1
                               CLC          ;Return with "no error" signal.
                      (AFDB)   RTS
                               ============

(AD2E)   LDX CURDIRNX ;(x) = index to file description entry in
                      ;the directory sector buffer.
(AD31)   LDA FIL1TYPE,X ;Get file type from the directory sec buf.
         BPL ALTRNTRY ;Branch if file is not locked.
(AD36)   JMP FILELOKD ;Err - can't DELETE a locked file so go
         ------------ ;handle error and exit.


(AD39)
ALTRNTRY LDX CURDIRNX ;(x) = index to the file description entry
                      ;in the directory sector buffer.
(AD3C)   LDA FIL1TSTK,X ;Get the trk # of the first T/S list sec.
         STA FIRSTSTK ;Copy it into the work area and into the
(AD42)   STA FIL1NAME+29,X ;last character position of the file
                      ;name field description.
(AD45)   LDA #$FF     ;Replace the original track # of the T/S
         STA FIL1TSTK,X ;list with #$FF to signal file is deleted.
         LDY FIL1TSSC,X ;Put the sector # of the file's first T/S
         STY FIRTSSEC ;list sec in the work area.
(AD50)   JSR WRDIRECT ;Write the modified directory sector.

                      * Write the directory buffer.
                      (B037)
                      WRDIRECT JSR PT2DIRBF

                                            * Designate the directory sector buffer
                                            * as the I/O buffer in RWTS's IOB.
                                            (B045)
                                            PT2DIRBF LDA ADRDIRBF ;Get the addr of the directory sec buf
                                                     STA IBBUFP   ;in the FM constants table.
                                                     LDA ADRDIRBF+1 ;Store it in RWTS's IOB.
                                                     STA IBBUFP+1
                                            (B051)   RTS

                      (B03A)   LDX CURDIRTK ;Enter RWTS driver with (x)/(y) = trk/sec vals.
                               LDY CURDIRSC
                               LDA #2       ;Write opcode for RWTS.
                      (B042)   JMP RWTSDRVR ;Call RWTS driver to write the directory sector buffer.
                               ------------

                      (B052)
                      RWTSDRVR .
                               .
                      (See dis'mbly of RWTS driver using WRITE.)
                               .
                               .
                               (RTS)


(AD53)   CLC          ;(c) = 0 = 1rst T/S list sec.
(AD54)                ;(c) = 1 = 2nd T/S list sec.
RDTS4DEL JSR READTS   ;Go read in a T/S list sector.

                      * Read T/S list sector.
                      (AF5E)
                      READTS   PHP          ;Save (c) denoting if 1rst T/S list or not.
                                            ;(c) = 0 = read 1rst T/S list sec.
                                            ;(c) = 1 = read next T/S list sec.
                      (AF5F)   JSR CKTSUPDT ;Write T/S list sec buf if updating is
                                            ;required.  (If T/S list buf has changed
                                            ;since last read or write, then write it
                                            ;back to the disk so don't overwrite buf
                                            ;and lose information when read the new
                                            ;T/S list sector.)

                                            * Check if T/S list requires updating.
                                            * (ie. Has T/S list buf changed since
                                            * the last read or write?)
                                            (AF34)
                                            CKTSUPDT LDA UPDATFLG
                                            (AF37)   BMI WRITETS  ;If bit 7 set, updating is required.
                                                                  ;NOT APPLICABLE TO THE DELETE FUNCTION.
                                            (AF39)   RTS

                      (AF62)   JSR SETTSIOB ;Prepare RWTS's IOB for READING a T/S list.

                                            * Prepare RWTS's IOB for reading
                                            * or writing the T/S list sector.
                                            (AF4B)
                                            SETTSIOB LDA TSBUFFM  ;Get adr of the T/S list buf from the FM
                                                     STA IBBUFP   ;parameter list & designate T/S list buf
                                                     LDA TSBUFFM+1 ;as the I/O buffer in RWTS's IOB.
                                                     STA IBBUFP+1
                                                     LDX CURTSTRK ;Set (x)/(y) = trk/sec of current T/S list.
                                                     LDY CURTSSEC
                                            (AF5D)   RTS

                      (AF65)   JSR SELTSBUF ;Select the T/S list buffer.

                                            * Point A4L/H at the T/S list sector buffer.
                                            (AF0C)
                                            SELTSBUF LDX #2       ;Index for T/S list buf.
                                            (AF0E)   BNE PT2FMBUF ;ALWAYS.

                                            (AF12)
                                            PT2FMBUF LDA WRKBUFFM,X ;Get address of the desired buffer from
                                                     STA A4L      ;the FM parameter list & put it in the
                                                     LDA WRKBUFFM+1,X ;A4L/H pointer.
                                                     STA A4L+1
                                            (AF1C)   RTS

                      (AF68)   PLP          ;Get saved (c) back from stack.
                      (AF69)   BCS RDNXTTS  ;If (c) = 1, already read first T/S list
                                            ;sec, so go read next one.
                                            ;(Not applicable on first entry cause (c) = 0).

                      * Read first T/S list sector.
                      * (Carry was clear.)
                      (AF6B)
                      RDFIRSTS LDX FIRSTSTK ;Set (x)/(y)=trk/sec of first T/S list sec.
                               LDY FIRTSSEC
                      (AF71)   JMP RDTSLST  ;Go read T/S list sector into buffer.
                               ------------

                      * Read the next T/S list sector.
                      * (Carry was set.)
                      (AF74)
                      RDNXTTS  LDY #1       ;Index into the T/S list buffer.
                               LDA (A4L),Y  ;Trk for link to next T/S list sector.
                      (AF78)   BEQ TSLNKZRO ;Link zeroed out so there are no more
                                            ;T/S list secs for this file.
                      (AF7A)   TAX          ;(x) = next T/S list sec number.
                               INY
                               LDA (A4L),Y  ;Sector # for link to next T/S list sec.
                               TAY          ;(y) = next T/S list sector number.
                      (AF7F)   JMP RDTSLST  ;Go read in the next T/S list.
                               -------------

                      * The T/S link zeroed out so we must decide
                      * if we got an error or not.  (That is, do
                      * we want to create another T/S list?)
                      (AF82)
                      TSLNKZRO LDA OPCODEFM ;Check if reading or writing to see
                               CMP #4       ;if we want to add another T/S list.
                      (AF87)   BEQ UPDATETS ;Writing - so go update link.
                                            ;(Never take with DELETE function.)
                      (AF89)   SEC          ;We were reading and the link zeroed out,
                      (AF8A)   RTS          ;so return with (c) = 1 to generate an error.
                               ============ ;(Remember, we previously set the return
                                            ;code to a default value for a file-not-found
                                            ;error.)

                      * Subroutine to read/write T/S list sector.
                      (AFB5)
                      RDTSLST  LDA #1       ;Read opcode for RWTS.

                      * Code common to read/write T/S list.
                      (AFB7)
                      RDWRTS   STX CURTSTRK ;New T/S list sector trk/sec values (x)/(y)
                               STY CURTSSEC ;become current T/S list trk/sec values.
                      (AFBD)   JSR RWTSDRVR ;Call RWTS driver to read/write current T/S
                                            ;list.

                                            * Read or write the current T/S list.
                                            (B052)
                                            RWTSDRVR .
                                                     .
                                            (See dis'mbly of RWTS driver using READ.)
                                                     .
                                                     .
                                                     (RTS)

                      * Update the FM work area
                      * (not in DOS buffer chain).
                      (AFC0)   LDY  #5      ;Offset into current T/S list buffer.
                               LDA (A4L),Y  ;Get & save the relative sector number of
                      (AFC4)   STA RELFIRST ;the first data sector that can be described in this
                                            ;T/S list.  (Possible values are: $0000, $007A,
                                            ;2*$007A, 3*$007A OR 4*$007A.)
                      (AFC7)   CLC          ;Add the maximum # of data secs that can be described
                               ADC MXSCURTS ;in this T/S list.
                               STA RELASTP1 ;Store maximum relative sector number (plus 1) of
                               INY          ;the last data sector that can be described in this list.
                               LDA (A4L),Y
                               STA RELFIRST+1
                               ADC MXSCURTS+1
                      (AFD7)   STA RELASTP1+1 ;(RELASTP1/+1 = $0000, $007A, 2*$007A,
                                            ;4*$007A or 5*$007A.)
                      (AFDA)   CLC          ;Return with "no error" signal.
                      (AFDB)   RTS

(AD57)   BCS DONEDEL  ;Branch if just read the last T/S list
                      ;sector associated  with this file.
(AD59)   JSR SELTSBUF ;Point A4L/H at the T/S list sector


                      * Point A4L/H at the T/S list sector buffer.
                      (AF0C)
                      SELTSBUF LDX #2       ;Index for T/S list buf.
                      (AF0E)   BNE PT2FMBUF ;ALWAYS.

                      (AF12)
                      PT2FMBUF LDA WRKBUFFM,X ;Get address of the desired buffer from
                               STA A4L      ;the FM parameter list & put it in the
                               LDA WRKBUFFM+1,X ;A4L/H pointer.
                               STA A4L+1
                      (AF1C)   RTS


(AD5C)   LDY #12      ;First data sector pair listed is offset 12
                      ;bytes from the start of the T/S list buf.
DELFREE  STY CURDIRNX ;Set (y) = index to data pair in the
(AD5E)                ;T/S list buffer.
(AD61)   LDA (A4L),Y  ;Get trk # of the data sector.
(AD63)   BMI BYPASDEL ;Neg track # is illegal (usually denotes
                      ;a deleted file).  (Can use neg track # as a
                      ;protection scheme.)
(AD65)   BEQ BYPASDEL ;Trk # of 0 = no more data secs listed in
                      ;the current T/S list sector.
(AD67)   PHA          ;Save trk # of data sector on the stack.
         INY          ;Get sec # of data sector.
         LDA (A4L),Y
         TAY          ;Condition (y) = sec & (a) = trk for entry
         PLA          ;into routines to free up sectors.
(AD6D)   JSR FREESEC  ;Free up sectors for the deleted file.

                      * Subroutine to free up a sector
                      * in the VTOC TRKMAP.
                      (AD89)
                      FREESEC  SEC          ;(c) = 1 so free up present sector when
                                            ;start rotating the assignment map.
                      (AD8A)   JSR SUB2FREE ;Adjust assignment map to FREE UP SECTORS
                                            ;BY SETTING BIT corresponding to the sector
                                            ;number.  Next, merge ASIGNMAP with the
                                            ;appropriate bit map in the VTOC.

                                            * Subroutine to free up sectors that were
                                            * deleted or prematurely assigned but not used.
                                            *
                                            * This tricky little routine is easy to
                                            * understand once you realize that:
                                            *   1) Unlike the VTOC, ASIGNMAP does not
                                            *      contain any unnecessarily assigned
                                            *      sectors.
                                            * 2) If the disk was just written to,
                                            *    ASIGNMAP does not house any newly
                                            *    assigned sectors (even if those sectors
                                            *    are necessary or not).
                                            * 3) Sectors are normally assigned in
                                            *    descending order.
                                            * 4) The number of ROR's done = number
                                            *    of sectors that need to be assigned.
                                            * For example:  If the last track had never
                                            * been assigned and only sectors $0F and
                                            * $0E were needed, then on entry to SUB2FREE,
                                            * the first two bytes would appear as follows:
                                            *       Sector numbers:  CBA98765 43210FED
                                            *           Bit values:  11111111 11111...
                                            * After the first ROR, the status of sector
                                            * $0D is determined by the entry status of
                                            * the carry (c):
                                            *       Sector numbers:  DCBA9876 543210FE
                                            *           Bit values:  c1111111 111111..
                                            * On the next ROR, the "CPY SECPERTK"
                                            * instruction conditions (c) to clear for
                                            * sector $0E:
                                            *       Sector numbers:  EDCBA987 6543210F
                                            *           Bit values:  0c111111 1111111.
                                            * On the next ROR, the "CPY SECPERTK"
                                            * instruction conditions (c) to clear for
                                            * sector $0F:
                                            *       Sector numbers:  FEDCBA98 76543210
                                            *           Bit values:  00c11111 11111111
                                            * When ASIGNMAP is merged with the corresponding
                                            * TRKMAP in the VTOC, the sectors that were
                                            * unnecessarily assigned in the VTOC are
                                            * freed.  (Note:  When used in the DELETE
                                            * function, SUB2FREE is repeatedly called
                                            * up by FREESEC to free one sector at a time.)
                                            (B2DD)
                                            SUB2FREE LDX #$FC     ;Set index to shift 4 bytes as a unit
                                            (B2DF)                ;(#$FC --> #$FF).
                                            STNDARD  ROR ASIGNMAP-$FC,X ;4 bytes = map for 1 track.
                                                     INX
                                                     BNE STNDARD
                                            (B2E5)   INY          ;When (y) = 16, ASIGNMAP is back in 
                                                                  ;standard position.
                                            (B2E6)   CPY SECPERTK ;Condition (c) for next shift.
                                                     BNE SUB2FREE
                                                     ASL          ;Trk*4 to index TRKMAP.
                                                     ASL
                                                     TAY
                                            (B2EE)   BEQ SUB2RTN  ;Track value of 0 not allowed.

                                            * ASIGNMAP now reflects the true sector assignment
                                            * and is in standard position.  Therefore, merge it
                                            * with the appropriate TRKMAP in the VTOC to free up
                                            * extra sectors.
                                            (B2F0)   LDX #4
                                            MERGMAPS LDA ASIGNMAP-1,X
                                                     ORA TRKMAP0+3,Y ;Do the merge.
                                                     STA TRKMAP0+3,Y
                                                     DEY          ;Reduce indices.
                                                     DEX
                                                     BNE MERGMAPS
                                            SUB2RTN  RTS
                                            (B2FF)

                      (AD8D)   LDA #0       ;Zero out ASIGNSEC, ASIGNTRK & ASIGNMAP
                               LDX #5       ;(6 bytes) in the work area.
                      RELEASEC STA ASIGNSEC,X
                               DEX
                               BPL RELEASEC
                      (AD97)   RTS

(AD70)
BYPASDEL LDY CURDIRNX ;Set (y) to index the first data pair.
         INY          ;Kick up (y) to point at next data pair.
         INY
(AD75)   BNE DELFREE  ;If (y) < > 0, then never ran off the end of
                      ;the T/S list buff yet, so go check if more
                      ;data pairs to do.


(AD77)   LDA CURTSTRK ;Trk # of current T/S list sec.
         LDY CURTSSEC ;Sec # of current T/S list sec.
(AD7D)   JSR FREESEC  ;Go free up the T/S list sec.

                      * Subroutine to free up a sector
                      * in the VTOC TRKMAP.
                      (AD89)
                      FREESEC  SEC          ;(c) = 1 so free up present sector when
                                            ;start rotating the assignment map.
                      (AD8A)   JSR SUB2FREE ;Adjust assignment map to FREE UP SECTORS
                                            ;BY SETTING BIT corresponding to the sector
                                            ;number.  Next, merge ASIGNMAP with the
                                            ;appropriate bit map in the VTOC.

                                            (B2DD)
                                            SUB2FREE .
                                                     .
                                            (See dis'mbly above.)
                                                     .
                                                     .
                                                     (RTS)

                      (AD8D)   LDA #0       ;Zero out ASIGNSEC, ASIGNTRK & ASIGNMAP
                               LDX #5       ;(6 bytes) in the work area.
                      RELEASEC STA ASIGNSEC,X
                               DEX
                               BPL RELEASEC
                      (AD97)   RTS

(AD80)   SEC
(AD81)   BCS RDTS4DEL ;ALWAYS.


(AD83)
DONEDEL  JSR WRITVTOC

                      * Write the updated VTOC to the disk.
                      (AFFB)
                      WRITVTOC LDA #2       ;Write opcode for RWTS.

                      * Common to read/write VTOC.
                      (AFFD)
                      RDWRVTOC LDY ADRVTOC  ;Get the address of the VTOC from the
                               STY IBBUFP   ;FM constants table and designate it as
                               LDY ADRVTOC+1 ;the I/O buffer in RWTS's IOB.
                               STY IBBUFP+1
                               LDX TRKWA    ;Enter RWTS driver with (x)/(y) equal to the
                               LDY #0       ;trk/sec values of the VTOC.
                      (B00E)   JMP RWTSDRVR ;Call RWTS driver to write the directory sector buffer.
                               ------------

                      (B052)
                      RWTSDRVR .
                               .
                      (See dis'mbly of RWTS driver using WRITE.)
                               .
                               .
                               (RTS)

(AD86)   JMP GOODFMXT ;Go exit file manager cleanly.
         -----------



(B35F)
LNGNOTAV LDA #1
(B361)   BNE BADFMXIT ;ALWAYS.

(B373)
FILENOT  LDA #6
         BNE BADFMXIT ;ALWAYS.
DISKFULL JMP FULLPTCH ;(See dis'mbly of errors.)
         NOP
FILELOKD LDA #10
         BNE BADFMXIT ;ALWAYS.
GOODFMXT LDA RTNCODFM
         CLC          ;(c) =  0 to signal good operation.
         BCC FMEXIT
BADFMXIT SEC          ;(c) = 1 to signal unsuccessful.
FMEXIT   PHP          ;Save status on stack.
         STA RTNCODFM ;Store return code in FM parameter list.
         LDA #0
         STA STATUS
(B38E)   JSR CPYFMWA  ;Copy the work area to the work buffer.

                      * Copy the FM work area (non-chain) to
                      * the FM work buffer (in DOS chain).
                      (AE7E)
                      CPYFMWA  JSR SELWKBUF ;Select the FM work buffer (in DOS chain).

                                            *  Point the A4L/H pointer at the FM work buffer.
                                            (AF08)
                                            SELWKBUF LDX #0       ;Set index to select work buffer.
                                            (AF0A)   BEQ PT2FMBUF ;ALWAYS.

                                            (AF12)
                                            PT2FMBUF LDA WRKBUFFM,X ;Get address of selected buffer from the
                                                     STA A4L      ;FM parameter list & put it in the pointer.
                                                     LDA WRKBUFFM+1,X
                                                     STA A4L+1
                                            (AF1C)   RTS

                      (AE81)   LDY #0       ;Initialize index.
                      STORWRK  LDA FMWKAREA,Y ;Get byte from the FM work area.
                               STA  (A4L),Y ;Put it in the work buffer.
                               INY
                               CPY #45      ;45 bytes to copy (0 to 44).
                               BNE STORWRK
                      (AE8D)   RTS

(B391)   PLP          ;Retrieve status of success of operation
                      ;from the stack.
(B392)   LDX STKSAV   ;Adjust stack pointer to force exit to the
         TXS          ;caller of the function even if we are
         RTS          ;several subroutines deeper than the
         ============ ;original entry point.  (That is, return to
                      ;AFTRFUNC ($A6AB) in the FMDRIVER routine
                      ;($A6A8).)