******************************************************************
*                                                                *
*                      RUN Command Handler                       *
*                                                                *
******************************************************************
*                                                                *
*      DOS's RUN command loads an Integer or Applesoft file and  *
* then attempts to execute it.  If the specified file is not on  *
* the disk, a file-not-found error message is printed.  If the   *
* file type code of the specified file is not compatible with    *
* the currently active language, the computer attempts to select *
* the correct basic before LOADing the file.                     *
*                                                                *
******************************************************************


* On entry - CUMLOPTN ($AA65) has been updated
*            to reflect parsed option words.
*            (Only volume (VOLPRSD), drive (DRVPRSD)
*            and slot (SLOTPRSD) parameters are
*            allowed with the DOS RUN command.)
*          - the validity of the options issued
*            with the command (and their numeric
*            values) have been checked.
*          - if a legal file name was issued, it has
*            been parsed & placed in the primary file
*            name buffer (PRIMFNBF, $AA75).
           - if no filename was issued with the RUN
*            comand, then execution doesn't get this far.
*            Instead, the DOS interpreter preceives the
*            "RUN" as a BASIC command & therefore sends
*            it along to the basic interpreter where it
*            attempts to RUN a program currently in memory.


(A4D1)
CMDRUN   LDA ACTBSFLG ;Check which basic is current.
                      ;(Int=$00, A(ROM)=$40, A(RAM0=$80)
(A4D4)   BEQ LOAD4RUN ;Branch if using integer.
(A4D6)   STA RUNTRUPT ;Set the RUN intercept flag to siganl that
                      ;we are about to interrupt the RUN command
                      ;to do a LOAD. ($40=A(ROM), $80=A(RAM).)

* GO LOAD THE PROGRAM.
* NOTE:  THE "JSR" INSTRUCTION SHOWN BELOW IS
* ACTUALLY A PLACEBO because after the file is
* loaded, execution goes into basic and then
* re-enters DOS.  Once DOS gets its mitts back
* into things, the RUNTRUPT flag is tested, THE
* STACK IS RESET and then execution flows to the
* next instruction (at RUNFPINT, $A4DC)).  
(A4D9)
LOAD4RUN JSR CMDLOAD

                      (A413)
                      CMDLOAD  .
                               .
                      (See dis'mbly below.)
                               .
                               .
                               (RTS)

(A4DC)
RUNFPINT JSR CRVIADOS

                      * Print a carriage return via DOS and the monitor.
                      (9FC8)
                      CRVIADOS LDA #$8D     ;Carriage return.
                      (9FCA)   JMP GODSPLY  ;Print char thru true output handler.
                               ------------

                      (9FC5)
                      GODSPLY  JMP (CSW)    ;CSW points to the true output handler (normally COUT1).
                               ------------

                      (FDF0)
                      COUT1    .
                               .
                      (Monitor ROM's screen output routine.)
                      (See dis'mbly in APPLE II REFERENCE MANUAL.)
                               .
                               .
                               (RTS)

(A4DF)   JSR INITIOHK

                      * Initialize the I/O hooks so that DOS
                      * intercepts all input and output.  For
                      * instance, if a routine encounters a
                      * "COUT  JMP (CSW)" then execution will
                      * actually flow to DOS's output handler
                      * 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 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 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 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 routine, so exit.

                      * Reset 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)

(A4E2)   JMP (RUNTRY) ;Go execute the program.
         ------------ ;(RUNTRY points to RUNFPROM if using A(ROM)
                      ;or RUNFPRAM if using A(RAM).)

(A4FC)
RUNFPROM JSR SETZPTRS

                      (D665)
                      SETZPTRS JSR SETXTPT

                                            * Set TXTPTR to approximate beginning of
                                            * program (ie. TXTPTR: TXTTAB-1, normally $800).
                                            (D697)
                                            SETXTPT  CLC
                                                     LDA TXTTAB   ;Add negative 1 to low byte.
                                                     ADC #$FF
                                                     STA TXTPTR
                                                     LDA TXTTAB+1 ;Add zero to hi byte if carry set.
                                                     ADC #$FF     ;Else add neg 1 to hi byte if carry clr.
                                                     STA TXTPTR+1
                                            (D6A4)   RTS

                      * Simulate a "CLEAR" statement.
                      * (Reset variable & string pointers.)
                      (D668)   LDA #0
                      CLEAR    BNE CLRTS
                      CLEARC   LDA MEMSIZ
                               LDY MEMSIZ+1
                               STA FRETOP   ;FRETOP: MEMSIZ
                               STY FRETOP+1
                               LDA VARTAB   ;ARYTAB: VARTAB
                               LDY VARTAB+1
                               STA ARYTAB
                               STY ARYTAB+1
                               STA STREND   ;STREND: VARTAB
                               STY STREND+1
                      (D680)   JSR RESTORE

                                            * Simulate a RESTORE statement.  That is, reset
                                            * the pointer which points to bytes in DATA
                                            * statement (DATPTR: TXTTAB-1).
                                            (D849)
                                            RESTORE  SEC
                                                     LDA TXTTAB
                                                     SBC #1
                                                     LDY TXTTAB+1
                                                     BCS SETDA
                                                     DEY
                                            SETDA    STA DATPTR   ;Otherwise, points to addr
                                                     STY DATPTR+1 ;of current DATA statement.
                                            (D857)   RTS

                      * Re-initialize stk while preserving return addr.
                      (D683)
                      STKINI   LDX #<TEMPST ;Set pointer to descriptor
                               STX TEMPPT   ;for garbage collection.
                               PLA          ;Save return address.
                               TAY
                               PLA
                               LDX #$F8     ;Adjust stack pointer to $1F8 in order to
                      (D68C)   TXS          ;leave enough room for links & line # bytes.
                                            ;(Actually reserves more space than needed.
                                            ;$1FB would have done just fine.)
                      (D68D)   PHA          ;Retrieve return address & put it back on stack.
                               TYA
                               PHA
                               LDA #0       ;Defeat any "CONT" statement.
                               STA OLDTEXT+1 ;Otherwise pts to last byte (an $00) of
                               STA SUBFLG   ;line just executed.
                      CLRTS    RTS
                      (D696)

(A4FF)   STA PROMPT   ;Zero out the prompt
         STA ERRFLG   ;and on-error flag.
(A503)   JMP NEWSTT   ;Jump back into APPLESOFT.
         ------------

(D7D2)
NEWSTT   .
         .
- collect & execute the program statements.
         .
         .
- Eventually the RUN command is exited via the
  RESTART ($D43C) routine.  The applicable version
  of the RESTART routine that is used is shown in
  the disassembly entitled "DOSWARMSTART".


===============================================================================================================================


******************************************************************
*                                                                *
*                      LOAD Command Handler                      *
*                                                                *
*----------------------------------------------------------------*
*                                                                *
*      DOS's LOAD command loads an Integer, Applesoft or A-type  *
* file from the disk.  Volume, drive and slot parameters are     *
* optional.  If no file name is issued with the command, DOS     *
* interprets the "LOAD" as a basic command and therefore passes  *
* it along to basic where it is used to load a file from a       *
* cassette tape.                                                 *
*                                                                *
*      A-type files are (like Applesoft files) represented in    *
* the catalog by the character "A".  Their hexadecimal file type *
* code is however different ($A0 = locked A-type, $20 = unlocked *
* A-type).  No formal structure of an A-type file has been       *
* defined.  Some authors modify DOS to generate files with a     *
* unique structure and then designate them as A-type files.  This*
* technique is often used as part of a protection scheme or to   *
* serve some specialized purpose (ex. WORD HANDLER files from    *
* Advanced Logic Systems).                                       *
*                                                                *
* Execution pattern:                                             *
*      The execution pattern of the load command is difficult to *
* follow because:                                                *
*      1) It is dependent upon the nature of the caller.         *
*      2) Execution automatically jumps into BASIC once the      *
*         program is in memory.                                  *
*      After closing all files (except an active EXEC file), the *
* common file manager command handler code (HNDLCMD, $A416) is   *
* called to assign a free DOS buffer to the named file and to    *
* customize the FM parameter list.  The file manager (FILEMGR,   *
* $AB06) is then called to open the file by reading its first    *
* track/sector list into the T/S list buffer.  (Failure to locate*
* the named file results in a file-not-found error.)             *
*      If the file just opened is NOT an Integer ($01), Applesoft*
* ($02) or A-type ($20) file, a type mismatch error message is   *
* printed.  Otherwise, the active basic flag (ACTBSFLG, $AAB6)   *
* is checked to see which basic is active.  When Integer is in   *
* effect, a branch is made to integer basic's load routine       *
* (LODINTGR, $A450).  If A(ROM) or A(RAM) are being used, the    *
* accummulator is loaded with the number "2" and SELCTBSC        *
* ($A4B1) is called to check if an Applesoft file was found.  If *
* a different file type was located, the computer assumes that   *
* the integer language is required and execution jumps to the    *
* INT command to switch languages.  (Note that this may          *
* eventually cause a crash if an A-type file was found.)  If an  *
* Applesoft file was found, execution returns to the main load   *
* routine at $A42D.                                              *
*      The length of the program is then read from the first two *
* bytes of the file and stored in the FM parameter list at       *
* LENADRBF ($AA60).  Next a check is made to see if enough free  *
* memory space is available to accommodate the program.  If      *
* (LENADRBF) + (TXTTAB) > = (MEMSIZ), a program-too-large error  *
* message is generated.   If enough space is available, the      *
* end-of-program (PRGEND, $AF) and start-of-variable-space       *
* (VARTAB, $67) pointers are set.                                *
*      The file is then read into free memory at the location    *
* defined by the start-of-program pointer (TXXTTAB, $67).  As    *
* the program is read in, LENADRBF is used as a byte counter.    *
* Once the entire program is in place, the file is closed and    *
* the I/O hooks are reset to point to DOS.  Execution then jumps *
* to the address pointed to by RLOCNTRY ($9D60).                 *
*      When Applesoft is being used, RLOCNTRY points to Applesoft*
* basic's relocation handler (SETLINKS, $D4F2).  It is this      *
* routine that reconfigures Applesoft programs and enables them  *
* to be relocatable.  Unfortunately, SETLINKS also has a darker  *
* side to its personality.  Because it clears all variable,      *
* string and data pointers, it prevents Applesoft programs from  *
* being "chainable."                                             *
*      After all of the Applesoft program's line links are       *
* adjusted to their new location, execution flows into Applesoft *
* basic's RESTART routine ($D43C).  However, the pattern of      *
* program flow depends upon the nature of the caller.  If the    *
* RUN command was interrupted to do a LOAD, the run interrupt    *
* flag (RUNTRUPT, $AAB7) is turned off and execution jumps to    *
* RUNFPINT ($A4DC) to complete the RUN command.  If the LOAD was *
* not called from the RUN command, a normal RESTART is done.     *
* (See formatted disassembly given in the file titled            *
* DOSWARMSTART.)                                                 *
*                                                                *
*      Note that the start-of-program pointer (TXTTAB, $67-$68)  *
* defines the load address.  Normally, this pointer contains an  *
* $801.  However, by simply zapping TXTTAB with a different value*
* prior to issuing the LOAD command, an Applesoft program can be *
* read into a non-standard location.  This techniques is often   *
* used to load a program above the graphics screen.              *
*      The indirect jump at $A44D represents an opportunity to   *
* divert the load routine to a user-installed patch.  For        *
* instance, you can simulate an Applesoft version of the CHAIN   *
* command by pointing RLOCNTRY at a patch that adjusts program   *
* line pointers and perserves all variables.                     *
*      If the exact file structure is known, it is sometimes a   *
* simple matter to modify the LOAD routine to accommodate certain*
* commercial programs that use A-type files.                     *
*                                                                *
******************************************************************


