💾 Archived View for spam.works › mirrors › textfiles › apple › ANATOMY › t.dos.ac58.aff6.txt captured on 2023-06-16 at 21:11:58.

View Raw

More Information

-=-=-=-=-=-=-



FNREAD LDA SUBCODFM ;CHK IF SUBCODE IS LEGAL.
 CMP #5 ;(MUST BE < = 5.)
 BCS TOERRSUB ;RANGE ERROR - ILLEGAL SUBCODE.

 ASL ;SUBCODE*2, CAUSE 2 BYTES/ADR.
 TAX ;INDEX TABLE OF SUBFUNCTION ADRS.
 LDA RDSUBTBL+1,X;GET ADDR (MINUS 1) OF SUBFUNCT
 PHA ;ENTRY POINT & PUT IT ON THE STK
 LDA RDSUBTBL,X ;(HI BYTE FIRST). THEN DO A STACK
 PHA ;JUMP TO EXECUTE THE GIVEN READ
 RTS ;SUBFUNCTION.

TOERRSUB JMP RNGERRSB ;GO HANDLE RANGE ERROR.

TOFILOCK JMP FILELOKD ;GO HANDLE LOCKED FILE ERROR.




FNWRITE LDA FILTYPWA ;CHK IF FILE IS LOCKED.
 BMI TOFILOCK ;ERROR - CAN'T WRITE 2 LCKD FILE.

 LDA SUBCODFM ;CHK IF SUBCODE IS LEGAL.
 CMP #5 ;(MUST BE < = 5.)
 BCS TOERRSUB ;ERROR - ILLEGAL SUBCODE.

 ASL ;SUBCODE*2, CAUSE 2 BYTES/ADR.
 TAX ;INDEX TABLE OF SUBFUNCTION ADRS.
 LDA WRSUBTBL+1,X;GET ADR (MINUS 1) OF SUBFUNCT
 PHA ;ENTRY POINT & STICK ON THE STACK
 LDA WRSUBTBL,X ;(HI BYTE FIRST). THEN DO A STACK
 PHA  ;JUMP TO EXECUTE THE GIVEN WRITE
 RTS ;SUBFUNCTION.




PSNRDONE JSR CALCFPTR ;USING R-, L- & B-PARAMETERS,CALC
;THE POS'N OF FILE PTR WANTED.




READONE JSR RDDATA ;GET DATA BYTE FROM DATA SEC BUF.
;(IF DESIRED DATA SECTOR IS NOT
;ALREADY IN MEMORY, THEN READ IT
;IN. HOWEVER, 1RST CHK IF PRESENT
;INFO IN DATA SEC NEEDS TO BE
;UPDATED SO DON'T OVERWRITE DATA
;IN BUF & LOOSE INFO.)

 STA ONEIOBUF ;PUT BYTE READ IN THE 1-BYTE BUF
;CONTAINED IN THE FM PARM LIST.
 JMP GOODFMXT ;EXIT THE FILE MGR.  EVENTUALLY
;RTNS TO AFTRFUNC ($A6AB) LOCATED
;IN THE FMDRIVER ROUTINE ($A6A8).




PSNRDRNG JSR CALCFPTR ;USING R-, L- & B-PARMS, CALC THE
;POS'N OF FILE POINTER WANTED.




READRNG JSR DECRWLEN ;DECREMENT THE # OF BYTES 2 READ.
;(DONE READING WHEN LEN2RDWR=0.)
 JSR RDDATA ;GET DATA BYTE FROM DATA SEC BUF.
;(IF DESIRED DATA SECTOR IS NOT
;ALREADY IN MEMORY, THEN READ IT
;IN. HOWEVER, 1RST CHK IF PRESENT
;INFO IN DATA SEC NEEDS TO BE
;UPDATED SO DON'T OVERWRITE DATA
;IN BUF & LOOSE INFO.)
 PHA ;SAVE SINGLE BYTE READ ON STK.
 JSR INCIOBUF ;INC THE CUR'NT TARGET RAM MEMORY
;LOCATION (BYTRNG) & POINT A4L/H
;AT TARGET LOCATION IN I/O BUF.
 LDY #0 ;INITIALIZE (Y) INDEX.
 PLA ;RETRIEVE BYTE READ.
 STA (A4L),Y ;PUT SINGLE BYTE READ INTO THE
;TARGET MEMORY LOCATION.
 JMP READRNG ;GO BK TO READ NEXT BYTE OF DATA.




RDDATA JSR NXTDATRD ;CHK IF DATA SEC WE WANT TO READ
;IS ALREADY IN MEMORY.  IF NOT,
;READ DATA SEC INTO DATA SEC BUF.
;HOWEVER, 1RST CHK IF DAT SEC BUF
;NEEDS UPDATING SO DON'T OVRWRITE
;DATA SEC BUF & LOSE INFO.
 BCS NDATERR ;BRANCH IF RAN OUT OF DATA SECS
