455 lines
24 KiB
Plaintext
455 lines
24 KiB
Plaintext
*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*
|
|
* *
|
|
* CATALOG Function Handler *
|
|
* *
|
|
*----------------------------------------------------------------*
|
|
* *
|
|
* This function handler is only called by the CATALOG *
|
|
* command. The overall execution pattern of the function, as *
|
|
* well as several customizing techniques, are described in the *
|
|
* preamble given with the catalog command handler (CMDCATLG, *
|
|
* $A56E). *
|
|
* *
|
|
*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*
|
|
|
|
|
|
(AD98)
|
|
FNCATLOG JSR ZWRKAREA ;Initialize the work area.
|
|
|
|
* Zero out the FM work area so it can be customized
|
|
* in accordance with the calling function.
|
|
* (Although some work bytes may not be subsequently
|
|
* altered, don't be lulled into thinking that they
|
|
* are not important. Zero values are just as relevant
|
|
* as non-zero values.)
|
|
* (P.S. Don't confuse the FM work area with its image
|
|
* (FM work buffer) that is housed in the chain of
|
|
* DOS buffers.)
|
|
(ABDC)
|
|
ZWRKAREA LDA #0
|
|
TAX ;Initialize the x-index.
|
|
ZEROWRKA STA FMWKAREA,X ;Put a $00 byte in work area.
|
|
INX
|
|
CPX #45 ;Work area is 45 bytes long.
|
|
(ABE5) BNE ZEROWRKA
|
|
|
|
* Begin customizing the work area.
|
|
* Get volume, drive, slot & catalog track
|
|
* values from the FM parameter list. Put
|
|
* drive, slot*16, catalog track and
|
|
* complemented volume number in the work area.
|
|
(ABE7) LDA VOLFM ;Volume number.
|
|
EOR #$FF ;Calculate 1's compliment of volume #.
|
|
STA VOLWA
|
|
LDA DRVFM ;Drive #.
|
|
STA DRVWA
|
|
LDA SLOTFM ;Get slot #.
|
|
ASL ;Calculate slot * 16.
|
|
ASL
|
|
ASL
|
|
ASL
|
|
TAX ;Set (x) = slot * 16.
|
|
STX SLOT16WA
|
|
LDA #$11 ;Normal catalog trk = #17.
|
|
STA TRKWA
|
|
(AC05) RTS
|
|
|
|
(AD9B) LDA #$FF ;Allow any volume to be cataloged.
|
|
(AD9D) STA VOLWA ;(When RWTS is later entered, this value is
|
|
;EORed with #$FF to simulate a complemented
|
|
;volume number of 0 (ie. #$FF EOR #$FF = $00).
|
|
;After RWTS reads the addr checksum, it chks
|
|
;to see if the correct volume was read off
|
|
;the disk. If the complement of the vol #
|
|
;is 0, or if it matches the vol # read off
|
|
;the disk, execution proceeds as if the
|
|
;correct volume was found.)
|
|
(ADA0) JSR READVTOC ;Read the VTOC.
|
|
|
|
* Read the Volume Table of Contents (VTOC).
|
|
(AFF7)
|
|
READVTOC LDA #1 ;Read opcode for RWTS.
|
|
(AFF9) BNE RDWRVTOC ;ALWAYS.
|
|
|
|
* Common to read/write the VTOC.
|
|
(AFFD)
|
|
RDWRVTOC LDY ADRVTOC ;Get the address of the VTOC from the FM
|
|
STY IBBUFP ;constants table & designate it as the
|
|
LDY ADRVTOC+1 ;I/O buffer in RWTS's IOB.
|
|
STY IBBUFP+1
|
|
LDX TRKWA ;Enter RWTS driver with (x)/(y) = trk/sec
|
|
LDY #0 ;values of the VTOC.
|
|
(B00E) JMP RWTSDRVR ;Call RWTS driver to read/write the VTOC.
|
|
------------
|
|
|
|
* Read/Write Track/Sector driver.
|
|
RWTSDRVR .
|
|
.
|
|
(See dis'mbly of RWTS driver using READ.)
|
|
.
|
|
.
|
|
(RTS)
|
|
|
|
(ADA3) LDA #22 ;Set index to allow 22 screen lines
|
|
(ADA5) STA SCRNSRCH ;between pauses.
|
|
|
|
* Print two <cr>'s & the words
|
|
* "disk volume".
|
|
(ADA8) JSR CRCATLOG
|
|
|
|
* Print a <cr> and check if a pause is required.
|
|
(AE2F)
|
|
CRCATLOG LDA #$8D ;Print a <cr>.
|
|
JSR COUT
|
|
(AE34) DEC SCRNSRCH ;Reduce line counter to see if a pause
|
|
;is required or not.
|
|
(AE37) BNE CRCATRTN ;No pause required.
|
|
(AE39) JSR RDKEY ;Pause until a key is pressed, so information
|
|
;can be absorbed before it scrolled off the
|
|
;screen.
|
|
(AE3C) LDA #21 ;Reset the screen line counter.
|
|
STA SCRNSRCH
|
|
CRCATRTN RTS
|
|
(AE41)
|
|
|
|
(ADAB) JSR CRCATLOG ;Do it again. (See dis'mbly above.)
|
|
(ADAE) LDX #11 ;12 chars to print (11 to 0).
|
|
PRDSKVOL LDA DSKVOLUM,X ;Get char of reverse string.
|
|
JSR COUT ;Print char.
|
|
DEX
|
|
BPL PRDSKVOL ;More chars in string.
|
|
(ADB9) STX A5L+1 ;Nonsense instruction (cause the hi byte is
|
|
;not used in the PRVOLNMB routine accessed
|
|
;below).
|
|
(ADBB) LDA IBSMOD ;Get vol # found (from RWTS's IOB) and put
|
|
STA A5L ;it in A5L.
|
|
(ADC0) JSR PRVOLNMB ;Go print the volume number.
|
|
|
|
* Convert 1 hex byte to a three-digit decimal
|
|
* number (with leading zeroes if applicable).
|
|
* NOTE: This is a BUGGY routine. Because it
|
|
* doesn't use the hi byte, numbers greater than
|
|
* 255 are expressed as 256 mod.
|
|
* (P.S. To use this as a stand-alone routine,
|
|
* load A5L with the hex value to be converted
|
|
* and then call PRVOLNMB. The (a) and (y)
|
|
* registers are destroyed. Conversion is done
|
|
* by simulating division via successive subtractions
|
|
* of powers of 10.)
|
|
(AE42)
|
|
PRVOLNMB LDY #2 ;Index for number of conversion factors
|
|
(AE44) ;and digits.
|
|
ZONSTK LDA #0 ;Initialize the count of the number of
|
|
;subtractions done.
|
|
(AE46) PHA ;Save the count on the stack.
|
|
GETVNMB LDA A5L ;Get the low byte hex value and compare it
|
|
(AE49) CMP BASETEN,Y ;to the table of conversion factors.
|
|
;Conversion table contains powers of 10:
|
|
; 10^2=100, 10^1=10, 10^0=1.
|
|
(AE4C) BCC TONEGASC ;Branch if number < 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 for the number of subtractions.
|
|
ADC #0 ;Add (c). If remainder > conversion factor,
|
|
PHA ;then add 1. Else, add nothing.
|
|
(AE5D) JMP GETVNMB ;Go back to do more subtractions with the
|
|
------------ ;same conversion factor.
|
|
TONEGASC PLA ;Get the result of the division (ie. the
|
|
(AE60) ;whole number of subtractions).
|
|
(AE61) ORA #$B0 ;Convert count to a negative ASCII char.
|
|
JSR COUT ;Print the character.
|
|
DEY ;3 chars/volume number (ie. 2 to 0).
|
|
BPL ZONSTK ;(3 conversion factors.)
|
|
(AE69) RTS
|
|
|
|
(ADC3) JSR CRCATLOG
|
|
|
|
* Print a <cr> and test if a pause is required.
|
|
(AE2F)
|
|
CRCATLOG LDA #$8D ;Print a <cr>.
|
|
JSR COUT
|
|
(AE34) DEC SCRNSRCH ;Reduce line counter to see if a pause
|
|
;is required or not.
|
|
(AE37) BNE CRCATRTN ;No pause required.
|
|
(AE39) JSR RDKEY ;Pause until a key is pressed, so information
|
|
;can be absorbed before it scrolled off the
|
|
;screen.
|
|
(AE3C) LDA #21 ;Reset the screen line counter.
|
|
STA SCRNSRCH
|
|
CRCATRTN RTS
|
|
(AE41)
|
|
|
|
(ADC6) JSR CRCATLOG ;Do it again.
|
|
|
|
* Read the directory sector into the
|
|
* directory sector buffer.
|
|
(ADC9) CLC ;(c) = 0, read the first directory sector.
|
|
(ADCA) ;(c) = 1, read the next directory sector.
|
|
RDDIRSEC JSR RDDIRECT ;Go read the directory sector.
|
|
|
|
* Read a directory sector.
|
|
(B011)
|
|
RDDIRECT PHP ;Save (c) on the stack:
|
|
; (c)=0=read the first directory sector.
|
|
; (c)=1=read the next directory sector.
|
|
(B012) JSR PT2DIRBF ;Select the directory sector buffer.
|
|
|
|
* Designate the directory sector buffer
|
|
* as the I/O buffer in RWTS's IOB.
|
|
(B045)
|
|
PT2DIRBF LDA ADRDIRBF ;Get the addr of the directory sector buffer
|
|
STA IBBUFP ;from the FM constants table & designate it
|
|
LDA ADRDIRBF+1 ;as the I/O buffer in RWTS's IOB.
|
|
STA IBBUFP+1
|
|
(B051) RTS
|
|
|
|
(B015) PLP ;Get signal back from stack to see if
|
|
;dealing with first directory sec or not.
|
|
(B016) BCS RDNXTDIR ;Go read the next directory sector.
|
|
|
|
* Read the first directory sector (c = 0).
|
|
(B018)
|
|
RDFIRDIR LDY FIRDIRSC ;(y)/(x) = trk/sec values of the first
|
|
LDX FIRDIRTK ;directory sector (from the the VTOC buf).
|
|
(B01E) BNE DODIRRD ;ALWAYS - go read in the directory sector.
|
|
|
|
* Read the next directory sector (c = 1).
|
|
(B020)
|
|
RDNXTDIR LDX DIRLNKTK ;Get the track number of the next directory
|
|
;sector from the link in the current
|
|
;directory sector.
|
|
(B023) BNE GETDIRLK ;Link not zeroed out.
|
|
SEC ;Link zeroed out, so exit with (c) = 1 to
|
|
(B026) RTS ;signal that there are no more directory
|
|
============ ;sectors.
|
|
|
|
(B027)
|
|
GETDIRLK LDY DIRLNKSC ;Get the sector number of the next directory
|
|
;sector from the link in the current
|
|
;directory sector.
|
|
|
|
* Call to read in the directory sector.
|
|
(B02A)
|
|
DODIRRD STX CURDIRTK ;Save the trk/sec values of the directory
|
|
(B02D) STY CURDIRSC ;sector that we are about to read (so that
|
|
;they will become the current directory
|
|
;sector values the next time around).
|
|
(B030) LDA #1 ;Read opcode for RWTS.
|
|
(B032) JSR RWTSDRVR ;Call RWTS driver to do the READ.
|
|
|
|
(B052)
|
|
RWTSDRVR .
|
|
.
|
|
(See dis'mbly of RWTS driver using READ.)
|
|
.
|
|
.
|
|
(RTS)
|
|
|
|
(B035) CLC ;Because link didn't zero out, signal that
|
|
(B036) RTS ;more directory sectors exist and then exit.
|
|
============
|
|
|
|
(ADCD) BCS TOFMXTOK ;Ran out of directory sectors so go exit.
|
|
(ADCF) LDX #0 ;Initialize index into the directory sec.
|
|
|
|
* Evaluate the track number.
|
|
(ADD1)
|
|
DESCRPTK STX CURDIRNX ;Save index to entries into the directory.
|
|
(ADD4) LDA FIL1TSTK,X ;Trk # of 1rst T/S list for file (from
|
|
;the file description in directory sec.)
|
|
(ADD7) BEQ TOFMXTOK ;Trk # = 0, so no more entries in the
|
|
;current directory buffer.
|
|
(ADD9) BMI NXDESCRP ;Trk# = $FF = deleted file, so skip it.
|
|
|
|
* Check the file status & then print
|
|
* a locked symbol ("*") or space.
|
|
(ADDB) LDY #" " ;Default (y) = space in case file not locked.
|
|
LDA FIL1TYPE,X ;Get the file type.
|
|
BPL PRLOCODE ;Hi bit is clear so file is unlocked.
|
|
(ADE2) LDY #"*" ;Reset (y) = locked symbol.
|
|
PRLOCODE TYA ;Either print an "*" or a space.
|
|
(ADE5) JSR COUT ;Go print char.
|
|
|
|
* Print the character code for the
|
|
* file type and a trailing space.
|
|
(ADE8) LDA FIL1TYPE,X ;Get the file type again & make
|
|
(ADEB) AND #$7F ;sure that the hi bit is off so we can
|
|
;index the table that contains character
|
|
;code symbols for the different file types.
|
|
(ADED) LDY #7 ;Set (y) to indicate that 7 relevant bits
|
|
;are left after the hi bit is shifted out.
|
|
(ADEE) ASL ;Throw away the hi bit.
|
|
CHRTYPIX ASL ;Shift remaining bits until a hi bit is set.
|
|
(ADF1) BCS PRTFTYPE ;The number of shifts required to set the
|
|
;carry designates the index to the table
|
|
;of characters representing the file types.
|
|
(ADF3) DEY ;Reduce counter for number of shifts done.
|
|
(ADF4) BNE CHRTYPIX ;No set bits encountered yet, so go back
|
|
(ADF6) ;to do more shifts.
|
|
PRTFTYPE LDA FTYPETBL,Y ;Got a set bit, so now get char from the
|
|
;table of file type symbols.
|
|
(ADF9) JSR COUT ;Print the file type symbol.
|
|
(ADFC) LDA #" " ;Print the trailing space.
|
|
|
|
* Print the file size (which is
|
|
* expressed in terms of sectors).
|
|
(AE01) LDA FIL1SIZE,X ;Get the low & hi bytes of the file size
|
|
STA A5L ;(in sectors) from the file description in
|
|
LDA FIL1SIZE+1,X ;the current directory sector & stick
|
|
STA A5L+1 ;them in A5L/H.
|
|
(AE0B) JSR PRVOLNMB ;Print the file size.
|
|
|
|
* Convert 1 hex byte to a three-digit decimal
|
|
* number (with leading zeroes if applicable).
|
|
* NOTE: This is a BUGGY routine. Because it
|
|
* doesn't use the hi byte, numbers greater than
|
|
* 255 are expressed as 256 mod.
|
|
* (P.S. To use this as a stand-alone routine,
|
|
* load A5L with the hex value to be converted
|
|
* and then call PRVOLNMB. The (a) and (y)
|
|
* registers are destroyed. Conversion is done
|
|
* by simulating division via successive subtractions
|
|
* of powers of 10.)
|
|
(AE42)
|
|
PRVOLNMB LDY #2 ;Index for number of conversion factors and
|
|
(AE44) ;digits.
|
|
ZONSTK LDA #0 ;Initialize the count of the number of
|
|
;subtractions done.
|
|
(AE46) PHA ;Save the count on the stack.
|
|
GETVNMB LDA A5L ;Get the low byte hex value and compare it
|
|
(AE49) CMP BASETEN,Y ;to the table of conversion factors.
|
|
;Conversion table contains powers of 10:
|
|
; 10^2=100, 10^1=10, 10^0=1.
|
|
(AE4C) BCC TONEGASC ;Branch if number < 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 for the number of subtractions.
|
|
ADC #0 ;Add (c). If remainder > conversion factor,
|
|
PHA ;then add 1. Else, add nothing.
|
|
(AE5D) JMP GETVNMB ;Go back to do more subtractions with the
|
|
------------ ;same conversion factor.
|
|
(AE60)
|
|
TONEGASC PLA ;Get the result of the division (ie. the
|
|
;whole number of subtractions).
|
|
(AE61) ORA #$B0 ;Convert count to a negative ASCII char.
|
|
JSR COUT ;Print the character.
|
|
DEY ;3 chars/volume number (ie. 2 to 0).
|
|
BPL ZONSTK ;(3 conversion factors.)
|
|
(AE69) RTS
|
|
|
|
(AE0E) LDA #" " ;Print a space after the size.
|
|
(AE10) JSR COUT
|
|
|
|
* Print the file name.
|
|
(AE13) INX ;Kick (x) up because the name starts at the
|
|
INX ;4th byte from the start of the file
|
|
INX ;description entry.
|
|
LDY #29 ;Counter for 30 characters/name (0 - 29).
|
|
PRTFNAME LDA FIL1TSTRK,X ;Get char for file name and print it.
|
|
(AE1B) JSR COUT ;(P.S. Since the output hook still points
|
|
;to DOS's output handler, ctrl-D and a
|
|
;subsequent DOS command can be embedded in
|
|
;the filename as a protection scheme.)
|
|
(AE1E) INX ;Kick up index into the file description.
|
|
DEY ;Reduce the character counter.
|
|
BPL PRTFNAME ;Branch if more characters to print.
|
|
(AE22) JSR CRCATLOG ;Print a <cr> after the name & chk 4 pause.
|
|
|
|
* Print a <cr> and test if a pause is required.
|
|
(AE2F)
|
|
CRCATLOG LDA #$8D ;Print a <cr>.
|
|
JSR COUT
|
|
(AE34) DEC SCRNSRCH ;Reduce line counter to see if a pause
|
|
;is required or not.
|
|
(AE37) BNE CRCATRTN ;No pause required.
|
|
(AE39) JSR RDKEY ;Pause until a key is pressed, so information
|
|
;can be absorbed before it scrolled off the
|
|
;screen.
|
|
(AE3C) LDA #21 ;Reset the screen line counter.
|
|
STA SCRNSRCH
|
|
CRCATRTN RTS
|
|
(AE41)
|
|
|
|
* Kick up the index into the current
|
|
* directory sector buffer to point at
|
|
* the start of the next file description entry.
|
|
(AE25)
|
|
NXDESCRP JSR NXPLUS35
|
|
|
|
* Add 35 bytes to the index so it points to
|
|
* the next entry in the current directory
|
|
* sector.
|
|
(B230)
|
|
NXPLUS35 CLC
|
|
LDA CURDIRNX
|
|
ADC #35
|
|
TAX ;Check if there is space left for more
|
|
CPX #245 ;entries in the current directory sector.
|
|
(B239) RTS ;Exit with (c) conditioned:
|
|
; (c) = 0 = more space in directory
|
|
; sector.
|
|
; (c) = 1 = no more space, ran off the end
|
|
; of the directory sector.
|
|
|
|
(AE28) BCC DESCRPTK ;(c)=0, so go look for more entries in this
|
|
;particular directory sector.
|
|
(AE2A) BCS RDDIRSEC ;(c)=1, so there are no more entries in this
|
|
------------ ;directory sector. There4, go back to read
|
|
;in another directory sector.
|
|
(AE2C)
|
|
TOFMXTOK JMP GOODFMXT ;Go exit the file manager cleanly.
|
|
------------
|
|
|
|
|
|
* Exit the file manager.
|
|
(B37F)
|
|
GOODFMXT LDA RTNCODFM
|
|
CLC ;(c) = 0 to signal good operation.
|
|
BCC FMEXIT
|
|
BADFMXIT SEC ;(c) = 1 to signal unsuccessful.
|
|
FMEXIT PHP ;Save status on stack.
|
|
STA RTNCODFM ;Store return code in FM parameter list.
|
|
LDA #0
|
|
STA STATUS
|
|
(B38E) JSR CPYFMWA ;Copy the work area to the work buffer.
|
|
|
|
* Copy the FM work area (non-chain) to
|
|
* the FM work buffer (in DOS chain).
|
|
(AE7E)
|
|
CPYFMWA JSR SELWKBUF ;Select the FM work buffer (in DOS chain).
|
|
|
|
* Point the A4L/H pointer at the FM work buffer.
|
|
(AF08)
|
|
SELWKBUF LDX #0 ;Set index to select work buffer.
|
|
(AF0A) BEQ PT2FMBUF ;ALWAYS.
|
|
|
|
(AF12)
|
|
PT2FMBUF LDA WRKBUFFM,X ;Get address of selected buffer from the
|
|
STA A4L ;FM parameter list & put it in the pointer.
|
|
LDA WRKBUFFM+1,X
|
|
STA A4L+1
|
|
(AF1C) RTS
|
|
|
|
(AE81) LDY #0 ;Initialize index.
|
|
STORWRK LDA FMWKAREA,Y ;Get byte from the FM work area.
|
|
STA (A4L),Y ;Put it in the work buffer.
|
|
INY
|
|
CPY #45 ;45 bytes to copy (0 to 44).
|
|
BNE STORWRK
|
|
(AE8D) RTS
|
|
|
|
(B391) PLP ;Retrieve status of success of operation
|
|
;from the stack.
|
|
(B392) LDX STKSAV ;Adjust stack pointer to force exit to the
|
|
TXS ;caller of the function handler even if we
|
|
(B396) RTS ;are several subroutines deeper than the
|
|
============ ;original entry point. (That is, return to
|
|
;AFTRFUNC ($A6AB) in the FMDRIVER routine
|
|
;($A6A8).)
|