*=====================================
* FREE UP SECTORS THAT WERE ASSIGNED
* BUT NOT USED.
*=====================================

* WHENEVER, SOMETHING IS WRITTEN TO
* THE DISK, THE WHOLE TRK IS ALLOCATED
* IN THE VTOC WHETHER IT IS NEEDED OR
* NOT.  THERE4, ONCE WE ARE DONE
* WRITING, GO BACK & FREE UP THE
* UNNEEDED SECTORS.

FIXMAP LDA ASIGNTRK ;HAS A TRK ALREADY BEEN ASSIGNED?
 BNE FREEXTRA ;YES - GO FREE UP EXTRA SECS.
 RTS ;NO - GO EXIT.

FREEXTRA PHA ;SAVE TRK # ON STK.
 JSR READVTOC ;READ IN THE VTOC.
 LDY ASIGNSEC ;SET (Y) = # OF NEXT SECTOR WHICH
;COULD HAVE BEEN WRITTEN.
 PLA ;GET ASSIGNMENT TRK# BAK FRM STK.
 CLC ;DON'T WANT 2 FREE LAST SEC USED,
;SO CLR (C) HERE SO DON'T FREE IT
;UP WHEN BEGIN ROTATING MAPS IN
;SUB2FREE ROUTINE.
 JSR SUB2FREE ;ADJUST ASIGNMAP TO FREE UP SECS
;BY SETTING BIT CORRESPONDING TO
;THE SEC #.  NEXT, MERGE ASIGNMAP
;WITH THE APPROPRIATE TRK MAP IN
;THE VTOC.
 LDA #0 ;NO MORE DEALLOCATIONS NEEDED.
 STA ASIGNTRK
 JMP WRITVTOC ;WRITE CORRECTED VTOC BACK 2 DSK.


*================================
* SUBROUTINE TO FREE UP SECS THAT
* WERE DELETED OR PREMATURELY
* ASSIGNED BUT NOT USED.
*================================

* THIS TRICKY LITTLE ROUTINE IS
* EASY TO UNDERSTAND ONCE YOU
* REALIZE THAT:
* 1) UNLIKE THE VTOC, ASIGNMAP
* DOES NOT CONTAIN UNNECESSARILY
* ASSIGNED SECTORS.
* 2) IF THE DISK WAS JUST WRITTEN
* TO, ASIGNMAP MAP DOES NOT HOUSE
* ANY NEWLY ASSIGNED SECS (EVEN
* IF THOSE SECS ARE NECESSARY OR
* NOT).
* 3) SECS ARE NORMALLY ASSIGNED
* IN DESCENDING ORDER.
* 4) # OF ROR'S = # OF SECS THAT
* NEED TO BE ASSIGNED.
*
* FOR EX:  IF LAST TRK HAD NEVER
* BEEN ASSIGNED & ONLY SECS $0F
* AND $0E WERE NEEDED, THEN ON
* ENTRY TO SUB2FREE, THE 1RST 2
* BYTES WOULD APPEAR AS FOLLOWS:
*    SEC NMB: CBA98765 43210FED
*    BIT VAL: 11111111 11111...
* AFTER THE 1RST ROR, THE STATUS
* OF SEC $0D IS DETERMINED BY THE
* ENTRY STATUS OF THE CARRY (C):
*    SEC NMB: DCBA9876 543210FE
*    BIT VAL: C1111111 111111..
* ON NEXT ROR, THE "CPY SECPERTK"
* INSTRUC CONDITIONS (C) TO CLR
* FOR SEC $0E:
*    SEC NMB: EDCBA987 6543210F
*    BIT VAL: 0C111111 1111111.
* ON NEXT ROR, THE "CPY SECPERTK"
* INSTRUC CONDITIONS (C) TO CLR
* FOR SEC $0F:
*    SEC NMB: FEDCBA98 76543210
*    BIT VAL: 00C11111 11111111
* WHEN ASIGNMAP IS MERGED WITH THE
* CORRESPONDING TRKMAP IN THE VTOC,
* THE SECS THAT WERE UNNECESSARILY
* ASSIGNED IN THE VTOC ARE FREED.
* (NOTE:  WHEN USED IN THE DELETE
* FUNCTION, SUB2FREE IS REPEATEDLY
* CALLED BY FREESEC TO FREE ONE
* SECTOR AT A TIME.)

