1110 lines
77 KiB
Plaintext
1110 lines
77 KiB
Plaintext
******************************************************************
|
|
* *
|
|
* WRITE Command Handler *
|
|
* *
|
|
*----------------------------------------------------------------*
|
|
* *
|
|
* The WRITE command prepares the computer to send subsequent*
|
|
* output to the disk. The command can only be used in the *
|
|
* deferred mode. R(ecord number) and B(yte offset into record) *
|
|
* parameters are optional. The presence or absence of an R- *
|
|
* parameter determines if the file is treated as a random access *
|
|
* or sequential text file (respectively). If no byte parameter *
|
|
* is given, writing begins at the first byte in a specific *
|
|
* record of a random access file. *
|
|
* *
|
|
* Execution pattern: *
|
|
* The CMDWRITE 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 *
|
|
* new file is created. Once a pre-existing or new 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 writing *
|
|
* to it. If the file is not already open, the WRITE command *
|
|
* opens it for you. However, the WRITE 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 *
|
|
* interpreter and set the input buffer 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 FILPTBYT, $B5E6) via the following *
|
|
* forumula: *
|
|
* 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 CMDWRITE routine at *
|
|
* $A513. The output conditon flag (OPUTCOND, $AA52) is then set *
|
|
* to condition 5 and the write command is exited after the I/O *
|
|
* hooks are reset to point to DOS. *
|
|
* Although the WRITE command per se does not actually write *
|
|
* anything to file, it leaves the computer in the write mode so *
|
|
* that data contained in subsequent PRINT statements are output *
|
|
* to the file. (However, a PRINT statement containing DOS's *
|
|
* control character (usually a ctrl-D) cancels the write mode.) *
|
|
* When a subsequent PRINT statement is encountered, *
|
|
* execution eventually flows into the WRITEXT ($A60E) routine *
|
|
* which sets up the FM parameter list to do the write function. *
|
|
* After storing a single data byte in the ONEIOBUF buffer *
|
|
* ($B5C3), the FM parameter list is set to write one byte. The *
|
|
* file manager (FILEMGR, $AB06) is then called to do the write *
|
|
* function and write-one-byte subfunction. *
|
|
* The write function handler (FNWRITE, $AC70) merely checks *
|
|
* the operation subcode (SUBCODFM, $B5BC) and then does a stack *
|
|
* jump to the write-one-byte subfunction handler (WRITEONE, *
|
|
* $ACBE). WRITEONE sets the accummulator with the byte to be *
|
|
* written and then calls INCIOBUF ($B1A2) to point the A4L/H *
|
|
* pointer ($42, $43) at the source location. If the file *
|
|
* pointer points beyond the present data sector in memory, or if *
|
|
* no data sector is currently in memory, the NXTDATRD routine *
|
|
* ($B0B6) is used to read in the correct data sector. The *
|
|
* output data byte is then stored in the data sector buffer and *
|
|
* the file pointer is incremented. After conditionally *
|
|
* displaying the output byte, the I/O hooks are reset to point *
|
|
* to DOS and the stack is reset to return to the caller. *
|
|
* *
|
|
* Note that the write subfunctions do not necessarily write *
|
|
* data to the disk. At the very least, they store data in the *
|
|
* data sector buffer. If single data bytes are added repeatedly,*
|
|
* the data buffer eventually is filled up. Once this happens, *
|
|
* RWTS ($BD00) is finally called to actually write the data to *
|
|
* the disk. However, if the write mode is exited before the *
|
|
* data sector buffer is full, bit six of the update flag *
|
|
* (UPDATFLG, $B5D5) is set. When the file is eventually closed, *
|
|
* the close command detects the set bit and writes the data *
|
|
* sector buffer to the disk. (The close command also updates *
|
|
* the T/S list and directory sector buffers if necessary.) *
|
|
* *
|
|
******************************************************************
|
|
|
|
|
|
* Conditions on entry:
|
|
* - If MON C was previously used, the Applesoft program line
|
|
* containing the WRITE command has been printed on the screen.
|
|
* - A valid filename has been parsed and copied into the primary
|
|
* file name buffer (PRIMFNBF, $AA75).
|
|
* - 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 Applesoft write command
|
|
* line into the input buffer (BUF200, $200). 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$;"WRITE NAME",
|
|
* then the line was originally coded in memory (in positive
|
|
* ASCII form) as follows:
|
|
* 22 08 64 00 BA 44 24 3B 22 57 52 49 54 45 20 4E 41 4D 45 22 00
|
|
* . . . . . D $ ; " W R I T E 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 D7 D2 C9 D4 E5 A0 CE C1 CD C5 8D
|
|
* . W R I T E spc N A M E rtn
|
|
* .
|
|
* ----> $84 = actual hex code for ctrl-D
|
|
*
|
|
* - The WRITE 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).
|
|
|
|
|
|
(A510)
|
|
CMDWRITE 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 ;Go get first byte of DOS name buffer.
|
|
------------
|
|
|
|
(A76E)
|
|
GETFNLNK JSR GETNXBUF
|
|
|
|
* Get addr of next filename buffer in chain
|
|
* from chain pointers buffer offset 37 & 36
|
|
* bytes from 1rst char of present filename
|
|
* buffer.
|
|
(A79A)
|
|
GETNXBUF LDY #37 ;Point the pointer at the chain buffer &
|
|
LDA (A3L),Y ;get addr of the next 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 ;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 from the 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.
|
|
(A78F) RTS
|
|
============
|
|
|
|
(A790)
|
|
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.
|
|
------------
|
|
|
|
* Open a specific file & check 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 message.
|
|
------------ ;(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
|
|
------------
|
|
|
|
* 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 ;Range error. See
|
|
(AB1F) ------------ ;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 in T/S list.
|
|
;(Not applicable to the open function.)
|
|
(A6B4) JMP OTHRERR ;No. Only take if got an error
|
|
------------ ;other than an end-of-data error.
|
|
;(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.
|
|
------------ ;(See dis'mbly of errors.)
|
|
|
|
CKTYPRTN RTS
|
|
(A7D3) ============
|
|
|
|
(A52E) JMP CKRBOPTN ;Go chk if R- or B-options were issued with the cmd.
|
|
------------
|
|
|
|
(A531)
|
|
BUFS4RW JSR BUFS2PRM
|
|
|
|
* Copy addresses of the different 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 FM driver 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.
|
|
(AB0A) 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
|
|
;as default cond.
|
|
(AE72)
|
|
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) ------------ ;(See dis'mbly of errors.)
|
|
|
|
* 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 in T/S list.
|
|
;(Not applicable to the position function.)
|
|
(A6B4) JMP OTHRERR ;No. Only take if got an error
|
|
------------ ;other than an end-of-data error.
|
|
;(See dis'mbly of errors.)
|
|
|
|
(A6C3)
|
|
FMDRVRTN RTS
|
|
|
|
RDWRRTN RTS
|
|
(A54E) ============
|
|
|
|
(A513) LDA #5 ;Set condition 5.
|
|
STA OPUTCOND
|
|
(A518) JMP FINSHCMD ;Exit with condition 5 set so that the
|
|
------------ ;next time a "PRINT" statement is encountered,
|
|
;execution will flow via the DOS hooks to send
|
|
;chars to the named file.
|
|
|
|
* 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 ASSOC WITH WRITE CMD
|
|
; (cause abbreviated NEG ASCII version of Applesoft
|
|
; program line containing the WRITE 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 5 still
|
|
; set to data will be routed to disk.
|
|
|
|
* MON C flag was on, so display command-terminating
|
|
* carriage return. (P.S. Applesoft detected the
|
|
* end-of-line marker ($00) and changed it to a <cr>.
|
|
* DOS then put the carriage return ($8D) as the last
|
|
* character in the input buffer.)
|
|
(9FA4)
|
|
DSPLYALL JSR RESTOREG
|
|
|
|
(9FBA)
|
|
RESTOREG LDA ASAVED ;Restore (a), (y) & (x) registers.
|
|
LDY YSAVED
|
|
LDX XSAVED
|
|
SEC ;Why?????
|
|
(9FC4) RTS
|
|
|
|
(9FA7) JSR GODSPLY ;Output char via true output handler.
|
|
|
|
(9FC5)
|
|
GODSPLY JMP (CSW)
|
|
------------
|
|
|
|
(FDF0)
|
|
COUT1 .
|
|
.
|
|
(Print char thru true output handler.)
|
|
(See dis'mbly of monitor in APPLE II REFERENCE MANUAL.)
|
|
.
|
|
.
|
|
(RTS)
|
|
============
|
|
|
|
(9FAA) STA ASAVED ;Save (a), (y) and (x) registers.
|
|
STY YSAVED
|
|
(9FB0) STX XSAVED
|
|
|
|
* Routine to exit DOS.
|
|
(9FB3)
|
|
DOSEXIT JSR INITIOHK ;Reset I/O hooks to point to DOS.
|
|
|
|
* Initialize the I/O hooks so that DOS intercepts
|
|
* all input & output. For instance, if a routine
|
|
* encounters a "COUT JMP (CSW)", then execution will
|
|
* actually flow to DOS's output routine (OPUTINCP,
|
|
* $9EBD). Similarly, any routine that refers to
|
|
* "RDKEY JMP (KSW)" will actually jump to DOS's
|
|
* input routine (INPTINCP, $9E81).
|
|
*
|
|
* The true (ie. normal) hooks are saved, ex:
|
|
* KSW: KEYIN --> KSWTRUE: KEYIN.
|
|
* CSW: COUT1 --> CSWTRUE: COUT1.
|
|
* The intercepts are then set as follows:
|
|
* ADINPTCP: INPTINCP --> KSW: INPTINCP.
|
|
* ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
|
|
|
|
* Check if the input hook needs to be reset.
|
|
(A851)
|
|
INITIOHK LDA KSW+1
|
|
CMP ADINPTCP+1
|
|
(A856) BEQ CKOUTHK ;Input hook already points to DOS's
|
|
;input handler, so go check output hook.
|
|
|
|
* Reset the input hook to point to DOS.
|
|
(A858) STA KSWTRUE+1 ;KSW: KEYIN --> KSWTRUE: KEYIN.
|
|
LDA KSW
|
|
STA KSWTRUE
|
|
LDA ADINPTCP ;ADINPTCP: INPTINCP --> KSW: INPTINCP.
|
|
STA KSW
|
|
LDA ADINPTCP+1
|
|
(A868) STA KSW+1
|
|
|
|
* Check if the output hook needs to be reset.
|
|
(A86A)
|
|
CKOUTHK LDA CSW+1
|
|
CMP ADOPUTCP+1
|
|
(A86F) BEQ SETHKRTN ;Output hook already points to DOS's
|
|
;output handler, so go exit.
|
|
|
|
* Reset the output hook to point to DOS.
|
|
(A871) STA CSWTRUE+1 ;CSW: COUT1 --> CSWTRUE: COUT1.
|
|
LDA CSW
|
|
STA CSWTRUE
|
|
LDA ADOPUTCP ;ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
|
|
STA CSW
|
|
LDA ADOPUTCP+1
|
|
STA CSW+1
|
|
SETHKRTN RTS
|
|
(A883)
|
|
|
|
(9FB6) LDX STKSAVED ;Retrieve saved stack pointer.
|
|
TXS ;(P.S. Don't confuse "STKSAVED" with "STKSAV".
|
|
RESTOREG LDA ASAVED ;Restore (a), (y) & (x) registers.
|
|
LDY YSAVED
|
|
LDX XSAVED
|
|
SEC ;Why?????
|
|
(9FC4) RTS ;Exit to caller of WRITE command.
|
|
============ ;Normally returns to $D533 in Applesoft ROM
|
|
;(part of INLINPL2 routine ($D52E).)
|
|
|
|
|
|
=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
|
|
|
|
NOTE: The WRITE command was exited without actually writing
|
|
anything to the file. However, because OPUTCOND ($AA52) was left
|
|
with a value of $05, the next time Applesoft encounters a
|
|
"PRINT" statement, execution flows via COUT ($FDED) and the DOS
|
|
hooks to send the characters contained in the "PRINT" statement to
|
|
the file as shown below:
|
|
|
|
(FDED)
|
|
COUT JMP (CSW)
|
|
------------
|
|
|
|
* DOS's output intercept routine.
|
|
(9EBD)
|
|
OPUTINCP JSR PREP4DOS
|
|
|
|
(9ED1)
|
|
PREP4DOS STA ASAVED ;Save (a), (y) & (x) registers.
|
|
STX XSAVED
|
|
STY YSAVED
|
|
TSX ;Adjust stack pointer and save it so that when later
|
|
INX ;restore it and hit an "RTS", we can return to the routine
|
|
INX ;that contained the "JSR PREP4DOS" instruction.
|
|
STX STKSAVED
|
|
UNCONDOS LDX #3 ;Handy entry point frequently used by assembly
|
|
(9EE0) ;language programmers to disconnect DOS completely.
|
|
(9EE2)
|
|
SETRUHKS LDA CSWTRUE,X ;Restore the I/O hooks to point to the true
|
|
STA CSW,X ;I/O handlers, ex: KSWTRUE: KEYIN --> KSW: KEYIN.
|
|
DEX ; CSWTRUE: COUT1 --> CSW: COUT1.
|
|
BPL SETRUHKS ;4 bytes (0 to 3) to move.
|
|
(9EEA) RTS
|
|
|
|
* Use current OPUTCOND value to index table containing
|
|
* address of output condition handlers. Do a "stack jump"
|
|
* to the appropriate condition handler entry point.
|
|
(9EC0) LDA OPUTCOND
|
|
ASL ;Times 2 cause 2 bytes/address.
|
|
TAX ;Set (x) to index table of entry point addresses.
|
|
LDA OPUTHNDTB+1,X ;Put adr of output handler on stack
|
|
PHA ;(hi byte first) and then do a "stack jump"
|
|
LDA OUTHNDTB,X ;to the appropriate entry point.
|
|
PHA
|
|
LDA ASAVED ;Save char to be printed.
|
|
(9ED0) RTS ;Execute the "stack jump".
|
|
|
|
.
|
|
.
|
|
STACK JUMP TO OPUTHDL5
|
|
.
|
|
.
|
|
* Output handler 5.
|
|
* - denotes start of writing chars to file.
|
|
* - evaluate start of data to write.
|
|
(9F61)
|
|
OPUTHDL5 CMP DCTRLCHR ;Is char = DOS's ctrl char (normally Ctrl-D)?
|
|
(9F64) BEQ OPUTHDL0 ;If (a) = DOS's ctrl char, exit via OPUTHDL0
|
|
;to cancel WRITE mode. This is why a
|
|
;statement such as: PRINT D$ will exit the
|
|
;write mode with the file still open. (Such
|
|
;a statement is often called a NULL command
|
|
;in the literature.)
|
|
(9F66) CMP #$8A ;line feed?
|
|
BEQ CMWRTBYT ;Yes - go write <lf> but stay in condition 5.
|
|
LDX #4 ;No - reset to condition 4 to signal that
|
|
STX OPUTCOND ; we want to write another line.
|
|
(9F6F) BNE OPUTHDL4 ;ALWAYS.
|
|
|
|
* Output handler 4.
|
|
* Writing data to the disk.
|
|
(9F52)
|
|
OPUTHDL4 CMP #$8D ;<cr>?
|
|
BNE CMWRTBYT ;No.
|
|
LDA #5 ;Set condition 5.
|
|
STA OPUTCOND
|
|
CMWRTBYT JSR WRITEXT ;Go write data byte to file.
|
|
(9F5B)
|
|
|
|
(A60E)
|
|
WRITEXT JSR CKBSCRUN
|
|
|
|
* Check if basic is running a program.
|
|
(A65E)
|
|
CKBSCRUN PHA ;Save (a) on stack.
|
|
LDA ACTBSFLG ;Check which basic is presently up.
|
|
(A662) BEQ INTBASIC ;Branch if using Integer basic.
|
|
|
|
* Using Applesoft - now if the line number
|
|
* is > 65288 ($FF in hi byte), then using
|
|
* immediate mode.
|
|
(A664) LDX CURLIN+1 ;Check hi byte of line number.
|
|
INX ;If $FF --> $00, then line # > 65288.
|
|
(A667) BEQ IMEDMODE ;Branch if using immediate mode.
|
|
|
|
* Applesoft appears to be running a prgm but, maybe
|
|
* CURLIN+1 was zapped, so also check prompt.
|
|
(A669) LDX PROMPT
|
|
CMP #$DD ;RH brackett = Applesoft prompt.
|
|
BEQ IMEDMODE ;Branch if in immediate mode.
|
|
RUNNING PLA ;Get saved (a) back from stack.
|
|
CLC ;(c) = 0 = signal program is running.
|
|
(A671) RTS
|
|
============
|
|
|
|
(A672)
|
|
INTBASIC LDA RUNMODE ;Check integer basic's run mode flag.
|
|
BMI RUNNING ;If negative, integer basic up but in deferred mode.
|
|
IMEDMODE PLA ;Get saved (a) back from stack.
|
|
SEC ;(c) = 1 = signal in immediate mode.
|
|
(A678) RTS
|
|
============
|
|
|
|
(A611) BCS CLOSZERO ;Basic prgm is not running, so go close
|
|
;the file, reset to condition 0 & then do
|
|
;a warmstart. (Remember, the WRITE
|
|
;command is restricted to the deferred mode.)
|
|
(A613) LDA ASAVED ;Retrieve byte to write.
|
|
STA ONEIOBUF ;Put it in the FM parameter list.
|
|
LDA #4 ;Set FM parm list to WRITE ONE BYTE.
|
|
STA OPCODEFM
|
|
LDA #1
|
|
STA SUBCODFM
|
|
(A623) JMP FMDRIVER ;Go to FM driver to write data byte.
|
|
------------
|
|
|
|
(A6A8)
|
|
FMDRIVER JSR FILEMGR ;CALL THE FILE MANAGER TO DO THE WRITE 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 ;assume 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.
|
|
|
|
.
|
|
.
|
|
(AC70) .
|
|
FNWRITE .
|
|
.
|
|
(See dis'mbly of FNWRITE function and
|
|
write-one-byte (WRITEONE, $ACBE) subfunction.)
|
|
.
|
|
.
|
|
(RTS)
|
|
============
|
|
|
|
TOERROP JMP RNGERROP ;Go handle range error.
|
|
(AB1F) ------------ ;(See dis'mbly of errors.)
|
|
|
|
* Return here after doing the WRITE 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 in T/S list.
|
|
;(Not applicable to the write function.)
|
|
(A6B4) JMP OTHRERR ;No. Only take if got an error
|
|
----------- ;other than an end-of-data error.
|
|
;(See dis'mbly of errors.)
|
|
|
|
(A6C3)
|
|
FMDRVRTN RTS
|
|
|
|
(9F5E) JMP DSPLYOUT ;Go display output conditionally.
|
|
------------
|
|
|
|
(9F99)
|
|
DSPLYOUT LDA #%00010000 ;Set bit pos'n 4.
|
|
(9F9B) BNE DSPLYCHR ;ALWAYS.
|
|
|
|
(9F9F)
|
|
DSPLYCHR AND CIOCUMUL ;Test flag to see if "MON O" is on.
|
|
(9FA2) BEQ DOSEXIT ;Flag to echo output is off, so skip screen print.
|
|
|
|
* Unconditionally dislay char.
|
|
(9FA4)
|
|
DSPLYALL JSR RESTOREG
|
|
|
|
* Restore the registers.
|
|
(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 IIREFERENCE MANUAL.)
|
|
.
|
|
.
|
|
(RTS)
|
|
============
|
|
|
|
(9FAA) STA ASAVED ;Save (a), (y) and (x) registers.
|
|
STY YSAVED
|
|
(9FB0) STX XSAVED
|
|
|
|
* Routine to exit DOS.
|
|
(9FB3)
|
|
DOSEXIT JSR INITIOHK ;Reset I/O hooks to point to DOS.
|
|
|
|
* Initialize the I/O hooks so that DOS intercepts
|
|
* all input & output. For instance, if a routine
|
|
* encounters a "COUT JMP (CSW)", then execution will
|
|
* actually flow to DOS's output routine (OPUTINCP,
|
|
* $9EBD). Similarly, any routine that refers to
|
|
* "RDKEY JMP (KSW)" will actually jump to DOS's
|
|
* input routine (INPTINCP, $9E81).
|
|
*
|
|
* The true (ie. normal) hooks are saved, ex:
|
|
* KSW: KEYIN --> KSWTRUE: KEYIN.
|
|
* CSW: COUT1 --> CSWTRUE: COUT1.
|
|
* The intercepts are then set as follows:
|
|
* ADINPTCP: INPTINCP --> KSW: INPTINCP.
|
|
* ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
|
|
|
|
* Check if the input hook needs to be reset.
|
|
(A851)
|
|
INITIOHK LDA KSW+1
|
|
CMP ADINPTCP+1
|
|
(A856) BEQ CKOUTHK ;Input hook already points to DOS's
|
|
;input handler, so go check output hook.
|
|
|
|
* Reset the input hook to point to DOS.
|
|
(A858) STA KSWTRUE+1 ;KSW: KEYIN --> KSWTRUE: KEYIN.
|
|
LDA KSW
|
|
STA KSWTRUE
|
|
LDA ADINPTCP ;ADINPTCP: INPTINCP --> KSW: INPTINCP.
|
|
STA KSW
|
|
LDA ADINPTCP+1
|
|
(A868) STA KSW+1
|
|
|
|
* Check if the output hook needs to be reset.
|
|
(A86A)
|
|
CKOUTHK LDA CSW+1
|
|
CMP ADOPUTCP+1
|
|
(A86F) BEQ SETHKRTN ;Output hook already points to DOS's
|
|
;output handler, so go exit.
|
|
|
|
* Reset the output hook to point to DOS.
|
|
(A871) STA CSWTRUE+1 ;CSW: COUT1 --> CSWTRUE: COUT1.
|
|
LDA CSW
|
|
STA CSWTRUE
|
|
LDA ADOPUTCP ;ADOPUTCP: OPUTINCP --> CSW: OPUTINCP.
|
|
STA CSW
|
|
LDA ADOPUTCP+1
|
|
STA CSW+1
|
|
SETHKRTN RTS
|
|
(A883)
|
|
|
|
(9FB6) LDX STKSAVED ;Retrieve saved stack pointer.
|
|
TXS ;(P.S. Don't confuse "STKSAVED" with "STKSAV".)
|
|
RESTOREG LDA ASAVED ;Restore (a), (y) & (x) registers.
|
|
LDY YSAVED
|
|
LDX XSAVED
|
|
SEC ;Why?????
|
|
(9FC4) RTS ;Exit to caller.
|
|
============
|
|
|
|
* Tried to write file while in the immediate mode.
|
|
* Close the file, set condition 0 and exit DOS.
|
|
* (Note: We can clear bit1 of the byte at $A91F
|
|
* in the command attribute table (CMDATTRB) and
|
|
* NOP-out the "BCS CLOSZERO" instruction at $A611
|
|
* in order to enable the write command to operate
|
|
* from the immediate mode.)
|
|
(A679)
|
|
CLOSZERO JSR CLOSEONE ;Go close the file.
|
|
|
|
* Close the file specified.
|
|
(A67C)
|
|
CLOSEONE .
|
|
.
|
|
(See dis'mbly given in formatted
|
|
listing of the the close command.)
|
|
.
|
|
.
|
|
(RTS)
|
|
|
|
(A67C) JSR RESTAT0
|
|
|
|
* Reset CONDNFLG and OPUTCOND to 0.
|
|
(A75B)
|
|
RESTAT0 LDY #0
|
|
STY CONDNFLG
|
|
STY OPUTCOND
|
|
(A763) RTS
|
|
|
|
(A67F) JMP DOSEXIT ;(Go back to exit DOS.)
|
|
------------
|