textfiles/apple/ANATOMY/cmdcatlg.txt

495 lines
36 KiB
Plaintext

******************************************************************
* *
* CATALOG Command Hanlder *
* *
*----------------------------------------------------------------*
* *
* The CATALOG command displays the volume number and a list *
* of file information. For each file on the disk, the following *
* data are printed: lock/unlock symbol, file type code, file *
* size in sectors and file name. Drive and slot parameters are *
* optional with the CATALOG command. *
* *
* Execution pattern: *
* The execution pattern is fairly straight forward. After *
* loading the accumulator with the catalog opcode, the common *
* file manager handler code (HNDLCMD1, $A2AA) is called to find *
* a free DOS buffer and customize the FM parameter list. The *
* file manager is then used to do the catalog function (FNCATLOG,*
* $AD98). FNCATLOG first sets up the FM work area. A volume *
* number of #$FF is stored in the work area to enable any volume *
* to be cataloged. (When RWTS is eventually entered, this value *
* is EORed with #$FF to simulate a complemented disk volume *
* number of zero (#$FF EOR #$FF = 0). After RWTS reads the *
* address checksum, it checks to see if the correct volume was *
* read off the disk. If the complement of the volume number *
* wanted is zero, or if it matches the number read off the disk, *
* execution proceeds as if the correct volume was found.) *
* After setting the complemented volume number, FNCATLOG *
* reads in the VTOC (so it can get the link bytes to the first *
* directory sector). Next, an index is set to allow up to 22 *
* screen lines to be displayed before the screen is frozen. *
* (This index is used in the CRCATLOG routine ($A2EF) to print a *
* carriage return and check if a pause is required.) After *
* CRCATLOG is called twice to print two carriage returns, the *
* words "DISK VOLUME " are displayed. The bug-ridden PRVOLNMB *
* routine ($AE42) is then called to print the volume number as a *
* 3-digit decimal number (with leading zeroes if applicable). *
* Next, the RDDIRECT routine is used to read in a directory *
* sector. If no more directory sectors are available, the carry *
* is set and the function handler is exited. A clear carry *
* signals that a directory sector was successfully read in. The *
* file information in the directory sector is subsequently *
* displayed. *
* Each directory sector can contain up to seven different *
* file descriptions. An example of the data contained in a *
* selected file description is shown below: *
* FIL1TSTK DS 1 ;Track # of first T/S list for file 1 *
* FIL1TSSC DS 1 ;Sector # of first T/S list for file 1 *
* FIL1TYPE DS 1 ;File type code for file 1. ($00=Text, *
* ;$01=Integer, $02=Applesoft, $04=Binary, *
* ;$08=S-type, $10=Relocatable, $20=A-type, *
* ;and $40=B-type.) If the hi bit is set, *
* ;the files are considered to be locked. *
* ;For example, $02 = unlocked Applesoft and *
* ;$82 = locked Applesoft. *
* FIL1NAME DS 30 ;Name of file 1. If a file name less than *
* ;30 bytes is used, trailing spaces are *
* ;are added to the name to fill the buffer. *
* FIL1SIZE DS 2 ;Size of file 1 in terms of the number of *
* ;sectors used. *
* (If a file was deleted, the track # of the first T/S list sec *
* was copied to the last char position of the name field. The *
* original track # byte (FIL1TSK) was then overwritten with an *
* #$FF.) *
* After reading in a directory sector, the index to the *
* file description entries is initialized. The track number of *
* the file's first T/S list is then analyzed. If this byte is a *
* zero, no more file descriptions are present in the directory *
* sector and the catalog function is exited (BEQ TOFMXTOK). A *
* negative value denotes that the description entry pertains to *
* a deleted file. The "BMI NXDESCRP" instruction is then taken *
* to skip the deleted file. A positive non-zero value means *
* that the file information should be processed. *
* After the type code is checked to determine if the file *
* is locked (negative) or unlocked (positive), an asterisk *
* (locked) or a space (unlocked) is printed. The lock bit (bit *
* 7) is then dropped from the file type code and the remaining *
* six bits are shifted until the carry is set. The number of *
* shifts needed to set the carry is used to index the table of *
* file type character symbols (FTYPETBL, $B3A7). After printing *
* the type symbol and a trailing space, the file size (in *
* sectors) is read from the description entry. PRVOLNMB ($AE42) *
* is then used to print the size as a 3-digit decimal number *
* (with leading zeroes if applicable). Because this routine *
* does not process the high byte of the file size correctly, *
* files greater than 255 sectors are expressed as 256 modular. *
* Thus a file that is actually 256 bytes long will be displayed *
* in the catalog as being "000" sectors in length. (Special *
* note should be taken of files that appear to be "001" sectors *
* long. Either these files are actually 257 sectors long (or *
* some multiple thereof) or else they were written to the disk *
* incorrectly. All valid files must be at least two sectors *
* because each file requires at least one T/S list sector and *
* one data sector. A file that is only one sector long was *
* opened but never closed properly. Such files are useless and *
* should be deleted from the disk.) *
* A space and the file name are printed after the file size.*
* Next the CRCATLOG ($AE2F) is again called to print a carriage *
* return and test for a screen pause. Finally, the index into *
* the current directory is kicked up by 35 bytes to point to the *
* next potential entry in the directory sector. If the resulting*
* index is 245 or greater, the carry is set. A set carry means *
* that the index points beyond the end of the current directory. *
* As a result, the "BCS RDDIRSEC" instruction is taken to read *
* in the next directory sector. If there is enough space left *
* on the directory sector for another file entry, the "BCC *
* DESCRPTK" is executed to process the next potential file *
* description. *
* Because the catalog's command and function handlers are *
* easy to relate to, almost everybody and his dog has taken a *
* crack at customizing the catalog with certain enhancements or *
* protection schemes. Most major Apple-orientated magazines *
* have printed articles which explain how to patch a free-space- *
* left-on-disk utility to the catalog or how to repair the bugs *
* in the PRVOLNMB routine ($AE42). Many commercial programs put *
* the real catalog on a different track and supply a phony *
* catalog on track #$11 (dec 17). Other developers zap the *
* file name fields of the description entries with names *
* containing "illegal" characters. For instance, you can insert *
* backspaces into a name in order to hide preceeding characters. *
* You can even zap the name field with a return, ctrl-D and a *
* DOS command to trick the catalog routine into doing some other *
* function if a person gets past earlier defence techniques. *
* Some developers are even silly (or paranoid) enough to zap the *
* sector size bytes with enlarged values in the hope that you *
* will think you're getting more bytes/buck. Some programs, *
* such as the word processor I am presently using, make it a *
* policy to always set the file size bytes to 0. *
* Data files are often protected from user abuse by simply *
* zapping the first byte of the file's description entry with an *
* illegal track number that is negative but less than #$FF. *
* (Obviously the driver routines must modify this code before *
* and after each access.) The illegal track # prevents the file *
* from being displayed on the catalog (via the BMI NXDESCRP" *
* instruction at $ADD9). However because the byte is less than *
* $FF, the corresponding file entry space is not considered to *
* be available by the write subfunctions. (When a new file is *
* being added to the disk, the first available space in a *
* directory is used for the new file description. Only potential*
* entry spaces that start with a $00 or a $FF are considered fair*
* game.) *
* Other "enchancements" that are commonly used include *
* changing the "LDA #22" instruction at $ADA3 to set the screen *
* line counter to a different value, modifying the lock symbol *
* ("LDY "*", $AD2E), changing the file type character codes in *
* the FTYPETBL table at $B3A7, changing the contents of the *
* DSKVOLUM table at $B3AF to print something other than "DISK *
* VOLUME ", NOPing out the "BMI NXDESCRP" instruction at $ADD9 *
* to list both active and deleted files, or changing "BMI *
* NXDESCRP" to "BPL NXDESCRP" to force the catalog to display *
* deleted files only. *
* Protection techniques that rely on modified file *
* descriptions are easy to discover. If you suspect that the *
* file description entries have been tampered with, simply *
* catalog the disk and inspect the directory sector buffer. If *
* the disk contains more than 7 files, only the last few entries *
* will be listed in the buffer. However, whenever DOS performs *
* a specific operation of a file, the description of the file is *
* left in the directory sector buffer. Therefore, if the file *
* of interest does not appear in the buffer when you do a *
* catalog, simply lock, unlock or verify a file listed above or *
* below the particular file of interest. You can then inspect *
* the file description entry belonging to the file you are *
* interested in. *
* *
******************************************************************
* On entry - CUMLOPTN ($AA65) has been updated
* to reflect any parsed option words.
* - the validity of the options issued
* with the command (and their numeric
* values) have been checked. (Only
* drive and slot parameters are optional.)
* - the first byte of the primary file name
* buffer (PRIMFNBF, $AA75) has been zeroed
* out.
(A56E)
CMCATLG LDA #6 ;Catalog opcode.
(A570) JSR HNDLCMD1 ;Call command handler to do the catalog.
* Part of common file manager command handler code.
(A2AA)
HNDLCMD1 STA TEMPBYT ;Store catalog 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 parameter list.
STA RECLENFM
LDA LENPRSD+1
STA RECLENFM+1
CLSLOCBF JSR CMDCLOSE ;Use close cmd to find a free DOS buffer.
(A2C8)
* NOTE: ONLY A MINOR PORTION OF THE CLOSE
* COMMAND IS SHOWN BELOW because only part of
* it is applicable to the catalog command.
* When accessed from the catalog command,
* the close command is actually only used to
* find a free DOS buffer.
(A2EA)
CMDCLOSE LDA PRIMFNBF ;Get 1rst char from primary name buffer.
CMP #" " ;Don't allow leading <spc> in name.
(A2EF) BEQ CLOSEALL ;Leading <spc> = signal to close all files.
;(A close cmd was issued with no
;accompanying file name.)
(A2F1) JSR GETBUFF ;Locate a DOS file buffer.
* Attempt to locate highest numbered (lowest
* in memory) free DOS name buffer.
*
* NOTE: Because a filename field is not
* applicable to the catalog command, earlier
* processing by DOS (at FNOTAPPL, $A0A0) has
* stuck a $00 in the first byte of the primary
* filename field buffer (PRIMFNBF, $AA75).
* This insures that:
* 1) Execution falls thru to the GETBUFF
* routine.
* 2) The GETBUFF routine never finds a DOS
* filename buffer with a filename that
* matches the "name" in the primary
* filename buffer. Instead, the GETBUFF
* routine is exited with A5L/H pointing to
* the filename field of the highest numbered
* (lowest in memory) free DOS buffer. If a
* free buffer can't be found, A5L+1 is left
* containing a default value of $00.
(A764)
GETBUFF LDA #0 ;Default hi-byte of pointer to 0
STA A5L+1 ;(ie. assume no free buff available).
(A768) JSR GETFNBF1 ;Get ptr to 1rst name buffer in chain.
* Point A3L/H at 1rst (ie. lowest numbered,
* highest in memory) DOS filename buffer.
* (Addr of this buf is kept in ADOSFNB1
* which occupies the 1rst two bytes of the
* table of relocatable address constants.)
(A792)
GETFNBF1 LDA ADOSFNB1 ;First link to chain
LDX ADOSFNB1+1 ;of DOS buffers.
(A798) BNE SETNXPTR ;ALWAYS.
(A7A4)
SETNXPTR STX A3L+1 ;Put addr of 1rst
STA A3L ;buffer in ptr.
TXA ;(a)= hi-byte of adr.
GETNXRTN RTS
(A7A9)
(A76B) JMP FNCHAR1 ;Get first byte of DOS name buffer.
------------
(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 at chain buf
(A79C) LDA (A3L),Y ;Pick up addr of nxt
;filename buffer.
(A79E) BEQ GETNXRTN ;If hi byte = 0 then
;link zeroed out.
(A7A0) TAX ;Save hi-byte in (x).
DEY ;Pick up low-byte.
LDA (A3L),Y
SETNXPTR STX A3L+1 ;Put adr of filename
STA A3L ;buf in pointer.
TXA ;Put hi-byte in (a).
GETNXRTN RTS
(A7A9)
(A771) BEQ NOFNMTCH ;Link zeroed out, end of chain.
FNCHAR1 JSR GETFNBY1 ;Get 1rst char of name from buf in chain.
(A773)
* Get 1rst char of name from current
* filename buffer in DOS buffer chain.
* (If first byte is $00, then buffer is
* free. Otherwise, it is the 1rst char
* in the name of the file which owns the
* DOS buffer.)
(A7AA)
GETFNBY1 LDY #0
LDA (A3L),Y
(A7AE) RTS
(A776) BNE NXFNBUF ;Take branch if buffer wasn't free.
LDA A3L ;Buffer was free, there4 put ptrs to free
STA A5L ;buffer in A5L/H.
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 buf. (Start with last char 1rst.)
(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. ALWAYS TAKE THIS
(A791) RTS ;ROUTE WITH CATALOG CMD.
============
(A2F4)
EVENTXIT BCS CLOSERTS ;ALWAYS TAKE WITH CATALOG CMD.
CLOSERTS RTS
(A330) ============
(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 ROUTINE IS ACTUALLY SUPERFULOUS TO
* THE CATALOG COMMAND because the first byte of
* the primary name buf (PRIMFNBF, $AA75) was
* previously zeroed out.
(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 catalog opcode back from the temporary
STA OPCODEFM ;buffer and put it in the FM parameter list.
(A2E7) JMP FMDRIVER
-------------
* Use the file manager driver
* to do the CATALOG 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.
.
.
(AD98)
FNCATLOG .
.
(See dis'mbly of CATALOG function.)
.
.
- initializes the FM work area (non chain)
& then copies volume #, etc from the FM
parameter list into the FM work area.
(The vol # is set to 0 so any vol of disk
can be cataloged.)
- reads in the VTOC.
- sets SCRNSRCH ($B39D) to allow 22 screen
lines before pause & subsequent scrolling.
- reads in all necessary directory secs
- for @ non-deleted file description entry
in @ directory sec, prints the following
file information: locked or unlocked, file
type code, file size in sectors & file name.
.
.
(RTS)
============
TOERROP JMP RNGERROP ;Go handle range error.
(AB1F) ------------ ;(See dis'mbly of errors.)
* Return here after doing the CATALOG 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 - Encountered a zeroed-out T/S link or
;a zeroed-out data pair (trk/sec vals)
;listed in the T/S list. (Not applicable to
;the catalog function.)
(A6B4) JMP OTHRERR ;No. See dis'mbly of errors.
------------
(A6C3)
FMDRVRTN RTS
(A573) LDA VOLFM ;Get volume # from FM parm list.
STA VOLPRSD ;Put it in the parsed table.
(A579) RTS ;Return to caller of the catalog command.
============ ;(Normally returns to AFTRCMD ($A17D)
;located in the command parsing and
;processing routines.)