*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::* * * * 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 's & the words * "disk volume". (ADA8) JSR CRCATLOG * Print a and check if a pause is required. (AE2F) CRCATLOG LDA #$8D ;Print a . 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 and test if a pause is required. (AE2F) CRCATLOG LDA #$8D ;Print a . 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 after the name & chk 4 pause. * Print a and test if a pause is required. (AE2F) CRCATLOG LDA #$8D ;Print a . 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).)