; XCAT v4.3 -- CATALOG CROSS-REFERENCE PROGRAM FOR MAST.CAT -- 11/20/85 ; ; COPYRIGHTED 1983, 1984, 1985 BY IRV HOFF ; ; This program makes a cross-reference listing of the MAST.CAT file. ; It names this new file MAST.LST. This file may then be listed using ; the normal printer routine, or viewed on the CRT using the TYPE com- ; mand. It is copryighted to deter commercialization. ; ; It can use any length MAST.CAT files, even beyond 6-8-10,000 file ; names. If the file is too long for available memory, it puts a note ; on the CRT to that effect, handles that portion of the file and con- ; tinues with the rest of the file until finished. A computer having ; 64k memory could typically handle about 3200 file names before this ; happens. ; ; Rapid information can also be obtained ; regarding any file and the disk it is on ; by using an auxiliary program 'FIND.COM' ; Example: ; ; ; A>FIND MAST.LST PIP ; ; This will print a list (on CRT and on hard copy via CTL-P) of ; any file names in the MAST.LST file having the characters PIP in ; the contents. (You can as easily find all .ASM files, etc.) ; The combination of MAST.LST plus FIND.COM makes an excellent way ; to keep an updated catalog listing without the necessity of hard ; copy. (Use XCAT.COM to keep the MAST.CAT file current.) ; ; This program assumes each disk has an unique volume number as a ; disk ID. It ignores any volume name that may be on the same ; line. An example of one method in common use: ; ; ; A>SAVE 0 B:-.123 ; A>SAVE 0 B:-01AUG82 ; A>SAVE 0 B:-UNIQUE ; ; The first line places a disk volume number on the B: disk of ; zero length. The "-" identifies it as a volume number for MCAT. ; The second line shows how, if desired, an extra unique disk vol- ; ume date could be added. The third line shows an unique volume ; name. All the lines could be used, but only the disk volume ; number is used for the MAST.LST cross-reference list. (Don't ; forget the period in front of the volume number to show it is a ; file type, not a file name. That automatically gives it eight ; spaces for a file name, so it will alphabetize ahead of any ; other lines startins with "-" and be considered the disk volume ; number.) ; ; If "USER" is set YES, it will include the user number for each ; program. (This assumes your MAST.CAT file has the user numbers ; included, which is an option on the MCAT catalog program. Even ; if it does have user numbers, you can still say NO to the USER ; equate if you wish.) If user numbers are not needed, just set ; "USER" to NO. ; ; FILENAME.TYP - 023 045 093 123 131 145 (no user numbers) ; ; FILENAME.TYP - 023/02 045/12 093/00 123/15 (w/user numbers) ; ; Irvin M. Hoff W6FFC ; Los Altos Hills, CA 94022 ; ;======================================================================= ; ; 11/20/85 Numerous changes. Major rewrite to fix an obscure error oc- ; v4.3 curing when the buffer was full (takes around 3000 filenames ; or so), which did not display or count the last filename ; properly. Many other subtle changes to simplify the program ; and speed up its response. - Irv Hoff ; ; 08/22/84 Fixed error, restored original format. ; v4.2 - Irv Hoff ; ; 08/20/84 Optional user area added. ; v4.1 - Paul Traina ; ; 11/20/83 Original version, fixed for use with MCAT, based on a 1979 ; v4.0 program called CROSREF. ; ;======================================================================= ; ; NO EQU 0 YES EQU NOT NO ; Some assemblers cannot use 0FFH here ; ; USER EQU NO ; Yes to display user numbers ; IF USER IDLEN EQU 7 ; Each entry is 7 characters long LENGTH EQU 19 ; Length of line to store NUMPRL EQU 7 ; Maximum number of entries per line ENDIF ; USER ; IF NOT USER IDLEN EQU 4 ; Each entry is 4 characters long LENGTH EQU 16 ; Length of line to store NUMPRL EQU 10 ; Maximum number of entries per line ENDIF ; NOT USER ; ; ; Equates ; DASLEN EQU 4 ; Length of dash line NAMTYP EQU 12 ; Length of filename/separator/extent ; ; ; BDOS commands ; BDOS EQU 0005H ; Bdos entry location ; RCFC EQU 1 ; Console input WCFC EQU 2 ; Console output WCLD EQU 5 ; Write character to list device KSTAT EQU 11 ; Get console status OPEN EQU 15 ; Open file CFFC EQU 16 ; Close file DFFC EQU 19 ; Delete file RNFC EQU 20 ; Read sequential WRFC EQU 21 ; Write sequential MFFC EQU 22 ; Make file SDMA EQU 26 ; Set 'DMA' address ;..... ; ; ; ASCII characters ; BS EQU 08H ; Backspace CR EQU 0DH ; Carriage return EX EQU 12 FN EQU 01 FT EQU 09 LF EQU 0AH ; Line feed NR EQU 32 SI EQU 16H ; Synch idle TFCB EQU 005CH ; Default file control block ;..... ; ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; ; ; ; PROGRAM STARTS HERE ; ; ; ; ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; ORG 100H ; ; START: LXI H,0 DAD SP ; 'CCP' return address SHLD STACK LXI SP,STACK ; LXI H,MSG0 ; Print sign-on message CALL WASC CALL INPUT ; Get keyboard character ANI 5FH ; Change to upper-case if needed CPI 'Y' JNZ START1 ; If not, exit XRA A ; Otherwise ignore and continue STA LOOP+1 ; START1: LXI H,MSG21 ; Turn up a new line CALL WASC ; ; ;------------------ read 'MAST.CAT' into memory ------------------------ ; ; ; Open MAST.CAT file to read filenames into buffer ; CALL SETR ; Disk read 'DMA' to 'BUFREC' address LXI D,FCB MVI C,OPEN CALL BDOS INR A LXI H,MSG7 JZ ERXIT ; Jump if unable to open CALL PRHC ; Want hard copy? LXI H,MSG8 ; Keep user informed CALL WASC LHLD BDOS+1 ; Start of 'BDOS' area MOV A,H SUI 8 STA CCP ; Store 'CCP' starting page LXI H,BUFREC+80 SHLD DBUFI ; Force initial disk read LXI H,FNTBL SHLD FNTP ; Initialize filename table pointer CALL CLEAR ; Clear useable RAM area ; ; ; Skip the 'IGNORE' file names at the head of the 'MAST.CAT' file ; SKPIGN: CALL RDCHR ; Get a character from the file CPI ')' JNZ SKPIGN ; Wait until at end of the IGNORE list ; ; ; Main read loop. Read a line from MAST.CAT, discard any disk name and ; put the rest into the FNTBL buffer. ; ; Skip to end of line (L/F) in MAST.CAT file ; SKIPLF: CALL TERM ; Ready to quit? CALL RDCHR ; Read until CPI LF JNZ SKIPLF ; Wait until next LF is found, skips CR ; ; ; See if the first character is a null (skips date lines, etc.) ; CALL RDCHR ORA A JZ SKIPLF ; If yes, ignore this line ; ; ; See if it is a '.FRE' line or one with '-' at start ; LOOP: CPI '+' ; (overwritten by "begin" if wanted) JZ SKIPLF ; If yes, ignore this line CPI '-' ; Ignore any lines starting with '-' JZ SKIPLF ; LHLD FNTP ; Get location in table XCHG ; Put into 'DE' ; ; Get the filename ; MVI B,8 CALL GETNF+3 ; ; ; Put in the separator (now instead of later) ; MVI A,'.' STAX D INX D ; ; ; Get the filetype ; MVI B,3 CALL GETNF ; ; ; Skip over any disk name and take only the disk number (up to three ; alphanumeric characters). ; PUSH D ; Save table pointer LXI D,TRASH ; Throw away any disk name MVI B,8 CALL GETNF ; ; ; Now move in the disk FILETYPE (number) ; POP D ; Get the table pointer back MVI A,' ' ; Put in leading space STAX D INX D MVI B,3 CALL GETNF ; File type ; IF USER MVI A,'/' ; And separator for user area STAX D INX D CALL RDCHR ; Get next char. (which is user area) CPI 'N'-40H ; CTL-N for user area? JNZ $+5 ; If not, skip next line MVI A,'0' ; Else show user 0 for '.FRE' line CPI 'A' ; Digits are 0-9 CC PAD0 ; No, go pad with 0 CNC PAD1 ; Otherwise go pad with a '1' JC NOCVT ; Not necessary to convert SUI 'A'-'0' ; Convert to decimal ; NOCVT: STAX D INX D ENDIF ; USER ; XCHG ; Put buffer position into 'HL' SHLD FNTP ; Save pointer for next character ; ; ; Bump the buffer by one line length to see if another line would be ; too much. ; LXI D,LENGTH ; Get length of filename, size, etc. DAD D ; Add to current position ; ; ; Stop if it will exceed the buffer length (jump into 'CCP' area) ; LDA CCP ; Get 'CCP' start page CMP H ; Compare addresses JNZ SKIPLF ; If less, ok to continue ; ; ; If running too long, print what we have, and get the rest later ; LHLD DBUFI ; See if next character is a CTL-Z INX H ; Index past last line feed char. MOV A,M CPI 'Z'-40H JZ $+8 ; If CTL-Z, do not show more coming MVI A,1 ; Some non-zero value STA NEXT STA ONCE LHLD FNTP ; End of buffer address MOV A,L ; Subtract one name length for last name SUI LENGTH MOV L,A MOV A,H SBI 0 MOV H,A LXI D,MSG11 ; Move file name into message MVI B,NAMTYP ; Length of filename/separator/extent CALL MOVE LXI H,MSG10 ; 'File too long' message CALL WASC ; Show the message ;..... ; ; ;----------------- Print file from 'FNTBL' to disk --------------------- ; ; Check first to see if have been this way before ; PRNT: CALL SETO ; Set disk output 'DMA' address CALL SETFNT ; Set the filename counters LDA REPEAT ORA A JZ PRNT1 ; LDA MATCH ; Was there a match, last time? ORA A JZ PRNT4 ; If not, proceed normally JMP PRNT5 ; If yes, see if new one matches ; ; ; Now see if an output file name was given initially ; PRNT1: INR A STA REPEAT ; Show we have been this way now LDA HCFLG ; For hard copy to printer ORA A JNZ PRNT3 ; If yes, do not open file LDA TFCB+FN ; Jump if non-blank name or type CPI ' ' JNZ PRNT2 LDA TFCB+FT ; Allow blank file type CPI ' ' JNZ PRNT2 LXI H,DEFLT ; Default to 'MAS.LST' LXI D,TFCB MVI B,NAMTYP ; Length of drive/filename/extent CALL MOVE ; PRNT2: XRA A STA TFCB+EX CALL CREATE INR A ; New file started ok? LXI H,MSG15 JZ ERXIT ; Error message if not LDA NEXT ORA A LXI H,MSG14 ; Says file is writing now CZ WASC XRA A STA TFCB+NR ; PRNT3: LXI H,BUFOUT SHLD DBUFO XRA A STA DBUFC ; ; ; Move filename, extent, file length and 'dash line' into OBUF line ; PRNT4: LHLD ICNT ; Copy name (ICNT) into 'OBUF' LXI D,OBUF MVI B,NAMTYP ; Copy filename into OBUF CALL MOVE PUSH H LXI H,DASH ; Copy ' - ' into 'OBUF' MVI B,DASLEN CALL MOVE POP H MVI B,IDLEN ; Copy disk designator CALL MOVE XRA A ; Flag end of 'OBUF' STAX D XCHG ; Put OBUF ending address into HL SHLD SAVEOB ; Save in case next line matches MVI A,1 ; Start with one disk ID on the line STA CNT CALL FILESD ; Increment the unique file count ; ; ; Compare file first filename/ext with second one for match ; PRNT5: CALL FILES ; Increment the total file count XRA A MVI C,NAMTYP ; Compare filename and type CALL COMP ; See if the same filename and type ; ; ; If the same except for disk ID, exit ; JZ PRNT6 ; ; ; Since different, put 'OBUF' into output buffer ; CALL WRBUF ; Write OBUF line to disk buffer LDA XDONE ; See if finished now ORA A JNZ PRNT10 ; If yes, go terminate STA MATCH ; Show this was not a match ; ; ; Check on end of filename buffer ; LHLD JCNT ; Get next 'second name' starting addr XCHG ; Put into DE LHLD FNTP ; Get end of buffer address MOV A,D ; Compare ones done with total CMP H JC PRNT4 ; If less, go get another MOV A,E CMP L JC PRNT4 ; If less go get another ; LDA NEXT ; See if more to come ORA A JNZ PRNT9 ; If more to come, exit INR A STA XDONE JMP PRNT4 ; ; ; Since file names are identical, cross-reference the disk ID. ; PRNT6: LHLD SAVEOB ; Get current end address on OBUF line XCHG LDA CNT ; Add one to number on line CPI NUMPRL ; Exit if less that maximum entries yet JC PRNT8 CALL WRBUF ; Write 'OBUF' line to disk buffer ; ; ; If maximum entries this line, start a new line, blank at beginning ; LXI D,OBUF ; Start new 'OBUF' line MVI B,LENGTH-1 MVI A,' ' ; PRNT7: STAX D INX D DCR B JNZ PRNT7 XRA A ; Back to one disk ID on 'OBUF' line ; ; ; Add new ID to this line ; PRNT8: INR A STA CNT ; Store number of ID entries STA MATCH MVI A,' ' ; Insert 1 blank in 'OBUF' STAX D INX D LHLD ICNT ; Copy disk ID (ICNT) into 'OBUF' LXI B,LENGTH-IDLEN ; Include filename, type and length DAD B MVI B,IDLEN ; Include the identifier initial CALL MOVE XRA A ; Terminate 'OBUF' line STAX D XCHG ; Compare address with end of buffer SHLD SAVEOB ; Save current end of OBUF line address XCHG ; Put back into 'DE' to compare end ; ; ; Now see if there are any more entries ; LHLD JCNT ; Start of next line in FNTBL XCHG ; Put into DE to compare end of buffer LHLD FNTP ; Get end of buffer address MOV A,D ; Compare ones done with total CMP H JC PRNT5 ; If less, go get another MOV A,E CMP L JC PRNT5 ; If less, go get another LDA NEXT ; More to come? ORA A JNZ PRNT9 ; If yes, exit MVI A,1 STA XDONE JMP PRNT5 ; ; ; See if there is still more 'MAS.CAT' file to input ; PRNT9: XRA A STA NEXT ; Reset the flag LHLD ICNT ; Count of last file name line LXI D,FNTBL ; Move last name to start of buffer MVI B,LENGTH ; Filename, extent and filesize CALL MOVE ; Put name into special buffer XCHG ; HL is now end of first name in buffer CALL CLEAR1+3 ; Clear rest of useable memory LXI H,FNTBL+LENGTH ; Start loading buffer after first name SHLD FNTP MVI A,1 STA REPEAT ; Show we have already opened the file CALL SETR ; Set disk recieve 'DMA' address LXI H,MSG13 CALL WASC ; Print the message JMP SKIPLF ; Get next group of files ;..... ; ; PRNT10: LXI H,LCNT ; Get the line count MOV A,M CPI 52 JNC PRNT11 ; If too close to end, skip MSG17 ADI 3 MOV M,A ; Store new line count LXI H,MSG17 CALL WASD ; PRNT11: CALL FLUSH ; Finish end of file LDA HCFLG ; Printing hard copy? ORA A JZ EXIT ; Exit if not XRA A STA STOP ; Reset flag if set CALL ROLL JMP EXIT ; Finished ;..... ; ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; SUPPLEMENTAL ROUTINES ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; ; Handle a backspace character while entering a file name ; BCKSP: MOV A,B ; Get position on line ORA A JNZ BCKSP1 ; Exit if at initial column MVI A,' ' ; Delete the character JMP BCKSP3 ; BCKSP1: DCR B ; Show one less column used DCX H ; Decrease buffer location MVI A,' ' MOV M,A ; Replace to original CALL WACC ; Backspace the CRT ; BCKSP2: MVI A,BS ; Reset the CRT again ; BCKSP3: CALL WACC ; Write to CRT RET ;..... ; ; ; Check to see if ready to start printing yet ; CKST: PUSH H ; Save the registers PUSH D PUSH B LXI H,PAGES+2 ; Address of starting page answer ; CKST1: INX H ; Find the rightmost digit MOV A,M CPI ' ' JNZ CKST1 DCX H LXI D,HEAD3+2 ; Rightmost digit for page number MVI C,2 ; CKST2: LDAX D ; Compare two strings of numbers CMP M JNZ CKST5 ; If different, not ready yet DCX D ; Check next digit DCX H DCR C JNZ CKST2 STA PRINT ; Allows hard copy to commence ; CKST3: DB 0,0,0 ; Overwritten if using roll paper DB 0,0,0 ; CKST4: LXI H,HEAD1-2 CALL WASD ; CKST5: POP B ; Restore the registers POP D POP H RET ;..... ; ; ; Check to see if ready to stop printing yet ; CKSP: PUSH H ; Save the registers PUSH D PUSH B LXI H,PAGEQ+2 ; Address of quitting page answer ; CKSP1: INX H ; Find the rightmost digit MOV A,M CPI ' ' JNZ CKSP1 DCX H LXI D,HEAD3+2 ; Rightmost digit for page number MVI C,2 ; CKSP2: LDAX D ; Compare two strings of numbers CMP M JNZ CKSP3 ; If different, not ready yet DCX D ; Check next digit DCX H DCR C JNZ CKSP2 STA STOP ; Allows hard copy to commence ; CKSP3: POP B ; Restore the registers POP D POP H RET ;..... ; ; ; Clear useable memory from start of buffer to start of 'CCP' ; CLEAR: LXI H,BUFOUT ; Clear all of user-ram above stack JMP CLEAR1+3 ; Skip next line ; CLEAR1: LXI H,FNTBL ; Start of file name table area LDA CCP ; Get 'CCP' starting page MOV D,A ; Put in 'D' reg. ; CLEAR2: MVI M,0 ; Null the location INX H ; Next location MOV A,H ; Check current page address CMP D ; Compare with stopping address JC CLEAR2 ; If less, keep going RET ;..... ; ; ; Close disk file ; CLOSE: PUSH H PUSH D PUSH B LXI D,TFCB MVI C,CFFC CALL BDOS LXI H,MSG16 ; Close error? CPI 0FFH JZ ERXIT ; Jump if so POP B POP D POP H RET ;..... ; ; ; Compare entries in 'FNTBL', and swap if necessary ; COMP: LHLD ICNT ; HL=FNTBL XCHG ; Put into DE LHLD JCNT ; DE=FNTBL+LENGTH ; COMP1: LDAX D ; Compare next byte ORA A ; Null for end-of-file? JZ COMP3 ; If yes, finished with line CMP M ; See if characters are the same JNZ COMP3 ; Return with 'Z' flag set if not eqaul INX D INX H DCR C ; Keep trying JNZ COMP1 ; If not done, check next character XRA A ; Strings are equal, so reset 'Z' flag JMP COMP3 ; COMP2: LDA NEXT ORA A JNZ COMP3 ; If more coming, back to work CALL WRBUF ; Write the final line POP H ; Clear stack from 'CALL COMP' JMP PRNT10 ; Terminate ;... ; ; ; Increment for next compare ; COMP3: LHLD ICNT LXI D,LENGTH DAD D SHLD ICNT DAD D SHLD JCNT RET ;..... ; ; ; Create disk file ; CREATE: PUSH H PUSH D PUSH B LXI D,TFCB MVI C,DFFC ; First erase any similar file CALL BDOS LXI D,TFCB MVI C,MFFC ; Now open new file CALL BDOS POP B POP D POP H RET ;..... ; ; ; Exit routines: ERXIT - come here on error of some type. Print ; msg in (HL), then print 'ABORT' msg. ; EXIRT - normal exit. Print msg in (HL) and ; return to CP/M. ; ERXIT: CALL WEOLC ; Initial CALL WASC LXI H,MSG20 CALL WASC JMP 0000H ; Warm boot - in case of an error ; EXIT: LXI H,MSG17 CALL WASC ; EXIT1: XRA A ; Clear the 'A' reg. and all flags LHLD STACK ; Get the original stack pointer back SPHL ; Set the stack pointer to that address RET ;..... ; ; ; Counts total number of files handled ; FILES: LXI H,MSG19+3 MVI C,5 CALL NMBR1 RET ;..... ; ; ; Counts total number of unique file names handled ; FILESD: LXI H,MSG18+3 MVI C,5 CALL NMBR1 RET ;..... ; ; ; Flush disk output buffer ; FLUSH: LDA HCFLG ; Hard copy this time? ORA A RNZ ; If yes, no file to close PUSH H PUSH D MVI A,1AH CALL WACD LHLD DBUFO LDA DBUFC ; FLUSH1: CPI 128 JZ FLUSH2 MVI M,1AH INX H INR A JMP FLUSH1 ; FLUSH2: CALL WRREC CALL CLOSE POP D POP H RET ;..... ; ; ; Get next filename or filetype from 'MAST.CAT'. Terminate when 'B' ; characterss have been read. If name is shorter than 'B' chars, left- ; justify and blank-fill. ; GETNF: CALL RDCHR ; Get one char from disk STAX D ; Assume good character CPI '.' ; End of filename? JZ PAD CPI ',' JZ PAD CPI ';' JZ PAD CPI CR JZ PAD INX D ; Else keep char & prepare for next DCR B ; Enough chars read? JNZ GETNF ; Jump if not CALL RDCHR ; Else throw away separator RET ; And return ;..... ; ; ; For hard copy to list device, character in 'A' reg. ; HCOPY: LDA PRINT ; Ready to start printing yet? ORA A JZ HCOPY2 ; If not, exit and wait LDA STOP ; Not supposed to print now? ORA A JNZ EXIT ; If not, exit and terminate POP PSW ; Get the character back CALL WACC ; Show on the CRT ; HCOPY1: PUSH H ; Save the values PUSH D PUSH B PUSH PSW MOV E,A MVI C,WCLD ; Send to list device CALL BDOS POP PSW POP B POP D POP H RET ;... ; ; HCOPY2: POP PSW RET ;..... ; ; ; Get a character from the keyboard ; INPUT: PUSH H ; Save the values PUSH D PUSH B MVI C,RCFC CALL BDOS ANI 7FH ; Strip off any parity POP B POP D POP H CPI 'C'-040H ; CTL-C? JZ EXIT1 ; If yes, terminate RET ;..... ; ; ; Move up to 256 bytes of memory, entry conditions ; ; 'HL' 'FWA' of source ; 'DE' 'FWA' of destination ; 'B' number of bytes to move ; MOVE: MOV A,M STAX D INX D INX H DCR B ; One less to go JNZ MOVE ; If not zero, do another RET ;..... ; ; ; Increment the page number for hard copy ; NMBR: LXI H,HEAD3+2 MVI C,2 ; NMBR1: MOV A,M ; Get the value CPI ' ' ; Is it a space? JNZ NMBR2 ; Exit if not MVI A,'0' ; Otherwise call it a zero ; NMBR2: INR A MOV M,A CPI '9'+1 ; Ready to start next digit? JNZ NMBR3 ; If not, finished MVI M,'0' ; Otherwise make this one a zero DCX H ; Work on next column DCR C ; One less to go JNZ NMBR1 ; Go do the next one ; NMBR3: RET ; Finished ;..... ; ; ; If no print, tell what maximum page was ; NOPNT: LXI H,MSG21 ; Turn up a blank line CALL WASC LXI H,MSG22 ; Final page msg CALL WASC LXI H,HEAD3 CALL WASC JMP EXIT ; All done now ; ; ; Fill area between file names and file types uniformly ; PAD: MVI A,' ' ; Blank-fill if necessary STAX D INX D DCR B JNZ PAD+2 RET ;..... ; ; PAD0: PUSH PSW MVI A,'0' JMP PADC ; PAD1: PUSH PSW MVI A,'1' ; PADC: STAX D INX D POP PSW RET ;..... ; ; ;---------------------------------------------------------------------- ; hard copy requests ; ; Print hard copy request from keyboard ; PRHC: LXI H,MSG2 ; Want hard copy? CALL WASC CALL INPUT ; Get character from keyboard ANI 5FH ; Change go upper-case if needed CPI 'Y' JNZ PRHC9 ; No hard copy if not 'Y' answer STA HCFLG ; Set flag for hard copy LXI H,MSG21 ; Turn up a line CALL WASC CALL RPAPER ; Using roll paper? ; ; ; Ask for current date ; LXI H,MSG4 ; Current date CALL WASC MVI B,0 LXI H,HEAD2 ; PRHC1: CALL INPUT ; Get keyboard character CPI CR ; Finished if 'RET' JZ PRHC3 CPI BS JNZ PRHC2 CALL BCKSP JMP PRHC1 ; PRHC2: MOV M,A INX H INR B MOV A,B CPI 34+1 JC PRHC1 CALL BCKSP2 CALL BCKSP1 ; Do not allow a too-long line JMP PRHC1 ; ; ; Ask for starting page ; PRHC3: LXI H,MSG21 ; Turn up a new line CALL WASC LXI H,MSG5 CALL WASC MVI B,0 LXI H,PAGES+2 ; Starting page storage ; PRHC4: CALL INPUT CPI CR JZ PRHC6 CPI BS JNZ PRHC5 CALL BCKSP JMP PRHC4 ; PRHC5: MOV M,A INX H INR B MOV A,B CPI 3+1 ; Three maximum page numbers JC PRHC4 CALL BCKSP2 CALL BCKSP1 ; Do not allow a too-long line JMP PRHC4 ; ; ; Ask for stopping page ; PRHC6: LXI H,MSG21 ; Turn up a new line CALL WASC LXI H,MSG6 CALL WASC MVI B,0 LXI H,PAGEQ+2 ; Quitting page storage ; PRHC7: CALL INPUT CPI CR JZ PRHC9 CPI BS JNZ PRHC8 CALL BCKSP JMP PRHC7 ; PRHC8: MOV M,A INX H INR B MOV A,B CPI 3+1 ; Three maximum page numbers JC PRHC7 CALL BCKSP2 CALL BCKSP1 ; Do not allow a too-long line JMP PRHC7 ; PRHC9: LXI H,MSG21 ; Turn up a new line CALL WASC RET ;..... ; ; end of hard copy requests ;----------------------------------------------------------------------- ; ; Read character from disk ; RDCHR: PUSH B PUSH D LXI D,BUFREC+80H ; One byte past buffer stop address LHLD DBUFI ; Buffer start address MOV A,H ; See if ready to get disk sector CMP D JC NOREAD ; If not continue reading LXI D,FCB ; Otherwise get next record from disk MVI C,RNFC CALL BDOS ORA A LXI H,MSG9 ; Early end? JNZ ERXIT ; Jump if so LXI H,BUFREC ; Pointers to start of buffer ; NOREAD: MOV A,M ; Get character INX H SHLD DBUFI POP D POP B CPI 'Z'-040H ; EOF? RNZ ; If not, keep going ; ; ; If CTL-Z, abort read routine and print the file - end of file marker ; POP H ; If yes, erase CALL from stack LDA ONCE ORA A LXI H,MSG12 CNZ WASC JMP PRNT ; Go print what we have in the buffer ;..... ; ; ; Option for roll paper (changes fanfold areas) ; RPAPER: LXI H,MSG3 CALL WASC CALL INPUT ANI 5FH ; Change to upper-case if needed CPI 'Y' JNZ PRAP1 ; If not, exit MVI A,21H ; 'LXI H,' instruction STA CKST3 MVI A,0CDH ; 'CALL' instruction STA CKST3+3 LXI H,WASD SHLD CKST3+4 LXI H,QUITR SHLD CKST3+1 ; Starts first page with tear tabs SHLD ROLL2+1 ; Finishes last page with tear tabs SHLD WRBUF2+1 ; Finishes each papge with tear tabs LXI H,HEAD1 SHLD CKST4+1 ; Start first page SHLD WRBUF3+1 ; Starts new page ; PRAP1: LXI H,MSG21 CALL WASC RET ;..... ; ; ; Roll up page to terminate ; ROLL: LDA PRINT ; Any printing yet? ORA A JZ NOPNT ; If not, display last page number MVI A,CR CALL HCOPY1 ; Send ; ROLL1: MVI A,LF CALL HCOPY1 ; Send LDA LCNT INR A STA LCNT CPI 54 JC ROLL1 ; ROLL2: LXI H,QUIT ; Final lines to finish page JMP WASD ;..... ; ; ; Set the filename counters to start of table ; SETFNT: PUSH D PUSH H LXI H,FNTBL ; Start of filename table SHLD ICNT ; For first name LXI D,LENGTH DAD D SHLD JCNT ; For second name POP H POP D RET ;..... ; ; ; Set 'DMA' address to 'BUFOUT' location for output to disk ; SETO: MVI C,SDMA LXI D,BUFOUT CALL BDOS RET ;..... ; ; ; Set 'DMA' address to 'BUFREC' location for input from disk ; SETR: MVI C,SDMA LXI D,BUFREC CALL BDOS RET ;..... ; ; ; See if ready to terminate ; TERM: PUSH B ; Save the values PUSH D PUSH H MVI C,KSTAT ; Read console status CALL BDOS ANI 1 ; CRT have a character? POP H POP D POP B JNZ INPUT ; Else get the character RET ;..... ; ; ; Write ASCII character to disk or to list device/CRT ; WAC: CPI SI ; Space take-up character RZ ; If yes, ignore PUSH PSW ; Save the character in 'A' reg. LDA HCFLG ; Making hard copy this time? ORA A JNZ HCOPY ; If yes, go write to list device POP PSW JMP WACD ; Otherwise write to disk ;..... ; ; ; Write ASCII character to console, entry conditions: ; 'A' character to write ; WACC: PUSH H PUSH D PUSH B PUSH PSW MOV E,A MVI C,WCFC CALL BDOS POP PSW POP B POP D POP H RET ;..... ; ; ; Write ASCII character to disk ; WACD: PUSH H PUSH PSW LDA DBUFC CPI 128 JC WACD1 CALL WRREC LXI H,BUFOUT SHLD DBUFO XRA A ; WACD1: INR A STA DBUFC POP PSW LHLD DBUFO MOV M,A INX H SHLD DBUFO POP H RET ;..... ; ; ; Write ASCII string to console, entry conditions: ; 'HL' 'FWA' of string (term. by zero byte) ; WASC: MOV A,M ORA A RZ ; Null character terminates the string ; CALL WACC INX H JMP WASC ; ; ; Write ASCII string to disk, entry conditions: ; 'HL' 'FWA' of string (terminated by zero byte) ; WASD: MOV A,M ORA A RZ ; Null character terminates string ; CALL WAC ; Write the ASCII character INX H JMP WASD ;..... ; ; ; Write end of line to console ; WEOLC: MVI A,CR CALL WACC MVI A,LF CALL WACC RET ;..... ; ; ; Write end of line to disk ; WEOLD: MVI A,CR CALL WAC ; Write the ASCII character MVI A,LF CALL WAC ; Write the ASCII character RET ;..... ; ; ; Write the 'OBUF' line into the disk buffer ; WRBUF: LDA HCFLG ; Printing hard copy? ORA A JZ WRBUF1 ; If not, exit right away ; CALL TERM ; Want to terminate? LDA PRINT ; Already printing? ORA A CZ CKST ; If not, check when ready ; WRBUF1: LXI H,OBUF ; Start of file name buffer CALL WASD ; Write into the buffer CALL WEOLD ; Finish the CR-LF at end of line LDA HCFLG ; Writing hard copy? ORA A RZ ; Exit if not ; LDA LCNT INR A STA LCNT CPI 54 RC ; Exit if less XRA A STA LCNT ; Otherwise reset the count PUSH H PUSH B CALL NMBR ; Increment page count in heading POP B ; WRBUF2: LXI H,QUIT CALL WASD CALL CKSP ; Check on stop request ; WRBUF3: LXI H,HEAD ; Send new page start CALL WASD POP H RET ;..... ; ; ; Write record to disk ; WRREC: PUSH H PUSH D PUSH B LXI D,TFCB MVI C,WRFC CALL BDOS LXI H,MSG16 ; Write error? ORA A JNZ ERXIT ; Jump if so POP B POP D POP H RET ;..... ; ; end of subroutines ;---------------------------------------------------------------------- ; data storage area ; ; Messages ; MSG0: DB CR,LF,'CATALOG X-REFERENCE PGM v4.2 - 11/20/85',CR,LF ; IF USER DB '(includes user numbers for each program)',CR,LF ENDIF ; USER ; MSG1: DB LF,'Do you want to include the ".FRE" space? (Y/N): ',0 MSG2: DB 'Do you want hard copy instead of a file? (Y/N): ',0 MSG3: DB 'Do you want tear tabs to use roll paper? (Y/N): ',0 MSG4: DB 'Current date is: ',0 MSG5: DB 'Start at page : ',0 MSG6: DB 'Quit at page : ',0 MSG7: DB '++ UNABLE TO OPEN MAST.CAT ++',CR,LF,0 MSG8: DB CR,LF,'** READING MAST.CAT FILE **',CR,LF,0 MSG9: DB '++ READ ERROR OR EARLY EOF ++',CR,LF,0 MSG10: DB CR,LF,' LAST NAME THIS SECTION: "' MSG11: DB ' "',CR,LF MSG12: DB ' WRITING TO OUTPUT FILE',CR,LF,LF,0 MSG13: DB ' WORKING ON NEXT SECTION',CR,LF,0 MSG14: DB '** WRITING OUTPUT FILE **',CR,LF,0 MSG15: DB '++ UNABLE TO MAKE OUTPUT FILE ++',CR,LF,0 MSG16: DB '++ DISK OR DIRECTORY FULL ++',CR,LF,0 MSG17: DB CR,LF,' DONE: ' MSG18: DB ' 0 UNIQUE NAMES',CR,LF,' ' MSG19: DB ' 0 TOTAL FILES',CR,LF,0 MSG20: DB '++ PROGRAM ABORTED ++' MSG21: DB CR,LF,0 MSG22: DB 'FINAL PAGE IS: ',0 ;.... ; ; ; Misc storage locations ; DASH: DB ' - ' ; Used to format printout (put length in ; 'DASLEN' equate) ;..... ; ; CCP: DB 0 ; Initial 'CCP' page CNT: DB 0 ; Number of diskid'S ON LINE DBUFC: DB 0 ; Output buffer count HCFLG: DB 0 ; Hard copy flag, '1' for hard copy MATCH: DB 0 ; Used if a match during "end around" LCNT: DB 0 ; Line count for hard copy NEXT: DB 0 ; Input next series of files ONCE: DB 0 ; For a particular print message PRINT: DB 0 ; Begin printing flag REPEAT: DB 0 ; For continuous printing STOP: DB 0 ; Stop printing flag XDONE: DB 0 ; Use last name file ; DBUFI: DW 0 ; Input buffer pointer DBUFO: DW 0 ; Output buffer pointer FNTP: DW 0 ; File name table pointer ICNT: DW 0 ; Outer loop index JCNT: DW 0 ; Inner loop index SAVEOB: DW 0 ; Save output buffer position ;..... ; ; ; Heading line for hard copy ; HEAD: DB CR,LF,LF,LF,CR,LF HEAD1: DB 'Master Catalog as of ' HEAD2: DB ' Page ' HEAD3: DB ' 1',CR,LF,LF,LF,0 PAGES: DB ' 1 ' PAGEQ: DB ' ' QUIT: DB CR,LF,LF,LF,LF,LF,0 QUITR: DB CR,LF,LF,LF,LF DB '- ' DB ' ' DB ' -' DB CR,LF,LF,LF,LF,LF,0 ;..... ; ; ; To give the final listing a left-margin so that it can be more easily ; used in a binder, extra spaces can be inserted automatically into ; 'HEAD1' and 'PRBUF' areas when answering the question at boot time. ; (None needed if your printer has ; adjustable margins.) ; OBUF: DB ' ' ; Output buffer, 75 columns max. DB ' ' DB ' ' DB ' ' DB ' ' TRASH: DB ' ' ; Storage for unwanted disk name ;..... ; ; ; FCB for reading MAST.CAT ; FCB: DB 0,'MAST CAT',0 ;2nd 0 = extent # DB ' ' DB ' ' ; Rest of 'FCB' for 32 bytes DB 0 ; Number field ; DEFLT: DB 0,'MAST ' DEF1: DB 'LST' ; Default output file name ;..... ; ; DS 80 ; Minimum stack size ; BUFF EQU ($+255)/256*256 ; Insures an even sector ORG BUFF ; 'BUFREC' needs to be on a half-page ; ; STACK EQU BUFF-2 ; Local stack BUFOUT: DS 128 ; 1-record output buffer BUFREC: DS 128 ; 1-record input buffer FNTBL: DS 0 ; File name table starts here ; END START