753 lines
60 KiB
Plaintext
753 lines
60 KiB
Plaintext
******************************************************************
|
|
* *
|
|
* CHAIN Command Handler *
|
|
* *
|
|
*----------------------------------------------------------------*
|
|
* *
|
|
* The CHAIN command LOADs and RUNs an INTEGER basic program *
|
|
* without first clearing variables and arrays. It is most often *
|
|
* used to execute as series of programs that can't all fit into *
|
|
* the free memory space at once. Unlike the LOAD and RUN *
|
|
* commands, all previous variable and arrays are preserved and *
|
|
* passed along to subsequently loaded programs. *
|
|
* A file name must be issued with the command. Volume, *
|
|
* drive and slot parameters are optional. *
|
|
* *
|
|
* Execution pattern: *
|
|
* After assigning a DOS buffer to the named file and *
|
|
* customizing the FM parameter list, the file manager (FILEMGR, *
|
|
* $AB06) is 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 message.) *
|
|
* 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). *
|
|
* LOADINTGR checks if an Integer file was found. If a *
|
|
* different file type was located, the computer assumes that the *
|
|
* Applesoft language is required and it tries to switch *
|
|
* languages. The contents of the primary file name buffer *
|
|
* (PRIMFNBF, $AA75) are copied into the secondary file name *
|
|
* buffer in case A(RAM) needs to be loaded from the System Master*
|
|
* disk. A jump is then made to execute the FP command (CMDFP, *
|
|
* $A57A). If the FP command is successful, an attempt is made to*
|
|
* CHAIN the non-integer file by loading the file. However, *
|
|
* because an Applesoft program that is loaded via the CHAIN *
|
|
* command is not closed correctly and because Applesoft's version*
|
|
* of the LOAD command does not preserve variables and arrays, all*
|
|
* is for naught. It therefore appears that the authors of DOS *
|
|
* forgot to provide adequate error trapping for the CHAIN *
|
|
* command. Although the CHAIN command only works with Integer *
|
|
* basic, page 106 of the THE DOS MANUAL (APPLE Computer Inc., *
|
|
* 1980) describes a method of passing variables from one *
|
|
* Applesoft program to another via the use of a program on the *
|
|
* System Master disk. *
|
|
* If the file found was indeed an Integer program, RDADRLEN *
|
|
* ($A47A) is called to read the length of the file and store it *
|
|
* in the FM parameter list at LENADRBF ($AA60). Next a check is *
|
|
* made to see if enough free space is available to accommodate *
|
|
* the program. If (HIMEM - length) < = LOMEM, the program *
|
|
* impinges on the free memory space and a program-too-large error*
|
|
* message is generated. (Remember that Integer files occupy the *
|
|
* top end of free memory whereas Applesoft files are usually *
|
|
* loaded into the lower end of the free memory space.) If all *
|
|
* is well, the start-of-program pointer (INTPGMST, $CA-$CB) is *
|
|
* set and then the file manager driver (FMDRIVER, $A6A8) is *
|
|
* called to read in the rest of the file. As the program is *
|
|
* read in, LENADRBF is used as a byte counter and variable and *
|
|
* array values are left intact. *
|
|
* After loading the file, a carriage return is printed via *
|
|
* DOS (CRVIADOS, $9FC8) and the I/O hooks are reset (INITIOHK, *
|
|
* $A851) to point to DOS's input and output handler routines. *
|
|
* Finally, execution branches into integer basic to execute *
|
|
* (ie. RUN) 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 CHAIN command.)
|
|
* - the validity of the options issued with
|
|
* the command (and their numeric operands)
|
|
* have been checked.
|
|
* - a legal file name has been parsed and
|
|
* placed in the primary file name buffer
|
|
* (PRIMFNBF, $AA75).
|
|
|
|
|
|
(A4F0)
|
|
CMDCHAIN JSR OPENLOAD ;Go load the INTEGER program.
|
|
|
|
(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
|
|
STX STKSAV ;to caller of FM. (That is, will return
|
|
(AB0A) JSR RSTRFMWA ;back into the FMDRIVER at AFTRFUNC
|
|
;($A6A8).)
|
|
|
|
* Copy FM work buf (in DOS chain) to
|
|
* FM work area (not in DOS chain).
|
|
(AE6A)
|
|
RSTRFMWA JSR SELWKBUF
|
|
|
|
* Get adr of FM
|
|
* work buff from
|
|
* the FM parm list
|
|
* & put it in the
|
|
* A4L/H pointer.
|
|
(AF08)
|
|
SELWKBUF LDX #0
|
|
(AFOA) BEQ PT2FMBUF
|
|
|
|
(AF12)
|
|
PT2FMBUF LDA WRKBUFFM,X
|
|
STA A4L
|
|
LDA WRKBUFFM+1,X
|
|
STA A4L+1
|
|
(AF1C) RTS
|
|
|
|
(AE6D) LDY #0 ;Zero out rtn code
|
|
(AE6F) STY RTNCODFM ;in FM parm list
|
|
;to signal no errs
|
|
;as the default
|
|
(AE72) ;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.
|
|
|
|
.
|
|
.
|
|
(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 ;If (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 (trk/sec vals in 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 ;Set bits 0, 1 and 5 as per above file types.
|
|
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.
|
|
|
|
* Load an integer program.
|
|
(A450)
|
|
LODINTGR LDA #1 ;(1 = code for integer file.)
|
|
(A452) JSR SELCTBSC
|
|
|
|
* 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 to see which basic to switch into.
|
|
BEQ SWTCH2FP ;Branch if switching from Integer to Applesoft.
|
|
(A4BF) JMP CMDINT ;Switch from Applesoft to integer.
|
|
------------ ;(See dis'mbly of INT command.)
|
|
|
|
* Type of basic required (ie. compatible
|
|
* with file type wanted) is currently active.
|
|
(A4D0)
|
|
SELBSRTN RTS ;Desired basic was active.
|
|
============
|
|
|
|
(A455) 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
|
|
(AB07) STX STKSAV ;pointer so can
|
|
;later return to
|
|
;caller of FM.
|
|
(AB0A) JSR RSTRFMWA
|
|
|
|
* Copy FM work buf
|
|
* (in DOS chain) to
|
|
* FM work area (not
|
|
* in DOS chain).
|
|
*
|
|
* Find FM work buf.
|
|
(AE6A)
|
|
RSTRFMWA JSR SELWKBUF
|
|
|
|
.
|
|
.
|
|
.
|
|
.....................
|
|
.
|
|
. * 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
|
|
.
|
|
.....................
|
|
.
|
|
.
|
|
.
|
|
* Zero out return
|
|
* code in FM parm
|
|
* list to assume
|
|
* no errors as
|
|
* default condition.
|
|
* Copy FM work buf
|
|
* to FM work area.
|
|
(AE6D) LDY #0
|
|
STY RTNCODFM
|
|
STORFMWK LDA (A4L),Y
|
|
STA FMWKAREA,Y
|
|
INY
|
|
CPY #45
|
|
BNE STORFMWK
|
|
CLC
|
|
(AE7D) RTS
|
|
|
|
(AB0D) LDA OPCODEFM ;Check if opcode
|
|
(AB10) CMP #13 ;is legal. (Must
|
|
;be less than 13.)
|
|
(AB12) BCS TOERROP ;Opcode too large
|
|
;so got range err.
|
|
(AB14) ASL ;Double val of opcode
|
|
;& put it in (x) so
|
|
(AB15) TAX ;it indexes tables of
|
|
;addresses.
|
|
(AB16) LDA FMFUNCTB+1,X ;Stick adr of
|
|
PHA ;appropriate function
|
|
LDA FMFUNCTB,X ;handler on stack
|
|
PHA ;(hi byte first).
|
|
(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 hndl range err.
|
|
(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.)
|
|
* (On entry, (c) = 0 if just read a byte from a
|
|
* data sector -- regardless if that byte was
|
|
* a $00 or not.)
|
|
(A6AB)
|
|
AFTRFUNC BCC FMDRVRTN ;If (c) = 0 = no errors.
|
|
LDA RTNCODFM ;Get error code from FM parameter list.
|
|
CMP #5 ;End-of-data error?
|
|
(A6B2) BEQ TOAPPTCH ;Yes - file ends at a full data sec and so
|
|
;we encountered a zeroed-out T/S link or
|
|
;zeroed-out data pair (trk/sec 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 status of append flag.
|
|
(BA69)
|
|
CKIFAPND LDX CMDINDEX ;Get command index.
|
|
CPX #$1C ;Are we APPENDing?
|
|
BEQ RTNCKAPN ;Yes.
|
|
LDX #0 ;No -turn off flag.
|
|
STX APPNDFLG
|
|
RTNCKAPN RTS
|
|
(BA75)
|
|
|
|
(A6BE) LDX #0 ;Zero out the one-data-byte buffer.
|
|
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 val just read in param list 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
|
|
|
|
* Calculate start of program
|
|
* (HIMEM - LENADRBF).
|
|
(A458) SEC
|
|
LDA HIMEM
|
|
SBC LENADRBF
|
|
TAX
|
|
LDA HIMEM+1
|
|
SBC LENADRBF+1
|
|
BCC TOTOOLRG ;Length > HIMEM so issue error message.
|
|
TAY
|
|
CPY LOMEM+1 ;Check if program < = LOMEM.
|
|
BCC TOTOOLRG ;Start of program too low, so go
|
|
BEQ TOTOOLRG ;issue a program-too-large error message.
|
|
STY INTPGMST+1 ;Set start of program pointer.
|
|
(A46F) STX INTPGMST
|
|
|
|
* 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 ;(That is, for a rtn to AFTRFUNC, $A6AB.)
|
|
|
|
* 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.)
|
|
* (On entry, (c) = 0 if just read a byte from a
|
|
* data sector, irregardless if that byte was
|
|
* a $00 or not.)
|
|
(A6AB)
|
|
AFTRFUNC BCC FMDRVRTN ;If (c) = 0 = no errors.
|
|
LDA RTNCODFM ;Get error code from FM parameter list.
|
|
CMP #5 ;End-of-data error?
|
|
(A6B2) BEQ TOAPPTCH ;Yes - file ends at a full data sec and so
|
|
;we encountered a zeroed-out T/S link or
|
|
;zeroed-out data pair (trk/sec 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 status of append flag.
|
|
(BA69)
|
|
CKIFAPND LDX CMDINDEX ;Get command index.
|
|
CPX #$1C ;Are we APPENDing?
|
|
BEQ RTNCKAPN ;Yes.
|
|
LDX #0 ;No -turn off the append flag.
|
|
STX APPNDFLG
|
|
RTNCKAPN RTS
|
|
(BA75)
|
|
|
|
(A6BE) LDX #0 ;Zero out the one-data-byte buffer.
|
|
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)
|
|
|
|
(A4F3) 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)
|
|
============
|
|
|
|
(A4F6) 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:
|
|
* ADINCPTCP: INPTINCP --> KSW: INPTINCP.
|
|
* ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
|
|
|
|
* Check if the input hook needs to be reset.
|
|
(A851)
|
|
INITIOHK LDA KSW+1
|
|
CMP ADINPTCP+1
|
|
(A856) BEQ CKOUTHK ;Input hook already points to DOS's
|
|
;input handler so go check output hook.
|
|
|
|
* Reset the input hook to point to DOS.
|
|
(A858) STA KSWTRUE+1 ;KSW: KEYIN --> KSWTRUE: KEYIN.
|
|
LDA KSW
|
|
STA KSWTRUE
|
|
LDA ADINPTCP ;ADINPTCP: INPTINCP --> KSW: INPTINCP.
|
|
STA KSW
|
|
LDA ADINPTCP+1
|
|
(A868) STA KSW+1
|
|
|
|
* Check if the output hook needs to be reset.
|
|
(A86A)
|
|
CKOUTHK LDA CSW+1
|
|
CMP ADOPUTCP+1
|
|
(A86F) BEQ SETHKRTN ;Output hook already points to DOS's
|
|
;output handler routine, so exit.
|
|
|
|
* Reset the output hook to point to DOS.
|
|
(A871) STA CSWTRUE+1 ;CSW: COUT1 --> CSWTRUE: COUT1.
|
|
LDA CSW
|
|
STA CSWTRUE
|
|
LDA ADOPUTCP ;ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
|
|
STA CSW
|
|
LDA ADOPUTCP+1
|
|
STA CSW+1
|
|
SETHKRTN RTS
|
|
(A883)
|
|
|
|
(A4F9) JMP (CHAINTRY) ;GO INTO INTEGER BASIC TO EXECUTE PRGM.
|
|
--------------
|
|
|
|
|
|
* Go issue a file-type-mismatch error msg.
|
|
(A410)
|
|
TOTYPMIS JMP TYPMISM ;(See dis'mbly of errors.)
|
|
------------
|
|
|
|
* Close file & issue a program-too-large error msg.
|
|
(A4AB)
|
|
TOTOOLRG JSR CMDCLOSE
|
|
|
|
(A2EA)
|
|
CMDCLOSE .
|
|
.
|
|
(See dis'mbly of CLOSE command.)
|
|
.
|
|
.
|
|
(RTS)
|
|
|
|
(A4AE) JMP TOOLARGE ;(See dis'mbly of errors.)
|
|
------------
|