💾 Archived View for mirrors.apple2.org.za › archive › www.textfiles.com › apple › ANATOMY › cmdelete… captured on 2024-08-19 at 03:01:40.
View Raw
More Information
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
- *****************************************************************
- *
- 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 <Rtn> & 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.)