;WHILE READING.
 LDA (A4L),Y ;GET SINGLE BYTE FRM DATA SEC BUF
 PHA ;SAVE IT ON STK.
 JSR INCREC ;EITHER INC REC # OR BYTE OFFSET
;INTO RECORD.
 JSR INCFILPT ;INC BYTE OFFSET INTO CURRENT
;DATA SEC OR, IF AT END OF SEC,
;INC THE SECTOR OFFSET INTO THE
;ENTIRE FILE.
 PLA ;GET DATA BYTE RD (BACK OFF STK).
 RTS

NDATERR JMP ENDOFDAT ;RAN OUT OF DATA WHILE READING.




PSNWRONE JSR CALCFPTR ;USING R-, L- & B-PARMS, CALC
;POS'N OF FILE POINTER WANTED.




WRITEONE LDA ONEIOBUF ;GET BYTE TO WRITE FROM ONE-BYTE
;BUFFER IN FM PARAMETER LIST.
 JSR WRTDATA ;STORE DATA TO WRITE IN THE DATA
;SECTOR BUFFER.  IF DATA SEC BUF
;IS FULL, THEN WRITE IT TO DISK
;AND UPDATE T/S LIST BUF.
 JMP GOODFMXT ;EXIT FILE MANAGER.  EVENTUALLY
;RTNS TO AFTRFUNC ($A6AB) LOCATED
;IN THE FMDRIVER ROUTINE ($A6A8).




PSNWRRNG JSR CALCFPTR ;USING R-, L- & B-PARMS, CALC
;POS'N OF FILE POINTER WANTED.




WRITERNG JSR INCIOBUF ;POINT A4L/H AT SOURCE BYTE.
 LDY #0 ;SET (Y) TO INDEX SOURCE BUF.
 LDA (A4L),Y ;GET BYTE TO WRITE.
 JSR WRTDATA ;PUT DATA BYTE IN DATA SEC BUF.
;(WRITE DATA SEC BUF TO DISK IF
;NECESSARY.  )
 JSR DECRWLEN ;CHECK IF DONE WRITING.  IF NOT,
;REDUCE COUNTER FOR # OF BYTES
;LEFT TO WRITE.
 JMP WRITERNG ;GO BACK TO WRITE NEXT DATA BYTE.




WRTDATA PHA ;SAVE BYTE TO WRITE ON STK.
 JSR NXTDATRD ;READ NXT DATA SEC BUF IF NEEDED.
 PLA ;GET DATA BYTE TO WRITE OFF STK.
 STA (A4L),Y ;PUT DATA BYTE IN DATA SEC BUF.
 LDA #%01000000 ;SET BIT6 TO SIGNAL DATA SEC BUF
 ORA UPDATFLG ;HAS CHANGED & THEREFOR, THE DISK
 STA UPDATFLG ;REQUIRES UPDATING.
 JSR INCREC ;EITHER INC THE RECORD NUMBER OR
;INC THE BYTE OFFSET INTO RECORD.
 JMP INCFILPT ;INC THE BYTE OFFSET INTO THE
;CURRENT DATA SECTOR.  IF AT THE
;END OF SECTOR, INC THE OFFSET
;INTO THE ENTIRE FILE INSTEAD.




FNLOCK LDA #$80 ;SET HI BIT IN LOCK/UNLOCK MASK.
 STA LOKUNMSK
 BNE COMNLOCK ;ALWAYS.


FNUNLOCK LDA #0 ;MAKE SURE HI BIT CLR IN LOKUNMSK
 STA LOKUNMSK

COMNLOCK JSR COMNOPEN ;LOCATE THE FILE WITH THE SAME
;NAME & OPEN IT.
 LDX CURDIRNX ;(X) = INDEX TO FILE DESCRIPTION
;ENTRY IN THE DIRECTORY SEC BUF.
 LDA FIL1TYPE,X ;GET OLD FILE TYPE.
 AND #$7F ;SHUT HI BIT OFF.
 ORA LOKUNMSK ;MERGE WITH LOKUNMSK 2 SET OR CLR
;(LOCK OR UNLOCK) HI BIT.
 STA FIL1TYPE,X ;STICK MODIFIED FILE TYPE BACK IN
;FILE DESCRIP PART OF DIR SEC BUF
 JSR WRDIRECT ;WRITE UPDATED DIREC SEC TO DISK.

TOOKFMXT JMP GOODFMXT ;EXIT FM CLEANLY. EVENTUALLY RTNS
;TO AFTRFUNC ($A6AB) LOCATED IN
;THE FMDRIVER ROUTINE ($A6A8).




FNPOSN JSR CALCFPTR ;USE R-, B- & L-PARAMETERS 2 CALC
;POSITION OF FILE POINTER WANTED.
 JMP GOODFMXT ;EXIT FILE MANAGER CLEANLY.
;EVENTUALLY RETURNS TO AFTRFUNC
;($A6AB) LOCATED IN THE FMDRIVER
;ROUTINE ($A6A8).