SUB2FREE LDX #$FC ;SET INDEX TO SHIFT 4 BYTES AS A
;UNIT (#$FC --> #$FF).
STNDARD ROR ASIGNMAP-$FC,X ;4 BYTES PER MAP FOR @ TRK.
 INX
 BNE STNDARD
 INY ;WHEN (Y) = 16, ASIGNMAP IS BACK
;IN STANDARD POS'N.
 CPY SECPERTK ;CONDITION (C) FOR NEXT SHIFT.
 BNE SUB2FREE
 ASL ;TRK*4 TO INDEX TRKMAP.
 ASL
 TAY
 BEQ SUB2RTN ;TRK VAL OF 0 NOT ALLOWED.

* ASIGNMAP NOW REFLECTS TRUE SEC
* ASSIGNMENT & IS IN STANDARD
* POSITION.  THERE4, MERGE IT
* WITH THE APPROPRIATE TRKMAP IN
* THE VTOC TO FREE UP EXTRA SECS.

 LDX #4
MERGMAPS LDA ASIGNMAP-1,X
 ORA TRKMAP0+3,Y ;DO THE MERGE.
 STA TRKMAP0+3,Y
 DEY ;REDUCE INDICES.
 DEX
 BNE MERGMAPS
SUB2RTN RTS


*==========================================
* CALCULATE THE EXACT POSITION OF THE
* 3-BYTE FILE POINTER:
*==========================================

* - FILPTSEC = SECTOR OFFSET (IN LOW/HI
*   FORMAT) INTO THE ENTIRE FILE (2 BYTES).
* - FILPTBYT = BYTE OFFSET INTO THE CURRENT
*   SECTOR (1 BYTE).
*
* ALL 3 BYTES BYTES DEFINE THE EXACT POS'N
* OF THE FILE POINTER VIA THE FOLLOWING
* FORMULA:
*  (REC# * REC LENGTH) + BYTE OFFSET
*  INTO THE RECORD.
* WHERE:
*   RECNMBFM=RECORD# FROM R-PARAMETER (SET
*            BY USER WHEN USING RANDOM
*            ACCESS FILES OR SIMPLY
*            INCREMENTED WHEN USING OTHER
*            FILE TYPES).
*   RECLENWA=RECORD LENGTH PARSED FROM
*            L-PARAMETER & ASSIGNED WITH
*            THE OPEN CMD (ELSE DEFAULTED
*            TO A SIZE OF 1).
*   BYTOFFFM=OFFSET INTO THE CURRENT RECORD
*            (SET BY USER WHEN USING THE
*            OPEN CMD OR OCCASIONALLY USED
*            WITH SEQUENTIAL FILES AS A
*            B-PARAMETER).
* NOTE THAT YOU CAN ACTUALLY DIRECTLY
* ACCESS ANY BYTE IN ANY FILE BY
* BYPASSING THE COMMAND INTERPRETER AND
* SETTING THE L-, B- AND R-PARAMETERS
* HOWEVER YOU WANT.

CALCFPTR LDA RECNMBFM ;PUT RECORD # IN MULTIPLIER AND
 STA FILPTBYT ;ALSO SAVE IT IN THE WORK AREA.
 STA RECNMBWA
 LDA RECNMBFM+1
 STA FILPTSEC
 STA RECNMBWA+1
 LDA #0 ;ZERO OUT HI ORDER BYTE OF SEC
 STA FILPTSEC+1 ;OFFSET INTO THE ENTIRE FILE.

* CALCULATE:  REC # * REC LENGTH.
* THIS ROUTINE IS JUST A BASIC
* MULTPLICATION OF TWO 16-BIT
* NUMBERS.  IT MAY AT FIRST SEEM
* CONFUSING BECAUSE FILPTSEC &
* FILPTBYT ARE USED BOTH FOR HOLDING
* THE MULTIPLIER (RECORD #) AND PART
* OF THE PRODUCT RESULT.  HOWEVER,
* THE BITS OF THE PRODUCTS DON'T GET
* MIXED UP WITH THE BITS OF THE
* MULTIPLIER BECAUSE ROLLING IN A
* PRODUCT BIT ALSO ROLLS OUT THE
* LAST-USED MULTIPLIER BIT (IE.,
* THERE IS NO BIT OVERLAP).

 LDY #16 ;16 BITS / ONE 2-BYTE NUMBER.
NMBXLEN TAX ;SAVE PART OF RUNNING PRODUCT.
;(ON 1RST ENTRY, SET (X) = 0.)
 LDA FILPTBYT ;GET (A) = MULTIPLIER.
 LSR ;PUT MULTIPLIER BIT IN CARRY.
 BCS NMBXLEN1 ;IF (C)=1, GO ADD MULTIPLICAND.
 TXA ;(A) = PART OF RUNNING PRODUCT.
 BCC NMBXLEN2 ;ALWAYS, NO USE +ING MULTIPLICAND
;CAUSE BIT IN MULTIPLIER IS A 0
;SO JUST GO SHIFT RUNNING PRODUCT
NMBXLEN1 CLC ;+ MULTIPLICAND 2 RUNNING VERSION
 LDA FILPTSEC+1 ;OF SHIFTED PRODUCT.
 ADC RECLENWA
 STA FILPTSEC+1
 TXA ;SET (A)=LOW BYT OF RUNNING PROD.
 ADC RECLENWA+1
NMBXLEN2 ROR ;SHIFT (AS A UNIT) RUNNING RESULT
 ROR FILPTSEC+1 ;1 BIT RIGHT 4 NEXT TIME AROUND.
 ROR FILPTSEC ;SHIFT LOWER 2 BYTES OF RUNNING
 ROR FILPTBYT ;PRODUCT & AT SAME TIME THROW OUT
;LAST-USED MULTIPLIER BIT.
 DEY ;REDUCE BIT COUNTER.
 BNE NMBXLEN ;TAKE IF NOT USED ALL 16 BITS YET

* COPY BYTE OFFSET INTO RECORD FROM
* THE FM PARAMETER LIST TO THE WORK
* AREA.

 CLC
 LDA BYTOFFFM
 STA BYTOFFWA

* CALCULATE THE LOWEST ORDER BYTE OF
* THE FILE POINTER:
* BYTOFFWA = OFFSET INTO CURRENT RECORD.
*          = BYTE OFFSET INTO RECORD
*            + (RECORD LENGTH * RECORD #).

 ADC FILPTBYT
 STA FILPTBYT
 LDA BYTOFFFM+1
 STA BYTOFFWA+1
 ADC FILPTSEC
 STA FILPTSEC
 BCC CALCRTS
 INC FILPTSEC+1
CALCRTS RTS

* RESIDUAL JUNK

 HEX B5 ;GARBAGE LEFT OVER FRM OLD ROUT'N
 RTS ;PRIOR TO PATCH TO CALCFPTR.
;CONSIDER AS FREE SPACE.


*=================================
*  EXIT FM WITH OR WITHOUT ERRS.
*=================================

LNGNOTAV LDA #1
 BNE BADFMXIT ;ALWAYS.
RNGERROP LDA #2
 BNE BADFMXIT ;ALWAYS.
RNGERRSB LDA #3
 BNE BADFMXIT ;ALWAYS.
WRITPROT LDA #4
 BNE BADFMXIT ;ALWAYS.
ENDOFDAT LDA #5
 BNE BADFMXIT ;ALWAYS.
FILENOT LDA #6
 BNE BADFMXIT ;ALWAYS.
DISKFULL JMP FULLPTCH
 NOP
FILELOKD LDA #10
 BNE BADFMXIT ;ALWAYS.

GOODFMXT LDA RTNCODFM
 CLC ;(C)=0 TO SIGNAL GOOD OPERATION.
 BCC FMEXIT

BADFMXIT SEC ;(C) = 1 TO SIGNAL UNSUCCESSFUL.

* COMMON FM EXIT ROUTINE.
* NOTE THAT ROUTINE IS EXITED BY
* RESETTING THE STACK POINTER.
* USUALLY RETURNS TO CALLER OF THE
* FUNCTION (IE. NORMALLY RETURNS TO
* AFTRFUNC, $A6AB) IN THE FMDRIVER
* ROUTINE ($A6A8).)  HOWEVER, THERE
* IS ONE EXCEPTION.  THE APPEND CMD
* HNDLR (CMDAPPND, $A298) MAY CALL
* THIS ROUTINE SEVERAL TIMES.  MOST
* OF THE TIME, EXECUTION RTNS TO
* AFTRFUNC.  HOWEVER, THE LAST TIME
* FMEXIT IS CALLED, THE CONTENTS OF
* STKSAV ($B39B) ARE ALTERED BEFORE
* FMEXIT IS ENTERED.  THIS FORCES
* AN EXIT TO CALLER OF APPEND CMD
* HNDLR (RATHER THAN TO CALLER OF
* FUNCTION HNDLR).  IN THIS LATER
* INSTANCE, EXECUTION ACTUALLY RTNS
* TO AFTRCMD ($A17D) LOCATED IN THE
* COMMAND PARSING & PROCESSING ROUTINES.


FMEXIT PHP
 STA RTNCODFM ;STORE RTN CODE IN FM PARM LIST.
 LDA #0 ;AVOID THAT INFAMOUS $48 BUG.
 STA STATUS
 JSR CPYFMWA ;COPY WORK AREA TO WORK BUFFER.
 PLP ;RETRIEVE STATUS OF SUCCESS OF
;OPERATION BACK OFF STK.
 LDX STKSAV ;ADJUST STK POINTER TO FORCE EXIT
 TXS ;TO CALLER EVEN IF SEVERAL
  RTS ;SUBRT'NS DEEPER THAN ORIG ENTRY.


*=================================
*   FILE MANAGER SCRATCH SPACE.
*        ($B397 - $B3A3)
*=================================

CURDIRTK DS 1 ;TRK# OF CURRENT DIRECTORY SEC.
CURDIRSC DS 1 ;SEC# OF CURRENT DIRECTORY SEC.
WABUFADR HEX 0000 ;UNUSED ($B399-$B39A).
STKSAV DS 1 ;SECOND STACK POINTER SAVE AREA.
;USED TO RESET THE STACK TO FORCE
;EXECUTION TO RTN TO A DESIRED
;ROUTINE.  (NORMALLY RETURNS TO
;AFTRFUNC ($A6AB) AFTR @ FUNCTION
;IS CALLED. HOWEVER, ALSO USED BY
;THE APPEND CMD 2 FORCE EXECUTION
;TO RTN TO AFTRCMD ($A17D).)
;P.S.  DON'T CONFUSE STKSAV WITH
;THE 1RST STACK POINTER SAVE AREA
;(STKSAVED, $AA59).
CURDIRNX DS 1 ;BYTE OFFSET OF FILE DESCRIPTION
;ENTRY INTO CURRENT DIREC SEC.
SCRNSRCH DS 1 ;- CATALOG SCRN LINE COUNTER.
;- DESCENDING CNTR 4 # OF SRCHS
;  DONE 2 LOCATE A MATCHING NAME
;  OR EMPTY SPACE FOR A NEW FILE
;  DESCRIP ENTRY IN DIRECTORY SEC
;  (SEARCH1 = 1, SEARCH2 = 0).
;- OFFSET OF DAT PR FROM START OF
;  A GIVEN T/S LIST.
TRK0YET DS 2 ;ASSIGNMENT FLAG = SIGNAL IF TRK0
;ENCOUNTERED YET (ONLY 1RST BYTE
;USED):
;   $00=TRK0 NOT ENCOUNTERED YET.
;   $01 = TRK0 ENCOUNTERED.
;(USED TO SEE IF ENTIRE DISK HAS
;BEEN SCANNED WHEN LOOKING 4 FREE
;SECS TO ASSIGN.)
LOKUNMSK = TRK0YET ;LOCK/UNLOCK MASK ($80/$00).
FRETKMSK HEX 0000FFFF ;4-BYTE MASK USED BY INIT FUNC'N
;TO FREE AN ENTIRE TRACK.


*=================================
*  CONVERSION TABLE FOR PRVOLNMB.
*       ($B3A4 - $B3A6)
*=================================

BASETEN HEX 010A64 ;10^0=0, 10^1=10, 10^2=100.


*=================================
* CHARACTER CODE FILE TYPE SYMBOLS
* USED BY THE CATALOG ROUTINE.
*       ($B3A7 - $B3AE)
*=================================

FTYPETBL ASC "TIABSRAB" ;TEXT, INTEGER, APPLESOFT, BINARY
;S-TYPE, R(ELOCATABLE)-TYPE,
;A-TYPE, B-TYPE.  THESE CODES ARE
;FREQUENTLY CHANGED BY HACKERS.)


*=================================
*  DISK VOLUME SPELLED BACKWARDS.
*        ($B3AF - $B3BA)
*=================================

DSKVOLUM ASC " EMULOV KSID" ;THESE CHRS ARE OFTEN CHANGED
;TO PERSONALIZE A CATALOG.


*=================================
* VOLUME TABLE OF CONTENTS (VTOC)
* BUFFER ($B3BB - $B4BA).
*=================================

VTOCBUFF DS 1 ;UNUSED ($B3BB).
;REFERENCE FOR START OF TABLE.
FIRDIRTK DS 1 ;TRK# OF 1RST DIRECTORY SECTOR.
FIRDIRSC DS 1 ;SEC# OF 1RST DIRECTORY SECTOR.
VERSION HEX 03 ;DOS VERSION RELEASE NUMBER.
 DS 2 ;UNUSED ($B3BF-$B3C0).
VOLUSED DS 1 ;DISK VOL# (NORMALLY, $FE).
 DS 32 ;UNUSED ($B3C2-$B3E1).
MXIN1TSL HEX 7A ;MAX # OF SECS THAT CAN BE LISTED
;IN A T/S LIST SEC ($7A, #122).
 DS 8 ;UNUSED ($B3E3-$B3EA).
NXTRKUSE DS 1 ;NEXT TRACK TO ASSIGN.
DRECTION DS 1 ;TRK ASGNMENT DIRECT'N (+1 OR -1)
 DS 2 ;UNUSED ($B3ED-$B3EE).
TKPERDSK HEX 23 ;TRKS/DISK (#35).
;AFTER DRIVE ADJUSTMENT, VALUE IN
;TKPERDSK CAN BE ALTERED 2 ENABLE
;THE USE OF AN EXTRA TRK ON DISK.
SECPERTK HEX 10 ;SECS/TRK ($10, #16, $00 --> $0F)
BYTPERSC HEX 0001 ;BYTES/SECTOR ($0100, #256).


*------------------------------------
*     TRACK/SECTOR MAPS IN VTOC.
*           ($B3F3 - $B47E)
*------------------------------------

* MAPS OF SECTOR USAGE ON EACH TRK.
* EACH TRK IS REPRESENTED BY FOUR
* BYTES.  THE BITS IN THESE BYTES
* DEFINE THE SECTOR USAGE BY THE
* FOLLOWING CONVENTION:
*          SET BIT = FREE SECTOR.
*        CLEAR BIT = USED SECTOR.
*        1RST BYTE:  FEDC BA98
*         2ND BYTE:  7654 3210
* (THE 3RD & 4TH BYTES ASSOCIATED
* WITH @ TRK ARE WASTED.  THESE BYTES
* ARE WASTED BECAUSE THEY ARE WRITTEN
* OVER BY DOS BUT NOT ACTUALLY USED
* FOR ANYTHING.  THERE4 THEY ARE NOT
* READILY AVAILABLE TO THE ASSEMBLY
* LANGUAGE PROGRAMMER THAT IS IN
* DESPERATE NEED OF AN AVAIABLE HOLE
* IN DOS.)

TRKMAP0 HEX 00000000 ;$B3F3: TRK0 (DOS IMAGE).
TRKMAP1 HEX 00000000 ;$B3F7: TRK1 (DOS IMAGE).
TRKMAP2 HEX 00000000 ;$B3FB: TRK2 (SECS 0 TO 4 USD FOR
;DOS IMAGE.  REST OF SECS ARE
;SET ASIDE BUT NOT USED BY DOS.
;THEY ARE FREE TO THE USER AFTER
;ALTERING TRKMAP2, USING RWTS
;DIRECTLY OR ALTERING THE BOOT.)
TRKMAP3 DS 4 ;$B3FF: TRK 3
TRKMAP4 DS 4 ;$B403: TRK4
TRKMAP5 DS 4 ;$B407: TRK5
TRKMAP6 DS 4 ;$B40B: TRK6
TRKMAP7 DS 4 ;$B40F: TRK7
TRKMAP8 DS 4 ;$B413: TRK8
TRKMAP9 DS 4 ;$B417: TRK9
TRKMAP10 DS 4 ;$B41B: TRK$0A
TRKMAP11 DS 4 ;$B41F: TRK$0B
TRKMAP12 DS 4 ;$B423: TRK$0C
TRKMAP13 DS 4 ;$B427: TRL$0D
TRKMAP14 DS 4 ;$B42B: TRK$0E
TRKMAP15 DS 4 ;$B42F: TRK$0F
TRKMAP16 DS 4 ;$B433: TRK $10
TRKMAP17 DS 4 ;$B437: TRK$11 (DIRECT/VTOC).
TRKMAP18 DS 4 ;$B43B: TRK$12
TRKMAP19 DS 4 ;$B43F: TRK$13
TRKMAP20 DS 4 ;$B443: TRK$14
TRKMAP21 DS 4 ;$B447: TRK$15
TRKMAP22 DS 4 ;$B44B: TRK$16
TRKMAP23 DS 4 ;$B44F: TRK$17
TRKMAP24 DS 4 ;$B453: TRK$18
TRKMAP25 DS 4 ;$B457: TRK$19
TRKMAP26 DS 4 ;$B45B: TRK$1A
TRKMAP27 DS 4 ;$B45F: TRK$1B
TRKMAP28 DS 4 ;$B463: TRK$1C
TRKMAP29 DS 4 ;$B467: TRK$1D
TRKMAP30 DS 4 ;$B46B: TRK$1E
TRKMAP31 DS 4 ;$B46F: TRK$1F
TRKMAP32 DS 4 ;$B473: TRK$20
TRKMAP33 DS 4 ;$B477: TRK$21
TRKMAP34 HEX FFFF0000 ;$B47B: TRK$22


*---------------------------------
*       UNUSED PART OF VTOC
*        ($B47F - $B4BA)
*---------------------------------

 DS 60 ;UNUSED ($B47F-$B4BA).


*=================================
*    DIRECTORY SECTOR BUFFER.
*       ($B4BB - $B5BA)
*=================================

DIRECBUF HEX 00 ;UNUSED-REFERENCE 4 START OF BUF.
DIRLNKTK DS 1 ;TRK OF NEXT DIRECTORY SECTOR.
DIRLNKSC DS 1 ;SECTOR OF NEXT DIRECTORY SECTOR.
 DS 8 ;UNUSED ($B4BC-$B4C5).


*---------------------------------
*    FILE DESCRIPTION ENTRIES.
*       ($B4C6 - $B5BA)
*---------------------------------

FIL1TSTK DS 1 ;FILE1: T/S LIST TRK ($B4C6)
FIL1TSSC DS 1 ;       T/S LIST SEC ($B4C7)
FIL1TYPE DS 1 ;       FILE TYPE ($B4C8)
FIL1NAME DS 30 ;       NAME ($B4C9-$B4E6)
FIL1SIZE DS 2 ;       SIZE ($B4E7-$B4E8)

FIL2TSTK DS 1 ;FILE2: T/S LIST TRK ($B4E9)
FIL2TSSC DS 1 ;       T/S LIST SEC ($B4EA)
FIL2TYPE DS 1 ;       TYPE ($B4EB)
FIL2NAME DS 30 ;       NAME ($B4EC-$B509)
FIL2SIZE DS 2 ;       SIZE ($B50A-$B50B)

FIL3TSTK DS 1 ;FILE3: T/S LIST TRK ($B50C)
FIL3TSSC DS 1 ;       T/S LIST SEC '$B50D)
FIL3TYPE DS 1 ;       TYPE ($B50E)
FIL3NAME DS 30 ;       NAME ($B50F-$B52C)
FIL3SIZE DS 2 ;       SIZE ($B52D-$B52E)

FIL4TSTK DS 1 ;FILE4: T/S LIST TRK ($B52F)
FIL4TSSC DS 1 ;       T/S LIST SEC ($B530)
FIL4TYPE DS 1 ;       TYPE ($B531)
FIL4NAME DS 30 ;       NAME ($B532-$B54F)
FIL4SIZE DS 2 ;       SIZE ($B550-$B551)

FIL5TSTK DS 1 ;FILE5: T/S LIST TRK ($B552)
FIL5TSSC DS 1 ;       T/S LIST SEC ($B553)
FIL5TYPE DS 1 ;       TYPE ($B554)
FIL5NAME DS 30 ;       NAME ($B555-$B572)
FIL5SIZE DS 2 ;       SIZE ($B573-$B574)

FIL6TSTK DS 1 ;FILE6: T/S LIST TRK ($B575)
FIL6TSSC DS 1 ;       T/S LIST SEC ($B576)
FIL6TYPE DS 1 ;       TYPE ($B577)
FIL6NAME DS 30 ;       NAME ($B578-$B595)
FIL6SIZE DS 2 ;       SIZE ($B596-$B597)

FIL7TSTK DS 1 ;FILE7: T/S LIST TRK ($B598)
FIL7TSSC DS 1 ;       T/S LIST SEC ($B599)
FIL7TYPE DS 1 ;       TYPE ($B59A)
FIL7NAME DS 30 ;       NAME ($B59B-$B5B8)
FIL7SIZE DS 2 ;       SIZE ($B5B9-$B5BA)


*=================================
*   FILE MANAGER PARAMETER LIST.
*        ($B5BB - $B5D0)
*=================================

OPCODEFM DS 1 ;FM OPERATION CODE.
SUBCODFM DS 1 ;FM OPERATION SUBCODE.
RECNMBFM DS 2 ;FM PARM LST VERSION OF RECORD #.
;(USUALLY 1 LESS THAN RECNMBWA.)
;(SEE DESCRIPTION OF THE RECORD
;NUMBER GIVEN IN THE WORK AREA
;LISTED BELOW.)
BYTOFFFM DS 2 ;BYTE OFFSET INTO RECORD.
LEN2RDWR DS 2 ;LENGTH TO READ OR LENGTH-1
;TO WRITE.  (INIT VAL & COUNTER).
;ALSO USED AS A TEMPORARY BUF TO
;TRANSFER ADDR & LENGTH BYTES TO
;ONEIOBUF BUF WHEN USING THE
;WRITE-ONE-BYTE AND READ-ONE-BYTE
;SUBFUNCTIONS.
CURIOBUF DS 2 ;ADDR OF CURRENT I/O BUFFER.
RTNCODFM DS 1 ;RETURN CODE.  (CONTRARY TO WHAT
;SOME ARTICLES SUGGEST, THE VALUE
;IN THIS BYTE IS ONLY RELEVANT IF
;AN ERROR OCCURS.)
 DS 1 ;UNUSED ($B5C6).
WRKBUFFM DS 2 ;PTS TO WORK BUF (IN DOS CHAIN).
TSBUFFM DS 2 ;PTS TO T/S LIST SEC BUF (CHAIN).
DATBUFFM DS 2 ;PTS TO DATA SECTOR BUF (CHAIN).
NXTNAME DS 2 ;PTS TO NEXT DOS NAME BUFFER IN
;CHAIN. (SET UP, BUT NOT USED.)
 DS 2 ;UNUSED ($B5CF-$B5D0).


FMPRMLST = OPCODEFM ;START OF FM PARAMETER LIST.

FIRDOSPG = OPCODEFM ;CONTAINS 1RST PAGE# OF DOS WHEN
;WRITING DOS IMAGE DURING INIT.

RECLENFM = RECNMBFM ;FM PARM LIST VERSION OF THE
;RECORD LENGTH.  (SEE DESCRIPTION
;OF RECORD LENGTH DESCRIBED IN
;THE WORK AREA LISTING BELOW.)
RENAMBUF = RECLENFM ;PTS 2 BUFFER CONTAINING NEW FILE
;NAME.  (USED IN RENAME CMD.)
VOLFM = BYTOFFFM ;VOLUME# WANTED.
DRVFM = BYTOFFFM+1 ;DRIVE# WANTED.

SLOTFM = LEN2RDWR ;SLOT NUMBER.
FILTYPFM = LEN2RDWR+1 ;FILE TYPE CODE (INCLUDING THE
;LOCKED/UNLOCKED STATUS).
FNAMBUFM = CURIOBUF ;FILE NAME ADDRESS.
ONEIOBUF = CURIOBUF ;A ONE-BYTE I/O BUFFER.


*=================================
*     FILE MANAGER WORK AREA.
*       ($B5D1 - $B5FF)
* (DON'T CONFUSE WITH THE VARIOUS
* WORK BUFFERS CONTAINED IN THE
* CHAIN OF DOS BUFFERS.)
*=================================

FMWKAREA DS 1 ;SIMPLY USED FOR REFERENCE POINT.

FIRSTSTK = FMWKAREA ;TRK# OF 1RST T/S LIST SEC.
FIRTSSEC DS 1 ;SEC # OF 1RST T/S LIST SEC.
CURTSTRK DS 1 ;TRK# OF CURRENT T/S LIST SEC.
CURTSSEC DS 1 ;SEC# OF CURRENT T/S LIST SEC.
UPDATFLG DS 1 ;FLAG TO UPDATE DIFFERENT TYPES
;OF SECTORS:
; $02=LAST OPERATION WAS A WRITE.
; $20=VTOC NEEDS UPDATING.
; $40=DATA SEC NEEDS UPDATING.
; $80=T/S LST SEC NEEDS UPDATING.
CURDATRK DS 1 ;TRK# OF CURRENT DATA SECTOR.
CURDATSC DS 1 ;SEC# OF CURRENT DATA SECTOR.
SECNXD1R DS 1 ;OFFSET OF FILE DESCRIPTION FROM
;THE VERY FIRST DIRECTORY SEC.
BYTNXD1R DS 1 ;OFFSET OF FILE DESCRIPTION INTO
;THE CURRENT DIRECTORY SEC.
MXSCURTS DS 2 ;MAXIMUM # OF SECS THAT CAN BE
;LISTED IN A T/S LIST.
RELFIRST DS 2 ;RELATIVE SEC # (IN RELATION TO
;THE ENTIRE FILE) OF THE FIRST
;DATA SEC THAT IS (OR CAN BE)
;LISTED IN THE CURRENT T/S LIST.
;(POSSIBLE VALS ARE:$0000, $007A,
;2*$007A, 3*$007A OR 4*$007A.)
RELASTP1 DS 2 ;ONE GREATER THAN THE MAXIMUM
;RELATIVE SEC# (IN RELATION 2 THE
;ENTIRE FILE) OF THE LAST DAT SEC
;THAT CAN POSSIBLY BE DESCRIBED
;IN THE CURRENT T/S LIST.
;(POSSIBLE VALUES ARE: $007A,
;2*$007A, 3*$007A, 4*$007A AND
;5*$007A.)
RELPREV DS 2 ;RELATIVE SEC# (IN RELATION 2 THE
;ENTIRE FILE) OF THE LAST DAT SEC
;THAT WAS READ OR WRITTEN.
;(POSSIBLE VAL ARE: $0000, $007A,
;2*$007A, 3*$007A OR 4*$007A.)
SECSIZWA HEX 0001 ;BYTES/SECTOR (#256, $00-$FF).

* --- FILE POINTER ---
*      (3 BYTES)
FILPTSEC DS 2 ;SECTOR OFFSET OF PTR (2 BYTES).
FILPTBYT DS 1 ;BYTE OFFSET PORTION OF POINTER.

WASTEBYT DS 1 ;WEIRD FLG USED BY THE APPEND CMD
;(VIA RSETPTRS, $B6B3) WHEN
;BACKING UP THE FILE POINTER AND
;TESTED (IN APNDPTCH, $B692)
;WHENEVER AN OUT-OF-DATA ERROR IS
;ENCOUNTERED.
RECLENWA DS 2 ;RECORD LENGTH.
RECNMBWA DS 2 ;CURRENT RECORD NUMBER.
BYTOFFWA DS 2 ;CURRENT BYTE OFFSET INTO RECORD.
;- RANDOM ACCESS TXT FILES HAVE A
;  FIXED RECORD LNGTH ASSIGNED BY
;  THE USER.
;- SEQUENTIAL TEXT AND APPLESOFT
;  FILES HAVE A RECORD LENGTH OF
;  ONE.
;- DURING A LOAD OR BLOAD, APPLE-
;  SOFT OR BINARY FILES ARE
;  CONSIDERED TO BE COMPOSED OF A
;  COLLECTION OF ONE-BYTE LONG
;  RECORDS.
;- WHEN SAVING OR BSAVING HOWEVER
;  THESE FILES ARE TREATED AS IF
;  THEY CONSIST OF A SINGLE VERY
;  LONG RECORD.
FILENSEC DS 2 ;FILE LENGTH IN SECTORS.
ASIGNSEC DS 1 ;NEXT SECTOR TO ASSIGN.
ASIGNTRK DS 1 ;NEXT TRK TO ASSIGN.
ASIGNMAP DS 4 ;4-BYTE MAP OF SEC USAGE ON THE
;TRK BEING ASSIGNED.
FILTYPWA DS 1 ;FILE TYPE CODE (INCLUDING THE
;LOCKED OR UNLOCKED STATUS).
SLOT16WA DS 1 ;SLOT*16.
DRVWA DS 1 ;DRIVE NUMBER.
VOLWA DS 1 ;1'S COMPLEMENT OF VOLUME NUMBER.
TRKWA DS 1 ;TRACK NUMBER.
 HEX 0000000000 ;UNUSED ($B5FB-$B5FF).


*=================================
*   IMAGE OF BOOT1 ($B600-$B6FF)
*=================================

* - STORED ON TRK0/SEC0.
* - READ IN AT $800-$8FF BY DISK CONTROLLER ROM (BOOT0).
* - EXECUTION BEGINS AT $0801 & USES THE CONTROLLER'S READ-
*   SECTOR SUBROUTINE (BTRDSEC, $CS00, WHERE S = SLOT # OF
*   CARD) TO READ IN TRK0/SEC9 DOWN TO TRK0/SEC1 (THAT IS,
*   $BFFF ----> $B600).

* NOTE:  IN ORDER TO GENERATE AN ACCURATE SYMBOL TABLE THAT
* CAN BE APPLIED TO BOTH THE FORMATTED AND LINEAR DIS-
* ASSEMBLIES, AND BECAUSE DIFFERENT ASSEMBLERS VARY IN
* THEIR ABILITIES TO ACCEPT CERTAIN OBJECT VALUES OR RE-ORG
* DURING ASSEMBLY, THE FOLLOWING SPECIAL LABEL SYSTEM HAS
* BEEN CREATED:
*  IMAGE LBL/ADR   EXECUTION LBL/ADR       COMMENTS
* ---------------  -----------------  --------------------
* SEC2RDB6, $B600  SEC2RDB08, $800    ;DEFINES # OF SECS 2
*                                     ;BE READ IN BY BOOT0
* BT1EXCB6, $B601  BT1EXC08, $801     ;START BT1 EXECUTION
*                                     ;BOOT0 JMPS TO HERE.
* SKPRELB6, $B61F  SKPREL08, $81F     ;TARGET LBL 4 BRNCH.
* PRP4B2B6, $B639  PRP4B208, $839     ;TARGET LBL 4 BRNCH.
*   IMG8FD, $B6FD  BT1LDADR, $8FD     ;BOOT1 LOAD ADDRESS.
*                                     ;VARIES FROM $B600 2
*                                     ;$BF00.  EVENTUALLY
*                                     ;PTS 2 START BOOT2
*                                     ;($B700).
*   IMG8FF, $B6FF  BT1PG2RD, $8FF     ;CONTAINS # OF SECS
*                                     ;TO READ IN WHEN
*                                     ;EXECUTING BOOT1.
*                                     ;ALSO DOUBLES AS
*                                     ;LOGICAL SEC #.
*                                     ;VARIES FROM:
*                                    ;$09 --> $00 --> $FF.
* AS INDICATED ABOVE, SEC2RD08 ($800) DEFINES # OF SECS
* TO BE READ IN BY BOOT0.  THIS VALUE IS NORMALLY $01
* (MEANING READ ONLY SEC0 OF TRK0).  HOWEVER, YOU CAN ZAP
* TRK0/SEC0/OFFSET0 WITH A LARGER VALUE ($01 TO $10) TO
* READ IN MORE SECS FROM TRK0.  ALSO NOTE THAT MOST
* REFERENCES SAY THAT SEC2RD08 NORMALLY CONTAINS A "$00"
* (RATHER THAN A "$01").  BECAUSE THE TEST AT $CS56 USES
* THE CARRY, EITHER VAL WILL CAUSE ONLY 1 SEC 2 BE READ IN
* HOWEVER, "$01" IS THE VALUE USED BY DOS.  (CONFUSION MAY
* STEM FROM THE FACT THAT APPLESOFT LATER STORES A $00 IN
* $800.)

SEC2RDB6 HEX 01 ;IMAGE OF SEC2RD08.  DENOTES # OF
;SECS TO BE READ FROM TRK0 DURING
;BOOT0.

BT1EXCB6 LDA PT2BTBUF+1 ;IMAGE OF BT1EXC08. GET NEXT PAGE
;TO BE READ IN.
 CMP #$09 ;IS IT PAGE 9 (IE. 1RST PAGE READ
;BY BOOT1)?
 BNE SKPRELB6 ;NO - ALREADY USED BY BOOT1 TO
;READ PAGE9, SO SKIP POINTER
;INITIALIZATION GIVEN BELOW.

* INITIALIZE THE POINTER (PTR2RDSC)
* TO POINT AT BOOT0'S READ SECTOR
* SUBROUTINE (BTRDSEC, $CS5C;
* WHERE S=SLOT#, NORMALLY $C65C).

 LDA SLT16ZPG ;(A) = SLOT*16 FROM ZERO PAGE.
 LSR ;DIVIDE BY 16.
 LSR
 LSR
 LSR
 ORA #$C0 ;MERGE WITH $C0 TO GET $CS, WHERE
;S=SLOT#.
 STA PTR2RDSC+1 ;STORE HI BYTE OF CONTROLLER'S
;READ-SECTOR SUBROUTINE ADDR.
 LDA #<BTRDSEC ;GET LOW BYTE OF SUBRTN ADR.
 STA PTR2RDSC ;(LOW BYTE IS A CONSTANT (#$5C) &
;IS THERE4 NOT VARIABLE WITH SLOT
;USED (AS IS HI BYTE).)


* READ IN 9 SECTORS REPRESENTED BY
* TRK0/SEC9 DOWN TO TRK0/SEC1 INTO
* $BFFF TO $B600.  NOTE THAT THE
* SECS ARE READ IN FROM HIGHER TO
* LOWER MEMORY. THESE SECS CONTAIN
* THE IMAGE OF BOOT1, PART OF THE
* FILE MANAGER AND ALMOST ALL OF
* RWTS & ITS ASSOCIATED ROUTINES.


* CALCULATE THE TARGET ADDR FOR
* THE FIRST SECTOR TO BE READ IN.

 CLC
 LDA BT1LDADR+1 ;CONTAINS $B6 ON 48K SLAVE.
 ADC BT1PG2RD ;CONTAINS #09 ON 48K SLAVE.
 STA BT1LDADR+1 ;(A) = $BF ON 48K SLAVE.

* DETERMINE # OF PAGES (SECS) LEFT
* 2 READ, PHYSICAL SECTOR# & TARGET
* ADDRESS.  THEN, GO READ IN THE
* NEXT SECTOR.

SKPRELB6 LDX BT1PG2RD ;IMAGE OF SKRPREL08 ($81F).
;(X)=PAGES LEFT 2 READ (MINUS 1).
;(ALSO DOUBLES AS LOGICAL SEC#.
;VARIES FROM $09-->$FF).
 BMI PRP4B2B6 ;WHEN (X) = #$FF, THEN WE HAVE
;READ ALL THE SECS IN, SO GO XIT.
 LDA PHYSECP8-$AE00,X ;EQUIVALENT 2 "LDA $84D,X".
;CONVERT LOGICAL SEC# 2 PHYS SEC#
 STA BOOTSEC ;STORE PHYSICAL SEC# IN PAGE0.
 DEC BT1PG2RD ;REDUCE PAGES (SECS) LEFT TO READ
;FOR NEXT TIME AROUND.
 LDA BT1LDADR+1 ;POINT BUFFER POINTER AT TARGET
 STA PT2BTBUF+1  ;ADR.  (VARIES FROM $BF TO $B6
;ON 48K SLAVE).
 DEC BT1LDADR+1 ;REDUCE HI BYTE OF I/O BUF FOR
;NEXT TIME AROUND.  (VARIES FROM
;$BF TO $B5 ON 48K SLAVE.)
 LDX SLT16ZPG ;SET (X) = SLOT*16.
 JMP (PTR2RDSC) ;EQUIVALENT TO "JMP ($8FD)" OR
;"JMP $CS5C" TO GO READ IN THE
;NEXT SECTOR.
;************ NOTE **************
;* GOES TO BT1EXC08 ($801) AFTER*
;* EACH SECTOR IS READ IN.      *
;* (REMEMBER, BT1EXCB6 IS A     *
;* CARBON COPY OF BT1EXC08.)    *
;********************************


* PREPARE FOR BOOT2.

PRP4B2B6 INC BT1LDADR+1 ;IMAGE OF PR4B208 ($839).
;POINT AT THE LOAD ADR FOR BOOT2.
 INC BT1LDADR+1 ;(AFTR INCS, = $B7 ON 48K SLAVE).

* SET FULL SCREEN TEXT & DESIGNATE
* KEYBOARD & SCREEN AS I/O DEVICES.

 JSR SETKBD ;SIMULATE IN#0 (SET KSW: KEYIN).
 JSR SETVID ;SIMULATE PR#0 (SET CSW: COUT1).
 JSR INIT ;SIMULATE A "TEXT" STATEMENT.
  LDX SLT16ZPG ;(X) = SLOT*16.

* ------ GO TO BOOT2 ------ *

 JMP (BT1LDADR) ;JMP 2 BOOT2 ($B700 ON 48K SLAVE)


*=================================
*  TABLE OF PHYSICAL SECTOR #'S.
*         ($B64D - $B65C)
* - AN IMAGE OF THIS TABLE IS
*   HOUSED AT $84D DURING THE BOOT.
*=================================

;CORRESPONDING LOGICAL SECTOR #
PHYSECP8 HEX 00 ;             $00
 HEX 0D ;             $01
 HEX 0B ;             $02
 HEX 09 ;             $03
 HEX 07 ;             $04
 HEX 05 ;             $05
 HEX 03 ;             $06
 HEX 01 ;             $07
 HEX 0E ;             $08
 HEX 0C ;             $09
 HEX 0A ;             $0A
 HEX 08 ;             $0B
 HEX 06 ;             $0C
 HEX 04 ;             $0D
 HEX 02 ;             $0E
 HEX 0F ;             $0F
�E