******************************************************************
*                                                                *
*                      READ Command Handler                      *
*                                                                *
*----------------------------------------------------------------*
*                                                                *
*      The READ command prepares DOS to retrieve data from a     *
* file in response to subsequent INPUT or GET statements.  The   *
* command can only be used in the deferred mode.  A filename     *
* must be issued with the command or else DOS interprets the     *
* "READ" as an Applesoft statement which is used to assign       *
* values to variables via DATA statements.                       *
*      R(ecord number) and B(yte offset) parameters are optional.*
* If an R-parameter is given, the file is treated as a random    *
* access file.  The absence of a an R-parameter defines a        *
* sequential text file.  Byte parameters can be used with either *
* type of file.  When used with random access files, the B-      *
* parameter defines the byte offset into a specific record.  When*
* used with sequential files, it supposedly defines an offset    *
* from the start of the file.  However, because the R-value can  *
* sometimes be defaulted to an unexpected value, you should      *
* always specify a record value of zero if you use a B-parameter *
* while reading a sequential file.                               *
*                                                                *
* Execution pattern:                                             *
*      The CMDREAD routine ($A510) first calls the common read/  *
* write routine (COMRDWR, $A526) to locate a DOS buffer whose    *
* name field contains the same name as the file wanted.  If the  *
* named file can't be located, CMDOPEN ($A2A3) is used to open   *
* the file.  If the file does not already exist on the disk, a   *
* file-not-found message is generated.  Once a file is opened, a *
* check is made to insure that the type code of the wanted file  *
* matches that of the file just opened.  If the codes don't      *
* match, the file is closed and the command is exited via a      *
* file-type-mismatch error.                                      *
*      Therefore, contrary to the information contained in THE   *
* DOS MANUAL, it is NOT necessary to OPEN a file before READing  *
* it.  If the file is not already open, the READ command opens   *
* it for you.  However, the READ command does not accept an L-   *
* parameter.  Therefore, if you wish to use a record length      *
* greater than the default value of one, you must either use     *
* the OPEN command or, using assembly language, bypass the       *
* command parsing interpreter and set the input and parsed       *
* table accordingly.                                             *
*      The COMRDWR routine eventually checks bits one and two of *
* CUMLOPTN ($AA65) to see if R- or B-parameters were issued with *
* the command.  If either parameter was given, the file manager  *
* (FILEMGR, $AB06) is called to do the position function         *
* FNPOSN, $AD12).  FNPOSN uses the L-, R- and B-parameters to    *
* calculate the desired position of the three-byte file pointer  *
* (FILPTSEC, $B5E4-$B5E5 and FILBYT, $B5E6) via the following    *
* formula:                                                       *
*      pointer position wanted = (record number * record length) *
*                                + byte offset into record.      *
* Once the file pointer is adjusted, or if no positioning is     *
* required, execution branches back into the CMDREAD routine at  *
* $A51E.  The output condition flag (OPUTCOND, $AA52) is then    *
* set to condition 1 and the READ command is exited after the    *
* I/O hooks are reset to point to DOS.                           *
*      Although the READ comand per se does not actually read    *
* anything from the file, it leaves the computer in the READ     *
* mode so that subsequent INPUT and GET statements take their    *
* input from the file.  (Note, a PRINT statement containing      *
* DOS's control character (usually ctrl-D) cancels the READ      *
* mode.)                                                         *
*      When Applesoft eventually picks up a subsequent INPUT or  *
* GET statement, execution bounces back and forth between        *
* Applesoft, DOS and monitor ROM.  DOS gets its mitts into the   *
* program because the READ command was exited with the I/O hooks *
* pointing at DOS's input and output handlers.                   *
*      A somewhat simplified example of the execution pattern    *
* associated with the INPUT command when the read mode is still  *
* in effect is shown in the formatted disassembly titled         *
* "CMDREAD CONTINUED".  Focus your attention on the RDTXTBYT     *
* routine ($A68C).  After putting the read opcode ($03) and      *
* read-one-byte subcode ($01) in the FM parameter list, the      *
* FMDRIVER ($A6A8) is called to do the read.  Therefore,         *
* execution eventually flows into the read function handler      *
* (FNREAD, $AC58).                                               *
*      FNREAD uses the subcode (SUBCODFM, $B5BC) to index the    *
* table of read subfunction handlers (RDSUBTBL, $AAE5) and then  *
* does a stack jump to the read-one-byte subfunction handler     *
* (READONE, $AC8A).                                              *
*      READONE first checks if the data sector wanted is         *
* presently in memory by comparing the highest two bytes (sector *
* offset bytes) of the filepointer with the relative number of   *
* the last data sector read.  If no data sector is currently in  *
* memory, or if the filepointer does not point to the data sector*
* presently in memory, the correct data sector is read in.       *
* However, if the data sector wanted is not listed in the        *
* current T/S list, then the appropriate T/S list is first read  *
* in order to get the trk/sec values for the data sector         *
* wanted.  Once the wanted data sector is in memory, the file    *
* pointer is used as an index to retrieve a single byte from     *
* the data buffer.  After saving the single byte on the stack,   *
* the INCREC routine ($B15B) is called to increment the record   *
* number or the byte offset into the record in anticipation of   *
* reading another byte.  Similarly, the file pointer is advanced *
* by the INCFILPT routine ($B194).  The byte wanted is retrieved *
* from the stack and stored in the single-byte buffer (ONEIOBUF, *
* $B5C3) in the FM parameter list.  The read function and read-  *
* one-byte subfunction are then exited.                          *
*      Once back into the calling program, the byte just read is *
* placed in the input buffer (BUF200, $200-$2FF) and             *
* conditionally displayed.  If the byte was not an input-        *
* command-terminating carriage return, or if 249 characters were *
* not yet read in response to the single INPUT statement,        *
* execution branches back to the NXTCHAR routine ($FD75) which   *
* eventually uses the RDTXTBYT routine to read another byte for  *
* the INPUT string.   When a carriage return is encountered,     *
* byte retrieval stops, the I/O hooks are reset to point to DOS  *
* and execution eventually flows back into Applesoft's INPUT     *
* routine where the data are assigned to a variable.  Finally,   *
* execution returns to the caller of the INPUT statement.        *
*                                                                *
******************************************************************