* On entry - CUMLOPTN ($AA65) has been updated
*            to reflect parsed option words.
*            (Only volume (VOLPRSD), drive (DRVPRSD)
*            and slot (SLOTPRSD) parameters are
*            allowed with the DOS LOAD command.)
*          - the validity of the options issued
*            with the command (and their numeric
*            values) have been checked.
*          - if a legal file name was issued, it has
*            been parsed & placed in the primary file
*            name buffer (PRIMFNBF, $AA75).
           - if no filename was issued with the LOAD
*            comand, then execution doesn't get this far.
*            Instead, the DOS interpreter preceives the
*            "LOAD" as a BASIC command & therefore sends
*            it along to the basic interpreter where it
*            is used to load the next sequential program
*            from a CASSETTE tape.


(A413)
CMDLOAD  JSR CLOSEALL

                      * CLOSE ALL FILES (EXCEPT AN ACTIVE EXEC FILE).
                      (A316)
                      CLOSEALL JSR GETFNBF1 ;Enter here when direct call or if 1rst char
                                            ;in primary filename field was a space.

                                            * Put address of 1rst DOS name buffer
                                            * (chain) in the A3L/H pointer.
                                            (A792)
                                            GETFNBF1 LDA ADOSFNB1 ;First link to chain of DOS buffers
                                                     LDX ADOSFNB1+1 ;(ie. pt to 1rst filename buffer 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 back in (a).
                                            GETNXRTN RTS
                                            (A7A9)

                      (A319)   BNE CKIFEXEC ;ALWAYS.

                      (A31B)
                      CHKNXBUF 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 ptr at chain buffer.
                                                     LDA (A3L),Y  ;Pick up hi byte of addr of nxt filename buffer.
                                                     BEQ  GETNXRTN ;If hi-byte is 0 then link 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          ;Condition z-flg in relation to hi byte .
                                            GETNXRTN RTS
                                            (A7A9)

                      (A31E)   BEQ CLOSERTS ;Link zeroed out, so now all files closed.
                      (A320)                ;Exit CLOSEALL via this route.
                      CKIFEXEC JSR CKEXCBUF

                                            * Check if current filename buffer
                                            * belongs to an EXEC file.
                                            (A7AF)
                                            CKEXCBUF LDA EXECFLAG ;Check to see if EXECing.
                                                     BEQ NOTEXCBF ;No sweat - not running exec file.
                                                     LDA EXECBUFF ;We are EXECing, there4 chk if addr of
                                                     CMP A3L      ;current filename buffer same as that
                                                     BNE CKEXCRTN ;for buffer belonging to EXEC.
                                                     LDA EXECBUFF+1 ;Maybe - low-bytes matched, now chk hi bytes.
                                                     CMP A3L+1
                                                     BEQ CKEXCRTN ;Exec buffer = current buffer.
                                            NOTEXCBF DEX          ;Not EXECing, there4 reduce (X) to make sure z-flag off.
                                            (A7C2)                ;(P.S. (x) was orig conditioned to a large non-zero
                                                                  ;value on entry to GETFNBF1.  There4, if now DEX then
                                            (A7C3)                ;can be sure z-flag will be off.)
                                            CKEXCRTN  RTS         ;If execing, rtn with z-flag on.

                      (A323)   BEQ CHKNXBUF ;EXEC WAS ACTIVE SO DON'T CLOSE ITS BUFFER
                                            ;OUT OR WILL END UP IN NEVER-NEVER-LAND.
                                            ;After all, don't want to close buffer
                                            ;if we are using it to exec (ie. would
                                            ;be like burying ourselves alive)!!!
                      (A325)   JSR GETFNBY1 ;Get first char of filename from buf in chain.

                                            * Get first byte from DOS name buffer.
                                            (A7AA)
                                            GETFNBY1 LDY #0       ;Buffer is free if 1rst byte = $00.
                                                     LDA (A3L),Y  ;If buffer is occuppied, the 1rst byte
                                            (A7AE)   RTS          ;in buf = 1rst char in name of file which
                                                                  ;owns the buffer.

                      (A328)   BEQ CHKNXBUF ;This file is already closed, so go back
                                            ;to close rest of files.
                      (A32A)   JSR CLOSEONE

                                            * CLOSE THE OPEN FILE.
                                            (A2FC)
                                            CLOSEONE JSR CKEXCBUF

                                                                  * Check if current filename buffer
                                                                  * belongs to an EXEC file.
                                                                  (A7AF)
                                                                  CKEXCBUF LDA EXECFLAG  ;Check to see if EXECing.
                                                                           BEQ NOTEXCBF ;No sweat - not running exec file.
                                                                           LDA EXECBUFF ;We are EXECing, there4 chk if addr of
                                                                           CMP A3L      ;current filename buffer same as that
                                                                           BNE CKEXCRTN ;for buffer belonging to EXEC.
                                                                  (A7BB)   LDA EXECBUFF+1 ;Maybe - low-bytes matched,
                                                                                        ;so now check hi bytes.
                                                                  (A7BE)   CMP A3L+1
                                                                           BEQ CKEXCRTN ;Exec buffer = current buffer.
                                                                  NOTEXCBF DEX         ;Not EXECing, DEX to make sure z-flag off.
                                                                  (A7C2)                ;(P.S. (x) orig conditioned to a large
                                                                                        ;non-zero value on entry to GETFNBF1.
                                                                                        ;There4, if now DEX then can be sure
                                                                  (A7C3)                ;z-flag will be off.)
                                                                  CKEXCRTN RTS          ;Exit with z-flag = 1 if execing.
                                                                                        ;                 = 0 if not execing.

                                            (A2FF)   BNE FREEBUFF ;ALWAYS BRANCH IF CLOSEONE IS ACCESSED VIA CLOSEALL.
                                                     LDA #0       ;Shut exec flag off.
                                            (A303)   STA EXECFLAG ;NOTE:  THIS INSTRUCTION IS NEVER CARRIED
                                                                  ;OUT IF ACCESSED VIA CLOSEALL.  (An active exec file
                                                                  ;was already detected and skipped by the "BEQ CHKNXBUF"
                                            (A306)                ;instruction at $A323.)
                                            FREEBUFF LDY #0
                                                     TYA          ;Free up the DOS buffer by poking a $00 in the
                                                     STA (A3L),Y  ;1rst byte of the filename field.
                                            (A30B)   JSR BUFS2PRM

                                                                  * GET addresses of the DOS buffers from chain
                                                                  * buffer & put them in FM parameter list.
                                                                  (A74E)
                                                                  BUFS2PRM LDY #30      ;Get addresses of FM Work buffer,
                                                                  ADRINPRM LDA (A3L),Y  ;T/S list buffer, Data sec buffer and 
                                                                           STA WRKBUFFM-30,Y ;NEXT filename buf from chain ptr
                                                                           INY          ;buf & put them in FM parameter list.
                                                                           CPY #38      ;(P.S. addr of NEXT filename buffer not
                                                                           BNE ADRINPRM ;used by DOS.)
                                                                  (A75A)   RTS

                                            (A30E)   LDA #2       ;Stick opcode for CLOSE function
                                                     STA OPCODEFM ;in the FM parameter list.
                                            (A313)   JMP FMDRIVER ;Get ready to do the function.
                                                     ------------

                                            (A6A8)
                                            FMDRIVER  JSR FILEMGR ;Call the file manager
                                                                  ;to execute the CLOSE function.

                                                                  (AB06)
                                                                  FILEMGR  TSX          ;Save stk pointer so can rtn to caller.
                                                                           STX STKSAV
                                                                  (AB0A)   JSR RSTRFMWA ;Copy FM work buffer (in DOS chain)
                                                                                        ;to FM work area (not in buffer chain).

                                                                                        (AE6A)
                                                                                        RSTRFMWA JSR SELWKBUF ;Find FM work buf.

                                                                                                           * Get adr of FM wrk buf
                                                                                                           * from FM parm list &
                                                                                                           * put it in A4L/H ptr.
                                                                                                           (AF08)
                                                                                                           SELWKBUF LDA #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 code
                                                                                        (AE6F)   STY RTNCODFM ;in FM parm list to
                                                                                        (AE72)                ;signal no errors.
                                                                                        STORFMWK LDA (A4L),Y  ;Copy FM work buf
                                                                                                 STA FMWKAREA,Y ;(in chain) to FM
                                                                                                 INY          ;wrk area (not in
                                                                                                 CPY #45      ;DOS buf chain).
                                                                                                 BNE STORFMWK
                                                                                                 CLC          ;Why?????
                                                                                        (AE7D)   RTS
 
                                                                  (AB0D)   LDA OPCODEFM ;Chk if opcode is legal.
                                                                           CMP #13      ;(Must be less than 13.)
                                                                           BCS TOERROP  ;Opcode too large, go to range error.
                                                                           ASL          ;Double val of opcode & get addr of
                                                                           TAX          ;appropriate function handler from table.
                                                                           LDA FMFUNCTB+1,X ;Stick adr on stack (hi byte first)
                                                                           PHA          ;& then do a "stack jump" to the appropriate
                                                                           LDA FMFUNCTB,X ;function handler.
                                                                           PHA
                                                                  (AB1E)   RTS

                                                                  (AC06)
                                                                  FNCLOSE  .
                                                                           .
                                                                           .
                                                                  (See dis'mbly of CLOSE function.)
                                                                           .
                                                                           .
                                                                  - if necessary, free up any sectors that
                                                                    were previously allocated to the file
                                                                    but not needed.
                                                                  - also updates the file size, fixes up
                                                                    links & updates data, VTOC, T/S list
                                                                    & directory sectors if necessary.
                                                                           .
                                                                           .
                                                                           (RTS)
                                                                           ============

                                                                  TOERROP  JMP RNGERROP ;To $B363 - see dis'mbly of errors.
                                                                  (AB1F)   ------------

                                            * Return here after doing the CLOSE function
                                            * (Cause after @ function is done, use stack
                                            * to get back to 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 values listed in
                                                                  ;a T/S list.  (Not applicable to the
                                                                  ;close function.)
                                            (A6B4)   JMP OTHRERR  ;No.  See dis'mbly of errors.
                                                     ------------

                                            (A6C3)
                                            FMDRVRTN RTS

                      (A32D)   JMP CLOSEALL ;Goes to next instruction (CLOSERTS) via CLOSEALL.
                               ------------

                      (A330)
                      CLOSERTS RTS
                               ============

(A416)
OPENLOAD JSR HNDLCMD  ;Go open the file.

                      * OPEN THE FILE.
                      * On entry from LOAD command, LENPRSD = 0.
                      *
                      * 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 CLOSEALL was just used to close all
                                              open files, this call to CMDCLOSE is only
                                              used for its reference to GETBUFF to
                                              locate a free DOS buffer.
                                                     .
                                                     .
                                            - If necessary, the CLOSE FUNCTION updates the data
                                              sector, T/S list sector & the VTOC.  It also fixes
                                              up links in the directory sectors and updates the
                                              file size if needed.
                                                     .
                                                     .
                                                     (RTS)

                      (A2CB)   LDA A5L+1    ;Hi byte of A5L/H pointer which points at the highest
                                            ;numbered (lowest in memory) free DOS name buffer (in chain).
                      (A2CD)   BNE SAVFNPTR ;Branch if found a free buffer.
                      (A2CF)   JMP NOBUFERR ;Go issue an out-of-buffers message.
                               ------------ ;(See dis'mbly of errors.)

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

                                            * NOTE:  This (re)assigns a DOS buffer to the file
                                            * we want to OPEN/LOAD.  The buffer may or may not
                                            * be the same one that was just released by the
                                            * CLOSE cmd above.  The highest numbered (lowest in
                                            * memory) free DOS buffer is used.
                                            (A743)
                                            CPYPFN   LDY #29      ;30 bytes to copy (0 to 29).
                                            CPYPRIM  LDA PRIMFNBF,Y ;Copy the name of the file wanted from
                                                     STA (A3L),Y  ;the primary filename buffer into the
                                                     DEY          ;filename field buffer (in DOS chain).
                                                     BPL CPYRIM   ;More chars to get.
                                            (A74D)   RTS
                                            
                      (A2DB)   JSR BUFS2PRM

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

                      (A2DE)   JSR CPY2PARM

                                            * Put volume, drive, & slot values plus the
                                            * address of the primary filename buffer
                                            * in the FM parameter list.
                                            (A71A)
                                            CPY2PARM LDA VOLPRSD  ;From parsed table.
                                                     STA VOLFM
                                                     LDA DRVPRSD  ;From parsed table.
                                                     STA DRVFM
                                                     LDA SLOTPRSD ;From parsed table.
                                                     STA SLOTFM
                                                     LDA ADRPFNBF ;Get the adr of the primary file
                                                     STA FNAMBUFM ;name buf from the constants tbl
                                                     LDA ADRPFNBF+1 ;and put it in the FM parm list.
                                                     STA FNAMBUFM+1
                                                     LDA A3L      ;Save adr of current DOS file name
                                                     STA CURFNADR ;buf in table of DOS variables.
                                                     LDA A3L+1
                                                     STA CURFNADR+1
                                            (A742)   RTS

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

                      * USE THE FILE MANAGER DRIVER
                      * TO DO THE OPEN 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.

                                                     .
                                                     .
                                            (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, issues a "file not found"
                                              message cause LOAD cmd can't create a new file.
                                            - reads T/S list back into T/S list buf.
                                                     .
                                                     .
                                                     (RTS)
                                                     ============

                                            TOERROP  JMP RNGERROP ;Go handle range error.
                                            (AB1F)   ------------ ;(See dis'mbly 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 values listed in
                                            ;a T/S list.  (Not applicable to the
                                            ;open function.)
                      (A6B4)   JMP OTHRERR  ;No.  See dis'mbly of errors.
                               ------------

                      (A6C3)
                      FMDRVRTN RTS

* Restrict LOAD command to Applesoft ($02),
* Integer ($01) or A-type ($20) files.
(A419)   LDA #$23
         AND FILTYPFM ;Type found (via OPEN function).
         BEQ TOTYPMIS ;Err - not one of the above file types.
         STA FILTYPFM ;Save type wanted in FM parameter list.
(A423)   LDA ACTBSFLG ;Check which basic is active:
                      ;        INT=$00, FP=$40 & A(RAM)=$80.
(A426)   BEQ LODINTGR ;Branch if Integer is active language.
                      ;(See linear disassembly.)
(A428)   LDA #2       ;Code for Applesoft (ie. FP).
(A42A)   JSR SELCTBSC ;Check if type wanted is Applesoft.

                      * Check if desired basic is up or not.
                      * Switch basic if necessary.
                      (A4B1)
                      SELCTBSC CMP FILTYPFM ;Basic wanted = basic found?
                      (A4B4)   BEQ SELBSRTN ;Yes - basic wanted is active.

                      * Type of file wanted is not compatible
                      * with current active language.
                      (A4B6)   LDX NDX2CMD  ;Save index to current command in case
                      (A4B9)   STX NEXTCMD  ;we are using integer & must load integer
                                            ;file called "APPLESOFT" in order to load A(RAM).
                      (A4BC)   LSR          ;Shift type wanted in order to see which basic to switch into.
                               BEQ SWTCH2FP
                      (A4BF)   JMP CMDINT   ;Switch from FP to Integer.
                               ------------

                      * Switching from Integer to Applesoft
                      * so copy name of file from primary
                      * to secondary name buffer in case we
                      * have to use RAM-based Applesoft.
                      (A4C2)
                      SWTCH2FP LDX #29      ;30 bytes to copy (0 to 29).
                      PRIM2SND LDA PRIMFNBF,X ;Get byte from primary.
                               STA SCNDFNBF,X ;Copy it to secondary.
                               DEX
                      (A4CB)   BPL PRIM2SND ;Branch if more bytes to copy.
                      
                      * Execute the FP command.
                      (A4CD)   JMP CMDFP    ;See dis'mbly of FP command.
                               ---------

                      * Type of basic required (ie. compatible
                      * with file type wanted) is currently active.
                      (A4D0)
                      SELBSRTN RTS          ;Desired basic was active.

(A42D)   JSR RDADRLEN

                      * READ THE LENGTH OF THE FP PRGM
                      * FROM THE FIRST TWO BYTES OF THE FILE.
                      (A47A)
                      RDADRLEN LDA ADLENADR ;Get adr of two-byte input buffer (LENADRBF,
                               STA CURIOBUF ;$AA60) from relocatable constants table and
                               LDA ADLENADR+1 ;designate it as the I/O buffer in the FM
                               STA CURIOBUF+1 ;parameter list.
                               LDA #0       ;Designate length to read as 2 bytes
                               STA LEN2RDWR+1 ;(ie. want to read load length which is
                               LDA #2       ;stored as the 1rst 2 bytes of the file).
                               STA LEN2RDWR
                               LDA #3       ;Set FM parm list to read a range of bytes.
                               STA OPCODEFM
                               LDA #2
                               STA SUBCODFM
                      (A49A)   JSR FMDRIVER

                                            * USE THE FILE MANAGER DRIVER
                                            * TO READ IN THE LOAD LENGTH.
                                            (A6A8)
                                            FMDRIVER JSR FILEMGR  ;Call the file manager to do the function.

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

                                                                                        * Copy FM work buf (in DOS chain) to
                                                                                        * FM work area (not in DOS chain).
                                                                                        (AE6A)
                                                                                        RSTRFMWA JSR SELWKBUF ;Find 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
                                                                                                          (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
                                                                                                              ;list to assume
                                                                                                              ;no errors as
                                                                                        (AE72)                ;default condition.
                                                                                        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.

                                                                           .
                                                                           .
                                                                  (AC58)
                                                                  FNREAD   .
                                                                           .
                                                                  (See dis'mbly of READ function
                                                                  and read-a-range (READRNG, $AC96)
                                                                  subfunction.)
                                                                           .
                                                                           .
                                                                  - reads in first two bytes of file to
                                                                    get length of file in bytes.
                                                                  - On entry:  LEN2RDWR: 2, FILPTSEC: $FFFF, RELFIRST: 0,
                                                                               RELASTP1: $7A, RELPREV: 0, RECNMBWA:0,
                                                                               RECNMBFM: 0, BYTOFFWA: 0, BYTOFFFM: 0,
                                                                               RECLENFM: 1, RECLENWA 1 and
                                                                               CURIOBUF = LENADRBF addr (normally $AA62).
                                                                           .
                                                                           .
                                                                           (RTS)
                                                                           ============

                                                                  TOERROP  JMP RNGERROP ;Go handle range error.
                                                                  (AB1F)   ------------ ;(See dis'mbly of errors.)

                                            * Return here after doing the READ FUNCTION.
                                            * (Cause after @ function is done, use stack
                                            * to get back to the original caller.)
                                            * Note that (c) = 0 if a byte from a data sector was
                                            * just read -- even if that byte was a $00.
                                            (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 values listed in
                                                                  ;a T/S list.
                                            (A6B4)   JMP OTHRERR  ;No.  See dis'mbly of errors.
                                            TOAPPTCH JMP APNDPTCH ;(See dis'mbly of errors.)
                                                     NOP
                                            BK2FMDRV JSR CKIFAPND ;Note:  APNDPTCH returns here.
                                            (A6BB)

                                                                  * Check if using the append command.
                                                                  (BA69)
                                                                  CKIFAPND LDX CMDINDEX ;Get command index.
                                                                           CPX #$1C     ;Are we APPENDing?
                                                                           BEQ RTNCKAPN ;Yes - leave flag on.
                                                                           LDX #0       ;No - turn off append flag.
                                                                           STX APPNDFLG
                                                                  RTNCKAPN RTS
                                                                  (BA75)
     

                                            (A6BE)   LDX #0       ;Zero out the one-data byte parameter in FM parm list.
                                                     STX ONEIOBUF ;(Also referred to as low byte of CURIOBUF.)
                                            FMDRVRTN RTS
                                            (A6C3)

                      * Prepare to read in file.
                      (A49D)   LDA LENADRBF+1 ;Get hi byte of length just read from disk.
                      (A4A0)   STA LEN2RDWR+1 ;Put length val just read into buffer so know how
                                            ;much to read when read in main body of file.
                      (A4A3)   TAY          ;Save hi byte in (y).
                               LDA LENADRBF ;Do likewise with low byte.
                               STA LEN2RDWR
                      (A4AA)   RTS

* Check to see if there is encough room
* between the program start position and
* MEMSIZ to accomodate file.
(A430)   CLC          ;Add length of file to start of
(A431)   ADC TXTTAB   ;program position (normally $801,
                      ;but FP prgm can be loaded at a
                      ;non-standard pos'n by first
                      ;zapping TXTTAB accordingly).
(A433)   TAX          ;Save low byte of prgm end in (x).
         TYA          ;Retrieve hi byte of length from (y).
         ADC TXTTAB+1
         CMP MEMSIZ+1
(A439)   BCS TOTOOLRG ;Branch if not enough room.
                      ;(Go issue program-too-large error message.)

* Program is short enough to be
* accomodated in free memory space.
*
* Set zero-page pointers.
(A43B)   STA PRGEND+1 ;Set end of program pointer.
         STA VARTAB+1 ;Set start of variable space.
         STX PRGEND   ;PRGEND: val in TXTTAB + length.
         STX VARTAB   ;VARTAB: val in TXTTAB + length.
         LDX TXTTAB
         LDY TXTTAB+1
(A447)   JSR LODINTFP ;Designate where in free memory to
                      ;load program and then go load it.

                      * GO DO THE ACTUAL LOAD.
                      * (Code common to both FP
                      * and Integer load commands.)
                      (A471)
                      LODINTFP STX CURIOBUF ;Designate load addr as I/O buffer
                               STY CURIOBUF+1 ;in the FM parameter list.
                      (A477)   JMP CLOSEFM  ;Use file manager to load the program
                               ------------ ;and then close the file.

                      * Load the program & then close the file.
                      (A40A)
                      CLOSEFM  JSR FMDRIVER ;Use file manager to load main body of file.

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

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

                                                                                        * Copy FM work buf (in DOS chain) to
                                                                                        * FM work area (not in DOS chain).
                                                                                        (AE6A)
                                                                                        RSTRFMWA JSR SELWKBUF ;Find 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
                                                                                                          (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
                                                                                                              ;list to assume
                                                                                                              ;no errors as
                                                                                        (AE72)                ;default condition.
                                                                                        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.

                                                                           .
                                                                           .
                                                                  (AC58)
                                                                  FNREAD   .
                                                                           .
                                                                  (See dis'mbly of READ function
                                                                  and read-a-range (READRNG, $AC96)
                                                                  subfunction.)
                                                                           .
                                                                           .
                                                                  - reads file into free memory starting
                                                                    at address designated in TXTTAB (normally $801).
                                                                  - On entry:  LEN2RDWR: contents of LENADRBF (val read off disk).
                                                                               FILPTSEC: 0, RELPREV:0, FILPTBYT:2,
                                                                               RECNMBWA: 2, RECNMBFM: 1, BYTOFFWA: 0,
                                                                               BYTOFFFM: 0 and CURIOBUF = TXTTAB
                                                                                                        = free memory target
                                                                                                          addr (normally $801).
                                                                           .
                                                                           .
                                                                           (RTS)
                                                                           ============

                                                                  TOERROP  JMP RNGERROP ;Go handle range error.
                                                                  (AB1F)   ------------ ;(See dis'mbly of errors.)

                                            * Return here after doing the READ FUNCTION.
                                            * (Cause after @ function is done, use stack
                                            * to get back to the original caller.)
                                            * Note that (c) = 0 if a byte from a data sector was
                                            * just read -- even if that byte was a $00.
                                            (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.
                                            (A6B4)   JMP OTHRERR  ;No.  See dis'mbly of errors.
                                            TOAPPTCH JMP APNDPTCH ;(See dis'mbly of errors.)
                                                     NOP
                                            BK2FMDRV JSR CKIFAPND ;Note:  APNDPTCH returns here.
                                            (A6BB)

                                                                  * Check if using the append command.
                                                                  (BA69)
                                                                  CKIFAPND LDX CMDINDEX ;Get command index.
                                                                           CPX #$1C     ;Are we APPENDing?
                                                                           BEQ RTNCKAPN ;Yes - leave flag on.
                                                                           LDX #0       ;No - turn off append flag.
                                                                           STX APPNDFLG
                                                                  RTNCKAPN RTS
                                                                  (BA75)

                                            (A6BE)   LDX #0       ;Zero out the one-data byte parameter in FM parm list.
                                                     STX ONEIOBUF ;(Also referred to as low byte of CURIOBUF.)
                                            FMDRVRTN RTS
                                            (A6C3)

                      (A40D)   JMP CMDCLOSE ;Go close the file.
                               ------------

                      (A2EA)
                      CMDCLOSE .
                               .
                      (See dis'mly of CLOSE command.)
                               .
                               .
                               (RTS)

(A44A)   JSR INITIOHK ;Point the I/O hooks at DOS.

                      * Initialize the I/O hooks so that DOS
                      * intercepts all input and output.  For
                      * instance, if a routine encounters a
                      * "COUT  JMP (CSW)" then execution will
                      * actually flow to DOS's output handler
                      * 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:
                      *    ADINCPTCP: INPTINCP --> KSW: INPTINCP.
                      *    ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.

                      * Check if 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 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 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 routine, so exit.

                      * Reset 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)

(A44D)   JMP (RLOCNTRY) ;Equivalent to "JMP SETLINKS".
                      ;**************** NOTE ********************
                      ;* This is a hacker's dream.  If you want *
                      ;* to get fancy & do intelligent tasks    *
                      ;* (like preserving variables for the     *
                      ;* prgm being loaded), you can zap        *
                      ;* RLOCNTRY ($9D60) to point to your own  *
                      ;* customized load-handling routines.     *
                      ;******************************************

* CAUTION:  ENTERING APPLESOFT ROM.
*
* Set important zero-page pointers and
* clear out any variables.
* Adjust stack while retaining the
* return address.
* Fix links (ptrs to next line) in
* each line of Applesoft program.

* Clear all variables & establish forward
* links.  (Note:  "0 <rtn>" is equivalent
* to "JSR SETLINKS").
(D4F2)
SETLINKS JSR SETZPTRS

                      (D665)
                      SETZPTRS JSR SETXTPT

                                            * Set TXTPTR to approximate beginning of
                                            * program (ie. TXTPTR: TXTTAB-1, normally $800).
                                            (D697)
                                            SETXTPT  CLC
                                                     LDA TXTTAB   ;Add negative 1 to low byte.
                                                     ADC #$FF
                                                     STA TXTPTR
                                                     LDA TXTTAB+1 ;Add zero to hi byte if carry set.
                                                     ADC #$FF     ;Else add neg 1 to hi byte if carry clr.
                                                     STA TXTPTR+1
                                            (D6A4)   RTS

                      * Simulate a "CLEAR" statement.
                      * (Reset variable & string pointers.)
                      (D668)   LDA #0
                      CLEAR    BNE CLRTS
                      CLEARC   LDA MEMSIZ
                               LDY MEMSIZ+1
                               STA FRETOP   ;FRETOP: MEMSIZ
                               STY FRETOP+1
                               LDA VARTAB   ;ARYTAB: VARTAB
                               LDY VARTAB+1
                               STA ARYTAB
                               STY ARYTAB+1
                               STA STREND   ;STREND: VARTAB
                               STY STREND+1
                      (D680)   JSR RESTORE

                                            * Simulate a RESTORE statement.  That is, reset
                                            * the pointer which points to bytes in DATA
                                            * statement (DATPTR: TXTTAB-1).
                                            (D849)
                                            RESTORE  SEC
                                                     LDA TXTTAB
                                                     SBC #1
                                                     LDY TXTTAB+1
                                                     BCS SETDA
                                                     DEY
                                            SETDA    STA DATPTR   ;Otherwise, points to addr
                                                     STY DATPTR+1 ;of current DATA statement.
                                            (D857)   RTS
     
                      * Re-initialize stk while preserving return addr.
                      (D683)
                      STKINI   LDX #<TEMPST ;Set pointer to descriptor
                               STX TEMPPT   ;for garbage collection.
                               PLA          ;Save return address.
                               TAY
                               PLA
                               LDX #$F8     ;Adjust stack pointer to $1F8 in order to
                      (D68C)   TXS          ;leave enough room for links & line # bytes.
                                            ;(Actually reserves more space than needed.
                                            ;$1FB would have done just fine.)
                      (D68D)   PHA          ;Retrieve return address & put it back on stack.
                               TYA
                               PHA
                               LDA #0       ;Defeat any "CONT" statement.
                               STA OLDTEXT+1 ;Otherwise pts to last byte (an $00) of
                               STA SUBFLG   ;line just executed.
                      CLRTS    RTS
                      (D696)

* Restablish the link pointer in case
* program wasn't loaded into the same
* position at which it was originally
* written.  (THIS ROUTINE ENABLES
* APPLESOFT PROGRAMS TO BE RELOCATABLE.)

* Point index at start of program.
(D4F5)
ESTPTRS  LDA TXTTAB
         LDY TXTTAB+1
         STA INDEX    ;INDEX: TXTTAB
(D4FC)   STY INDEX+1

* Check if at end of program.
* (ie. Is hi byte of links a "$00"?)
* Remember that the structure of an
* Applesoft program is as follows:
*      lnk low / lnk hi / ln # low / ln # hi / token .....etc. / 00 (EOL marker)
(D4FD)   CLC
LOCEOP   LDY #1
         LDA (INDEX),Y ;Get hi byte of present link to next line.
(D502)   BNE STARTNXT ;Link not zero, so go find start of next line.

* Found end of program cause link zeroed out.
(D504)   LDA VARTAB
         STA PRGEND   ;Set PRGEND: VARTAB
         LDA VARTAB+1
         STA PRGEND+1
(D50C)   JMP RESTART  ;Jump into Basic's warmstart routine.
         ------------

* Find end of present Applesoft line.
(D50F)
STARTNXT LDY #4
LOCEOL   INY          ;First possible EOL is offset at (y) = 5.
         LDA (INDEX),Y
(D514)   BNE LOCEOL

* Calculate address of next line and
* set link in current line to point
* to the start of the next line.
(D516)   INY          ;Point (y) at start of next line.
         TYA
         ADC INDEX
         TAX          ;Save address of start of next line in (x).
         LDY #0       ;(y) = 0 for link in current line.
(D51D)   STA (INDEX),Y ;Set low byte of link in current line to
                      ;point to start of next line.
(D51F)   LDA INDEX+1  ;Calculate hi byte of link.
         ADC #0       ;Add 0 if carry clr or add 1 if carry set.
         INY
(D524)   STA (INDEX),Y ;Set hi byte of link in current line to
                      ;point to start of next line.
(D526)   STX INDEX    ;Reset index to start of next line.
         STA INDEX+1
(D52A)   BCC LOCEOP   ;ALWAYS.

****************************** NOTE *****************************
*                                                               *
*      Execution now flows into Applesoft's RESTART routine.    *
* However, the pattern of program flow depends upon the nature  *
* of the caller of the LOAD command.  If the LOAD command was   *
* called via the RUN command, then execution follows the pattern*
* shown below.  If the LOAD command was not called from a RUN,  *
* the program exits via the version of the RESTART routine      *
* disassembled in the section titled "DOSWARMSTART".            *
*                                                               *
*****************************************************************

(D43C)
RESTART  JSR CRDO

                      (DAFB)
                      CRDO     LDA #$0D     ;Positive ASCII carriage return.
                      (DAFD)   JSR OUTDO

                                            (DB5C)
                                            OUTDO    ORA #$80     ;Convert char to negative ASCII.
                                                     CMP #" "     ;Is it a ctrl char?
                                                     BCC GODOPUT  ;Branch if not ctrl char.
                                                     ORA FLSHMSK  ;Contains #$40 for flash or else is #$00.
                                            GODOPUT  JSR COUT
                                            (DB64)

                                                                  (FDED)
                                                                  COUT     JMP (CSW)    ;DOS intercepts output.
                                                                           ------------

                                                                  (9EBD)
                                                                  OPUTINCP JSR PREP4DOS

                                                                                        * Save registers & restore hooks.
                                                                                        (9ED1)
                                                                                        PREP4DOS STA ASAVED   ;Save (a), (x) & (y)
                                                                                                 STX XSAVED   ;registers.
                                                                                                 STY YSAVED
                                                                                                 TSX          ;Adjust stk pointer
                                                                                                 INX          ;& save it so when
                                                                                                 INX          ;we later restore
                                                                                        (9EDD)   STX STKSAVED ;it & hit an "RTS"
                                                                                                              ;we can return to
                                                                                                              ;the routine that
                                                                                                              ;called the routine
                                                                                                              ;that contained the
                                                                                                              ;"JSR PREP4DOS"
                                                                                                              ;instruction.
                                                                                                              ;(In this case, set
                                                                                        (9EE0)                ;to rtn to $DB67.)
                                                                                        UNCONDOS LDX #3
                                                                                        SETRUHKS LDA CSWTRUE,X ;Restore I/O hooks
                                                                                                 STA CSW,X    ;to point to true
                                                                                                 DEX          ;I/O handlers.
                                                                                                 BPL SETRUHKS ;4 bytes to move
                                                                                        (9EEA)   RTS          ;(0 TO 3).

                                                                  * Use current value of OPUTCOND to index
                                                                  * table containing addresses of output
                                                                  * condition handlers.  Do a "stack jump"
                                                                  * to appropriate handler.
                                                                  (9EC0)   LDA OPUTCOND
                                                                           ASL          ;Times 2 cause 2 bytes / address.
                                                                           TAX          ;Set (x) to index table of addresses.
                                                                           LDA OUTHNDTB+1,X ;Put adr of output handler on stack
                                                                           PHA          ;(hi byte first) & then do "stack jump"
                                                                           LDA OUTHNDTB,X ;to appropriate handler.
                                                                           PHA
                                                                           LDA ASAVED   ;GET CHAR TO BE PRINTED.
                                                                  (9ED0)   RTS

                                                                           .
                                                                           .
                                                                       STACK JUMP
                                                                           .
                                                                           .
                                                                   OUTPUT HANDLER 0.
                                                                  (Evaluate start of line.)
                                                                  (9EEB)
                                                                  OPUTHDL0 LDX RUNTRUPT ;Contains a nonzero value if RUN cmd was
                                                                                        ;interrupted to do a LOAD.
                                                                  (9EEE)   BEQ NONTRUPT ;Branch if RUN not interrupted.
                                                                  (9EF0)   JMP FINSHRUN ;Finish off the RUN command.
                                                                           ------------

                                                                  (9F78)
                                                                  FINSHRUN LDA #0       ;ZERO OUT THE RUN INTERCEPT FLAG CUASE
                                                                  (9F7A)   STA RUNTRUPT ;NOW WE'RE INTO THE ROUTINE TO FINISH
                                                                                        ;OFF THE RUN COMMAND.
                                                                  (9F7D)   JSR INITIOHK

                                                                                        * Reset the I/O hooks to point to DOS.
                                                                                        (A851)
                                                                                        INITIOHK .
                                                                                                 .
                                                                                        (See dis'mbly above.)
                                                                                                 .
                                                                                                 .
                                                                                                 (RTS)

                                                                  (9F80)   JMP RUNFPINT ;JUMP BACK INTO THE RUN COMMAND
                                                                           ------------ ;TO FINISH IT OFF.
                                                                                        ;*************** NOTE ******************
                                                                                        ;* THE STACK WAS RESET SO WE RETURN TO *
                                                                                        ;* THE CORRECT LEVEL.                  *
                                                                                        ;***************************************



===============================
     ERROR INTERCEPTION
===============================


* Go issue a type-mismatch error message.
(A410)
TOTYPMIS JMP TYPMISM  ;(See dis'mbly of errors.)
         ------------

* Close file & issue a program-too-large
* error message.
(A4AB)
TOTOOLRG JSR CMDCLOSE

                      (A2EA)
                      CMDCLOSE .
                               .
                      (See dis'mbly of CLOSE command.)
                               .
                               .
                               (RTS)

(A4AE)   JMP TOOLARGE ;(See dis'mbly of errors.)
         ------------