FNVERIFY JSR COMNOPEN ;LOCATE FILE WITH SAME NAME
;& OPEN IT.
VRFYREAD JSR NXTDATRD ;READ NEXT DATA SEC IN.  (ASSUME
;DATA SEC WE WANT NOT PRESENTLY
;IN MEMORY.)
 BCS TOOKFMXT ;END OF FILE DETECTED - EXIT FM.
;EVENTUALLT RETURNS TO AFTRFUNC
;($A6AB) LOCATED IN THE FMDRIVER
;ROUTINE ($A6A8).
 INC FILPTSEC ;KICK UP FILE POINTER POS'N
 BNE VRFYREAD ;AND THEN GO BACK TO READ NEXT
 INC FILPTSEC+1 ;DATA SECTOR UNTIL ENCOUNTER END
 JMP VRFYREAD ;OF FILE MARKER.




FNDELETE JSR COMNOPEN ;LOCATE FILE WITH SAME NAME AND
;THEN OPEN IT.
 LDX CURDIRNX ;(X) = INDEX TO FILE DESCRIPTION
;IN DIRECTORY SECTOR BUFFER.
 LDA FIL1TYPE,X ;GET FILE TYPE FROM DIR SEC BUF.
 BPL ALTRNTRY ;BRANCH IF FILE NOT LOCKED.
 JMP FILELOKD ;ERR - CAN'T DELETE A LOCKED FILE
;SO GO HANDLE ERR & EXIT.



ALTRNTRY LDX CURDIRNX ;(X) = INDEX TO FILE DESCRIPTION
;ENTRY IN DIRECTORY SEC BUFFER.
 LDA FIL1TSTK,X ;GET TRK # OF 1RST T/S LIST SEC.
 STA FIRSTSTK ;COPY IT IN2 WORK AREA & LAST CHR
 STA FIL1NAME+29,X ;POS'N OF FILE NAME FLD DSCRP
 LDA #$FF ;REPLACE ORIG TRK # OF T/S LIST
 STA FIL1TSTK,X ;WITH $FF TO SIGNAL FILE DELETED.
 LDY FIL1TSSC,X ;PUT SEC # OF FILE'S 1RST T/S LST
 STY FIRTSSEC ;IN THE WORK AREA.
 JSR WRDIRECT ;WRITE MODIFIED DIREC SEC 2 DISK.



 CLC ;(C)=0, SIGNAL 1RST T/S LIST SEC.
RDTS4DEL JSR READTS ;GO READ IN T/S LIST.
 BCS DONEDEL ;BRNCH IF JUST READ LAST T/S LIST
;SEC ASSOCIATED WITH THIS FILE.
 JSR SELTSBUF ;POINT A4L/H AT T/S LIST SECTOR
;BUFFER.(GET ADR FRM FM PRM LST.)



 LDY #12 ;1RST DATA SEC PAIR LISTED IS
;OFFSET 12 BYTES FROM START OF
;T/S LIST BUFFER.
DELFREE STY CURDIRNX ;SET (Y) = INDEX TO THE DATA PAIR
;LISTED IN THE T/S LIST BUFFER.
 LDA (A4L),Y ;GET TRK # OF DATA SEC.
 BMI BYPASDEL ;NEG TRK # ILLEGAL. (CAN USE AS
;A PROTECTION SCHEME.)
 BEQ BYPASDEL ;TRK # OF 0 = NO MORE DATA SECS
;LISTED IN CURRENT T/S LIST.
 PHA ;SAVE TRK # OF DATA SEC ON STK.
 INY ;GET SEC # OF DATA SEC.
 LDA (A4L),Y
 TAY ;CONDITION (Y)=SEC & (A)=TRK FOR
 PLA ;ENTRY IN2 ROUT'N 2 FREE UP SECS.
 JSR FREESEC ;FREE UP SECTOR FROM DELETED FILE
BYPASDEL LDY CURDIRNX ;SET (Y) 2 INDEX START DATA PAIR.
 INY ;KICK UP (Y) 2 PT AT NXT DATA PR.
 INY
 BNE DELFREE ;IF (Y) < > 0, THEN NEVER RAN OFF
;END OF T/S LIST SEC BUF YET, SO
;GO CHK IF MORE DATA PRS TO DO.



 LDA CURTSTRK ;TRK # OF CURRENT T/S LIST SEC.
 LDY CURTSSEC ;SEC # OF CURRENT T/S LIST SEC.
 JSR FREESEC ;GO FREE UP THE T/S LIST SEC.
 SEC
 BCS RDTS4DEL ;ALWAYS.



DONEDEL JSR WRITVTOC ;WRITE UPDATED VTOC TO DISK.
 JMP GOODFMXT ;GO EXIT FM CLEANLY.  EVENTUALLY
;RTNS TO AFTRFUNC ($A6AB) LOCATED
;IN THE FMDRIVER ROUTINE ($A6A8).




FREESEC SEC ;SET CARRY SO FREE UP PRESENT SEC
;WHEN START ROTATING ASSIGNMENT
;MAP.
 JSR SUB2FREE ;ADJUST ASSIGNMENT MAP TO FREE UP
