💾 Archived View for mirrors.apple2.org.za › archive › www.textfiles.com › apple › ANATOMY › fncatlog… captured on 2024-08-19 at 03:02:08.
View Raw
More Information
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*
- *
- 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
(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.
------------
(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).)