home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
CATLOG
/
XCAT43.LBR
/
XCAT43.AQM
/
XCAT43.ASM
Wrap
Assembly Source File
|
2000-06-30
|
32KB
|
1,474 lines
; 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 CROSSREF. - Irv Hoff
;
;=======================================================================
;
;
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 <LF>
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
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 <CR><LF>
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