💾 Archived View for spam.works › mirrors › textfiles › apple › ANATOMY › cmdread.txt captured on 2023-06-16 at 21:11:15.
View Raw
More Information
-=-=-=-=-=-=-
- *****************************************************************
- *
- READ Command Handler *
- *
- ----------------------------------------------------------------*
- *
- The READ command prepares DOS to retrieve data from a *
- file in response to subsequent INPUT or GET statements. The *
- command can only be used in the deferred mode. A filename *
- must be issued with the command or else DOS interprets the *
- "READ" as an Applesoft statement which is used to assign *
- values to variables via DATA statements. *
- R(ecord number) and B(yte offset) parameters are optional.*
- If an R-parameter is given, the file is treated as a random *
- access file. The absence of a an R-parameter defines a *
- sequential text file. Byte parameters can be used with either *
- type of file. When used with random access files, the B- *
- parameter defines the byte offset into a specific record. When*
- used with sequential files, it supposedly defines an offset *
- from the start of the file. However, because the R-value can *
- sometimes be defaulted to an unexpected value, you should *
- always specify a record value of zero if you use a B-parameter *
- while reading a sequential file. *
- *
- Execution pattern: *
- The CMDREAD routine ($A510) first calls the common read/ *
- write routine (COMRDWR, $A526) to locate a DOS buffer whose *
- name field contains the same name as the file wanted. If the *
- named file can't be located, CMDOPEN ($A2A3) is used to open *
- the file. If the file does not already exist on the disk, a *
- file-not-found message is generated. Once a file is opened, a *
- check is made to insure that the type code of the wanted file *
- matches that of the file just opened. If the codes don't *
- match, the file is closed and the command is exited via a *
- file-type-mismatch error. *
- Therefore, contrary to the information contained in THE *
- DOS MANUAL, it is NOT necessary to OPEN a file before READing *
- it. If the file is not already open, the READ command opens *
- it for you. However, the READ command does not accept an L- *
- parameter. Therefore, if you wish to use a record length *
- greater than the default value of one, you must either use *
- the OPEN command or, using assembly language, bypass the *
- command parsing interpreter and set the input and parsed *
- table accordingly. *
- The COMRDWR routine eventually checks bits one and two of *
- CUMLOPTN ($AA65) to see if R- or B-parameters were issued with *
- the command. If either parameter was given, the file manager *
- (FILEMGR, $AB06) is called to do the position function *
- FNPOSN, $AD12). FNPOSN uses the L-, R- and B-parameters to *
- calculate the desired position of the three-byte file pointer *
- (FILPTSEC, $B5E4-$B5E5 and FILBYT, $B5E6) via the following *
- formula: *
- pointer position wanted = (record number * record length) *
- + byte offset into record. *
- Once the file pointer is adjusted, or if no positioning is *
- required, execution branches back into the CMDREAD routine at *
- $A51E. The output condition flag (OPUTCOND, $AA52) is then *
- set to condition 1 and the READ command is exited after the *
- I/O hooks are reset to point to DOS. *
- Although the READ comand per se does not actually read *
- anything from the file, it leaves the computer in the READ *
- mode so that subsequent INPUT and GET statements take their *
- input from the file. (Note, a PRINT statement containing *
- DOS's control character (usually ctrl-D) cancels the READ *
- mode.) *
- When Applesoft eventually picks up a subsequent INPUT or *
- GET statement, execution bounces back and forth between *
- Applesoft, DOS and monitor ROM. DOS gets its mitts into the *
- program because the READ command was exited with the I/O hooks *
- pointing at DOS's input and output handlers. *
- A somewhat simplified example of the execution pattern *
- associated with the INPUT command when the read mode is still *
- in effect is shown in the formatted disassembly titled *
- "CMDREAD CONTINUED". Focus your attention on the RDTXTBYT *
- routine ($A68C). After putting the read opcode ($03) and *
- read-one-byte subcode ($01) in the FM parameter list, the *
- FMDRIVER ($A6A8) is called to do the read. Therefore, *
- execution eventually flows into the read function handler *
- (FNREAD, $AC58). *
- FNREAD uses the subcode (SUBCODFM, $B5BC) to index the *
- table of read subfunction handlers (RDSUBTBL, $AAE5) and then *
- does a stack jump to the read-one-byte subfunction handler *
- (READONE, $AC8A). *
- READONE first checks if the data sector wanted is *
- presently in memory by comparing the highest two bytes (sector *
- offset bytes) of the filepointer with the relative number of *
- the last data sector read. If no data sector is currently in *
- memory, or if the filepointer does not point to the data sector*
- presently in memory, the correct data sector is read in. *
- However, if the data sector wanted is not listed in the *
- current T/S list, then the appropriate T/S list is first read *
- in order to get the trk/sec values for the data sector *
- wanted. Once the wanted data sector is in memory, the file *
- pointer is used as an index to retrieve a single byte from *
- the data buffer. After saving the single byte on the stack, *
- the INCREC routine ($B15B) is called to increment the record *
- number or the byte offset into the record in anticipation of *
- reading another byte. Similarly, the file pointer is advanced *
- by the INCFILPT routine ($B194). The byte wanted is retrieved *
- from the stack and stored in the single-byte buffer (ONEIOBUF, *
- $B5C3) in the FM parameter list. The read function and read- *
- one-byte subfunction are then exited. *
- Once back into the calling program, the byte just read is *
- placed in the input buffer (BUF200, $200-$2FF) and *
- conditionally displayed. If the byte was not an input- *
- command-terminating carriage return, or if 249 characters were *
- not yet read in response to the single INPUT statement, *
- execution branches back to the NXTCHAR routine ($FD75) which *
- eventually uses the RDTXTBYT routine to read another byte for *
- the INPUT string. When a carriage return is encountered, *
- byte retrieval stops, the I/O hooks are reset to point to DOS *
- and execution eventually flows back into Applesoft's INPUT *
- routine where the data are assigned to a variable. Finally, *
- execution returns to the caller of the INPUT statement. *
- *
- *****************************************************************
- Conditions on entry:
- - If MON C was previously used, the Applesoft program line
- containing the READ command has been printed on the screen.
- - A valid filename has been parsed and copied into the primary
- filename buffer (PRIMFNBF, $AA75). (If a valid filename was
- not issued with the command, execution doesn't get this far
- because DOS's command parsing routine (PARSECMD, $9FCD)
- interprets the "READ" as an Applesoft statement.)
- - If applicable, volume, drive, slot, record number and byte
- offset values have been parsed, checked for validity and
- stored in the parsed options table (VOLPRSD, DRVPRSD,
- SLOTPRSD, RECPRSD & BYTPRSD respectively).
- - Previous use of the OPEN command has also placed the record
- length (RECPRSD) in the parsed options table.
- - The appropriate DOS condition handler has copied an abbreviated
- version of the original Applesot READ command line into the
- input buffer (BUF200). Delimiters have been dropped and the
- Applesoft end-of-line marker (eol, $00) has been replaced with a
- return code ($8D). For example, if the original Applesoft line
- was: 100 PRINT D$;"READ NAME", then the line was originally
- coded in memory (in positive ASCII form) as follows:
- 22 08 64 00 BA 44 24 3B 22 52 45 41 44 20 4E 41 4D 45 22 00
- . . . . . D $ ; " R E A D spc N A M E " eol marker
- . . . . .
- . . . . ---> PRINT token
- . . . ----> line number (hi)
- . . -----> line number (low)
- . ------> ptr to next line (hi) (varies)
- -------> ptr to next line (low) (varies)
-
- The abbreviated (negative ASCII) version placed in the keyboard
- input buffer by DOS would be as follows:
- 84 D2 C5 C1 C4 A0 CE C1 CD C5 8D
- . R E A D spc N A M E rtn
- .
- ----> $84 = actual hex code for ctrl-D
-
- - The READ command is normally entered with OPUTCOND: 00,
- CONDNFLG: 00, and the I/O hooks pointing to the true I/O
- handlers (ex. CSW: COUT1 & KSW: KEYIN).
(A51B)
CMDREAD JSR COMRDWR ;Call common read/write routine.
* Code common to read/write.
(A526)
COMRDWR JSR GETBUFF ;Locate a DOS buffer.
* Locate buffer with same name.
* If that fails, locate a free buffer.
(A764)
GETBUFF LDA #0 ;Default hi-byte of pointer to 0
STA A5L+1 ;(ie. assume no free buff available).
(A768) JSR GETFNBF1 ;Get pointer to 1rst filename buffer in chain.
(A792)
GETFNBF1 LDA ADOSFNB1 ;First link to chain of DOS buffers
LDX ADOSFNB1+1 ;(ie. pt 2 1rst name buf in chain).
(A798) BNE SETNXPTR ;ALWAYS.
(A7A4)
SETNXPTR STX A3L+1 ;Put addr of 1rst filename buffer in ptr
STA A3L ;(ie. highest name buffer in chain).
TXA ;Get hi-byte of addr in back in (a).
GETNXRTN RTS
(A7A9)
(A76B) JMP FNCHAR1 ;Get 1rst byte in DOS name buf.
------------
(A76E)
GETFNLNK JSR GETNXBUF
* Get addr of next DOS name buffer in chain
* from chain pointers buffer offset 37 & 36
* bytes from 1rst char of present filename
* buffer.
(A79A)
GETNXBUF LDY #37 ;Point the pointer at the chain buffer &
LDA (A3L),Y ;get addr of the next filename buffer.
BEQ GETNXRTN ;If hi-byte is 0, then lnk zeroed out.
TAX ;Save hi-byte in (x).
DEY ;Pick up low-byte.
LDA (A3L),Y
SETNXPTR STX A3L+1 ;Stick addr of filename buffer in ptr.
STA A3L
TXA ;Get hi-byte back in (a).
GETNXRTN RTS
(A7A9)
(A771) BEQ NOFNMTCH ;Link zeroed out, end of chain.
FNCHAR1 JSR GETFNBY1 ;Get the 1rst char of filename from buf in chain.
(A773)
* Get first byte in DOS name buffer.
(A7AA)
GETFNBY1 LDY #0 ;Buffer is free if 1rst byte = $00.
LDA (A3L),Y ;If buf occuppied, the 1rst byte = 1rst
(A7AE) RTS ;char of filename which owns buffer.
(A776) BNE NXFNBUF ;Take branch if buffer wasn't free.
LDA A3L ;Buffer was free, there4, point the A5L/H pointer
STA A5L ;at the free buffer.
LDA A3L+1
STA A5L+1
(A780) BNE GETFNLNK ;ALWAYS.
(A782)
NXFNBUF LDY #29 ;Buffer not free there4 compare name
CMPFNCHR LDA (A3L),Y ;of owner with name of file in primary
CMP PRIMFNBF,Y ;name buffer. (Start with last char first.)
(A789) BNE GETFNLNK ;Char doesn't match, there4 look for another
;buffer that might have same name.
(A78B) DEY ;That char matched, how bout rest of name?
BPL CMPFNCHR ;30 chars in name (ie. 0 to 29).
CLC ;Clr carry to signal match.
(878F) RTS
============
(8790)
NOFNMTCH SEC ;Link zeroed out.
(A791) RTS
============
(A529) BCC BUFS4RW ;Branch if matching buffer was found
;(ie. file was already open).
* FILE NOT ALREADY OPEN, SO GO OPEN IT.
(A52B) JSR CMDOPEN
(A2A3)
CMDOPEN LDA #0 ;0 = code for text file.
(A2A5) JMP OPNCKTYP ;Go open the file & chk its type.
------------
(A3D5)
OPNCKTYP STA FILTYPFM ;Put code for file type in the
(A3D8) PHA ;Fm parameter list & save it on stk.
;($00=Text, $01=Integer, $02=Applesoft,
;$04=Binary, $08=S-type, $10=Relocatable,
;$20=A-type and $40=B-type.)
(A3D9) JSR HNDLCMD ;Use FM cmd handler to open file.
* Common file manager command handler code.
(A2A8)
HNDLCMD LDA #1 ;1 = open opcode.
HNDLCMD1 STA TEMPBYT ;Store opcode in temporary location.
LDA LENPRSD ;Get L-parameter from parsed table.
BNE SAVLENFM ;Was a non-zero L-parm issued with cmd?
LDA LENPRSD+1
BNE SAVLENFM
LDA #1 ;Length was 0 so make it 1 instead.
STA LENPRSD
SAVLENFM LDA LENPRSD ;Put length in FM parm list.
STA RECLENFM
LDA LENPRSD+1
STA RECLENFM+1
CLSLOCBF JSR CMDCLOSE ;Close file if it's already open.
(A2C8)
(A2EA)
CMDCLOSE .
.
(See dis'mbly of CMDCLOSE.)
.
.
- because a matching filename does not
exist, only one pass is made through
the CLOSE command. A5L/H is normally
left pointing at the highest numbered
(lowest in memory) free DOS buffer when
CMDCLOSE is exited via EVENTXIT and
CLOSERTS. If no free buffer is
available, A5L/H contains a zero.
.
.
(RTS)
(A2CB) LDA A5L+1 ;Hi byte of A5L/H ptr which points at
;the highest numbered (lowest in memory)
;free DOS name buffer (in chain).
(A2CD) BNE SAVFNPTR ;Branch if found a free buffer.
(A2CF) JMP NOBUFERR ;Go issue an out-of-buffers error msg.
------------ ;(See dis'mbly of errors.)
(A2D2)
SAVFNPTR STA A3L+1 ;Reset A3L/H to point at DOS buffer that
LDA A5L ;we will use for file name field buffer.
STA A3L
(A2D8) JSR CPYPFN
* Assign DOS buffer to file we want to
* open. Copy the name of the file wanted
* from the primary file name buf to the
* DOS buffer's filename field.
(A743)
CPYPFN LDY #29 ;30 bytes to copy
(A745) ;(0 to 29).
CPYPRIM LDA PRIMFNBF,Y ;Copy name of
STA (A3L),Y ;file wanted from
DEY ;primary name buf
BPL CPYRIM ;into the DOS
(A74D) RTS ;name buffer.
(A2DB) JSR BUFS2PRM
* Get addrs of the various DOS bufs
* from the chain buf & put them in
* the FM parameter list.
(A74E)
BUFS2PRM LDY #30 ;Get adr of FM work
ADRINPRM LDA (A3L),Y ;buf, T/S list buf,
STA WRKBUFFM-30,Y ;data sec buf
INY ;& next DOS name buf
CPY #38 ;from chain pointer
BNE ADRINPRM ;buf & put them in
(A75A) RTS ;FM parm list.
;(P.S. Adr of next
;DOS name buf is
;not used by DOS.)
(A2DE) JSR CPY2PARM
* Put volume, drive, & slot values plus
* the address of the primary filename
* buffer in the FM parameter list.
(A71A)
CPY2PARM LDA VOLPRSD ;From parsed table.
STA VOLFM
LDA DRVPRSD ;From parsed table.
STA DRVFM
LDA SLOTPRSD ;From parsed table.
STA SLOTFM
LDA ADRPFNBF ;Get adr of the
STA FNAMBUFM ;primary name buf
LDA ADRPFNBF+1 ;from constants
(A735) STA FNAMBUFM+1 ;tbl and put it
;in FM parm list.
(A738) LDA A3L ;Save the adr of
STA CURFNADR ;current DOS name
LDA A3L+1 ;buf in table of
STA CURFNADR+1 ;DOS variables.
(A742) RTS
(A2E1) LDA TEMPBYT ;Get open opcode back from temporary buf
STA OPCODEFM ;and put it in the FM parameter list.
(A2E7) JMP FMDRIVER ;Do function via FM driver.
------------
* USE THE FILE MANAGER DRIVER
* TO DO THE OPEN FUNCTION.
(A6A8)
FMDRIVER JSR FILEMGR ;Call the file manager to do function.
* File manager proper.
(AB06)
FILEMGR TSX ;Save stk pointer
(AB07) STX STKSAV ;so can later rtn
;to caller of FM.
(AB0A) JSR RSTRFMWA
* Copy FM work buf
* (in DOS chain) to
* FM work area (not
* in DOS chain).
(AE6A)
RSTRFMWA JSR SELWKBUF
l
l
----------------------
l * Get adr of FM work
l * buff from FM parm
l * list & put it in
l * A4L/H pointer.
l (AF08)
l SELWKBUF LDX #0
l (AF0A) BEQ PT2FMBUF
l
l (AF12)
l PT2FMBUF LDA WRKBUFFM,X
l STA A4L
l LDA WRKBUFFM+1,X
l STA A4L+1
l (AF1C) RTS
l ---------------------
l
l
* Zero out return
* code in FM parm
* 2 signal no errs.
(AE6D) LDY #0
(AE6F) STY RTNCODFM
* Copy FM work buf
* to FM work area.
(AE72)
STORFMWK LDA (A4L),Y
STA FMWKAREA,Y
INY
CPY #45
BNE STORFMWK
CLC
(AE7D) RTS
* Check if opcode is legal.
* (Must be less than 13.)
(AB0D) LDA OPCODEFM
CMP #13
(AB12) BCS TOERROP ;Opcode too large
;(got range err).
(AB14) ASL ;Double val of
(AB15) TAX ;opcode & put it
;in (x) so it
;indexes tbl of
;addresses.
(AB16) LDA FMFUNCTB+1,X ;Stick adr of
PHA ;the appropriate
LDA FMFUNCTB,X ;function hndlr
(AB1D) PHA ;on stack (hi byte
;first).
(AB1E) RTS ;DO STACK JUMP TO
;FUNCTION ENTRY
;POINT.
.
.
(AB22) .
FNOPEN .
.
(See dis'mbly of OPEN function.)
.
.
- uses part of COMNOPEN routine.
- reads in VTOC to get link to 1rst
directory.
- reads directory secs in & looks for
file description entry with matching
filename.
- if matching name found, reads in the
1rst T/S list sector belonging to the
file.
- if no match found, starts a new file:
(1) creates new file description entry
- copies name to 1rst available spc
in direc sec (if can't find spc,
then issues disk full error msg).
- allocates secs for file.
- writes updated VTOC to disk.
- puts link to first T/S list, file
size, etc in directory entry spc.
- writes directory sector buffer to
disk.
(2) creates new T/S list & writes it to
disk.
- reads T/S list back into T/S list
buffer.
.
.
(RTS)
============
TOERROP JMP RNGERROP ;(See dis'mbly
(AB1F) ------------ ;of errors.
* Return here after doing the OPEN function.
* (Cause after @ function is done, use stack
* to get back to the original caller.)
(A6AB)
AFTRFUNC BCC FMDRVRTN ;(c) = 0 = no errors.
LDA RTNCODFM ;Get error code from FM parameter list.
CMP #$5 ;End-of-data error?
(A6B2) BEQ TOAPPTCH ;Yes - Got a zeroed-out T/S link or a
;zeroed-out data pair listed in a
;T/S list. (Not applicable to the
;open function.)
(A6B4) JMP OTHRERR ;No. (See dis'mbly of errors.)
------------
(A6C3)
FMDRVRTN RTS
(A3DC) PLA ;Get file type wanted off of stack.
(A3DD)) JMP CHKFTYPE ;Go check if type wanted equals type found.
------------
* Check if file type wanted = file type found.
* (If using open command to open a pre-exisiting file,
* may get a type mismatch. However, a mismatch error
* is not possible when opening a new file.)
(A7C4)
CHKFTYPE EOR FILTYPFM ;Type found (via open function).
(A7C7) BEQ CKTYPRTN ;Branch if type wanted = type found.
* File types didn't match.
* Check if correct type but locked.
(A7C9) AND #%01111111 ;Maybe matched - Check again
;but this time disregard lock bit.
(A7CB) BEQ CKTYPRTN ;Branch if matched.
* Type wanted < > type found!!!!!
* So go close file & then issue a
* type mismatch error message.
(A7CD) JSR CMDCLOSE ;Wrong kind of file so go close it.
* Because the file is already open, execution flows through
* the close cmd twice. The first time thru, the matching
* DOS filename buffer is located & then CLOSEONE is used to
* close the file via the open FUNCTION. The 2nd time thru, a
* matching filename buffer is not found because the DOS
* buffer was released on the first pass. Therefore, A5L/H is
* left pointing at the highest numbered (lowest in memory)
* FREE DOS buffer when the close command is exited via EVENTXIT
* and CLOSERTS.
(A2EA)
CMDCLOSE .
.
(See dis'mbly of CLOSE command.)
.
.
(RTS)
(A7D0) JMP TYPMISM ;Go handle type mismatch error.
------------ ;(Eventually exits into DOS's warmstart routine.)
;(See dis'mbly of errors.)
CKTYPRTN RTS
(A7D3) ============
(A52E) JMP CKRBOPTN ;Go chk if R- & B-parms were issued with cmd.
------------
BUFS4RW JSR BUFS2PRM
(A531)
* Copy addresses of the various DOS buffers
* from the DOS chain buffer to the FM parameter list.
(A74E)
BUFS2PRM LDY #30 ;Get addr of FM work buf, T/S list
ADRINPRM LDA (A3L),Y ;buf, data sector buf & next DOS
STA WRKBUFFM-30,Y ;filename buf from chain
INY ;pointer buffer & put them in FM parm list.
CPY #38 ;(P.S. Adr of next DOS file name buf is
BNE ADRINPRM ;not used by DOS.)
(A75A) RTS
* Check if R- or B-parameters were issued with command.
(A534)
CKRBOPTN LDA CUMLOPTN ;Chk if R- or B- parms issued.
AND #%00000110 ;(R=$04, B=$02.)
(A539) BEQ RDWRRTN ;NO - skip positioning of file pointer.
* Copy B- and R-parameters from option
* parsed table to FM parameter list.
(A53B) LDX #3
CPYBPARM LDA RECPRSD,X ;Get value of parameter.
STA RECNMBFM ;Store it in FM parameter list.
DEX ;4 bytes to copy (3 to 0).
(A544) BPL CPYBPARM ;More bytes to copy.
* CALL THE FILE MANAGER WITH THE POSITION OPCODE.
(A546)
BK2APND LDA #$0A ;Opcode for position.
STA OPCODEFM ;Put opcode in FM parm list.
(A54B) JSR FMDRIVER ;Call file manager to do the position function.
(A6A8)
FMDRIVER JSR FILEMGR ;Call the file manager to do the function.
* File manager proper.
(AB06)
FILEMGR TSX ;Save stk pointer so can later return
STX STKSAV ;to the caller of the file manager.
(AB07) JSR RSTRFMWA
* Copy FM work buf (in DOS chain) 2
* FM work area (not in DOS chain).
(AE6A)
RSTRFMWA JSR SELWKBUF
* Get addr of FM work
* buf from FM parm
* list & put it in
* the A4L/H pointer.
(AF08)
SELWKBUF LDX #0
(AF0A) BEQ PT2FMBUF
(AF12)
PT2FMBUF LDA WRKBUFFM,X
STA A4L
LDA WRKBUFFM+1,X
STA A4L+1
(AF1C) RTS
(AE6D) LDY #0 ;Zero out return
(AE6F) STY RTNCODFM ;code in FM parm
;to assume no errs
(AE72) ;as default cond.
STORFMWK LDA (A4L),Y ;Copy FM work buf
STA FMWKAREA,Y ;to FM work area.
INY
CPY #45 ;45 bytes to copy.
BNE STORFMWK ;(0 to 44).
CLC ;WHY?????
(AE7D) RTS
(AB0D) LDA OPCODEFM ;Check if opcode is legal.
CMP #13 ;(Must be less than 13.)
BCS TOERROP ;Opcode too large so got range error.
ASL ;Double val of opcode & put it in (x)
TAX ;so it indexes tables of adrs.
LDA FMFUNCTB+1,X ;Stick adr of appropriate function
PHA ;handler on stack (hi byte first).
LDA FMFUNCTB,X
PHA
(AB1E) RTS ;DO STACK JUMP TO FUNCTION ENTRY POINT.
.
.
(AD12) .
FNPOSN .
.
(See dis'mbly of POSITION function.)
.
.
(RTS)
============
TOERROP JMP RNGERROP ;Go handle range error.
(AB1F) ------------
* Return here after doing the POSITION FUNCTION.
* (Cause after @ function is done, use stack
* to get back to the original caller.)
(A6AB)
AFTRFUNC BCC FMDRVRTN ;(c) = 0 = no errors.
LDA RTNCODFM ;Get error code from FM parameter list.
CMP #$5 ;End-of-data error?
(A6B2) BEQ TOAPPTCH ;Yes - Got a zeroed-out T/S link or a
;zeroed-out data pair listed in a T/S list.
;(Not applicable to the position function.)
(A6B4) JMP OTHRERR ;No. (See dis'mbly of errors.)
------------
(A6C3)
FMDRVRTN RTS
(A54E)
RDWRRTN RTS
============
(A51E) LDA #1 ;Set condition flag to designate reading status so
(A520) STA CONDNFLG ;subsequent INPUT & GET statements will take
;data from the disk.
(A523) JMP FINSHCMD
------------
- Finish off the DOS command.
(9F83)
FINSHCMD LDA BUF200 ;Get first char in buffer.
(9F86) CMP DCTRLCHR ;Was command done via DOS's control char?
;(Normally ctrl-D.)
(9F89) BEQ DSPLYCMD ;Yes - ALWAYS TAKE WHEN USING READ CMD
; (cause abbreviated NEG ASCII version of Applesoft
; program line containing the READ cmd is still
; in the keyboard input buffer, BUF200).
(9F95)
DSPLYCMD LDA #%01000000 ;Set bit 6 to see if using "MON C".
(9F97) BNE DSPLYCHR ;ALWAYS.
(9F9F)
DSPLYCHR AND CIOCUMUL ;Test flag - see if should display.
(9FA2) BEQ DOSEXIT ;No - so just exit DOS with condition 1 still
; set so file data will be read.
- MON C flag was on, so display command-terminating
- carriage return. (P.S. Applesoft detected the
- end-of-line marker ($00) and changed it to a <cr>.
- DOS then put the carriage return ($8D) as the last
- character in the input buffer.)
(9FA4)
DSPLYALL JSR RESTOREG
(9FBA)
RESTOREG LDA ASAVED ;Restore (a), (y) & (x) registers.
LDY YSAVED
LDX XSAVED
SEC ;Why?????
(9FC4) RTS
(9FA7) JSR GODSPLY ;Output char via true output handler.
(9FC5)
GODSPLY JMP (CSW)
------------
(FDF0)
COUT1 .
.
(Print char thru true output handler.)
(See dis'mbly of monitor in APPLE II REFERENCE MANUAL.)
.
.
(RTS)
============
(9FAA) STA ASAVED ;Save (a), (y) and (x) registers.
STY YSAVED
(9FB0) STX XSAVED
(9FB3)
DOSEXIT JSR INITIOHK ;Reset I/O hooks to point to DOS.
* Initialize the I/O hooks so that DOS intercepts
* all input & output. For instance, if a routine
* encounters a "COUT JMP (CSW)", then execution will
* actually flow to DOS's output routine (OPUTINCP,
* $9EBD). Similarly, any routine that refers to
* "RDKEY JMP (KSW)" will actually jump to DOS's
* input routine (INPTINCP, $9E81).
*
* The true (ie. normal) hooks are saved, ex:
* KSW: KEYIN --> KSWTRUE: KEYIN.
* CSW: COUT1 --> CSWTRUE: COUT1.
* The intercepts are then set as follows:
* ADINPTCP: INPTINCP --> KSW: INPTINCP.
* ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
* Check if the input hook needs to be reset.
(A851)
INITIOHK LDA KSW+1
CMP ADINPTCP+1
(A856) BEQ CKOUTHK ;Input hook already points to DOS's
;input handler, so go check output hook.
* Reset the input hook to point to DOS.
(A858) STA KSWTRUE+1 ;KSW: KEYIN --> KSWTRUE: KEYIN.
LDA KSW
STA KSWTRUE
LDA ADINPTCP ;ADINPTCP: INPTINCP --> KSW: INPTINCP.
STA KSW
LDA ADINPTCP+1
(A868) STA KSW+1
* Check if the output hook needs to be reset.
(A86A)
CKOUTHK LDA CSW+1
CMP ADOPUTCP+1
(A86F) BEQ SETHKRTN ;Output hook already points to DOS's
;output handler, so go exit.
* Reset the output hook to point to DOS.
(A871) STA CSWTRUE+1 ;CSW: COUT1 --> CSWTRUE: COUT1.
LDA CSW
STA CSWTRUE
LDA ADOPUTCP ;ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
STA CSW
LDA ADOPUTCP+1
STA CSW+1
SETHKRTN RTS
(A883)
(9FB6) LDX STKSAVED ;Retrieve saved stack pointer.
TXS ;(P.S. Don't confuse "STKSAVED" with "STKSAV".)
RESTOREG LDA ASAVED ;Restore (a), (y) & (x) registers.
LDY YSAVED
LDX XSAVED
SEC ;Why?????
(9FC4) RTS ;Exit to caller of READ command.
============ ;(Normally returns to $D533 in Applesoft
;ROM -- part of INLINPL2 routine ($D52E).)
- ***********************************
- *
- NOTE: See formatted disassembly *
- titled "CMDREAD CONTINUED". *
- *
- ***********************************