* Conditions on entry:
* - If MON C was previously used, the Applesoft program line
*   containing the READ command has been printed on the screen.
* - A valid filename has been parsed and copied into the primary
*   filename buffer (PRIMFNBF, $AA75).  (If a valid filename was
*   not issued with the command, execution doesn't get this far
*   because DOS's command parsing routine (PARSECMD, $9FCD)
*   interprets the "READ" as an Applesoft statement.)
* - If applicable, volume, drive, slot, record number and byte
*   offset values have been parsed, checked for validity and
*   stored in the parsed options table (VOLPRSD, DRVPRSD,
*   SLOTPRSD, RECPRSD & BYTPRSD respectively).
* - Previous use of the OPEN command has also placed the record
*   length (RECPRSD) in the parsed options table.
* - The appropriate DOS condition handler has copied an abbreviated
*   version of the original Applesot READ command line into the
*   input buffer (BUF200).  Delimiters have been dropped and the
*   Applesoft end-of-line marker (eol, $00) has been replaced with a
*   return code ($8D).  For example, if the original Applesoft line
*   was:  100 PRINT D$;"READ NAME", then the line was originally
*   coded in memory (in positive ASCII form) as follows:
*          22 08 64 00 BA 44 24 3B 22 52 45 41 44 20 4E 41 4D 45 22 00
*          .  .  .  .  .  D  $  ;  "  R  E  A  D spc N  A  M  E  "  eol marker
*          .  .  .  .  .
*          .  .  .  .  ---> PRINT token
*          .  .  .  ----> line number (hi)
*          .  .  -----> line number (low)
*          .  ------> ptr to next line (hi) (varies)
*          -------> ptr to next line (low) (varies)
*
*  The abbreviated (negative ASCII) version placed in the keyboard
*  input buffer by DOS would be as follows:
*          84 D2 C5 C1 C4 A0 CE C1 CD C5 8D
*          .  R  E  A  D spc N  A  M  E  rtn
*          .
*          ----> $84 = actual hex code for ctrl-D
*
* - The READ command is normally entered with OPUTCOND: 00,
*   CONDNFLG: 00, and the I/O hooks pointing to the true I/O
*   handlers (ex. CSW: COUT1 & KSW: KEYIN).


