****************************************************************** * * * DELETE Command Handler * * * *----------------------------------------------------------------* * * * The DELETE command erases a named file from the disk. * * Volume, drive and slot parameters are optional. If the named * * file is locked or not present on the disk, an error message * * is generated. The following sequence of instruction can be * * used to safely delete a TEXT file while running an Applesoft * * program: 10 D$ = CHR$(13) + CHR$ (4): REM & ctrl-D * * 20 PRINT D$; "OPEN NAMEDFILE" * * 30 PRINT D$; "UNLOCK NAMEDFILE" * * 40 PRINT D$; "DELETE NAMEDFILE" * * * * The delete command appears to have a slightly confusing * * execution pattern which is summarized below: * * 1) close the file & release its DOS buffer. * * 2) reassign a DOS buffer to the file. * * 3) delete the file: * * - Alter the file's description entry in the * * directory sector buffer by (a) overwriting * * the last byte in the name field with the track * * number of the first T/S list and (b) putting * * an $FF in the byte where the track number of * * the first T/S list sector is usually stored. * * (See formatted disassembly of the delete function * * handler for an explanation of the structure * * of file description entries.) * * - release the data and T/S list sectors in the * * VTOC. * * - write the updated directory and VTOC back to * * the disk. * * 4) find the DOS buffer associated with the file. * * 5) release the DOS buffer associated with the file. * * (NOTE: To reincarnate a deleted file which hasn't been over- * * written, you simply reverse the process given in step 3 above.)* * * ****************************************************************** * On entry - CUMLOPTN ($AA65) has been updated * to reflect any option words that * were parsed with the command (V,D,S). * - the validity of the options issued * with the command (and their numeric * values) have been checked. * - a legal file name has been parsed and * stored in the primary file name buffer * (PRIMFNBF, $AA75). (A263) CMDELETE LDA #5 ;Opcode for delete. (A265) JSR HNDLCMD1 ;Close the file & release its buf. ;Reassign a DOS buf to file. ;Change file description in directory ;sector buffer & then write updated ;directory sec back to disk. ;Free up data & T/S list sectors. ;Write updated VTOC. * Part of common file manager command handler code. (A2AA) HNDLCMD1 STA TEMPBYT ;Store opcode in temporary location. LDA LENPRSD ;Get L-parameter from parsed table. BNE SAVLENFM ;Was a non-zero L-parm issued with cmd? LDA LENPRSD+1 BNE SAVLENFM LDA #1 ;Length was 0 so make it 1 instead. STA LENPRSD SAVLENFM LDA LENPRSD ;Put length in FM parm list. STA RECLENFM LDA LENPRSD+1 STA RECLENFM+1 CLSLOCBF JSR CMDCLOSE ;Close file if it's already open. (A2C8) (A2EA) CMDCLOSE . . (See dis'mbly of CMDCLOSE given below.) . . - Note that execution flows thru CMDCLOSE twice if the file is already open. - The first time thru, the matching DOS filename buffer is located & then CLOSEONE is used to close the file. - Execution then jumps back to the start of CMDCLOSE. - On this second pass, a matching filename is not found because the DOS filename buffer was released on the first pass. Therefore, A5L/H is left pointing at the highest numbered (lowest in memory) FREE DOS buffer when CMCLOSE is exited via EVENTXIT and CLOSERTS. - If the file is not already open on the first entry to CMDCLOSE, only one pass is made. This single pass resembles the second pass mentioned above. . . - If necessary, the CLOSE FUNCTION updates the data sector, T/S list sector & the VTOC. It also fixes up links in the directory sectors and updates the file size if needed. . . (RTS) (A2CB) LDA A5L+1 ;Hi byte of A5L/H pointer which points at the highest ;numbered (lowest in memory) free DOS name buffer (in chain). (A2CD) BNE SAVFNPTR ;Branch if found a free buffer. (A2CF) JMP NOBUFERR ;Go issue an out-of-buffers message. ------------ ;(See dis'mbly of errors.) (A2D2) SAVFNPTR STA A3L+1 ;Reset A3L/H to point at DOS buffer that we LDA A5L ;will use for file name field buffer (chain). STA A3L (A2D8) JSR CPYPFN * NOTE: This (re)assigns a DOS buffer to the * file we want to delete. The buffer may or may not * be the same one that was just released by the CLOSE cmd * above. The highest numbered (lowest in memory) free * DOS buffer is used. (A743) CPYPFN LDY #29 ;30 bytes to copy (0 to 29). CPYPRIM LDA PRIMFNBF,Y ;Copy the name of the file wanted from STA (A3L),Y ;the primary filename buffer into the DEY ;filename field buffer (in DOS chain). BPL CPYRIM ;More chars to get. (A74D) RTS (A2DB) JSR BUFS2PRM * Get addresses of the various DOS buffers from the * chain buffer & put them in the FM parameter list. (A74E) BUFS2PRM LDY #30 ;Get addr of FM work buf, T/S list ADRINPRM LDA (A3L),Y ;buf, data sector buf & next DOS STA WRKBUFFM-30,Y ;filename buf from chain INY ;pointer buffer & put them in FM parm list. CPY #38 ;(P.S. Adr of next DOS file name buf is BNE ADRINPRM ;not used by DOS.) (A75A) RTS (A2DE) JSR CPY2PARM * Put volume, drive, & slot values plus the * address of the primary filename buffer * in the FM parameter list. (A71A) CPY2PARM LDA VOLPRSD ;From parsed table. STA VOLFM LDA DRVPRSD ;From parsed table. STA DRVFM LDA SLOTPRSD ;From parsed table. STA SLOTFM LDA ADRPFNBF ;Get the adr of the primary file STA FNAMBUFM ;name buf from the constants tbl LDA ADRPFNBF+1 ;and put it in the FM parm list. STA FNAMBUFM+1 LDA A3L ;Save adr of current DOS file name STA CURFNADR ;buf in table of DOS variables. LDA A3L+1 STA CURFNADR+1 (A742) RTS (A2E1) LDA TEMPBYT ;Get delete opcode back from temporary buffer STA OPCODEFM ;and put it in the FM parameter list. (A2E7) JMP FMDRIVER ------------ * Use the file manager driver * to do the DELETE FUNCTION. (A6A8) FMDRIVER JSR FILEMGR ;Call the file manager to do the function. * File manager proper. (AB06) FILEMGR TSX ;Save stk pointer so can later rtn to caller of FM. STX STKSAV (AB0A) JSR RSTRFMWA * Copy FM work buf (in DOS chain) to * FM work area (not in DOS chain). (AE6A) RSTRFMWA JSR SELWKBUF ;Point A4L/H at FM work buf. * Get addr of FM work buff from * the FM parm list & put it in * the A4L/H pointer. (AF08) SELWKBUF LDX #0 ;Offset to select ;work buffer. (AF0A) BEQ PT2FMBUF ;ALWAYS. (AF12) PT2FMBUF LDA WRKBUFFM,X STA A4L LDA WRKBUFFM+1,X STA A4L+1 (AF1C) RTS (AE6D) LDY #0 ;Zero out return code in FM parm list to STY RTNCODFM ;signal no errors as default condition. STORFMWK LDA (A4L),Y ;Copy FM work buf to FM work area. STA FMWKAREA,Y INY CPY #45 ;45 bytes to copy (0 to 44). BNE STORFMWK CLC ;WHY????? (AE7D) RTS (AB0D) LDA OPCODEFM ;Check if opcode is legal. CMP #13 ;(Must be less than 13.) BCS TOERROP ;Opcode too large so got range error. ASL ;Double val of opcode & put it in (x) TAX ;so it indexes tables of adrs. LDA FMFUNCTB+1,X ;Stick adr of appropriate function PHA ;handler on stack (hi byte first). LDA FMFUNCTB,X PHA (AB1E) RTS ;DO STACK JUMP TO FUNCTION ENTRY POINT. . . (AD2B) . FNDELETE . . (See dis'mbly of DELETE function.) . . Modify file description in directory sec: - transpose orig trk # of 1rst T/S list sector to the last char pos'n in the filename description. - put an $FF in byte where trk # of 1rst T/S list sec was originally stored. Write updated directory sec to disk. Free up data & T/S list sectors. Write VTOC back to disk. . . (RTS) ============ TOERROP JMP RNGERROP ;Go handle range error. (AB1F) ------------ ;(See dis'mbly of errors.) * Return here after doing the DELETE FUNCTION. * (Cause after @ function is done, use stack * to get back to the original caller.) (A6AB) AFTRFUNC BCC FMDRVRTN ;(c) = 0 = no errors. LDA RTNCODFM ;Get error code from FM parameter list. CMP #$5 ;End-of-data error? (A6B2) BEQ TOAPPTCH ;Yes. Got a zeroed-out T/S link or a ;zeroed-out data pair listed in a T/S list. ;(Not applicable to the delete function.) (A6B4) JMP OTHRERR ;No. See dis'mbly of errors. ------------ (A6C3) FMDRVRTN RTS (A268) JSR GETBUFF ;Locate DOS buff belonging to file so we ;can free it up. * Locate DOS buffer with same name as file * just partially deleted. (A764) GETBUFF LDA #0 ;Default hi-byte of pointer to 0 STA A5L+1 ;(ie. assume no free buff available). (A768) JSR GETFNBF1 ;Get pointer to 1rst filename buffer in chain. * Put addr of name buffer (located in chain * of DOS buffers) in the A3L/H pointer. (A792) GETFNBF1 LDA ADOSFNB1 ;First link to chain of DOS buffers LDX ADOSFNB1+1 ;(ie. pt 2 1rst name buf in chain). (A798) BNE SETNXPTR ;ALWAYS. (A7A4) SETNXPTR STX A3L+1 ;Put addr of 1rst filename buffer in ptr STA A3L ;(ie. highest name buffer in chain). TXA ;Get hi-byte of addr in back in (a). GETNXRTN RTS (A7A9) (A76B) JMP FNCHAR1 ;Go get first byte of DOS name buf. ------------ (A76E) GETFNLNK JSR GETNXBUF * Get addr of next filename buffer in chain * from chain pointers buffer offset 37 & 36 * bytes from 1rst char of present filename * buffer. (A79A) GETNXBUF LDY #37 ;Point the pointer at the chain buffer & LDA (A3L),Y ;get addr of the next filename buffer. BEQ GETNXRTN ;If hi-byte is 0, then lnk zeroed out. TAX ;Save hi-byte in (x). DEY ;Pick up low-byte. LDA (A3L),Y SETNXPTR STX A3L+1 ;Stick addr of filename buffer in ptr. STA A3L TXA ;Get hi-byte back in (a). GETNXRTN RTS (A7A9) (A771) BEQ NOFNMTCH ;Lnk zeroed out, end of chain. FNCHAR1 JSR GETFNBY1 ;Get the 1rst char of filename from buf in chain. (A773) * Get first byte from DOS name buffer. (A7AA) GETFNBY1 LDY #0 ;Buffer is free if 1rst byte = $00. LDA (A3L),Y ;If buf occuppied, the 1rst byte = 1rst (A7AE) RTS ;char of filename which owns buffer. (A776) BNE NXFNBUF ;Take branch if buffer wasn't free. LDA A3L ;Buffer was free, there4, point the A5L/H pointer STA A5L ;at the free buffer. LDA A3L+1 STA A5L+1 (A780) BNE GETFNLNK ;ALWAYS. (A782) NXFNBUF LDY #29 ;Buffer not free there4 compare name CMPFNCHR LDA (A3L),Y ;of owner with name of file in primary CMP PRIMFNBF,Y ;name buffer. (Start with last char first.) (A789) BNE GETFNLNK ;Char doesn't match, there4 look for another ;buffer that might have same name. (A78B) DEY ;That char matched, how bout rest of name? BPL CMPFNCHR ;30 chars in name (ie. 0 to 29). CLC ;Clr carry to signal match. (A78F) RTS ============ (A790) NOFNMTCH SEC ;Link zeroed out. (A791) RTS ============ (A26B) LDY #0 ;Free up the DOS name buffer associated with TYA ;file by storing a $00 in the first byte of STA (A3L),Y ;its filename field. (A270) RTS ;Return to caller of DELETE commandl ============ ;(Normally returns to AFTRCMD ($A17D) ;located in the command parsing and ;processing routines.)