;SEC BY SETTING BIT CORRESPONDING
;TO SEC #.  NEXT, MERGE ASIGNMAP
;WITH THE APPROP BIT MAP IN VTOC.
 LDA #0 ;ZERO OUT ASIGNSEC, ASIGNTRK
 LDX #5  ;& ASIGNMAP (6 BYTES) IN WRK AREA
RELEASEC STA ASIGNSEC,X
 DEX
 BPL RELEASEC
 RTS




FNCATLOG JSR ZWRKAREA ;INITIALISE THE FM WORK AREA.
 LDA #$FF ;ALLOW ANY VOL TO BE CATALOGED.
 STA VOLWA ;(WHEN RWTS LATER ENTERED, THIS
;VALUE IS EORED WITH  #$FF TO
;SIMULATED A COMPLEMENTED VOL #
;OF 0 (IE. #$FF EOR #$FF = #$00).
;AFTER RWTS READS THE ADDRESS
;CHECKSUM, IT CHECKS 2 SEE IF THE
;CORRECT VOL # WAS READ OFF THE
;DISK.  IF THE COMPLEMENT OF THE
;VOL # IS 0, OR IF IT MATCHES THE
;VOL # READ OFF DSK, EXECUTION
;PROCEEDS AS IF THE CORRECT VOL
;WAS FOUND.)
 JSR READVTOC ;READ VOLUME TABLE OF CONTENTS.
 LDA #22 ;SET INDEX TO ALLOW 22 SCREEN
 STA SCRNSRCH ;LINES BETWEEN PAUSES.


 JSR CRCATLOG ;PRT <CR> & TEST IF PAUSE NEEDED.
 JSR CRCATLOG ;DO IT AGAIN.
 LDX #11 ;12 CHARS TO PRT (11 TO 0).
PRDSKVOL LDA DSKVOLUM,X ;GET CHAR OF REVERSE STRING.
 JSR COUT ;PRINT CHAR.
 DEX
 BPL PRDSKVOL ;MORE CHARS IN STRING.
 STX A5L+1 ;NONSENSE INSTRUCTION (CAUSE THE
;HI BYTE IS NOT USED IN THE
;PRVOLNMB ROUTINE ($AE42).)
 LDA IBSMOD ;GET VOL# FOUND (FROM RWTS'S IOB)
 STA A5L ;AND PUT IT IN A5L.
 JSR PRVOLNMB ;GO PRINT VOL # (BUGGY ROUTINE).
 JSR CRCATLOG ;PRT <CR> & TEST IF PAUSE NEEDED.
 JSR CRCATLOG ;DO IT AGAIN.



 CLC ;(C)=0, READ 1RST DIR SEC.
;(C)=1, READ NEXT DIR SEC.
RDDIRSEC JSR RDDIRECT ;GO READ DIRECTORY SECTOR.
 BCS TOFMXTOK ;RAN OUT OF DIR SECS SO GO EXIT.
 LDX #0 ;INITIALIZE INDEX INTO DIR SEC.



DESCRPTK STX CURDIRNX ;SAVE NDEX TO ENTRIES IN DIR SEC.
 LDA FIL1TSTK,X ;TRK # OF FILE'S 1RST T/S LIST
;(FROM THE FILE'S DESCRIPTION IN
;THE DIRECTORY SECTOR).
 BEQ TOFMXTOK ;TRK # = 0, SO NO MORE ENTRIES IN
;CURRENT DIRECTORY BUFFER.
 BMI NXDESCRP ;TRK#=$FF=DELETED FILE SO SKIP IT



 LDY #" " ;DEFAULT (Y)=<SPC> N CASE NOT LCK
 LDA FIL1TYPE,X ;GET FILE TYPE.
 BPL PRLOCODE ;HI BIT CLR SO FILE UNLOCKED.
 LDY #"*" ;RESET (Y) = LOCKED SYMBOL.
PRLOCODE TYA ;EITHER PRINT "*" OR <SPC>.
 JSR COUT



 LDA FIL1TYPE,X ;GET FILE TYPE AGAIN & MAKE SURE
 AND #$7F ;HI BYTE IS OFF SO CAN INDEX TBL
;THAT CONTAINS SYMBOLS FOR TYPES.
 LDY #7 ;SET (Y) TO INDICATE 7 RELEVANT
;BITS AFTER SHIFT OUT HI BIT.
 ASL ;THROW AWAY HI BIT.
CHRTYPIX ASL  ;SHIFT REST OF BITS UNTIL HI SET.
 BCS PRTFTYPE ;# OF SHIFTS 2 SET (C) DESIGNATES
;INDEX TO TYPE CHAR TABLE.
 DEY ;REDUCE COUNT OF SHIFTS.
 BNE CHRTYPIX ;NO SET BITS ENCOUNTERED YET, SO
;GO BACK TO DO MORE SHIFTS.
PRTFTYPE LDA FTYPETBL,Y ;GOT A SET BIT SO NOW GET CHAR
;FROM TABLE OF TYPE SYMBOLS.
 JSR COUT ;PRINT TYPE SYMBOL.
 LDA #" " ;PRINT TRAILING <SPC>.
 JSR COUT



 LDA FIL1SIZE,X ;GET LOW & HI BYTES OF FILE SIZE
 STA A5L ;(IN SECTORS) FROM FILE DESCRIP
 LDA FIL1SIZE+1,X ;IN CUR DIR SEC & STICK THEM IN
 STA A5L+1 ;IN A5L/H.
 JSR PRVOLNMB ;PRINT FILE SIZE.
;*** NOTE *** - ROUTINE IS BUGGY.
;(DOESN'T USE HI BYTE, SO FILES
;> 255 SECS LONG ARE EXPRESSED
;AS 256 MOD.)
 LDA #" " ;PRINT <SPC> AFTER SIZE.
 JSR COUT



 INX ;KICK (X) UP CAUSE NAME STARTS AT
 INX ;4TH BYTE FROM START OF FILE
 INX ;DESCRIPTION ENTRY.
 LDY #29 ;COUNTER FOR 30 CHRS/NAME (0-29).
PRTFNAME LDA FIL1TSTK,X ;GET CHR 4 FILE NAME & PRINT IT.
 JSR COUT ;(P.S.  BECAUSE THE OUTPUT HOOK
;STILL PTS TO DOS'S OUTPUT HNDLR,
;CTRL-D AND A SUBSUBSEQUENT DOS
;CMD CAN BE EMBEDDED IN THE FILE
;NAME AS A PROTECTION SCHEME.)
 INX ;KICK UP INDEX INTO FILE DESCRIP.
 DEY ;REDUCE THE CHARACTER COUNTER.
 BPL PRTFNAME ;BRANCH IF MORE CHARS TO PRT.
 JSR CRCATLOG ;PRT <CR> AFTR NAME, TEST 4 PAUS.



NXDESCRP JSR NXPLUS35 ;ADD 35 BYTES TO INDEX SO IT PTS
;TO NEXT ENTRY IN CURRENT DIR SEC.
 BCC DESCRPTK ;(C) = 0, SO GO LOOK FOR MORE
;ENTRIES IN THIS PARTICULAR
;DIRECTORY SECTOR.
 BCS RDDIRSEC ;(C) = 1, SO THERE AREN'T MORE
;ENTRIES IN THIS DIRECT SECTOR.
;THERE4, GO BACK TO READ IN
;ANOTHER DIRECTORY SECTOR.




TOFMXTOK JMP GOODFMXT ;EVENTUALY RETURNS TO AFTRFUNC
;($A6AB) LOCATED IN THE FMDRIVER
;ROUTINE ($A6A8).




CRCATLOG LDA #$8D ;PRINT A <CR>.
 JSR COUT
 DEC SCRNSRCH ;DEC INDEX 2 SEE IF PAUSE NEEDED.
 BNE CRCATRTN ;PAUSE NOT REQUIRED.
 JSR RDKEY ;PAUSE SO INFO CAN BE ABSORBED
 LDA #21 ;BEFORE SCROLLED OFF SCRN.
 STA SCRNSRCH ;RESET INDEX FOR FRESH SCRN INFO.
CRCATRTN RTS






PRVOLNMB LDY #2 ;INDEX TO # OF CONVERSION FACTORS
;AND DIGITS.
ZONSTK LDA #0 ;INIT COUNT OF # OF SUBTR'S DONE.
 PHA ;SAVE COUNT ON STACK.
GETVNMB LDA A5L ;GET LOW BTE HEX AND CMP IT TO
 CMP BASETEN,Y ;TABLE OF CONVERSION FACTORS.
;CONVERSION TABLE CONTAINS POWERS
;OF 10: 10^2=100, 10^1=10, 10^0=1
 BCC TONEGASC ;BRANCH IF # < CONVERSION FACTOR.
 SBC BASETEN,Y ;SUBTRACT THE CONVERSION FACTOR.
 STA A5L ;STORE THE REMAINDER.
 LDA A5L+1 ;NONSENSE - NOT USED.
 SBC #0 ;NONSENSE - NOT USED.
 STA A5L+1 ;NONSENSE - NOT USED.
 PLA ;GET COUNTER OF # OF SUBT'S AND
 ADC #0 ;ADD (C). IF REMAIN. > CONVERSION
 PHA  ;FACTOR, ADD 1, ELSE ADD NOTHING.
 JMP GETVNMB ;GO BACK TO DO MORE SUBT'S WITH
;SAME CONVERSION FACTOR.
TONEGASC PLA ;GET RESULT OF DIV (IE. WHOLE #
;OF SUBTRACTIONS).
 ORA #$B0 ;CONVERT COUNT TO NEG ASCII CHAR.
 JSR COUT ;PRT CHAR.
 DEY ;3 CHARS/VOL# (IE. 2 TO 0).
 BPL ZONSTK ;(3 CONVERSION FACTORS.)
 RTS




RSTRFMWA JSR SELWKBUF ;PT A4L/H AT FM WORK BUF.
;(GET ADR FRM FM PARAMETER LIST.)
 LDY #0 ;ZERO OUT RETURN CODE IN FM PARM
 STY RTNCODFM ;LIST TO SIGNAL NO ERORS.
STORFMWK LDA (A4L),Y ;COPY FM WORK BUF 2 FM WORK AREA.
 STA FMWKAREA,Y
 INY
 CPY #45 ;45 BYTES TO COPY (0 TO 44).
 BNE STORFMWK
 CLC ;WHY?????
 RTS




CPYFMWA JSR SELWKBUF ;PT A4L/H AT FM WORK BUF (CHAIN).
;(GET ADR FROM FM PARM LIST.)
 LDY #0 ;INITIALIZE INDEX.
STORWRK LDA FMWKAREA,Y ;COPY WORK AREA ----->  WORK BUF.
 STA (A4L),Y
 INY
 CPY #45 ;45 BYTES TO COPY (0 TO 44).
 BNE STORWRK
 RTS




FNINIT JSR ZWRKAREA ;INIT THE FM WRK AREA (NON-CHAIN)
 LDA #4 ;OPCODE FOR FORMAT.



 JSR RWTSDRV1 ;CALL RWTS DRIVER TO FORMAT DISK.



 LDA VOLWA ;COMPLEMENTED VOL# (FRM WRK AREA)
 EOR #$FF ;UNCOMPL. IT & PUT VOL# IN VTOC.
 STA VOLUSED
 LDA #$11 ;USE TRK # 17 FOR CATALOG TRK.
 STA NXTRKUSE ;SET CAT TRK AS NXT TRK TO ALLOC.
;(NXTRKUSE IS LOCATED IN VTOC.)
 LDA #1 ;ALLOCATION DIRECTION = FORWARD.
 STA DRECTION



 LDX #56 ;OFFSET INTO VTOC TO TRKMAP0.
 LDA #0
ZVTOC STA VTOCBUFF,X ;ZERO OUT A TRKMAP BYTE.
 INX
 BNE ZVTOC



 LDX #$0C ;OFFSET TO START OF TRKMAP3.
FREETRK CPX #$8C ;OFFSET 1 PAST END OF TRKMAP34.
 BEQ FREEDTKS ;DONE UP TO END OF TRKMAP34.
 LDY #3 ;INIT INDEX TO END OF FRETKMSK.
FREEIT LDA FRETKMSK,Y ;FREE MOST TRKMAPS.  (STARTING
;WITH TRKMAP3).
;NOTE:  NOT FREEING UP VTOC SEC
;OR TRKS USED BY DOS.
 STA TRKMAP0,X ;FREE TRKS BY PLACING FOLLOWING
;BYTES IN @ TRKMAP:  "FF FF 00 00"
 INX ;KICK UP INDEX TO BYTE IN TRKMAP.
 DEY ;REDUCE INDEX TO FRETKMSK CAUSE
;LOADING FROM END OF FRETKMSK:
;                  "00 00 FF FF".
 BPL FREEIT ;(4BYTES/TRKMAP & 4BYTS/FRETKMSK)
 CPX #$44 ;OFFSET TO START OF TRKMAP17
;(IE. CATALOG TRACK).
 BNE FREETRK ;HAVE WE FREED TRKS 3 TO 16 YET?
;IF NOT - BRANCH.
 LDX #$48 ;OFFSET TO TRK 18 (IE. SKIP THE
;CATALOG TRACK).
 BNE FREETRK ;ALWAYS - GO FREE TRKS 18 TO 34.
