textfiles/apple/ANATOMY/t.dos.ac58.aff6.txt
2021-04-15 13:31:59 -05:00

958 lines
27 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

*=================================
* READ FUNCTION HANDLER.
*=================================
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.
*=================================
* WRITE FUNCTION HANDLER.
*=================================
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.
*=================================
* POSITION AND READ-ONE-BYTE
* SUBFUNCTION HANDLER.
*=================================
PSNRDONE JSR CALCFPTR ;USING R-, L- & B-PARAMETERS,CALC
;THE POS'N OF FILE PTR WANTED.
*==================================
* READ-ONE-BYTE SUBFUNCTION HANDLER
*==================================
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).
*=================================
* POSITION & READ-A-RANGE-OF-BYTES
* SUBFUNCTION HANDLER.
*=================================
PSNRDRNG JSR CALCFPTR ;USING R-, L- & B-PARMS, CALC THE
;POS'N OF FILE POINTER WANTED.
*=================================
* READ-RANGE-OF-BYTES
* SUBFUNCTION HANDLER.
*=================================
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.
*=================================
* SUBROUTINE TO READ A DATA BYTE.
*=================================
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.
*=================================
* POSITION & WRITE-ONE-BYTE
* SUBFUNCTION HANDLER.
*=================================
PSNWRONE JSR CALCFPTR ;USING R-, L- & B-PARMS, CALC
;POS'N OF FILE POINTER WANTED.
*=================================
* WRITE-ONE-BYTE SUBFUNCTION HNDLR
*=================================
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).
*=================================
* POSITION & WRITE-RANGE-OF-BYTES
* SUBFUNCTION HANDLER.
*=================================
PSNWRRNG JSR CALCFPTR ;USING R-, L- & B-PARMS, CALC
;POS'N OF FILE POINTER WANTED.
*=================================
* WRITE RANGE-OF-DATA-BYTES
* SUBFUNCTION HANDLER.
*=================================
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.
*=================================
* SUBROUTINE WHICH WRITES 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.
*=================================
* LOCK & UNLOCK FUNCTION HANDLERS.
*=================================
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).
*=================================
* POSITION FUNCTION HANDLER.
*=================================
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).
*=================================
* VERIFY FUNCTION HANDLER.
*=================================
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.
*=================================
* DELETE FUNCTION HANDLER.
*=================================
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.
* GET TRK # OF FILES 1RST T/S LIST
* FROM FILE DESCRIP ENTRY IN DIR
* SEC BUF. PUT IT IN THE WRK AREA
* & WRITE IT OVER THE LAST CHAR
* POS'N IN THE APPROPRIATE FILE
* NAME FIELD IN DIRECTORY SECTOR.
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.
* READ T/S LIST SEC INTO T/S LIST BUF.
* (NEED THIS INFO SO KNOW WHAT SECS
* TO RELEASE.)
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.)
* FREE ALL SECS LISTED IN THE T/S
* LIST THAT CURRENTLY OCCUPIES THE
* T/S LIST BUFFER.
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.
* FREE UP SECTOR CONTAINING THE
* T/S LIST.
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.
* DONE FREEING UP ALL SECTORS
* ASSOCIATED WITH THIS FILE, SO
* NOW WRITE MODIFIED VTOC BACK
* TO THE DISK.
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).
*=================================
* SUBROUTINE TO FREE UP A SECTOR
* IN A TRKMAP OF THE VTOC.
*=================================
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
*=================================
* CATALOG FUNCTION HANDLER.
*=================================
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.
* PRINT 2 <CR>'S & THE WORDS
* "DISK VOLUME".
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.
* READ DIRECTORY SECTOR INTO THE
* DIRECTORY SECTOR BUFFER.
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.
* ANALYZE THE TRACK NUMBER.
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
* CHK FILE STATUS & PRINT LOCKED
* SYMBOL ("*") OR SPACE.
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
* PRINT CHAR CODE FOR FILE TYPE &
* A TRAILING <SPC>.
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
* PRINT FILE SIZE (EXPRESSED IN
* TERMS OF SECTORS).
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
* PRINT THE FILE NAME.
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.
* KICK UP INDEX INTO CURRENT DIRECTORY
* SECTOR BUF TO PT AT START OF NEXT
* FILE DESCRIPTION ENTRY.
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.
*=================================
* EXIT FILE MANAGER CLEANLY.
*=================================
TOFMXTOK JMP GOODFMXT ;EVENTUALY RETURNS TO AFTRFUNC
;($A6AB) LOCATED IN THE FMDRIVER
;ROUTINE ($A6A8).
*=================================
* PRINT <CR> & CHK FOR PAUSE.
*=================================
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
*=================================
* CONVERT 1 HEX BYTE TO 3-DIGIT
* DECIMAL (WITH LEADING ZEROES IF
* APPLICABLE).
*=================================
* NOTE: THIS IS A BUGGY ROUTINE
* - DOESN'T USE HI BYTE SO NUMBERS
* GREATER THAN 255 ARE EXPRESSED
* AS 256 MOD.
*
* (PS. TO USE AS A STAND-ALONE
* ROUTINE, LOAD A5L WITH HEX & CALL
* PRVOLNMB. DESTROYS (A) & (Y) REGS.
* CONVERSION DONE BY SIMULATING
* DIVISION VIA SUCCESSIVE SUBTRACTIONS
* OF POWERS OF 10.)
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
*=================================
* COPY CONTENTS OF FM WORK BUFFER
* (IN DOS CHAIN) TO FM WORK AREA
* (NOT IN DOS CHAIN).
*=================================
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
*=================================
* COPY FM WORK AREA TO FM WORK BUF
* (LOCATED IN CHAIN OF DOS BUFS).
*=================================
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
*=================================
* INIT FUNCTION HANDLER.
*=================================
FNINIT JSR ZWRKAREA ;INIT THE FM WRK AREA (NON-CHAIN)
LDA #4 ;OPCODE FOR FORMAT.
* GO FORMAT THE DISK.
JSR RWTSDRV1 ;CALL RWTS DRIVER TO FORMAT DISK.
* PUT VOL#, # OF NEXT TRK TO BE
* ASSIGNED & ASSIGNMENT DIRECTION
* IN THE VTOC SECTOR BUFFER.
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
* ZERO OUT VTOC FROM TRKMAP0 TO
* END OF SECTOR. (NOTE: THIS
* ASSIGNS ALL TRACKS.)
LDX #56 ;OFFSET INTO VTOC TO TRKMAP0.
LDA #0
ZVTOC STA VTOCBUFF,X ;ZERO OUT A TRKMAP BYTE.
INX
BNE ZVTOC
* FREE UP ALL TRKS EXCEPT TRKS 0,
* 1, 2 & CAT TRK (#17).
*
* NOTE: DOS ONLY OCCUPIES SECTORS
* 0 TO 4 ON TRK 2, BUT ROUTINE
* TAKES REST OF SECS ON TRK 2 OUT
* OF CIRCULATION.
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.
* CLEAR OUT THE DIRECTORY SEC BUF.
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.
* WRITE DIRECTORY SECS (TRK17,
* SECS 15 TO 1) TO DISK.
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.
* ROUTINE TO WRITE THE DOS
* IMAGE ON TRACKS 0 TO 2.
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).
*=================================
* POINT A4L/H AT A SPECIFIC
* SECTION OF A DOS BUFFER.
*=================================
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
*=================================
* CHK IF DATA SEC BUF HAS CHANGED
* SINCE LAST READ OR WRITE.
*=================================
CKDATUP BIT UPDATFLG ;CHK BIT6 SO SEE IF CHANGED.
BVS WRITDATA ;TAKE BRANCH IF CHANGED.
RTS
*=================================
* WRITE PRESENT DATA SECTOR BUFFER
* TO THE DISK. (UPDATES DISK SO
* CAN READ IN NEXT DATA SEC WITH-
* OUT OVERWRITING AND THEREFORE
* LOSING PREVIOUS DATA.)
*---------------------------------
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
*===================================
* CHK IF T/S LIST REQUIRES UPDATING.
* (HAS T/S LIST BUF CHANGED SINCE
* LAST READ OR WRITE?)
*===================================
CKTSUPDT LDA UPDATFLG
BMI WRITETS ;IF BIT7 SET, UPDATING REQUIRED.
RTS
*=================================
* UPDATE T/S LIST SEC BUF ON DISK.
*---------------------------------
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
*=================================
* PREPARE RWTS'S IOB FOR READING
* OR WRITING T/S LIST SEC.
*=================================
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
*=================================
* READ T/S LIST SEC TO BUFFER.
*=================================
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.
* READ 1RST T/S LIST SEC.
* (CARRY WAS CLR.)
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.
* ---
* READ NEXT T/S LIST SEC.
* (CARRY WAS SET.)
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.
* ---
* T/S LINK ZEROED OUT SO
* DECIDE IF ERROR OR NOT.
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
* === ;ERROR. (REMEMBER, PREVIOUSLY SET
;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.
* WRITING & LNK ZEROED OUT SO MUST
* ALLOCATE A NEW T/S LIST SECTOR.
UPDATETS JSR ASGNTKSC ;FIND & RESERVE TRK/SEC VALS FOR
;A NEW T/S LIST SECTOR.
* LINK THE NEW T/S LIST SECTOR TO
* THE LAST T/S LIST SECTOR AND
* THEN WRITE THE UPDATED VERSION
* OF THE LAST T/S LIST SECTOR TO
* THE DISK.
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.
* SET UP A BRAND NEW T/S LIST
* SECTOR & WRITE IT 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.
* ---
* SUBROUTINE TO READ T/S LIST SEC.
RDTSLST LDA #1 ;READ OPCODE FOR RWTS.
* COMMON TO READ/WRITE T/S LIST.
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.
* UPDATE FM WORK AREA BUF (NON-CHAIN).
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
*=================================
* READ DATA SEC TO DATA SEC BUF.
*=================================
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.
*=================================
* PREP RWTS'S IOB TO READ
* OR WRITE THE DATA SECTOR.
*==================================
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.
$