707 lines
55 KiB
Plaintext
707 lines
55 KiB
Plaintext
******************************************************************
|
||
* *
|
||
* MAXFILES Command Handler *
|
||
* *
|
||
*----------------------------------------------------------------*
|
||
* *
|
||
* The MAXFILES command is used to define the maximum number *
|
||
* of files that can be opened at one time (1 - 16). A default *
|
||
* value of 3 is used for cold starts (i.e. when the disk is *
|
||
* booted) or when the FP or INT commands are issued. This value *
|
||
* can be changed by altering the contents of MAXDFLT ($AAB1). *
|
||
* A diagram representing the structure of the DOS buffers *
|
||
* is given at the end of this listing. Note that 595 bytes are *
|
||
* reserved for each file and that a DOS buffer is composed of a *
|
||
* number of smaller buffers: data sector buffer, track/sector *
|
||
* list buffer, file name buffer and chain pointers buffer. The *
|
||
* first six bytes of the chain pointers buffer point to the *
|
||
* different sections of a given file buffer. The last two bytes *
|
||
* in the chain pointers buffer provide a link to the name buffer *
|
||
* of the next active file. If there are no more buffers in the *
|
||
* DOS buffer chain, the last two bytes of the last chain pointer *
|
||
* buffer are zeroed out. Similarly, if A DOS buffer is not *
|
||
* being used, the first byte in its filename buffer is $00. *
|
||
* Note that the addr of the 1rst DOS buffer at its filename *
|
||
* field (ADOSFNB1) is a constant because DOS buffers are built *
|
||
* from higher memory downward. (I.e. DOS buffer 1 is built 1rst *
|
||
* and occupies the highest memory location whereas DOS buffer *
|
||
* 16 is built last & occupies the lowest memory location.) The *
|
||
* highest numbered DOS buffer (i.e. the lowest in memory) is *
|
||
* always assigned first. *
|
||
* MAXFILES cannot normally be used successfully from an exec*
|
||
* file. Although the command is indeed executed, the computer *
|
||
* is inflicted with a terminal case of amnesia. Disorientation *
|
||
* occurs because MAXFILES shuts off the exec flag & CLOSEALL *
|
||
* subsequently releases the exec buffer. However, both *
|
||
* debilitating events can be prevented simply by NOPing out the *
|
||
* STA EXECFLAG instruction at $A253. The MAXFILES command *
|
||
* destroys Integer programs and messes up Applesoft strings. *
|
||
* This occurs because MEMSIZ & FRETOP (Applesoft) or HIMEM & *
|
||
* INTPGMST (Integer) are reset. Under special circumstances, *
|
||
* you can prevent some of these problems by placing a premature *
|
||
* "RTS" instruction in the ZLNK2NXT ($A82D) routine. You can *
|
||
* also issue a MAXFILES command from a running Applesoft program *
|
||
* if it is executed before any strings are defined or other files*
|
||
* are opened. *
|
||
* Programmers are often hard pressed to find a safe place *
|
||
* where basic won't write over their custom machine language *
|
||
* routines. Short routines are commonly put in page 3 or in the *
|
||
* tail end of the input buffer if little input is expected. A *
|
||
* few programmers even take great pains to write relocatable *
|
||
* routines that can be moved around at will or hidden in an *
|
||
* Applesoft program. However, the area between DOS & its buffers*
|
||
* represents a sanctuary for machine language programs. Although*
|
||
* this region is normally only seven bytes long, it can be *
|
||
* enlarged by fooling DOS into building its buffers at a lower *
|
||
* location. The procedure is as follows: *
|
||
* 1) load ADOSFNBF1 with a value equal to: *
|
||
* ADOSFNB1 - (L$ + $26) (where ADOSFNB1 = $9D00, *
|
||
* and L$ = hex length of program to be BLOADed. *
|
||
* $26 (dec 38) represents the bytes that normally *
|
||
* occur between the start of a DOS buffer & the 1rst *
|
||
* byte of its filename field or, in decimal notation: *
|
||
* POKE 40192, 40192 - (L# + #38). *
|
||
* 2) BLOAD your program at: A$ = ADOSFNB1 - L$, or in *
|
||
* decimal notation: A = 40192 - L#. *
|
||
* 3) call the cold start routine ($3D2), MAXFILES, FP *
|
||
* or INT to rebuild the DOS buffers. *
|
||
* Greeting programs designed to accommodate Applesoft *
|
||
* editing programs often use this technique to install the *
|
||
* editor program between DOS and its buffers. (If you are *
|
||
* writing commercial (nonturnkey) assembly language programs *
|
||
* that are designed to run on different-sized machines or *
|
||
* accommadate an altered version of DOS, note the last two *
|
||
* paragraphs at the end of this disassembly. These describe how *
|
||
* to find moved DOS buffers from an assembly language program *
|
||
* that only accesses DOS via indirect addressing.) *
|
||
* Inspection of the raw data in a DOS buffer can often *
|
||
* reveal protection techniques embedded in a program or its file *
|
||
* description (ex. non-listable programs, programs with file *
|
||
* names containing back spaces or other illegal control *
|
||
* characters, driver programs made "user unloadable" through the *
|
||
* use of illegal T/S list sector values, etc.). (See the *
|
||
* preamble given with the disassembly of the catalog command for *
|
||
* an alternate method of inspecting file descriptions. *
|
||
* *
|
||
******************************************************************
|
||
|
||
|
||
* Execution pattern:
|
||
* - Make sure that the EXEC mode is turned off.
|
||
* - Close all files.
|
||
* - Save the MAXFILES argument in the main variables table
|
||
* (MXFILVAL, $A7D4).
|
||
* - Build the indicated number of DOS buffers.
|
||
* - Check which basic is active and reset the Applesoft
|
||
* (MEMSIZ, $73-$74 & FRETOP, $6F-$70) or Integer (HIMEM,
|
||
* $4C-$4B & INTPGMST, $CA-$CB) zero-page pointers.
|
||
|
||
|
||
* On entry:
|
||
* - A5L ($44) contains the numeric argument that was issued
|
||
* with the MAXFILES command. The argument was previously
|
||
* screened to insure that it was between 1 and 16.
|
||
* Screening was done via a section ($A0AA - $A0C7) in the
|
||
* command parsing and processing routines.
|
||
|
||
|
||
(A251)
|
||
CMDMXFIL LDA #0 ;Shut off the exec flag.
|
||
STA EXECFLAG
|
||
LDA A5L ;Get argument issued with MAXFILES
|
||
(A258) PHA ;cmd and save it on the stk.
|
||
|
||
(A259) JSR CLOSEALL
|
||
|
||
* Close all files.
|
||
(A316)
|
||
CLOSEALL JSR GETNBF1
|
||
|
||
* Put address of the 1rst DOS name buffer
|
||
* (chain) in the A3L/H pointer.
|
||
(A792)
|
||
GETFNBF1 LDA ADOSFNB1 ;First link to chain of DOS buffers
|
||
LDA 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 the pointer at chain buffer.
|
||
LDA (A3L),Y
|
||
BEQ GETNXRTN ;If hi byte is 0, the 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-flag 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, return 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 the first byte in the DOS name buffer.
|
||
|
||
* Get first byte from 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.
|
||
|
||
(A328) BEQ CHKNXBUF ;This one 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.
|
||
LDA EXECBUFF+1 ;Maybe - low bytes matched,
|
||
CMP A3L+1 ;so now check hi bytes.
|
||
BEQ CKEXCRTN ;Exec buffer = current buffer.
|
||
NOTEXCBF DEX ;Not EXECing, so DEX to make sure z-flag
|
||
(A7C2) ;is off. (P.S. (x) was orig conditioned
|
||
;to a large non-zero val on entry to
|
||
;GETFNBF1. There4, if now DEX then
|
||
(A7C3) ;can be sure z-flag will be off.)
|
||
CKEXCRTN RTS ;If execing, return with z-flag on.
|
||
|
||
(A2FF) BNE FREEBUFF ;ALWAYS BRANCH IF CLOSEONE IS
|
||
;ACCESSED VIA CLOSEALL.
|
||
(A301) LDA #0 ;Shut the 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 ;first byte of the filename field.
|
||
(A30B) JSR BUFS2PRM
|
||
|
||
* Get addresses of the DOS buffers from chain
|
||
* buffer and put then in the 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 name buf from the chain pointer
|
||
INY ;buffer & put them in the FM parameter list.
|
||
CPY #38 ;(P.S. Addr of NEXT filename buffer is
|
||
BNE ADRINPRM ;NOT 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 we can rtn to caller.
|
||
STX STKSAV ;Save stk pointer.
|
||
(AB0A) JSR RSTRFMWA ;Copy contents of FM work buf (in DOS chain)
|
||
;to FM work area (not in buffer chain).
|
||
|
||
(AE6A)
|
||
RSTRFMWA JSR SELWKBUF ;Find FM work buf.
|
||
|
||
* Get the addr of
|
||
* the FM work buffer
|
||
* from the FM parm
|
||
* list & stick it
|
||
* it in the A4L/H
|
||
* pointer.
|
||
(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 rtn code
|
||
(AE6F) STY RTNCODFM ;in FM parm list
|
||
(AE72) ;to signal no errs.
|
||
STORFMWK LDA (A4L),Y ;Copy FM work buffer
|
||
STA FMWKAREA,Y ;(in chain) to FM
|
||
INY ;wrk area (nonchain).
|
||
CPY #45
|
||
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, got range error.
|
||
ASL ;Double val of opcode & get addr of
|
||
TAX ;appropriate function handler from tbl.
|
||
LDA FMFUNCTB+1,X ;Stick addr 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 afterr doing the CLOSE 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 close function.)
|
||
(A6B4) JMP OTHRERR ;(See dis'mbly of errors.)
|
||
------------
|
||
|
||
(A6C3)
|
||
FMDRVRTN RTS ;Return to caller of FMDRIVER.
|
||
|
||
(A32D) JMP CLOSEALL ;Go to CLOSERTS via CLOSEALL.
|
||
------------
|
||
|
||
CLOSERTS RTS
|
||
(A330) ============
|
||
|
||
(A25C) PLA ;Get argument issued with maxfiles command
|
||
STA MXFILVAL ;and save it in the main variable table.
|
||
(A260) JMP BILDBUFS ;Go build maxfiles # of buffers.
|
||
------------
|
||
|
||
* Build the DOS buffers
|
||
|
||
* Point A3L/H at FIRST DOS FILENAME BUFFER. Example calcs for FIRST set of DOS
|
||
* (Note: First DOS name buffer is lowest buffers on a 48K machine
|
||
* numbered but highest in memory.) ----------------------------------
|
||
(A7D4)
|
||
BILDBUFS SEC ;Wasted byte, might as well be a "NOP".
|
||
LDA ADOSFNB1 ;Get addr of 1rst filename field
|
||
STA A3L ;and put it in A3L/H.
|
||
LDA ADOSFNB1+1
|
||
(A7DD) STA A3L+1 (A3L/+1) = ($9CD3)
|
||
|
||
* Get # of maxfiles wanted & store it
|
||
* in the temporary counter (TEMPBYT).
|
||
(A7DF) LDA MXFILVAL
|
||
(A7E2) STA TEMPBYT
|
||
|
||
* Free buffer by zeroing out the
|
||
* 1rst byte of the filename field.
|
||
(A7E5)
|
||
ZDOSBUFN LDY #0 (y) = 0
|
||
TYA (a) = 0
|
||
(A7E8) STA (A3L),Y (9CD3),0: 00 --> 9CD3:00
|
||
|
||
* Point link in chain pointers buffers
|
||
* at the FM WORK BUFFER.
|
||
(A7EA) LDY #30 ;Set (y) to index 1rst link (y) = 1E
|
||
;in chain pointers buffer.
|
||
(A7EC) SEC
|
||
LDA A3L ;Subtract 45 from low byte of addr (a) = D3
|
||
SBC #45 ;of filename buf to calc low byte (a) = D3 - 2D = A6
|
||
STA (A3L),Y ;of addr of FM work buf & put it in 9CD3,1E: A6 --> 9CF1: A6
|
||
PHA ;the chain pointer & on the stk. (a) = A6
|
||
LDA A3L+1 ;Subtract carry from hi byte of addr of (a) = 9C
|
||
SBC #0 ;filename buf to get hi byte of FM wrk buf. (a) = 9C - 0 = 9C
|
||
(A7F8) INY ;Kick up (y) to index addr of hi byte of (y) = 1F
|
||
;link in chain pointers.
|
||
(A7F9) STA (A3L),Y ;Store hi byte of addr of FM wrk buf 9CD3,1F: 9C --> 9CF2: 9C
|
||
;in the link.
|
||
;(Note: Above calculations affect (a)
|
||
;but not A3L/H.)
|
||
|
||
* Point link in chain pointers buffer
|
||
* at the T/S LIST SECTOR BUFFER.
|
||
(A7FB) TAX ;Put hi byte of addr of FM wrk buf in (x) = 9C
|
||
(A7FC) DEX ;(x) & kick it down so it indexes hi byte (x) = 9B
|
||
;of T/S list buf. (T/S list buf is $100
|
||
;bytes long.)
|
||
(A7FD) PLA ;Get low byte of addr of FM wrk buf back (a) = A6
|
||
PHA ;from stack.
|
||
INY ;Kick index up to link in chain pointers. (y) = 20
|
||
(A800) STA (A3L),Y ;Put low byte of addr of FM wrk buf in 9CD3,20: A6 ---> 9CF3: A6
|
||
;link buffer's pointer.
|
||
(A802) TXA ;Get hi byte of T/S list buf in (a). (a) = 9B
|
||
INY ;Kick up index in chain pointers buf. (y) = 21
|
||
(A804) STA (A3L),Y ;Set hi byte of link in chain pointers. 9CD3,21: 9B --> 9CF4: 9B
|
||
|
||
* Point the link in the chain pointers
|
||
* buffer at the DATA SECTOR BUFFER.
|
||
(A806) TAX ;Put hi byte of addr of T/S list buf (a) = 9B
|
||
(A807) DEX ;in (x) & kick it down to correspond to (x) = 9A
|
||
;hi byte of addr of data sec buf.
|
||
(A808) PLA ;Get low byte of T/S list buf from (a) = A6
|
||
(A809) PHA ;stack & use it for low byte of data Saved (a) = A6
|
||
;sec buf (cause they are exactly 1 page
|
||
;apart).
|
||
(A80A) INY ;Kick up index to chain pointers buf. (y) = 22
|
||
(A80B) STA (A3L),Y ;Put low byte of addr of data sec buf in 9CD3,22: A6 --> 9CF5: A6
|
||
;the link buf.
|
||
(A80E) INY ;Kick up index to chain pointers buf. (y) = 23
|
||
TXA ;Get hi byte of adr of T/S list buf & (a) = 9A
|
||
(A80F) STA (A3L),Y ;designate it as hi byte of link. 9CD3,23: 9A --> 9CF6: 9A
|
||
|
||
* Reduce counter for number
|
||
* of buffers built so far.
|
||
(A811) DEC TEMPBYT ;If counter goes to zero, then just
|
||
(A814) BEQ ZLNK2NXT ;did last buffer & should zero out link.
|
||
|
||
* Not done all bufs yet so point
|
||
* link in chain pointers at NEXT
|
||
* FILENAME BUFFER.
|
||
(A816) TAX ;Set (x) = low byte of addr of data (a) = 9A
|
||
;sector buffer.
|
||
(A817) PLA ;Get low byte of addr of data sec buf (a) = A6
|
||
;back off of stack.
|
||
(A818) SEC ;Subtract 38 from low byte of data sec
|
||
SBC #38 ;to index NEXT filename field buf. (a) = A6-26 = 80
|
||
INY ;Kick up index to chain pointers buf. (y) = 24
|
||
STA (A3L),Y ;Store low byte of next filename buf 9CD3,24: 80 --> 9CF7: 80
|
||
PHA ;in link & then save it on stk. Saved (a) = 80
|
||
TXA ;Get hi byte of data sec buf from (x) (a) = 9A
|
||
(A820) SBC #0 ;& subtract carry (in case cross (a) = 9A
|
||
;page boundary) to get (a) = hi byte
|
||
;of NEXT filename field buffer.
|
||
(A822) INY ;Kick index up to chain pointers buf (y) = 25
|
||
(A823) STA (A3L),Y ;& store hi byte of NEXT filename field 9CD3,25: 9A --> 9CF8: 9A
|
||
;in link.
|
||
|
||
* Set A3L/H to point to NEXT
|
||
* filename field buffer.
|
||
(A825) STA A3L+1 A3L+1 = 9A
|
||
PLA (a) = 80
|
||
STA A3L A3L = 80 therefore, (A3L/+1) --> ($9A80)
|
||
(A82A) JMP ZDOSBUFN ;Go back to free NEXT DOS filename
|
||
------------ ;buffer & build more DOS bufs.
|
||
|
||
* No more buffers to build so zero out
|
||
* the link that would normally point to
|
||
* the next filename field buffer.
|
||
(A82D)
|
||
ZLNK2NXT PHA ;Save low byte of addr of data buf on stk.
|
||
LDA #0 ;Zero out link to next filename field buf.
|
||
INY
|
||
STA (A3L),Y
|
||
INY
|
||
(A834) STA (A3L),Y
|
||
|
||
* Check which basic is active.
|
||
(A836) LDA ACTBSFLG ;Check if active basic is FP or Integer.
|
||
(A839) BEQ SETINTPT ;Branch if Integer.
|
||
|
||
* Using Applesoft so initialize
|
||
* MEMSIZ & FRETOP (string storage)
|
||
* to a value 1 byte greater than
|
||
* highest memory location available
|
||
* to basic program.
|
||
(A83B) PLA
|
||
STA MEMSIZ+1
|
||
STA FRETOP+1
|
||
PLA
|
||
STA MEMSIZ
|
||
STA FRETOP
|
||
(A845) RTS ;Exit to caller of maxfiles cmd.
|
||
============ ;Normally exits to AFTRCMD ($A17D) in the
|
||
;command parsing and processing routines.
|
||
|
||
* Using Integer, so set HIMEM
|
||
* & program pointer (INTPGMST).
|
||
(A846)
|
||
SETINTPT PLA
|
||
STA HIMEM+1
|
||
STA INTPGMST+1
|
||
PLA
|
||
STA HIMEM
|
||
STA INTPGMST
|
||
(A850) RTS ;Exit to caller of maxfiles cmd.
|
||
============ ;Normally exits to AFTRCMD ($A17D) in the
|
||
;command parsing and processing routines.
|
||
|
||
|
||
|
||
|
||
DOS BUFFER DEFAULT LOCATIONS ON A 48K MACHINE
|
||
|
||
|
||
l Memory available to Applesoft program l
|
||
l l
|
||
Addrs on 48 K system l l Offset from
|
||
(when MXFILVAL = 3) l l start of DOS buffer
|
||
l================================================================l
|
||
>>>>>>>>>>>>>>> $9600 l l $00
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l Data Sector Buffer l
|
||
^ l (DOS Buffer 3) l
|
||
^ l (256 bytes) l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ l l
|
||
^ $96FF l l $0FF
|
||
^ l----------------------------------------------------------------l
|
||
^ >>>>>>>>> $9700 l l $100
|
||
^ ^ l l
|
||
^ ^ l l
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l T/S List Sector Buffer l ^
|
||
^ ^ l (DOS Buffer 3) l Z
|
||
^ ^ l (256 bytes) l E
|
||
^ ^ l l R
|
||
^ ^ l l O
|
||
^ ^ l l S
|
||
^ ^ l l
|
||
^ ^ l l O
|
||
^ ^ l l U
|
||
^ ^ l l T
|
||
^ ^ l l ^
|
||
^ ^ $97FF l l $1FF ^
|
||
^ ^ l----------------------------------------------------------------l ^
|
||
^ ^ >>> $9800 l l $200 ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l FM Work Area Buffer l ^
|
||
^ ^ ^ l (DOS Buffer 3) l ^
|
||
^ ^ ^ l (45 bytes) l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ $982C l l $22C ^
|
||
^ ^ ^ l----------------------------------------------------------------l ^
|
||
^ ^ ^ $982D l l $22D <<<< ^
|
||
^ ^ ^ l l ^ ^
|
||
^ ^ ^ l Filename Field Buffer l ^ ^
|
||
^ ^ ^ l (DOS Buffer 3) l ^ ^
|
||
^ ^ ^ l (30 bytes) l ^ ^
|
||
^ ^ ^ $984A l l $24A ^ ^
|
||
^ ^ ^ l----------------------------------------------------------------l ^ ^
|
||
^ ^ ^...$984B l l $24B ^ ^
|
||
^ ^.................l Chain Pointers Buffer l ^ ^
|
||
^.......................l (DOS Buffer 3) l ^ ^
|
||
$9852 l (8 bytes) ($0000) l $252...........^
|
||
l=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-l ^
|
||
>>>>>>>>>>>>>>> $9853 l l $00 ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l Data Sector Buffer l ^
|
||
^ l (DOS Buffer 2) l ^
|
||
^ l (256 bytes) l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ $9952 l l $0FF ^
|
||
^ l----------------------------------------------------------------l ^
|
||
^ >>>>>>>>> $9953 l l $100 ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l T/S List Sector Buffer l ^
|
||
^ ^ l (DOS Buffer 2) l ^
|
||
^ ^ l (256 bytes) l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ $9A52 l l $1FF ^
|
||
^ ^ l----------------------------------------------------------------l ^
|
||
^ ^ >>> $9A53 l l $200 ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l FM Work Area Buffer l ^
|
||
^ ^ ^ l (DOS Buffer 2) l ^
|
||
^ ^ ^ l (45 bytes) l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ $9A7F l l $22C ^
|
||
^ ^ ^ l----------------------------------------------------------------l ^
|
||
^ ^ ^ $9A80 l l $22D <<<<<<<<<<<
|
||
^ ^ ^ l l ^ ^
|
||
^ ^ ^ l Filename Field Buffer l ^ ^
|
||
^ ^ ^ l (DOS Buffer 2) l ^ ^
|
||
^ ^ ^ l (30 bytes) l ^ ^
|
||
^ ^ ^ $9A9C l l $24A ^ ^
|
||
^ ^ ^ l----------------------------------------------------------------l ^ ^
|
||
^ ^ ^...$9A9D l l $24B ^ ^
|
||
^ ^.................l Chain Pointers Buffer l ^ ^
|
||
^.......................l (DOS Buffer 2) l ^ ^
|
||
$9AA5 l (8 bytes) l $252 ...^ ^
|
||
l=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-l ^
|
||
>>>>>>>>>>>>>>> $9AA6 l l $00 ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l Data Sector Buffer l ^
|
||
^ l (DOS Buffer 1) l ^
|
||
^ l (256 bytes) l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ l l ^
|
||
^ $9BA5 l l $0FF ^
|
||
^ l----------------------------------------------------------------l ^
|
||
^ >>>>>>>>> $9BA6 l l $100 ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l T/S List Sector Buffer l ^
|
||
^ ^ l (DOS Buffer 1) l ^
|
||
^ ^ l (256 bytes) l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ l l ^
|
||
^ ^ $9CA5 l l $1FF ^
|
||
^ ^ l----------------------------------------------------------------l ^
|
||
^ ^ >>> $9CA6 l l $200 ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l FM Work Area Buffer l ^
|
||
^ ^ ^ l (DOS Buffer 1) l ^
|
||
^ ^ ^ l (45 bytes) l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ l l ^
|
||
^ ^ ^ $9CD2 l l $22C ^
|
||
^ ^ ^ l----------------------------------------------------------------l ^
|
||
^ ^ ^ $9CD3 l l $22D <<<< ^
|
||
^ ^ ^ l l ^ ^
|
||
^ ^ ^ l Filename Field Buffer l ^ ^
|
||
^ ^ ^ l (DOS Buffer 1) l ^ ^
|
||
^ ^ ^ l (30 bytes) l ^ ^
|
||
^ ^ ^ $9CF0 l l $24A ^ ^
|
||
^ ^ ^ l----------------------------------------------------------------l ^ ^
|
||
^ ^ ^...$9CF1 l ex. A6, 9C l $24B ^ ^
|
||
^ ^.................l ex. A6, 9B Chain Pointers Buffer l ^ ^
|
||
^.......................l ex. A6, 9A (DOS Buffer 1) l ^ ^
|
||
$9CF8 l (8 bytes) ex. 80, 9A l $252...........^
|
||
l=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-l ^
|
||
$9CF9 l (7 unused bytes) l $253 ^
|
||
$9CFF l l $259 ^
|
||
l================================================================l ^
|
||
$9D00 l (ADOSFNB1/+1)---> l..........^
|
||
l DOS l
|
||
l l
|
||
(Normally, the byte at $3D2 corresponds to the page
|
||
number of the start of DOS. This byte can there4 be used
|
||
to determine if DOS is at its "normal" location.
|
||
If $3D2 contains a value less than #$9D then the computer
|
||
has less than 48K of RAM. A value equal to #$9D means that
|
||
DOS is at its normal 48K location whereas a larger value
|
||
describes a machine with at least 48K of memory. In the
|
||
later instance, DOS may reside on the language card.)
|
||
|
||
Note that the first two bytes of DOS point to the first
|
||
DOS buffer at its filename field. Therefore, once you
|
||
find the start of DOS (via the high byte of the warm-
|
||
start vector), you can use the first two bytes of DOS to
|
||
locate the DOS buffer chain even if an editor program is
|
||
installed between DOS and its buffers.
|
||
|