FREEDTKS JSR WRITVTOC ;WRITE FREED UP VTOC TO DISK.



 LDX #0
 TXA
CLRDIREC STA DIRECBUF,X
 INX
 BNE CLRDIREC
 JSR PT2DIRBF ;DESIGNATE DIR SEC BUF AS I/O BUF
 LDA #$11 ;(A) = # OF CAT TRK.
 LDY SECPERTK ;# OF SECS/TRK = 16.
 DEY
 DEY
 STA IBTRK ;PUT CAT TRK IN IOB.



SETLNKTK STA DIRLNKTK ;SET TRK/SEC VALS FOR LINK 2 NEXT
SETLNKSC STY DIRLNKSC ;DIRECTORY SECTOR.
 INY ;GET SEC # TO WRITE & PUT IT IN
 STY IBSECT ;RWTS'S IOB.
 LDA #2 ;WRITE OPCODE.
 JSR RWTSDRV1 ;WRITE DIRECTORY SEC TO DISK.
 LDY DIRLNKSC ;SEC VAL OF NEXT DIR SEC 2 WRITE.
 DEY ;KICK IT DWN (WILL INC IT LATER).
 BMI DOIMAGE ;DON'T DO SEC 0 CAUSE THAT'S VTOC
 BNE SETLNKSC ;GO WRITE SECS 2 TO 15.
 TYA
 BEQ SETLNKTK ;GO BACK TO WRITE SEC 1 AND ZERO