(A51B)
CMDREAD  JSR COMRDWR  ;Call common read/write routine.

                      * Code common to read/write.
                      (A526)
                      COMRDWR  JSR GETBUFF  ;Locate a DOS buffer.

                                            * Locate buffer with same name.
                                            * If that fails, locate a free buffer.
                                            (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.

                                                                  (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  ;Get 1rst byte in DOS name buf.
                                                     ------------

                                            (A76E)
                                            GETFNLNK JSR GETNXBUF

                                                                  * Get addr of next DOS name 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 ;Link zeroed out, end of chain.
                                            FNCHAR1 JSR GETFNBY1 ;Get the 1rst char of filename from buf in chain.
                                            (A773)

                                                                  * Get first byte in 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.
                                            (878F)   RTS
                                                     ============

                                            (8790)
                                            NOFNMTCH SEC          ;Link zeroed out.
                                            (A791)   RTS
                                                     ============
 
                      (A529)   BCC BUFS4RW  ;Branch if matching buffer was found
                                            ;(ie. file was already open).

                      * FILE NOT ALREADY OPEN, SO GO OPEN IT.
                      (A52B)   JSR CMDOPEN

                                            (A2A3)
                                            CMDOPEN  LDA #0       ;0 = code for text file.
                                            (A2A5)   JMP OPNCKTYP ;Go open the file & chk its type.
                                                     ------------

                                            (A3D5)
                                            OPNCKTYP STA FILTYPFM ;Put code for file type in the
                                            (A3D8)   PHA          ;Fm parameter list & save it on stk.
                                                                  ;($00=Text, $01=Integer, $02=Applesoft,
                                                                  ;$04=Binary, $08=S-type, $10=Relocatable,
                                                                  ;$20=A-type and $40=B-type.)
                                            (A3D9)   JSR HNDLCMD  ;Use FM cmd handler to open file.

                                                                  * Common file manager command handler code.
                                                                  (A2A8)
                                                                  HNDLCMD  LDA #1       ;1 = open opcode.
                                                                  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.)
                                                                                                 .
                                                                                                 .
                                                                                        - because a matching filename does not
                                                                                          exist, only one pass is made through
                                                                                          the CLOSE command.  A5L/H is normally
                                                                                          left pointing at the highest numbered
                                                                                          (lowest in memory) free DOS buffer when
                                                                                          CMDCLOSE is exited via EVENTXIT and
                                                                                          CLOSERTS.  If no free buffer is
                                                                                          available, A5L/H contains a zero.
                                                                                                 .
                                                                                                 .
                                                                                                 (RTS)

                                                                  (A2CB)   LDA A5L+1    ;Hi byte of A5L/H ptr 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 error msg.
                                                                           ------------ ;(See dis'mbly of errors.)

                                                                  (A2D2)
                                                                  SAVFNPTR STA A3L+1    ;Reset A3L/H to point at DOS buffer that
                                                                           LDA A5L      ;we will use for file name field buffer.
                                                                           STA A3L
                                                                  (A2D8)   JSR CPYPFN

                                                                                        * Assign DOS buffer to file we want to
                                                                                        * open.  Copy the name of the file wanted
                                                                                        * from the primary file name buf to the
                                                                                        * DOS buffer's filename field.
                                                                                        (A743)
                                                                                        CPYPFN   LDY #29      ;30 bytes to copy       
                                                                                        (A745)                ;(0 to 29).
                                                                                        CPYPRIM  LDA PRIMFNBF,Y ;Copy name of
                                                                                                 STA (A3L),Y  ;file wanted from
                                                                                                 DEY          ;primary name buf
                                                                                                 BPL CPYRIM   ;into the DOS
                                                                                        (A74D)   RTS          ;name buffer.
                                            
                                                                  (A2DB)   JSR BUFS2PRM

                                                                                        * Get addrs of the various DOS bufs 
                                                                                        * from the chain buf & put them in
                                                                                        * the FM parameter list.
                                                                                        (A74E)
                                                                                        BUFS2PRM LDY #30      ;Get adr of FM work
                                                                                        ADRINPRM LDA (A3L),Y  ;buf, T/S list buf,
                                                                                                 STA WRKBUFFM-30,Y ;data sec buf
                                                                                                 INY          ;& next DOS name buf
                                                                                                 CPY #38      ;from chain pointer
                                                                                                 BNE ADRINPRM ;buf & put them in
                                                                                        (A75A)   RTS          ;FM parm list.
                                                                                                              ;(P.S.  Adr of next
                                                                                                              ;DOS name buf is
                                                                                                              ;not used by DOS.)

                                                                  (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 adr of the
                                                                                                 STA FNAMBUFM ;primary name buf
                                                                                                 LDA ADRPFNBF+1 ;from constants
                                                                                        (A735)  STA FNAMBUFM+1 ;tbl and put it
                                                                                                              ;in FM parm list.
                                                                                        (A738)   LDA A3L      ;Save the adr of
                                                                                                 STA CURFNADR ;current DOS name
                                                                                                 LDA A3L+1    ;buf in table of
                                                                                                 STA CURFNADR+1 ;DOS variables.
                                                                                        (A742)   RTS

                                                                  (A2E1)   LDA TEMPBYT  ;Get open opcode back from temporary buf
                                                                           STA OPCODEFM ;and put it in the FM parameter list.
                                                                  (A2E7)   JMP FMDRIVER ;Do function via FM driver.
                                                                           ------------

                                                                  * USE THE FILE MANAGER DRIVER
                                                                  * TO DO THE OPEN FUNCTION.
                                                                  (A6A8)
                                                                  FMDRIVER JSR FILEMGR  ;Call the file manager to do function.

                                                                                        * File manager proper.
                                                                                        (AB06)
                                                                                        FILEMGR  TSX          ;Save stk pointer
                                                                                        (AB07)   STX STKSAV   ;so can later rtn
                                                                                                              ;to caller of FM.
                                                                                        (AB0A)   JSR RSTRFMWA

                                                                                                           * Copy FM work buf
                                                                                                           * (in DOS chain) to
                                                                                                           * FM work area (not
                                                                                                           * in DOS chain).
                                                                                                           (AE6A)
                                                                                                           RSTRFMWA JSR SELWKBUF
                                                                                                                             l
                                                                                                                             l
                                                                                                        ----------------------
                                                                                                        l * Get adr of FM work
                                                                                                        l * buff from FM parm
                                                                                                        l * list & put it in
                                                                                                        l * A4L/H pointer.
                                                                                                        l (AF08)
                                                                                                        l SELWKBUF LDX #0
                                                                                                        l (AF0A)   BEQ PT2FMBUF
                                                                                                        l
                                                                                                        l (AF12)
                                                                                                        l PT2FMBUF LDA WRKBUFFM,X
                                                                                                        l          STA A4L
                                                                                                        l          LDA WRKBUFFM+1,X
                                                                                                        l          STA A4L+1
                                                                                                        l (AF1C)   RTS
                                                                                                        l ---------------------
                                                                                                                              l
                                                                                                                              l
                                                                                                           * Zero out return
                                                                                                           * code in FM parm
                                                                                                           * 2 signal no errs.
                                                                                                           (AE6D)   LDY #0
                                                                                                           (AE6F)   STY RTNCODFM

                                                                                                           * Copy FM work buf
                                                                                                           * to FM work area.
                                                                                                           (AE72)
                                                                                                           STORFMWK LDA (A4L),Y
                                                                                                                    STA FMWKAREA,Y
                                                                                                                    INY
                                                                                                                    CPY #45
                                                                                                                    BNE STORFMWK
                                                                                                                    CLC
                                                                                                           (AE7D)   RTS

                                                                                        * Check if opcode is legal.
                                                                                        * (Must be less than 13.)
                                                                                        (AB0D)   LDA OPCODEFM
                                                                                                 CMP #13
                                                                                        (AB12)   BCS TOERROP  ;Opcode too large
                                                                                                              ;(got range err).
                                                                                        (AB14)   ASL          ;Double val of
                                                                                        (AB15)   TAX          ;opcode & put it
                                                                                                              ;in (x) so it 
                                                                                                              ;indexes tbl of
                                                                                                              ;addresses.
                                                                                        (AB16)   LDA FMFUNCTB+1,X ;Stick adr of
                                                                                                 PHA          ;the appropriate
                                                                                                 LDA FMFUNCTB,X ;function hndlr
                                                                                        (AB1D)   PHA          ;on stack (hi byte
                                                                                                              ;first).
                                                                                        (AB1E)   RTS          ;DO STACK JUMP TO
                                                                                                              ;FUNCTION ENTRY
                                                                                                              ;POINT.
                                                                                                 .
                                                                                                 .
                                                                                        (AB22)   .
                                                                                        FNOPEN   .
                                                                                                 .
                                                                                        (See dis'mbly of OPEN function.)
                                                                                                 .
                                                                                                 .
                                                                                        - uses part of COMNOPEN routine.
                                                                                        - reads in VTOC to get link to 1rst
                                                                                          directory.
                                                                                        - reads directory secs in & looks for
                                                                                          file description entry with matching
                                                                                          filename.
                                                                                        - if matching name found, reads in the
                                                                                          1rst T/S list sector belonging to the
                                                                                          file.
                                                                                        - if no match found, starts a new file:
                                                                                          (1) creates new file description entry
                                                                                              - copies name to 1rst available spc
                                                                                                in direc sec (if can't find spc,
                                                                                                then issues disk full error msg).
                                                                                              - allocates secs for file.
                                                                                              - writes updated VTOC to disk.
                                                                                              - puts link to first T/S list, file
                                                                                                size, etc in directory entry spc.
                                                                                              - writes directory sector buffer to
                                                                                                disk.
                                                                                          (2) creates new T/S list & writes it to
                                                                                              disk.
                                                                                        - reads T/S list back into T/S list
                                                                                          buffer.
                                                                                                 .
                                                                                                 .
                                                                                                 (RTS)
                                                                                                 ============

                                                                                        TOERROP  JMP RNGERROP ;(See dis'mbly
                                                                                        (AB1F)   ------------ ;of errors.

                                                                  * Return here after doing the OPEN 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
                                                                                        ;open function.)
                                                                  (A6B4)   JMP OTHRERR  ;No.  (See dis'mbly of errors.)
                                                                           ------------

                                                                  (A6C3)
                                                                  FMDRVRTN RTS
     
                                            (A3DC)   PLA          ;Get file type wanted off of stack.
                                            (A3DD))  JMP CHKFTYPE ;Go check if type wanted equals type found.
                                                     ------------

                                            * Check if file type wanted = file type found.
                                            * (If using open command to open a pre-exisiting file,
                                            * may get a type mismatch.  However, a mismatch error
                                            * is not possible when opening a new file.)
                                            (A7C4)
                                            CHKFTYPE EOR FILTYPFM ;Type found (via open function).
                                            (A7C7)   BEQ CKTYPRTN ;Branch if type wanted = type found.

                                            * File types didn't match.
                                            * Check if correct type but locked.
                                            (A7C9)   AND #%01111111 ;Maybe matched - Check again
                                                                  ;but this time disregard lock bit.
                                            (A7CB)   BEQ CKTYPRTN ;Branch if matched.

                                            * Type wanted < > type found!!!!!
                                            * So go close file & then issue a
                                            * type mismatch error message.
                                            (A7CD)   JSR CMDCLOSE ;Wrong kind of file so go close it.

                                                                  * Because the file is already open, execution flows through
                                                                  * the close cmd twice.  The first time thru, the matching
                                                                  * DOS filename buffer is located & then CLOSEONE is used to
                                                                  * close the file via the open FUNCTION.  The 2nd time thru, a
                                                                  * matching filename buffer is not found because the DOS
                                                                  * buffer was released on the first pass.  Therefore, A5L/H is
                                                                  * left pointing at the highest numbered (lowest in memory)
                                                                  * FREE DOS buffer when the close command is exited via EVENTXIT
                                                                  * and CLOSERTS.
                                                                  (A2EA)
                                                                  CMDCLOSE .
                                                                           .
                                                                  (See dis'mbly of CLOSE command.)
                                                                           .
                                                                           .
                                                                           (RTS)

                                            (A7D0)   JMP TYPMISM  ;Go handle type mismatch error.
                                                     ------------ ;(Eventually exits into DOS's warmstart routine.)
                                                                  ;(See dis'mbly of errors.)

                                            CKTYPRTN RTS
                                            (A7D3)   ============

                      (A52E)   JMP CKRBOPTN ;Go chk if R- & B-parms were issued with cmd.
                               ------------

                      BUFS4RW  JSR BUFS2PRM
                      (A531)

                                            * Copy addresses of the various DOS buffers
                                            * from the DOS chain buffer to 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

                      * Check if R- or B-parameters were issued with command.
                      (A534)
                      CKRBOPTN LDA CUMLOPTN ;Chk if R- or B- parms issued.
                               AND #%00000110 ;(R=$04, B=$02.)
                      (A539)   BEQ RDWRRTN  ;NO - skip positioning of file pointer.

                      * Copy B- and R-parameters from option
                      * parsed table to FM parameter list.
                      (A53B)   LDX #3
                      CPYBPARM LDA RECPRSD,X ;Get value of parameter.
                               STA RECNMBFM ;Store it in FM parameter list.
                               DEX          ;4 bytes to copy (3 to 0).
                      (A544)   BPL CPYBPARM ;More bytes to copy.

                      * CALL THE FILE MANAGER WITH THE POSITION OPCODE.
                      (A546)
                      BK2APND  LDA #$0A     ;Opcode for position.
                               STA OPCODEFM ;Put opcode in FM parm list.
                      (A54B)   JSR FMDRIVER ;Call file manager to do the position 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 return
                                                                           STX STKSAV   ;to the caller of the file manager.
                                                                  (AB07)   JSR RSTRFMWA

                                                                                        * Copy FM work buf (in DOS chain) 2
                                                                                        * FM work area (not in DOS chain).
                                                                                        (AE6A)
                                                                                        RSTRFMWA JSR SELWKBUF

                                                                                                          * Get addr of FM work
                                                                                                          * buf from FM parm
                                                                                                          * list & put it in
                                                                                                          * the A4L/H pointer.
                                                                                                          (AF08)
                                                                                                          SELWKBUF LDX #0
                                                                                                          (AF0A)   BEQ PT2FMBUF

                                                                                                          (AF12)
                                                                                                          PT2FMBUF LDA WRKBUFFM,X
                                                                                                                   STA A4L
                                                                                                                   LDA WRKBUFFM+1,X
                                                                                                                   STA A4L+1
                                                                                                          (AF1C)   RTS

                                                                                        (AE6D)   LDY #0       ;Zero out return
                                                                                        (AE6F)   STY RTNCODFM ;code in FM parm
                                                                                                              ;to assume no errs
                                                                                        (AE72)                ;as default cond.
                                                                                        STORFMWK LDA (A4L),Y  ;Copy FM work buf
                                                                                                 STA FMWKAREA,Y ;to FM work area.
                                                                                                 INY
                                                                                                 CPY #45      ;45 bytes to copy.
                                                                                                 BNE STORFMWK ;(0 to 44).
                                                                                                 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.

                                                                           .
                                                                           .
                                                                  (AD12)   .
                                                                  FNPOSN   .
                                                                           .
                                                                  (See dis'mbly of POSITION function.)
                                                                           .
                                                                           .
                                                                           (RTS)
                                                                           ============

                                                                  TOERROP  JMP RNGERROP ;Go handle range error.
                                                                  (AB1F)   ------------

                                            * Return here after doing the POSITION 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 position function.)
                                            (A6B4)   JMP OTHRERR  ;No.  (See dis'mbly of errors.)
                                                     ------------

                                            (A6C3)
                                            FMDRVRTN RTS

                      (A54E)
                      RDWRRTN  RTS
                               ============

(A51E)   LDA #1       ;Set condition flag to designate  reading status so
(A520)   STA CONDNFLG ;subsequent INPUT & GET statements will take
                      ;data from the disk.
(A523)   JMP FINSHCMD
         ------------

* Finish off the DOS command.
(9F83)
FINSHCMD LDA BUF200   ;Get first char in buffer.
(9F86)   CMP DCTRLCHR ;Was command done via DOS's control char?
                      ;(Normally ctrl-D.)
(9F89)   BEQ DSPLYCMD ;Yes - ALWAYS TAKE WHEN USING READ CMD
                      ;      (cause abbreviated NEG ASCII version of Applesoft
                      ;      program line containing the READ cmd is still
                      ;      in the keyboard input buffer, BUF200).

(9F95)
DSPLYCMD LDA #%01000000 ;Set bit 6 to see if using "MON C".
(9F97)   BNE DSPLYCHR ;ALWAYS.

(9F9F)
DSPLYCHR AND CIOCUMUL ;Test flag - see if should display.
(9FA2)   BEQ DOSEXIT  ;No - so just exit DOS with condition 1 still
                      ;     set so file data will be read.

* MON C flag was on, so display command-terminating
* carriage return.  (P.S. Applesoft detected the
* end-of-line marker ($00) and changed it to a <cr>.
* DOS then put the carriage return ($8D) as the last
* character in the input buffer.)
(9FA4)
DSPLYALL JSR RESTOREG

                      (9FBA)
                      RESTOREG LDA ASAVED   ;Restore (a), (y) & (x) registers.
                               LDY YSAVED
                               LDX XSAVED
                               SEC          ;Why?????
                      (9FC4)   RTS

(9FA7)   JSR GODSPLY  ;Output char via true output handler.

                      (9FC5)
                      GODSPLY  JMP (CSW)
                               ------------

                      (FDF0)
                      COUT1    .
                               .
                      (Print char thru true output handler.)
                      (See dis'mbly of monitor in APPLE II REFERENCE MANUAL.)
                               .
                               .
                               (RTS)
                               ============
     
(9FAA)   STA ASAVED   ;Save (a), (y) and (x) registers.
         STY YSAVED
(9FB0)   STX XSAVED

* Routine to exit DOS.
(9FB3)
DOSEXIT  JSR INITIOHK ;Reset I/O hooks to point to DOS.

                      * Initialize the I/O hooks so that DOS intercepts
                      * all input & output.  For instance, if a routine
                      * encounters a "COUT  JMP (CSW)", then execution will
                      * actually flow to DOS's output routine (OPUTINCP,
                      * $9EBD).  Similarly, any routine that refers to
                      * "RDKEY  JMP (KSW)" will actually jump to DOS's
                      * input routine (INPTINCP, $9E81).
                      *
                      * The true (ie. normal) hooks are saved, ex:
                      *     KSW: KEYIN --> KSWTRUE: KEYIN.
                      *     CSW: COUT1 --> CSWTRUE: COUT1.
                      * The intercepts are then set as follows:
                      *     ADINPTCP: INPTINCP --> KSW: INPTINCP.
                      *     ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.

                      * Check if the input hook needs to be reset.
                      (A851)
                      INITIOHK LDA KSW+1
                               CMP ADINPTCP+1
                      (A856)   BEQ CKOUTHK  ;Input hook already points to DOS's
                                            ;input handler, so go check output hook.

                      * Reset the input hook to point to DOS.
                      (A858)   STA KSWTRUE+1 ;KSW: KEYIN --> KSWTRUE: KEYIN.
                               LDA KSW
                               STA KSWTRUE
                               LDA ADINPTCP ;ADINPTCP: INPTINCP --> KSW: INPTINCP.
                               STA KSW
                               LDA ADINPTCP+1
                      (A868)   STA KSW+1

                      * Check if the output hook needs to be reset.
                      (A86A)
                      CKOUTHK  LDA CSW+1
                               CMP ADOPUTCP+1
                      (A86F)   BEQ SETHKRTN ;Output hook already points to DOS's
                                            ;output handler, so go exit.

                      * Reset the output hook to point to DOS.
                      (A871)   STA CSWTRUE+1 ;CSW: COUT1 --> CSWTRUE: COUT1.
                               LDA CSW
                               STA CSWTRUE
                               LDA ADOPUTCP ;ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
                               STA CSW
                               LDA ADOPUTCP+1
                               STA CSW+1
                      SETHKRTN RTS
                      (A883)

(9FB6)   LDX STKSAVED ;Retrieve saved stack pointer.
         TXS          ;(P.S.  Don't confuse "STKSAVED" with "STKSAV".)
RESTOREG LDA ASAVED   ;Restore (a), (y) & (x) registers.
         LDY YSAVED
         LDX XSAVED
         SEC          ;Why?????
(9FC4)   RTS          ;Exit to caller of READ command.
         ============ ;(Normally returns to $D533 in Applesoft
                      ;ROM -- part of INLINPL2 routine ($D52E).)


************************************
*                                  *
* NOTE:  See formatted disassembly *
* titled "CMDREAD CONTINUED".      *
*                                  *
************************************
