495 lines
36 KiB
Plaintext
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.)
|