;OUT THE DIRECTORY SECTOR LINKS.



DOIMAGE JSR PRPWRDOS ;GET READY TO WRITE DOS IMAGE.
 JSR WRDOSIMG ;WRITE DOS IMAGE TO DISK.
 JMP GOODFMXT ;EXIT FM CLEANLY. EVENTUALLY RTNS
;TO AFTRFUNC ($A6AB) LOCATED IN
;THE FMDRIVER ROUTINE ($A6A8).




SELWKBUF LDX #0 ;SELECT WORK BUFFER.
 BEQ PT2FMBUF ;ALWAYS.
SELTSBUF LDX #2 ;SELECT T/S LIST BUFFER.
 BNE PT2FMBUF ;ALWAYS.
SELDABUF LDX #4 ;SELECT DATA BUFFER.
PT2FMBUF LDA WRKBUFFM,X ;GET ADDR OF SELECTED BUF FROM
 STA A4L ;FM PARM LST & PUT IT IN POINTER.
 LDA WRKBUFFM+1,X
 STA A4L+1
 RTS




CKDATUP BIT UPDATFLG ;CHK BIT6 SO SEE IF CHANGED.
 BVS WRITDATA ;TAKE BRANCH IF CHANGED.
 RTS




WRITDATA JSR PRPDAIOB ;PREPARE RWTS'S IOB FOR WRITING
;DATA SEC BUF TO DISK.
 LDA #2 ;OPCODE FOR WRITE CMD.
 JSR RWTSDRVR ;CALL DRIVER 2 WRT DATA SEC BUF.
 LDA #%10111111 ;SHUT BIT6 OFF IN UPDATE FLAG TO
 AND UPDATFLG ;SIGNAL THAT THE DATA SECTOR BUF
 STA UPDATFLG ;IS UP TO DATE.
 RTS




CKTSUPDT LDA UPDATFLG
 BMI WRITETS ;IF BIT7 SET, UPDATING REQUIRED.
 RTS




WRITETS JSR SETTSIOB ;PREPARE RWTS'S IOB FOR WRITING
;T/S LIST BUFFER TO DISK.
 LDA #2 ;RWTS'S WRITE OPCODE.
 JSR RWTSDRVR ;CALL RWTS DRIVER 2 WRITE T/S LST
 LDA #$7F ;CLR BIT7 OF UPDATE FLAG 2 SIGNAL
 AND UPDATFLG ;THAT T/S LIST IS UP TO DATE.
 STA UPDATFLG
 RTS




SETTSIOB LDA TSBUFFM ;GET ADR OF T/S LIST BUF FROM
 STA IBBUFP ;FM PARM LIST & DESIGNATE AS I/O
 LDA TSBUFFM+1 ;BUF IN RWTS'S IOB.
 STA IBBUFP+1
 LDX CURTSTRK ;SET (X)/(Y) = TRK/SEC OF CURRENT
 LDY CURTSSEC ;T/S LIST SECTOR.
 RTS




READTS PHP ;SAVE CARRY ON STK.
;(C)=0=READ 1RST T/S LIST SEC.
;(C)=1=READ NEXT T/S LIST SEC.
 JSR CKTSUPDT ;WRITE T/S LIST SEC BUF IF
;UPDATING REQUIRED.  (IF T/S LST
;BUF HAS CHANGED SINCE LAST READ
;OR WRITE, THEN WRITE IT BACK TO
;DISK SO DON'T OVERWRITE BUF AND
;LOSE INFO WHEN RD NEW T/S LIST.)
 JSR SETTSIOB ;PREP RWTS'S IOB FOR READING T/S
;LIST SEC.
 JSR SELTSBUF ;POINT A4L/H AT T/S LIST BUF.
;(GETS ADR FROM FM PARM LIST.)
 PLP ;GET SAVED (C) BACK FROM STK.
 BCS RDNXTTS ;IF (C)=1, ALREADY READ 1RST T/S
;LIST SEC, SO GO READ NEXT ONE.



RDFIRSTS LDX FIRSTSTK ;SET (X)/(Y)=TRK/SEC OF 1RST T/S
 LDY FIRTSSEC ;LIST SECTOR.
 JMP RDTSLST ;GO READ T/S LIST SEC INTO BUF.




RDNXTTS LDY #1 ;INDEX INTO T/S LIST BUF.
 LDA (A4L),Y ;TRK FOR LNK 2 NEXT T/S LIST SEC.
 BEQ TSLNKZRO ;LINK ZEROED OUT SO NO MORE
;T/S LIST SECS FOR FILE.
 TAX ;(X) = NEXT T/S LIST TRK.
 INY
 LDA (A4L),Y ;SEC# FOR LNK 2 NXT T/S LIST SEC.
 TAY ;(Y) = NEXT T/S LIST SEC.
 JMP RDTSLST ;GO READ NEXT T/S LIST SEC IN.




TSLNKZRO LDA OPCODEFM ;CHK R/W STATUS TO SEE IF WANT TO
 CMP #4 ;ADD ANOTHER T/S LIST.
 BEQ UPDATETS ;WRITING - GO UPDATE LINK.
 SEC ;WERE READING & LNK ZEROED OUT,
 RTS ;SO RTN WITH (C)=1 SO GENERATE AN

;RTN CODE TO A DEFAULT VALUE FOR
;FILE-NOT-FOUND.) HOWEVER, IF
;READING IS BEING DONE FOR AN
;APPEND OR VERIFICATION, THEN THE
;SET (C) JUST DENOTES THAT HAVE
;REACHED THE END OF THE FILE.



UPDATETS JSR ASGNTKSC ;FIND & RESERVE TRK/SEC VALS FOR
;A NEW T/S LIST SECTOR.



LNKOLDNW LDY #2 ;OFFSET TO SEC# LINK BYTE.
 STA (A4L),Y ;PUT NEW SEC VAL IN LINK AND THEN
 PHA ;SAVE IT ON STK.
 DEY ;OFFSET TO TRK BYTE OF LINK.
 LDA ASIGNTRK ;PUT NEW TRK VAL IN LINK.
 STA (A4L),Y
 PHA ;SAVE TRK VAL ON STK.
 JSR WRITETS ;WRITE UPDATED T/S LIST TO DISK.



ZOUTTS JSR ZCURBUF ;ZERO OUT T/S LIST BUF.
 LDY #5 ;AT OFFSETS 5 & 6 IN2 THE NEW T/S
 LDA RELASTP1 ;LIST, PUT REL SEC # PLUS 1 (IN
 STA (A4L),Y ;RELATION TO THE ENTIRE FILE) OF
 INY ;THE 1RST DATA PAIR THAT WILL BE
 LDA RELASTP1+1 ;DESCRIBED IN THIS NEW T/S LIST.
 STA (A4L),Y ;(POSSIBLE VALUES ARE:  $007A,
;2*$007A, 3*$007A AND 4*$007A.
 PLA ;GET (X)/(Y)=TRK/SEC VALS 4 THIS
 TAX ;NEW T/S LIST SEC OFF STACK.
 PLA
 TAY
 LDA #2 ;WRITE OPCODE FOR RWTS.
 BNE RDWRTS ;ALWAYS - GO WRITE T/S LIST SEC.




RDTSLST LDA #1 ;READ OPCODE FOR RWTS.



RDWRTS STX CURTSTRK ;NEW T/S LIST SECTOR TRK/SEC VALS
 STY CURTSSEC ;BECOME CURRENT TRK/SEC VALS.
 JSR RWTSDRVR ;CALL RWTS DRIVER 2 READ OR WRITE
;THE CURRENT T/S LIST SECTOR.



 LDY #5 ;OFFSET IN2 CURRENT T/S LIST BUF.
 LDA (A4L),Y ;STORE REL SEC # OF 1RST DAT PAIR
 STA RELFIRST ;THAT CAN BE DESCRIBED IN THIS
;T/S LIST. (POSSIBLE VALUES ARE:
;$0000, $007A, 2*$007A, 3*$007A
;AND 4*$007A.)
 CLC ;ADD THE MAXIMUM # OF DATA SECS
 ADC MXSCURTS ;THAT CAN POSSIBLY BE DESCRIBED
;IN THIS T/S LIST.
 STA RELASTP1 ;STORE THE MAXIMUM RELATIVE SEC #
 INY ;(PLUS 1) OF THE LAST DATA PAIR
;THAT CAN POSSIBLY BE DESCRIBED
;IN THIS T/S LIST.
 LDA (A4L),Y
 STA RELFIRST+1
 ADC MXSCURTS+1
 STA RELASTP1+1 ;(RELASTP1/+1 IS ALWAYS SET TO
;$007A BY FNOPEN.  (POSSIBLE VALS
;ARE:  $007A, 2*$007A, 3*$007A,
;4*$007A OR 5*$007A.)
 CLC ;RETURN WITH NO ERRORS SIGNAL.
 RTS




READDATA JSR PRPDAIOB ;SET UP RWTS'S IOB 2 RD DATA SEC.
 LDA #1 ;READ OPCODE FOR RWTS.
 JMP RWTSDRVR ;CALL RWTS DRIVER 2 READ DAT SEC.




PRPDAIOB LDY DATBUFFM ;GET ADR OF DATA SEC BUF FROM THE
 LDA DATBUFFM+1 ;FM PARM LIST & DESIGNATE IT AS
 STY IBBUFP ;THE I/O BUF FOR RWTS'S IOB.
 STA IBBUFP+1
 LDX CURDATRK ;ENTER RWTS DRIVER WITH (X)/(Y)
 LDY CURDATSC ;CONTAINING THE TRK/SEC VALUES OF
 RTS ;THE DATA SECTOR.
$