.Z80 CSEG ; versno equ '0' revno equ '2' ; ; XCAT version 5 -- CATALOG CROSS-REFERENCE PROGRAM FOR MAST.CAT ; ; by Harold F. Bower, WA5JAY ; 23 June 1985 ; ; Derived from XCAT42.ASM BY IRV HOFF ; ;---------------------------------------------------------------------- ; Many of the basic routines to access DateStamper(tm) and perform ; Cursor activities in conformance with the DateStamper(tm) standard ; were provided by Bridger Mitchell of Plu*Perfect Systems. ; ; DateStamper is a trademark of Plu*Perfect Systems, Idyllwild, CA ;---------------------------------------------------------------------- ; ; This program makes a cross-reference listing of the MAST.CAT file. ; It can display listings to the Console, Printer or a Disk file. ; ; Full compatibility with the previous version of XCAT is ; provided by Version 5. Additionly, significant enhancements to ; user interface have been provided in a general manner so that ; the user should have no difficulty in tailoring XCAT to his own ; terminal. A default line-oriented mode of operation is also ; provided in a manner similar to older versions. Operation is ; still enhanced due to the ability to repeat execution from within ; the program, and to vary the program parameters using assigned ; control keys. ; ; The parameters that can be varied from within the program ; and the assigned keys are: ; ; ^F (Control-F) - Change the fields to be appended to disk #s ; Prompts are given for USER and DATE fields. ; ^L (Control-L) - Log the Drive and User where the desired ; Master Catalog (MAST.CAT) is located. ; ^O (Control-O) - Output device. The user is asked to select ; among Console, Printer and Disk File. If the ; printer is selected, additional questions on ; whether to use roll paper with cut lines or ; Hardware formfeed, and spaces to adjust the ; left margin are asked. If a Disk file is ; selected, the drive/user and file name can ; be changed. ; ^S (Control-S) - Define Search mask. Enters an ambiguous ; or unambiguous file name and type and optional ; disk ID (three char type) to match during the ; X-Ref process. Only matching names will be ; included in the output. If a non-ambiguous ; disk ID is given, a special Directory form of ; output is used. A leading comma is used to ; indicate that the entry is a Disk ID. ; ^Z (Control-Z) - This key re-draws the screen and erases any ; accumulated screen messages. This command ; does not appear on the displayed commands. ; ; In addition, the basic parameters can be assigned from the ; basic command line as an 'Expert' mode of operation. When argu- ; ments are passed on the command line as shown below, the program ; is executed immediately after the windows are formed, and runs ; to execution. If an error is detected, the program reverts to ; the menu-driven mode for correction and re-execution. Examples ; of proper entries are: ; ; XCAT d5:MAST.PRN -F $U ; Get MAST.CAT from Drive B, user 0, and place a file on ; Drive D, User 5. Output will be directed to the File ; and will only include basic data and USER field. ; XCAT *.MAC,504 -C A3: -F ; Get MAST.CAT from the current drive/user, and output ; to a default MAST.LST file on Drive A, user 3. ; XCAT ?CAT??.COM $D -P ; Get MAST.CAT from current drive/user, Output only files ; matching "?CAT??.COM" to the Printer with only dates. ; XCAT ,810 -C ; Get MAST.CAT from default drive/user and list directory ; format for disk -.810 to the console. ; ; The ordering of these parameters is not important. The basic ; operators are signified by the following characters: ; ; "<" - Select drive/user holding the MAST.CAT file ; ">" - Select destination of the optional disk file ; "-" - Specify which output device gets the data ; "$" - Define optional fields to append to file names. ; "," - Specifies an ambiguous or non-ambiguous disk ID ; for a search criteria. ; - No leading operator signifies that entry is name ; and type to match during X-Ref output. A comma ; may follow the disk Name.Typ to select certain ; disk(s), as : "*.MAC,8??". ; ; This version also incorporates a method of sensing the format ; of MAST.CAT (which optional fields are present). This is done ; by the addition of a special entry as the first 'IGNORE' entry ; in the brackets at the beginning of each MAST.CAT file. The ; entry is added automatically if MAST.CAT is formed by the compan- ; ion MCAT version 5.xx, but can be manually generated as: ; ; ({;|85}) ; / || \ \ \___Closing bracket. Add any Ignore names before ; Opening / || \ \ this closing bracket ; Bracket _/ / \ \ \____Current year. Add if Vertical Bar present. ; / \ \_______Vertical Bar. Add if DATES to be added. ; Opening Left \___Semicolon. Add if USER areas to be added. ; Curly Brace. ; ; If Only basic File and disk names/types are to be cataloged, ; only the left and right curly braces should be added to tell ; XCAT that neither optional field are present. If the left ; curly brace is not sensed immediately after the opening bracket, ; XCAT assumes that no definition is present, and assumes the ; flags are as stated in the Status window when XCAT is activated. ; Default settings are that both are TRUE, but this can be changed ; by varying the DEFB statements for DATES and USER. ; ; In addition to flags for optional fields, other flags have ; been added to provide default values for: disk/user for MAST.CAT, ; date format (mm/dd/yy or dd/mm/yy), date separation character ; (typically "/" for US dates, and "." for European dates), default ; output device (Console, Printer or Disk File), size of the CCP, ; and number of lines per page to be printed on hardcopy output. ; ; Harold F. Bower 'Hal' WA5JAY ; Box 946 ; APO NY 09128 ; ;======================================================================= ; ; 08/23/85 Restructured groupings of routines, changed screen layout, ; v5.02 added buffered input and disk output, selective search by ; disk type, and option for Hardware formfeed and # lines. ; Fixed bug in setting flags with MAST.CAT having only dates. ; - Harold F. Bower ; ; 06/23/85 Bug-fixing release. Added screen redraw command and CCP ; v5.01 and CCP sizing word in header for non-standard CCP (or rep- ; lacement) sizes. - Harold F. Bower ; ; 06/16/85 Basic release. ; v5.00 - Harold F. Bower ; ;---------------------- Previous Versions ------------------------------ ; v4.2 - 08/22/84 Fixed error, restored original format - Irv Hoff ; v4.1 - 08/20/84 Optional user area added - Paul Traina ;======================================================================= ; NO EQU 0 YES EQU NOT NO ; FALSE EQU NO TRUE EQU YES ;..... ; ; ASCII characters ; BELL EQU 07H ; Bell character BS EQU 08H ; Backspace LF EQU 0AH ; Line feed FF EQU 0CH ; Form Feed character CR EQU 0DH ; Carriage return SI EQU 16H ; Synch Idle EOF EQU 1AH ; End of File character ESC EQU 1BH ; Escape character DEL EQU 7FH ; Delete Character ; ; M80 EQU YES ; Assembler type. YES = Macro-80 ; if NOT M80 ORG 100H endif ; ; JP START ; ;======================================================================= ; DateStamper TERMCAP Terminal Install data required by SETTERM ; Do NOT insert any code generating instructions between ; the following definitions and the initial JUMP ; and keep all definitions to the same length. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ROWNO: defb 0 ; Terminal number in data base & rowno TNAME: defb 'Heath 19' defb 0,0,0,0,0,0,0 ; 15 bytes ; THEIGHT: defb 24 ; Rows TWIDTH: defb 80 ; Columns USELAST: defb 0 ; Use last w/o scrolling ROWFIRST: defb 0FFH ; TRUE if ROW sent first BINARY: defb 0FFH ; Send binary (not ASCII) coordinates ROWBIAS: defb 20H COLBIAS: defb 20H COMPFLG: defb 0 ; Complement binary value ; LEADIN: defb ESC,'Y',0,0,0,0,0 FASTFLG: defb 0 ; Last byte NZ --> use fast routine MIDSTR: defb 0,0,0,0, 0,0,0,0 TAILSTR: defb 0,0,0,0, 0,0,0,0 ; CLRSCRSTR: defb ESC,'E',0,0, 0,0,0,0 ; Clear screen & home CLREOSSTR: defb ESC,'J',0,0, 0,0,0,0 ; Clear to end of scr CLREOLSTR: defb ESC,'K',0,0, 0,0,0,0 ; Clear to end of line ; INSLINSTR: defb ESC,'L',0,0, 0,0,0,0 ; Insert line DELLINSTR: defb ESC,'M',0,0, 0,0,0,0 ; Delete line CURRUPSTR: defb ESC,'A',0,0, 0,0,0,0 ; Cursor up HILITSTR: defb ESC,'p',0,0, 0,0,0,0 ; Hilite ON UNHILITSTR: defb ESC,'q',0,0, 0,0,0,0 ; Hilite OFF VCSTR: defb '|',0,0,0, 0,0,0,0 ; Vertical divider HCSTR: defb '=',0,0,0, 0,0,0,0 ; Horizontal divider ; ; These are slow on H19 ; ;VCSTR: defb ESC,'F',96,ESC,'G',0,0,0 ; Vertical divider ;HSCTR: defb ESC,'F',97,ESC,'G',0,0,0 ; Horizontal divider ; defb 0,0,0,0,0,0,0,0 ; 16 bytes filler defb 0,0,0,0,0,0,0,0 ; KAYVIDPORT equ 1DH ; Kaypro Video port address for configuration ; ;--------------- Additional Configuration Flags ------------------------ ; ; The following stores the BCD default year for header data ; when DateStamper(tm) is not installed. It MUST immediately ; follow the above Configuration File. ; CURYR: defb 85H ; Current Year ; ; Select NO for MAST.CAT files that do not include date fields stored ; as : |ddmmyy. Set to YES if date fields are in the MAST.CAT file. ; DATES: defb YES ; YES to display date fields ; ; Select NO for normal display or YES if your MAST.CAT file includes ; user numbers for each program. ; USER: defb YES ; YES to display user numbers ; ; This byte stores the binary drive designator to use for the default ; location of the MAST.CAT file. Change it to the drive you want the ; program to assume that a Master Catalog exists at startup. It can ; be overridden by command line or menu command. Insert 0FFH to ; default to current drive. ; DEFMDR: defb 0FFH ; This assumes drive C. ; ; This byte stores the user area on the default drive for the MAST.CAT ; file. Change it to suit your storage policy for a Master Catalog. It ; can be overridden by command line or menu command. Insert 0FFH to ; default to current user area. ; DEFMUS: defb 0FFH ; This assumes user area 0. ; ; Change the following byte to reflect your default output if ; no redirection operator is specified on the input line. ; 'C' = Console ; 'F' = Disk File ; 'P' = Printer ; ODEVICE: defb 'C' ; Output re-direction operator ; ; Change the following to suit yout tastes in date field of ; the cross-referenced output. Conventional forms are mm/dd/yy ; for US format (set below to "YES" and "/") and dd.mm.yy for ; European format (set below to "NO" and "."). ; USEURF: defb YES ; YES = mm/dd/yy, NO = dd/mm/yy SEPCHR: defb '/' ; Character to separate day,month,year ; ; The following value is extracted from the code to provide the ; ability to adapt XCAT to non-standard CCP (or replacement) sizes. ; Replace the listed value with the size of your CCP in bytes. ; CCPOFFSET: defw 0800H ; Standard CCP size is 2K bytes (0800H) ; ; This byte stores the number of lines per page of output to the ; Printer. Insert the number of lines you want to constitute a page ; of output. With roll paper, this will be the total number of lines ; between cut lines. When hardware formfeed is selected, the number ; of printed entries will be six less than the value stored here. ; DEFLPP: defb 60 ; ;======================================================================= ; ; Offsets into Directory FCB ; FN EQU 01 FT EQU 09 EX EQU 12 NR EQU 32 ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; P R O G R A M S T A R T S H E R E ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; START: LD HL,0 ADD HL,SP ;'CCP' return address LD (STACK),HL LD SP,STACK ; ; Print opening banner and terminal type (if any) ; call ILPRT defb CR,LF,'XCAT 5 ',0 ld hl,TNAME ; See if terminal installed ld a,(hl) or a jp z,NOTERM push hl call ILPRT defb 'for - ',0 pop hl call HLPRT ld bc,0 ; Give max delay STDLY: dec bc ld a,b or c jp nz,STDLY ; Pause a little while ; ld hl,TNAME ; Check for Kaypro version. ld a,(hl) ; Get first char of term name call UPPER cp 'K' jp nz,NOTERM inc hl ld a,(hl) call UPPER cp 'A' jp nz,NOTERM ld a,CR call CRTOUT in a,(KAYVIDPORT) ; Read Kaypro-84 video port inc a jp nz,NOTERM ; xor a ; FF => Kaypro-83 ld (HILITSTR),a ; Zap Kaypro-84 attributes ld (UNHILITSTR),a ld a,'|' ; ..and set ordinary chars ld (VCSTR),a ld a,'-' ld (HCSTR),a ; ..fall thru.. ; NOTERM: LD A,(TBUF+2) ; Was help requested ? CP '?' jp nz,STARTX ld a,(TBUF) ; Only one question mark ? cp 2 ; ..if more, then file spec. JP Z,HELP ; Jump if so, and exit ; ; Set High memory page limit for Master Catalog data ; STARTX: LD HL,(BDOS+1) ;start of 'BDOS' area ld l,0 ex de,hl ; Move to DE.. ld hl,(CCPOFFSET) ; ..and get offset ld a,e ; 16-bit subtract sub l ld l,a ld a,d sbc a,h LD (CCP),A ;store 'CCP' starting page ; ; Set buffer sizes and starting addresses ; and 0FCH ; Set on 1K boundary ld h,a ld bc,FNT ld a,b and 0FCH ; Buffer start on 1K boundary add a,04H ; ..past top of pgm ld d,a sub h jp nc,MEMERR ; ..Error if no space ld a,h sub d ; Calculate total #K avail rra ; Divide by 2 ld b,a ld c,0 ; Null low bytes ld e,c ld l,c ld (MEMTOP),hl ; Save top of high buffer ex de,hl ld (INADR),hl ; Save start of Input buffer add hl,bc ; ..add BUFLEN ld (OUTADR),hl ; Save start of Output buffer ld h,b ld (BUFLEN),hl ; Save buffer length ; ; Initialize software left margin for printed output ; ld de,HEAD1 ; Reset leading spaces. ld a,SI ; ..with NOP Shift-in chars ld b,9 call PADDIT ld de,PRBUF ld b,9 call PADDIT ; ; Set the default number of lines per page for printer. ; ld a,(DEFLPP) ; Get default sub 6 ; ..subtract header length ld (LPP1+1),a ; ..and store ld (LPP2+1),a ; ; Clear Screen and check for DateStamper(tm) ; call CHKCRLF ; Do CRLF if no cursor addr. ld hl,CLRSCRSTR ; Clear screen if possible call HLPRT ld a,6 ; Set current line ld (SCRLIN),a ld d,a ; ..and cursor (for errors) ld e,0 call SETCUR ; call CKCLK ; See if DateStamper installed ld a,l or h jp nz,ST0 ; Bypass next code if not there call ILPRNL defb ' !! DateStamper NOT Installed !!',BELL,0 xor a ; Flag the fact jp ST1 ; ST0: ld a,YES ; Show that clock here ST1: ld (DSFLAG),a or a ; Test it jp z,ST2 ; ..if not there, manually enter date call GTDATE jp ST3 ; ST2: call CURDAT ; Get manual date ; ST3: ld hl,TBUF ; Move command tail to Command.. ld de,CBUFF ; ..Buffer for processing ld b,32 call MOVE ; ; See if this is for immediate execution, and set flag accordingly ; ld hl,TBUF ; Point to CP/M Buffer ld a,(hl) or a jp z,ST3AA ; Show not immediate if no tail ld b,a ST3LL: inc hl ld a,(hl) cp ' ' ; Is this space ? ld a,TRUE jp nz,ST3AA ; ..If not show Immed execution dec b jp nz,ST3LL xor a ; If done, all spaces. ST3AA: ld (IMMED),a ; ; Initialize search criteria to everything ; ld de,SRNAM ; search name string ld b,14 ; ..name and type plus disk name ld a,'?' call PADDIT ; ld b,12 ; Number of chars to move ld de,DEFLT ; Destination 0,name.typ call DEFLT2 defb 0,'MAST LST' DEFLT2: pop hl ; Get source string addr call MOVE ; ld a,(ODEVICE) ; Set Console default device ld (OUTFLG),a ; ; Get current user and disk, save for EXITing ; ld c,CURDSK ; Get current disk call BDOS ld hl,CDRIVE ld (hl),a ; ..Save in Current Disk.. inc hl inc hl ld (hl),a ; ..and Output File drive ld a,(DEFMDR) ; Store default drive.. cp 0FFH ; Use default drive ? jp nz,DEFLT0 ; ..jump if not ld a,(CDRIVE) ; Get default DEFLT0: dec hl ld (hl),a ; ..in master. ; call GETUSR ; Now get current user ld hl,CUSER ; ..and save in Current user.. ld (hl),a inc hl inc hl ld (hl),a ; ..and Output File user. ld a,(DEFMUS) ; Get default master user.. cp 0FFH ; Use default user ? jp nz,DEFLT1 ; ..Jump if NOT ld a,(CUSER) ; ..else get current user DEFLT1: dec hl ld (hl),a ; ..and store. ; ; Examine command line arguments, and Parse string if present. ; ld hl,CBUFF+1 ; Set buffer address ld (CMDPTR),hl call PARSE ; Parse Command tail if present ; ; Draw screen and set current line for SCROLL routine reference. ; ld hl,CLRSCRSTR call HLPRT ld a,5 ld (SCRLIN),a call DRAWSCR ; Draw the screen ; call ILPRNL defb 'For Help, reboot then type : XCAT ?',0 call SCROLL ; ld a,(LEADIN) ; Give CRLF and text if no cursor addr or a jp nz,START2 call CRLF call ILPRT defb 'Today''s Date is : ',0 jp START3 ; ;************************************************ ; M A I N P R O G R A M L O O P * ;************************************************ ; DRWAG0: ld a,5 ; Reposition to line 6.. ld (SCRLIN),a ld de,5*256+0 ; Position cursor call SETCUR jp DRWAG1 ; ..and resume. ; ; Rewrite Screen in case something messed it up. ; DRWAGN: ld a,5 ; Position to line 6.. ld (SCRLIN),a call DRAWSCR ; Draw the whole screen DRWAG1: call SCROLL ; Go to next line call CLEOSCR ; ..and clear rest of screen START2: ld a,(TWIDTH) ; Get screen width sub 15 ; ..move in from edge ld e,a ld d,0 call SETCUR START3: call DATLIN ; Convert date to string ld a,FALSE ; Let it read clock ld (RELCLK),a call RDTIM ; ..read time ld a,(SCRLIN) ; ..and re-position cursor ld d,a ld e,0 call SETCUR ; AGAIN: call STSCLR ; Clear status window ; ; Clear working storage memory ; ld de,CNT ; From here through TMPSEP ld hl,TMPSEP ld a,l sub e ; One byte since < 128 ld b,a inc b xor a call PADDIT ; ..fill with zeros. ; ; Set flags for search criteria ; ld hl,SRNAM ; Set for name search ld a,'?' ld b,11 SNLOOP: cp (hl) jp nz,STPCHK ; Jump if not same inc hl dec b jp nz,SNLOOP ld a,TRUE ; Set true for all names ld (ALLNAM),a ; STPCHK: ld hl,SRDISK ld a,'?' ld b,3 STLOOP: cp (hl) jp nz,STNEQL inc hl dec b jp nz,STLOOP ld a,TRUE ; Set true for all IDs ld (ALLDSK),a ; ; Reset page numbers and file counts ; STNEQL: ld de,HEAD3 ld b,2 call PAD call PAD0 ld de,MSG9A ; Now File counts ld b,3 call PAD call PAD0 ld de,MSG9B ld b,3 call PAD call PAD0 ; call CALCLENS ; Calculate entry lengths ; ; Reset File buffer In/Out lengths to maximum size. ; ld hl,(BUFLEN) ld (INLEN),hl ld (OUTLEN),hl ld (INPTR),hl ; Set for initial read ; ;================== read 'MAST.CAT' ======================== ; ld a,(IMMED) ; No prompt if immediate execution or a jp nz,START9 ; call CHKCRLF ; Crlf if no Screen installed. START1: call ILPRT defb CR,'READY - (^C = Abort, Space or = Continue) : ',0 CALL CMDIN ;get char from kybd & sense commands CP ' ' jp z,START9 ; This is CONTINUE cp CR jp nz,START1 ; ..repeat if not right answer ; START9: call ILPRT defb 'Executing...',0 call SCROLL ; ; Open MAST.CAT ; call ilpsts ; Inform user defb '..Opening MAST.CAT..',0 ; xor a ; Clear FCB elements for OPEN ld (FCB+EX),a ld (FCB+NR),a call OPEN ; Open input file ld hl,0000 ld (OUTPTR),hl ; Set pointer for clear buffer ; call STSCLR ;-- ; ; Check for DataBase layout in IGNORE list and load if so. ; Skip the 'IGNORE' file names at the head of the 'MAST.CAT' file ; SKPIGN: call RDCHR ; Check for start of Ignore cp EOF jp z,PREEOF ; Abort if premature EOF cp '(' jp nz,SKPBAD ; ..skip to error msg ; call RDCHR ; Get next character cp '{' ; Curly braces starts format hdr. jp z,SKIPGO ; ..jump if OK..else.. ; SKPBAD: call ILPRNL defb '** ERROR in MAST.CAT Ignore list **',0 call ILPRNL defb '** Proceeding with Defaults **',0 call SCROLL jp SKPIG3 ; ; Examine Database FORMAT entry in IGNORE list, and set flags ; SKIPGO: xor a ; Preset DIFF to show same ld (DIFF),a ; ld hl,USER ; Set first flag position ld de,DBUSER ; ..and Database flag pos'n call RDCHR ; Get first option cp ';' jp nz,GT0 ld a,TRUE call CPDIFF ; Compare for differences call RDCHR ; ..get next one jp GT01 ; GT0: push af ; Save prev char ld a,FALSE call CPDIFF ; Compare for differences pop af ; ..now restore GT01: cp '|' ; ..Check DATES included ld hl,DATES ; Set pointers for next field ld de,DBDATE ld a,FALSE jp nz,GT1 ld a,TRUE call CPDIFF ld de,MYEAR ; Default Master Year is next call GET2 ; ..so load jp GT11 ; GT1: call CPDIFF ; Check differences GT11: ld a,(DIFF) ; Check flag for differences or a jp z,SKPIG1 ; Jump if defaults and DB same call ILPRNL defb '++ MAST.CAT and Default Different ++',BELL,0 call ILPRNL defb '==> Proceed (P), Change (C), or Abort (A) : ',0 GT15: call GETCH ; Get response cp 'P' jp z,GT20 cp 'C' jp z,GT30 cp 'A' jp z,GT40 ld a,BELL call CRTOUT jp GT15 ; GT20: call CRTOUT ; Echo letter call SCROLL jp SKPIG1 ; and keep going ; GT30: call CRTOUT ; Echo 'C' call SCROLL ld a,(DBUSER) ; update user ld (USER),a ld a,(DBDATE) ; ..and date ld (DATES),a call STUPD1 ; Update status line jp SKPIG1 ; and Continue ; GT40: call CRTOUT call SCROLL jp AGAIN ; Jump back to main loop ; SKPIG1: CALL RDCHR ; ..else use defaults and skip SKPIG2: cp EOF jp z,PREEOF CP ')' ;end of ignore? JP NZ,SKPIG1 ; ; Set lengths and defaults in the single record buffer. ; SKPIG3: call CALCLENS ; Re-calculate entry lengths ld a,'-' ; Reset defaults ld de,RECUSR ld b,2 call PADDIT call NULDAT ; ; Main read loop: Read FN,FT,DN,DT from MAST.CAT, discard DN, enter the ; rest in the FNT. IDLEN characters are placed in memory for each file ; name. ; SKPLOP: call STSCLR ; Clear status message window ; ; Skip to end of line (L/F) in MAST.CAT file ; SKIPLF: CALL TERM ;ready to quit? CALL RDCHR ;read until cp EOF jp z,PREEOF ; Exit if Premature EOF CP LF JP NZ,SKIPLF ; ;================= Process file from 'FNT' to output ======================= ; ; Open output file if destination is to disk file. ; ld hl,SRDISK ; Check for Dir type list ld b,3 ld a,'?' PRNTTL: cp (hl) jp z,PNODIR ; If match, Not Dir output inc hl dec b jp nz,PRNTTL ; ..check all three chars ld a,TRUE jp PNODI0 ; PNODIR: xor a ; Cheap NO PNODI0: ld (DIRFLG),a ; Set flag ; ld de,DHEAD1 ; Move disk ID to header ld hl,IBUF+11 ld b,3 call MOVE ; ld a,(OUTFLG) ; Print header for correct device cp 'P' push af call z,WRBUF0 ; Print header banner 1st page pop af cp 'F' call z,DSKHDR ; ..special banner for disk ; ld a,(DIRFLG) or a ; Bypass setup if Not Dir jp z,PRNT ld b,4 ; Start with 4 per line ld a,(DATES) or a jp z,PNODI2 ; Keep 4 if No Dates present dec b ; ..3 if dates.. ld a,(USER) or a jp z,PNODI2 dec b ; ..2 if both PNODI2: ld a,b ld (NUMPRL),a ; Store entries per line ; PRNT: ld a,(OUTFLG) ; Does output go to Disk File ? cp 'F' call z,CREATE ; If so, make output file ; PRNT3: call PRIME ; Load unpacked buffer ; ld a,(XDONE) ; If EOF here, then No matches or a jp nz,PRNT13 ; ld a,(DIRFLG) ; Normal or Dir listing ? or a jp nz,DPRNT ; ..jump if Directory Format ; PRNT4: ld de,IBUF ; Move Name/typ/ID to temp ld hl,RECNAM ld b,14 push hl call MOVE pop hl LD DE,OBUF LD B,8 CALL MOVE LD A,'.' ;copy '.' into 'OBUF' LD (DE),A INC DE LD B,3 ;copy type(ICNT) into 'OBUF' CALL MOVE LD HL,DASH ;copy ' - ' into 'OBUF' LD B,5 CALL MOVE ; call MVDATA ; Copy User/Date as required ; XOR A ;flag end of 'OBUF' LD (DE),A inc a ;start with one disk ID on the line LD (CNT),A ; PRNT5: CALL FILES ;increment file count push de ; Preserve OBUF call PRIME ; Load next record pop de LD C,11 ;compare file name and file type CALL COMP ;see if the same but for disk id ; ; If the same filename and type, jump to add data ; JP Z,PRNT6 ; ; Since different, put 'OBUF' into output buffer ; PRNT5A: CALL FILESD CALL WRBUF ;write the line to disk buffer LD A,(XDONE) ;see if finished now OR A JP NZ,PRNT13 ;if yes, go terminate JP PRNT4 ; Go get another output line ; ; Since file names are identical, cross-reference the disk ID. ; PRNT6: ld a,(XDONE) ; If EOF detected, Write buffer and quit or a jp nz,PRNT5A ld a,(NUMPRL) ld c,a ld a,(CNT) ; Add one to number on line cp c ; Exit if less than max number on line JP C,PRNT8 CALL WRBUF ;write 'OBUF' line to disk buffer LD DE,OBUF ;start new 'OBUF' line ; LD B,15 LD A,' ' call PADDIT ; XOR A ;back to one disk ID on 'OBUF' line ; PRNT8: INC A LD (CNT),A LD A,' ' ;insert 2 blanks in 'OBUF' call TWOCHR call MVDATA ; Move User/Date to OBUF XOR A ; ..flag end LD (DE),A JP PRNT5 ; PRNT13: call PRMSG9 PRNT14: CALL FLUSH ;finish end of file ld a,(OUTFLG) ; Printing Hard Copy ? cp 'P' jp nz,PRNT15 CALL ROLL ld a,(HWFFD) or a ; No CRLF if HW formfeed jp nz,PRNT15 call WEOLD ; Compensate for end-of-page PRNT15: ld a,(IMMED) ; If immediate, or a jp nz,EXIT1 ; ..just quit. ld a,(THEIGHT) ; Don't blank screen too soon sub 2 ; ..if too close to bottom.. ld b,a ld a,(SCRLIN) cp b call nc,WRPAUS ; ..pause til it is read JP AGAIN ;finished ; ;..... ; Process Directory form of output ; DPRNT: call DIRFORM ; Output directory ; xor a ; Flag end of 'OBUF' ld (de),a inc a ; Start with one entry on the line ld (CNT),a ; DPRNT5: call FILES ; Increment file count push de ; Preserve OBUF call PRIME ; Load next record pop de ; ld a,(XDONE) ; If EOF, write Buffer & quit or a jp nz,PRNT5A ld a,(NUMPRL) ld c,a ld a,(CNT) ; Add one to number on line cp c ; Exit if less than max number on line jp c,DPRNT8 call WRBUF ; Write 'OBUF' line to disk buffer ld de,OBUF ; Start new line ; DPRNT6: xor a ; Back to one ID on OBUF line DPRNT8: inc a ld (CNT),a cp 1 ; No separation on first entry jp z,DPRN8C ld hl,SEPSTR ld b,5 call MOVE DPRN8C: call DIRFRM ; Output record xor a ; ..flag end ld (de),a jp DPRNT5 ; ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; SUPPLEMENTAL ROUTINES ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ;..... ; Load Default year into OUTPUT file ; DEFYR: ld a,(MYEAR) ; Get first byte.. ld (de),a ; ..and load inc de ld a,(MYEAR+1) ; ..Now second digit ld (de),a inc de ret ; ;..... ; Set Values for entry size and length based on options ; CALCLENS: ld a,(DATES) ; Check for DATE option ld e,10 ; Assume NO and put # entries ld d,4 ; (size of entry) or a jp z,ST2A ; ..bypass actual load if not. ld e,4 ld d,13 ; ST2A: ld a,(USER) ; Check for USER option or a jp z,ST2B ; ..bypass if no option ld a,e ; Have USER, so check for DATE cp 10 ; ..10 means NO Dates ld e,7 ; Assume just USER.. ld d,7 jp z,ST2B ; ..and jump if so. ld e,3 ; Else set size for both options ld d,16 ST2B: ld a,e ; Set number of entries ld (NUMPRL),a ld a,d ; ..and Size of entry ld (IDLEN),a ret ; ;..... ; Compare Filename.typ in IBUF with that in Record buffer. ; COMP: PUSH HL PUSH DE ld hl,IBUF ld de,RECNAM ; COMP1: LD A,(DE) ;compare next byte CP (HL) JP NZ,COMP2 ;jump if not equal INC DE INC HL DEC C ;keep trying JP NZ,COMP1 XOR A ;strings are equal ; COMP2: POP DE POP HL RET ; ;..... ; Compares value in A with (hl) and stores A in (de), ; Then stores TRUE in location DIFF if not equal. ; (used in sensing defaults with mask in IGNORE lists) ; CPDIFF: cp (hl) ld (de),a ret z push hl ld hl,DIFF ld (hl),TRUE pop hl ret ; ;..... ; Move up to 256 bytes of memory, entry conditions: ; HL - Addr of Source DE - Addr of Destination ; B - number of bytes to move ; MOVE: LD A,(HL) LD (DE),A INC DE INC HL DEC B ;one less to go JP NZ,MOVE ;if not zero, do another RET ; ;..... ; Fill area between file names and file types uniformly ; PAD: LD A,' ' ;blank-fill if necessary PADDIT: LD (DE),A INC DE DEC B JP NZ,PADDIT RET ; ;..... PAD0: PUSH AF LD A,'0' JP PADC ; PAD1: PUSH AF LD A,'1' ; PADC: LD (DE),A INC DE POP AF RET ; ;..... ; Check for ASCII digit in range '0'-'9'. Return Carry set if not ; NUMCK: cp '0' ret c cp '9'+1 ccf ret ; ;..... ; Convert Low Nybble in A-register to Hex ASCII digit ; MAKHEX: and 0FH ; Mask off Hi Nybble add a,90H daa adc a,40H daa ret ; ;............................................................ ; Status Reporting and Updating Routines. | ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;..... ; Counts total number of files handled ; FILES: PUSH BC PUSH HL LD HL,MSG9A+3 LD C,4 CALL NMBR1 POP HL POP BC RET ; ;..... ; Counts total number of unique file names handled ; FILESD: PUSH BC PUSH HL LD HL,MSG9B+3 LD C,4 CALL NMBR1 POP HL POP BC RET ; ;..... ; Increment the page number for hard copy ; NMBR: LD HL,HEAD3+2 LD C,2 ; NMBR1: LD A,(HL) ;get the value CP ' ' ;is it a space? JP NZ,NMBR2 ;exit if not LD A,'0' ;otherwise call it a zero ; NMBR2: INC A LD (HL),A CP '9'+1 ;ready to start next digit? ret NZ ;if not, finished LD (HL),'0' ;otherwise make this one a zero DEC HL ;work on next column DEC C ;one less to go JP NZ,NMBR1 ;go do the next one ; NMBR3: RET ;finished ; ;..... ; Print Ending message to appropriate device ; PRMSG9: ld a,(OUTFLG) ; For console ? cp 'C' jp z,PRMS9A ; Print status to console ; call PRMS9A ; First print on console.. call WEOLD ld hl,MSG9A ; Print first part of msg9 call WASD ld a,(DIRFLG) or a jp nz,WEOLD ld hl,MSG9C ; ..last part if not Dir call WASD jp WEOLD ; New line and exit ; PRMS9A: call ILPRNL ; Start on New Line defb ' Done : ' MSG9A: defb ' 0 File Names',0 ld a,(DIRFLG) or a jp nz,SCROLL ; Quit here if Directory list call ILPRT MSG9C: defb ' - (' MSG9B: defb ' 0 Unique Names)',0 jp SCROLL ; ;..... ; Print error in status window if Premature EOF ; PREEOF: call ilpsts defb '..Premature EOF..',0 jp AGAIN ; ;..... ; In-line Print of message in status window ; ilpsts: ld a,(LEADIN) ; Check for screen installation or a jp z,ILPNOI ; ..bypass print if not ; ld de,4*256+34 ; Position for status window call SETCUR call HILIT ; Hilite message pop hl call HLPRT ; Print message inc hl push hl STSXX: call UHILIT ; ..stop hiliting.. call CLEOLN ; ..and clear rest of line ld a,(SCRLIN) ; Restore cursor ld d,a ld e,0 jp SETCUR ; Re-set cursor and return ; ILPNOI: ex (sp),hl ; Scan to end of message.. ILPNOL: ld a,(hl) inc hl or a jp nz,ILPNOL ex (sp),hl ret ; ..and quit ;..... ; Clear status window. ; STSCLR: ld a,(LEADIN) ; Quit if no screen instl. or a ret z ld de,4*256+34 ; Position for status window call SETCUR jp STSXX ; ;..... ; Error exit if TPA is too small to execute program. ; MEMERR: call ILPRT defb BELL,CR,LF,'*** Not Enough Memory ***',CR,LF,0 jp EXIT1 ; ;............................................................ ; Output control routines (less buffered disk) | ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;..... ; Write the 'OBUF' line to the proper device (Disk/Printer/CRT) ; WRBUF: ld a,(OUTFLG) cp 'F' call nz,TERM ; Check terminate if not Disk Out ; LD HL,PRBUF ;include any needed leading spaces CALL WASD ;write into the buffer CALL WEOLD ;finish the CR-LF at end of line LD A,(OUTFLG) ; Check output device cp 'F' RET Z ;exit if Disk File cp 'C' jp z,WRBUFC LD A,(LCNT) INC A LD (LCNT),A LPP1: CP 0 ; Set by initialization...lines/page RET C ;exit if less jp WRBUF0 ; Keep going if Hard Copy ; WRBUFC: push bc ; Save BC ld a,(THEIGHT) ; Process CRT output, but.. dec a ; ..see if at bottom first. ld b,a ld a,(SCRLIN) cp b pop bc ret c ; Quit here if not end of screen WRPAUS: call ILPRT defb '[more]',0 call CMDIN ; ..and pause for any character jp SCROLL ; Reset cursor and proceed. ; WRBUF0: ld a,0 ; Start at line 1 LD (LCNT),A ;otherwise reset the count PUSH HL PUSH BC CALL NMBR ;increment page count in heading POP BC ; ld a,(HWFFD) ; Check for H/W FormFeed or a jp z,WRBUF2 ld a,FF call HCOPY1 ; Output FF char. ld a,CR call HCOPY1 ; ..and CR. DSKHDV: ld hl,HEAD+2 call WASD jp WRBUF3 ; WRBUF2: call ROLL2 ; LFs and cut line ; WRBUF3: LD HL,HEAD1 ;send new page start call WASD ld hl,HEAD1A ; Prepare header text ld a,(DIRFLG) or a jp z,WRBUF4 ld hl,DHEAD ; ..else directory header WRBUF4: CALL WASD ld hl,HEAD2 call WASD ld hl,HEAD2A ; Prepare page #s for H/C ld a,(OUTFLG) cp 'P' jp z,WRBUF5 ld hl,QUIT ; ..else just newlines WRBUF5: call WASD POP HL RET ; DSKHDR: push hl ; Write disk header jp DSKHDV ; ;..... ; Write end-of-line to Output device ; WEOLD: ld a,(OUTFLG) ; Is this to CRT ? cp 'C' jp z,SCROLL ; ..do scroll if so LD A,CR CALL WAC ;write the ASCII character LD A,LF jp WAC ;write the ASCII character ; ;..... ; Write Zero-terminated ASCII string to output device. ; Starting address of string in HL reg pair. ; WASD: LD A,(HL) OR A RET Z CALL WAC ;write the ASCII character INC HL JP WASD ; ;..... ; Write ASCII character to proper output device (Disk/Printer/CRT) ; WAC: CP SI ;space take-up character RET Z ;if yes, ignore PUSH AF ;save the character in 'A' reg. ld a,(OUTFLG) ; Check output device to use cp 'P' jp z,HCOPY ; Go write to list device cp 'F' ; ..File ? jp z,WACF ; Go write to disk pop af cp LF ; No LFs to CRT.. jp z,SCROLL ; ..do this instead. jp CRTOUT ; ..else write console. ; ;..... ; For hard copy to list device, character on top of stack. ; HCOPY: POP AF ;get the character back ; HCOPY1: PUSH HL ;save the values PUSH DE PUSH BC PUSH AF LD E,A LD C,LISTC ;send to list device CALL BDOS POP AF POP BC POP DE POP HL RET ; ;..... ; Print file name and type on CRT ; NAMOUT: ld b,8 ; 8 Chars in name call NAM0 ld a,'.' call CRTOUT ld b,3 ; ..and 3 in type NAM0: ld a,(hl) inc hl call CRTOUT dec b jp nz,NAM0 ret ; ;............................................................ ; Routines supporting Buffered Disk Output. | ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;..... ; Put one character to disk file buffer, write if full. ; ..Adapted from buffered routines in MCAT45.. ; WACF: pop af ; Enter here from WAC WACD: PUSH HL push de push af ld hl,(OUTLEN) ; See if buffer full ex de,hl ld hl,(OUTPTR) ld a,l sub e ld a,h sbc a,d jp c,PUTOK ; ..jump if space avail. ; call ilpsts defb '..Writing Output..',0 ; ld hl,0000 ; ..else write buffer ld (OUTPTR),hl ; PUTLOP: ex de,hl ld hl,(OUTLEN) ; Check for buffer empty ld a,e sub l ld a,d sbc a,h jp nc,PUTFST ; ..if so, put in first loc'n ld hl,(OUTADR) ; ..else calc addr add hl,de ex de,hl call SDMA ; Set DMA address call WRREC ; ..and write one sector jp nz,EXIT ; If disk error, exit ld de,128 ; Bump address ld hl,(OUTPTR) add hl,de ld (OUTPTR),hl jp PUTLOP ; PUTFST: call DFLTAD ; Set Default DMA addr call STSCLR ld hl,0000 ld (OUTPTR),hl ; PUTOK: ex de,hl ld hl,(OUTADR) ; Calculate buffer address add hl,de ex de,hl pop af ld (de),a ; ..and put character ld hl,(OUTPTR) inc hl ; Bump pointer ld (OUTPTR),hl pop de POP HL ret ; ;............................................................ ; Routines supporting Buffered Disk reading. | ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;..... ; Prime the single-record buffer for selection checks. ; PRIME: call TERM ; Ready to quit ? call RDCHR cp EOF ; Return if EOF ret z cp LF ; Read until jp nz,PRIME ; ld de,RECNAM ; Get buffer address ; call RDCHR ; If first char is NULL.. or a jp z,PRIME ; ..ignore this line ; ; cp '+' ; Ignore special files ; jp z,PRIME cp '-' jp z,PRIME ; ld b,8 ; Get filename.. call GETNF0 ld b,3 ; ..and type call GETNF ; ; Shall we include this record ? ; ld a,(ALLNAM) or a jp nz,PRIME0 push de ld hl,RECNAM call CKINCL pop de jp nz,PRIME ; ; Scan past Disk ID name, just get type. ; PRIME0: call RDCHR cp EOF ; Exit if EOF ret z cp '.' jp nz,PRIME0 ld b,3 call GETNF ld (TMPSEP),a ; ; Include this disk in the output ? ; ld a,(ALLDSK) or a jp nz,PRIME1 push de ld hl,RECDSK call CKINCT pop de jp nz,PRIME ; ; Add User area if present, else leave dummy value ; PRIME1: ld a,(DBUSER) ; Is data in the database ? or a jp z,PRIME2 ; ..jump to default ; call RDCHR ; Get next character (user area) cp 'A' ; Digits are 0-9 jp c,ONEDIG ; Pad single digit with a zero sub 'A'-10 ; Convert A-Z to 10-36 binary ld c,0 ; Divide by 10s, count in C DIVLP: inc c ; ..bump count sub 10 jp nc,DIVLP ; ..loop to excess.. add a,10 ; ..and correct ld b,a ; Saves ones digit ld a,c ; ..retrieve tens digit dec a ; ..and correct value add a,'0' ; ..to ASCII ld (de),a ; Put away inc de ld a,b ; Now ones digit add a,'0' jp NOCVT ; ONEDIG: ld c,a ; Save single ASCII digit cp '-' jp z,ONEDI0 ; If dash, Do two ld a,'0' ; ..output leading zero ONEDI0: ld (de),a inc de ld a,c ; Get back digit ; NOCVT: LD (DE),A INC DE jp PRIME3 ; Get date ; PRIME2: inc de ; Leave default in place inc de ; ; Get Date info if in database, else leave default in place ; PRIME3: ld a,(DBDATE) ; Is date info in database ? or a ret z ; ..else leave default & return. ld a,(USEURF) ; Format US (m/d) or European (d/m) ? or a jp z,PRIM3A ; Jump to EUR if NO call USFORM ; If US format, proceed ret z ; ..Return if Invalid jp GETYR ; ..jump to GETYR ; PRIM3A: call GET2 ; Get 2-byte day call CKVALD ; ..and see if Valid date ret z ; Quit if Default year ld a,(SEPCHR) ; ..separate ld (de),a inc de call GET2 ; ..Get 2-byte Month GETYR: ld a,(SEPCHR) ; ..separate ld (de),a inc de call RDCHR ; Get next character cp CR jp z,DEFYR ; ..if CR, use Year in header ld (de),a inc de jp GET1 ; ..get last number ; ;..... ; Get next filename or filetype from 'MAST.CAT'. Terminate when 'B' ; characters have been read. If name is shorter than 'B' chars, left- ; justify and blank-fill. ; GETNF: CALL RDCHR ;get one char from disk GETNF0: LD (DE),A ;assume good char CP '.' ;end of filename? JP Z,PAD CP ',' ;FN,DN separator? JP Z,PAD CP ';' ; User separator? JP Z,PAD cp '|' ; Date separator? jp z,PAD CP CR ;end of line? JP Z,PAD INC DE ;else keep char & prepare for next DEC B ;enough chars read? JP NZ,GETNF ;jump if not CALL RDCHR ;else throw away separator RET ;and return ; ;..... ; Get Two characters from input file and store them at (DE) ; GET2: call RDCHR ; Get first char ld (de),a ; ..and save inc de ; Bump pointer GET1: call RDCHR ; ..and get second char ld (de),a inc de ; Bump pointer.. ret ; ...and return ; ;..... ; Buffered single character read routine extracted from ; MCAT45.ASM. ; RDCHR: push hl push de push bc ld hl,(INLEN) ; Get input length ex de,hl ld hl,(INPTR) ; ..and current pointer ld a,l sub e ld a,h sbc a,d jp c,NOREAD ; Jump if no need to read disk ; call ilpsts ; Update status line defb '..Reading MAST.CAT..',0 ; ld hl,0 ; ..else setup read ld (INPTR),hl ; RDLOOP: ex de,hl ld hl,(INLEN) ; Have we reached the end ? ld a,e sub l ld a,d sbc a,h jp nc,RDLEND ; ..exit read loop if so. ld hl,(INADR) add hl,de ex de,hl call SDMA ; Set DMA address call RDSEC ; Read Master Input file jp nz,RDERR ; Jump if errors ld de,128 ; ..add another sector ld hl,(INPTR) add hl,de ld (INPTR),hl jp RDLOOP ; ..and back for more ; RDERR: ld hl,(INPTR) ld (INLEN),hl ; Set top of useable ; RDLEND: call DFLTAD ; Set default DMA addr. call STSCLR ; Clear status window. ; ld hl,0000H ld (INPTR),hl ; ..and pointer to start ; NOREAD: ex de,hl ld hl,(INADR) ; Get input address add hl,de ex de,hl ld hl,(INLEN) ld a,l or h ld a,EOF ; Preset End-of-file jp z,RDEXIT ; ld a,(de) ; Get character ld hl,(INPTR) ; ..and bump pointer inc hl ld (INPTR),hl RDEXIT: cp EOF ; Set XDONE non-zero if EOF jp nz,RDEXI0 ld (XDONE),a RDEXI0: pop bc pop de pop hl ret ; Exit ; ;............................................................ ; Routines supporting Formatting and selection functions. | ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;..... ; Format Entry for Disk Directory style of output ; DIRFORM: ld de,OBUF DIRFRM: ld a,(USER) ; Check for User # prefix or a jp z,DIRFO0 ; ..jump if not ld hl,RECUSR ld a,(hl) cp '0' jp nz,DIRFO1 ; Print space for leading zero ld a,' ' DIRFO1: ld (de),a ; Move two digit user # inc hl inc de ld a,(hl) ld (de),a inc de ld a,':' ; ..now separator ld (de),a inc de ld a,' ' ld (de),a ; ..and a space inc de DIRFO0: ld b,8 ; Move Filename.Type to OBUF ld hl,RECNAM call MOVE ld a,'.' ld (de),a inc de ld b,3 call MOVE ld a,(DATES) ; Should we include dates ? or a ret z ; ..return if not ld hl,DASH+1 ld b,3 call MOVE ld hl,RECDAT ; ..else move date string ld b,8 jp MOVE ; ..and return ; ;..... ; Move User and Date data from Record buffer to Output buffer. ; MVDATA: ld hl,RECDSK ; Move 3-char disk ID ld b,3 call MOVE ld a,(USER) ; Should we have user data ? or a jp z,MVDAT1 ; ..jump if not ld a,'/' ld (de),a ; Put separator inc de ld b,2 call MOVE ; MVDAT1: ld a,(DATES) ; Should we have dates ? or a ret z ; ..return if not ld hl,RECDAT ; Set source date string ld a,'-' ld (de),a ; Put separator inc de ld b,8 jp MOVE ; ;..... ; Format year in US method; mm/dd and jump back for year ; USFORM: push de ld de,TMPDAY ; Get day and temp save. call GET2 pop de ; Now get month in original place call GET2 call CKVALD ; See if date valid ret z ; Return w/Zero set if Invalid ld a,(SEPCHR) ; ..separate ld (de),a inc de ld a,(TMPDAY) ; Now restore day ld (de),a inc de ld a,(TMPDAY+1) ld (de),a inc de ld a,TRUE or a ; Reset Zero to show valid date ret ; ..and back for year ; ;..... ; Check last two digits addressed by de for 00. If so, load ; invalid date string. ; CKVALD: push de ; Save current pointer dec de ; ..last digit ld a,(de) dec de ; ..first ex de,hl cp (hl) ; Compare both ex de,hl jp nz,ISVALD cp '0' ; Now check for zeros jp nz,ISVALD call NULDAT xor a ISVALD: pop de ret ; ;..... ; Fill address at (DE) with null date string ; NULDAT: call TWODSH ; Pad with dashes ld a,(SEPCHR) ; ..separate ld (de),a inc de call TWODSH ld a,(SEPCHR) ld (de),a inc de ; ..and fall thru... ; TWODSH: ld a,'-' TWOCHR: ld (de),a inc de ld (de),a inc de ret ; ;..... ; Check Disk ID for include. Conditions same as CKINCL ; CKINCT: ld de,SRDISK ; Check Disk ID ld b,3 jp CKINC0 ; ..continue below ; ;..... ; Check FN.FT for include. Return Z set if OK. ; HL addresses record to check ; CKINCL: ld de,SRNAM ; Check Filename.typ ld b,11 CKINC0: ld a,(de) cp '?' ; OK if ambiguous jp z,CKINOK cp (hl) ret nz CKINOK: inc hl inc de dec b jp nz,CKINC0 ret ; ;..... ; Process hard copy request from keyboard ; PRHC: call ILPRNL ;turn up a line defb 'Do you want Roll Paper with tear tabs ? (Y/N) : ',0 CALL CRTIN CP 'N' push af call z,CRTOUT pop af jp nz,PRHC00 ; ..if not, bypass ld a,TRUE ; Show H/W FormFeed ld (HWFFD),a jp PRHC0 ; PRHC00: ld a,FALSE ld (HWFFD),a ; Show Simulated formfeed ld a,'Y' call CRTOUT ; ; Ask for any fill characters to augment left margin ; PRHC0: call ILPRNL ;want fill chars.? defb 'Spaces (0-9) to augment left margin (=0) ? : ',0 CALL GETCH ;get keyboard answer call NUMCK ; Is it a number ? JP C,PRHC50 push af ; ..Save character call PRHC5 ; Valid number so echo pop af ; ..and restore char SUB '0' ;change to binary from ASCII LD HL,HEAD1 LD DE,PRBUF LD B,A LD A,' ' ; PRHC1: LD (HL),A ;store at 'HL' LD (DE),A ;store at 'DE' INC DE ;next 'DE' location INC HL ;next 'HL' location DEC B ;one less to go JP NZ,PRHC1 ;if not zero, do another ret ; PRHC50: ld a,'0' PRHC5: call CRTOUT jp SCROLL ; ;..... ; Roll up page to terminate ; ROLL: LD A,CR CALL HCOPY1 ;send ; ld a,(HWFFD) ; Hardware FormFeed ? or a jp z,ROLL1 ; ..no, jump. ld a,FF ; ..Yes, send FF char. jp HCOPY1 ; ..and Exit. ; ROLL1: LD A,LF CALL HCOPY1 ;send LD A,(LCNT) INC A LD (LCNT),A LPP2: CP 0 ; Set by initialization...lines/page JP C,ROLL1 ld b,2 jp ROLL2A ; ROLL2: ld b,4 ; Final lines to finish page ROLL2A: call WEOLD dec b jp nz,ROLL2A ld a,'-' ; Cut line.. call HCOPY1 call HCOPY1 ld a,' ' ; ..spaces.. ld b,71 ROLL2B: call HCOPY1 dec b jp nz,ROLL2B ld a,'-' ; ..cut line.. call HCOPY1 call HCOPY1 ld b,5 ROLL2C: call WEOLD ; Roll up page dec b jp nz,ROLL2C ret ; ;-------------------------------------------- ; Routines to Support Command Line Parsing | ;-------------------------------------------- ; ; Main Command Line Parsing routine. Loops til no more chars ; PARSE: call GTNOSP ; Get first non-space char ret z PARSE0: cp '<' ; Get from ? jp z,PARS01 cp '>' ; Put to drive ? jp z,PARS02 cp '$' ; Format options ? jp z,PARS03 cp '-' ; Redirect output ? jp z,PARS04 cp ',' ; Disk ID Search ? jp z,PARS2A ; ld de,SRNAM ; ..Then must be search pattern ld b,8 call PRSNA0 ; Get name ld b,3 ; Now get type or a ; If end of input.. jp z,PARSE1 ; ..pad type and exit. cp ',' jp z,PARSE2 ; Fill TYP with spaces and proc disk cp ' ' ; Space is time for another field push af ; Save flags for later test call z,PADDIT pop af jp z,PARSE cp '.' ; Start of type ? jp nz,PARSE ; ..Exit if not call PRSNAM cp ',' jp z,PARS2A jp PARSE ; Back to main loop ; ; Fill Type with spaces ; PARSE1: call PAD jp PARSE ; ; Fill Type with spaces, and load disk number for search ; PARSE2: call PAD PARS2A: ld de,SRDISK ld b,3 call PRSNAM jp PARSE ; ; Get characters from input line to DE for B chars ; PRSNAM: call GTCCHR ; Get char from comd line jp z,PRSNA1 PRSNA0: cp '*' ; Is it ambiguous ? jp z,PRSNA2 ld (de),a ; Assume it is OK cp '.' ; ..End ? jp z,PRSNA1 ; ..Fill w/spaces if so cp ',' ; Sep for disk ? jp z,PRSNA1 cp ' ' ; End of entry field ? jp z,PRSNA1 inc de dec b ; At end ? jp nz,PRSNAM ; ..back for more til done PRSNA3: call GTCCHR ret z cp '.' ret z cp ' ' ret z cp ',' jp nz,PRSNA3 ret ; PRSNA1: push af ; Save character and status call PAD pop af ret ; PRSNA2: ld a,'?' ; Fill with spaces call PADDIT jp PRSNA3 ; PARS01: call SRCDSK ; Set Source Disk for MAST.CAT PARSEV: ret z call GTSPAC ; Scan until space jp PARSE ; PARS02: call DSTDSK ; Set Destination Disk for Output jp PARSEV ; PARS03: call GETOPT ; Get DB Options jp PARSEV ; PARS04: call REDIR ; Set Output device jp PARSEV ; ; Set Destination disk drive ; DSTDSK: ld a,'F' ; Assume Disk file output, else ld (OUTFLG),a ; ..why do this command ??? call GTCCHR ret z ld c,a call CKDRU ; See if colon present (Drv/Usr?) ld a,c jp nz,DSTDK0 call NUMCK jp nc,DSTDK ; If number, process user sub 'A' ; Make drive binary ld (ODRIVE),a call GTCCHR ret z call NUMCK jp c,DSTDS0 DSTDK: call GETDIG ; Get the digit push af ; ..save while move ld a,(TUSER) ; Get place where stored ld (OUSER),a pop af ; Retrieve last char DSTDS0: cp ' ' jp z,GTBAK1 ; ..quit here if space cp ':' ; Check for Separator ret nz call GTCCHR ret z DSTDK0: cp ' ' ; No Name ? jp z,GTBAK1 push af ; ..else save char ld b,11 ld de,DEFLT+1 call PAD pop af ld de,DEFLT+1 ; Put name here ld b,8 ; ..8 chars long jp DSTDS9 ; ..bypass next GET ; DSTDS1: call GTCCHR jp z,DSTDS6 DSTDS9: cp '.' ; End of name ? jp z,DSTDS2 cp ' ' jp z,GTBAK1 ; Quit if end of entry ld (de),a inc de dec b ; Countdown jp nz,DSTDS1 DSTDS3: call GTCCHR jp z,DSTDS6 cp ' ' jp z,GTBAK1 cp '.' jp nz,DSTDS3 ; DSTDS2: call GTCCHR ; Process type ld b,3 ld de,DEF1 ; Put it here jp DSTDS5 ; DSTDS4: call GTCCHR DSTDS5: jp z,DSTDS6 cp ' ' ; Quit now if space jp z,GTBAK1 ; Decrement counter before returning ld (de),a inc de dec b jp nz,DSTDS4 DSTDS6: ld a,0FFH or a ; Make sure Zero is off. ret ; GTBAK1: ld hl,(CMDPTR) ; decrement pointer.. dec hl ld (CMDPTR),hl ld hl,CBUFF ; and increment char count inc (hl) ret ; CKDRU: ld hl,(CMDPTR) ; Relead pointer dec hl ; ..to present char ld b,4 CKDRU1: ld a,(hl) ; Scan 4 places for colon cp ':' ret z or a ret z inc hl dec b jp nz,CKDRU1 ld a,0FFH ; Show No Zero if No Colon or a ret ; ; Get MAST.CAT Format symbols ; GETOPT: xor a ; Set both FALSE ld (USER),a ld (DATES),a GETOPX: call GTCCHR ; Get first ret z cp 'D' ; DATES ? jp z,GETOP1 cp 'U' ; USERS ? ret nz ld a,TRUE ; Set USER true ld (USER),a jp GETOPX ; GETOP1: ld a,TRUE ; Set DATES true. ld (DATES),a jp GETOPX ; ; Set Source disk drive for MAST.CAT ; SRCDSK: call GTCCHR ret z call NUMCK jp nc,SRCDS0 ; If number, process user sub 'A' ; Make drive binary ld (MDRIVE),a call GTCCHR ret z call NUMCK jp nc,SRCDS0 cp ':' jp z,GTCCHR ret ; SRCDS0: call GETDIG ; Get the digit push af ; ..save while move ld a,(TUSER) ; Get number ld (MUSER),a pop af ret ; ; Set Output Redirection flag to correct device ; REDIR: call GTCCHR ; Get next character ret z cp 'C' ; Console output ? jp z,REDIR0 cp 'P' ; Printer output ? jp z,REDIR0 cp 'F' ; File Output ? jp nz,REDIR1 REDIR0: ld (OUTFLG),a REDIR1: jp GTCCHR ; Return with next char ; ; Get command line char, return in uppercase ; GTCCHR: ld a,(CBUFF) ; Any char left ? or a ret z ; ..ret if not dec a ld (CBUFF),a ld hl,(CMDPTR) ld a,(hl) ; Get character inc hl ; ..advance ptr ld (CMDPTR),hl jp UPPER ; ..and convert to UCase ; ; Get char while skipping over spaces ; GTNOSP: call GTCCHR ret z cp ' ' jp z,GTNOSP ret ; ; Read command line until space detected. ; GTSPAC: cp ' ' ret z call GTCCHR ret z jp GTSPAC ; ; Gather binary number from command line decimal digits ; GETDIG: call GTBAK1 ; First backup one char ld e,0 ; Initialize counter GETDI0: call GTCCHR ; Get character jp z,GETDIX ; ..exit if null cp ' ' jp z,GETDIX ; ..or space call NUMCK ; Is it a digit ? jp c,GETDIX sub '0' ; ..Yes, so process ld b,a ld a,e ; Multiply old digit times 10 add a,a ; * 2 add a,a ; * 4 add a,e ; * 5 add a,a ; * 10 add a,b ; Add in new digit ld e,a jp GETDI0 ; GETDIX: push af ld a,e ld (TUSER),a ; Store User area for file pop af or a ret ; ;----------------------------------------------------- ; Disk Access Commands Consolidated here. ;----------------------------------------------------- ; ; Set 'DMA' address to the 'TBUF' default location ; DFLTAD: LD DE,TBUF SDMA: ld c,SETDMA jp BDOS ; ; Reset Disk System, and return with Drive A: selected. ; RESDSK: ld c,RESET jp BDOS ; ; Get/Set User routine. ; GETUSR: ld e,0FFH SETUSR: ld c,G$SUSR jp BDOS ; ;..... ; Select a Specified Disk Drive in the E register ; SELECT: ld c,SELDSK jp BDOS ; ;..... ; Close File GP access. ; CLOSIT: ld c,CLOSF jp BDOS ; ;..... ; Open MAST.CAT for Reading with error detection ; OPEN: ld a,(MDRIVE) ; First select right drive ld e,a call SELECT ld a,(MUSER) ; ..and right user ld e,a call SETUSR ld de,FCB ld c,OPENF call BDOS inc a ret nz ; Return if OK call SCROLL call ERXIT ; Jump error with message defb '++ Unable to Open MAST.CAT ++',BELL,0 ; ;..... ; Write Master Record to Disk ; WRREC: PUSH HL PUSH DE PUSH BC ld a,(ODRIVE) ; Select the drive ld e,a call SELECT ld a,(OUSER) ; ..and the user ld e,a call SETUSR LD DE,TFCB LD C,WRITEF CALL BDOS OR A jp z,WRROK ; Jump if Good Read call SCROLL call ERXIT ; Jump error with message defb '++ Disk or Directory FULL ++',BELL,0 ; ;..... ; Flush buffer and Close Output file with Error Reporting. ; FLUSH: ld a,(OUTFLG) ; Output to Disk File ? cp 'F' RET NZ ; If not, no file to close ; FLUSH1: LD A,EOF CALL WACD LD HL,(OUTPTR) ld a,l and 7FH jp nz,FLUSH1 ; Loop til sector end ld (OUTLEN),hl ld a,EOF CALL WACD ; ..Fall thru.. ; CLOSE: push hl ; Save registers push de push bc ; call ilpsts ; Show closing output defb '..Closing Output file..',0 ; ld a,(ODRIVE) ; Select drive.. ld e,a call SELECT ld a,(OUSER) ; ..and user ld e,a call SETUSR ld de,TFCB call CLOSIT ; Attempt to close Output file INC A ; push af call STSCLR ; Clear status window pop af ; JP NZ,WRROK ; Jump if No errors, & Rename call ILPRNL defb BELL,'++ Cannot Close ',0 ld hl,TFCB+1 xor a ; Set ending ld (TFCB+EX),a call HLPRT call ERXIT ; Jump error with message defb ' ++',0 ; ;..... ; Make/Create the Output file with Error Reporting ; CREATE: call ilpsts defb '..Opening Output File..',0 LD HL,DEFLT ; Default to 'MAST.LST' LD DE,TFCB LD B,12 CALL MOVE ; XOR A ; Clean FCB LD (TFCB+EX),A LD (TFCB+NR),A ld a,(ODRIVE) ; Put on right drive ld e,a call SELECT ld a,(OUSER) ; ..and user ld e,a call SETUSR LD DE,TFCB ; Erase existing copy of File ld c,ERASF call BDOS ld de,TFCB ld c,MAKEF call BDOS ; Make new Output File INC A jp nz,CREAT1 ; Return if OK call ERXIT defb BELL,'++ Can''t Make Output...No Directory Space ++',0 ; CREAT1: call STSCLR ; Clear status window & ret XOR A LD (TFCB+NR),A ret ; ;..... ; Read sector from disk ; RDSEC: PUSH HL PUSH DE push bc ld a,(MDRIVE) ; Set right drive ld e,a call SELECT ld a,(MUSER) ; ..and user ld e,a call SETUSR LD DE,FCB ;otherwise get next record from disk LD C,READF CALL BDOS OR A WRROK: pop bc pop de pop hl ret ; ;----------------------------------------------------- ; Command Support routines trapped from CRTIN routine. ;----------------------------------------------------- ; ; <^O> Change Output Device. ; CMDOUT: ld de,1*256+34 ; Col 34, line 1 ld hl,OUTSTR ; Load command string call SHOSCR ; Show command and scroll call ILPRT defb '==> Output to File/Console/Printer (F/C/P)? : ',0 CMDOU1: call GETCH ; Get letter cp 'C' jp z,CMDOUX cp 'P' jp z,CMDOUX cp 'F' jp z,CMDOUX cp CR ; Don't change if CR jp z,CMDDRX ld a,BELL ; Ring bell if no good.. call CRTOUT jp CMDOU1 ; ..Back for another try CMDOUX: ld (OUTFLG),a ; ..and store cp 'P' ; See if printer push af call z,PRHC ; ..set parameters if so pop af cp 'F' jp nz,CMDOUY ; Jump if not file output call SCROLL call ILPRT defb ' Current file : ',0 call STUP3B ; Print current file data call ILPRT defb ' - OK ? (Y/N) : ',0 call CRTIN cp 'Y' jp z,CMDOUY ; Exit if no change call SHOW$N call SCROLL call ILPRT defb '==> Dest file (DU:Name.Typ ) : ',0 ld hl,CBUFF ; Set up buffer for destination ld (hl),1 ; ..one char to start inc hl ld (hl),'>' inc hl ld (hl),0 call INLINE ; Get response ld hl,CBUFF+1 ld (CMDPTR),hl call PARSE ; ..extract FN.FT to buffer CMDOUY: call STUPD3 ; Update status CMDDRX: ld hl,CMDO jp ENDCMD ; Exit properly ; OUTSTR: defb 'UTPUT',0 ; ;..... ; <^L> Log Drive/User location of MAST.CAT. ; CMDMST: ld de,1*256+50 ; Col 50, line 1 ld hl,MSTSTR ; Get Active string call SHOSCR ; Show comd and scroll call ILPRT defb '==> MAST.CAT on Drive/User (DU) : ',0 ld e,0 ; Initialize counter call GETCH cp CR jp z,CMDMX ; Quit w/No changes if CR.. cp ' ' jp z,CMDMX ; ..space.. cp 'C'-40H jp z,CMDMX ; ..or Control-C call NUMCK ; Check for number jp nc,CMDMS0 ; ..Process User area if so call CRTOUT sub 'A' ld (MDRIVE),a ; Else save drive CMDMS1: call GETCH ; Get next character call NUMCK ; ..See if number jp c,CMDMSX ; Exit if not number CMDMS0: call CRTOUT ; ..else echo char sub '0' ; make binary ld b,a ld a,e ; last result add a,a ; * 2 add a,a ; * 4 add a,e ; * 5 add a,a ; * 10 add a,b ; Add last digit ld e,a ; ..and store jp CMDMS1 ; CMDMSX: ld a,e ; Get user area.. ld (MUSER),a ; ..and Store call STUPD1 ; Update status line CMDMX: ld hl,CMDL jp ENDCMD ; MSTSTR: defb 'OG MAST.CAT',0 ; ;..... ; <^F> Change Database Format ; CMDFMT: ld de,1*256+66 ; Col 66, Line 1 ld hl,FMTSTR ; Get active string call SHOSCR ; Show comd and scroll call ILPRT defb '==> Add USER Field (Y/N) : ',0 call CRTIN cp 'N' ; Check response ld a,FALSE ; ..preload NO push af call z,SHOW$N pop af jp z,CMDFM0 call SHOW$Y ld a,TRUE CMDFM0: ld (USER),a call ILPRNL defb '==> Add DATE Field (Y/N) : ',0 call CRTIN cp 'N' ; Check response ld a,FALSE ; ..and preload NO push af call z,SHOW$N pop af jp z,CMDFM1 call SHOW$Y ld a,TRUE CMDFM1: ld (DATES),a ; Save DATES flag call STUPD1 ; Update status ld hl,CMDF jp ENDCMD ; ..and Exit ; FMTSTR: defb 'ORMAT (DU)',0 ; ;..... ; <^S> Define Search criteria ; CMDSCH: ld de,1*256+2 ; Col 2, Line 1 ld hl,SCHSTR ; Get active string call SHOSCR ; Show comd and scroll call ILPRT defb '==> Enter Search Filename (FN.FT) for Search : ',0 ld hl,CBUFF ; Set up buffer for search ld (hl),0 inc hl ld (hl),0 call INLINE ; Get response ld hl,CBUFF+1 ld (CMDPTR),hl call PARSE ; Set search criteria call STUPD2 ; Update status ld hl,CMDS jp ENDCMD ; ..and Exit ; SCHSTR: defb 'EARCH',0 ; ; Support Routine to position cursor, show comd and scroll ; SHOSCR: call SHOCMD ; Show command ld a,(SCRLIN) ; Get current line ld d,a ld e,0 call SETCUR ; Position cursor jp SCROLL ; ;-------------------------------------------------------- ; Keyboard Input routines Consolidated here. ;-------------------------------------------------------- ; Basic direct Console read routine ; GETCH: push hl ; Save regs push de push bc GETCH0: ld c,TRMIO ; Use CP/M 2.2 direct method ld e,0FFH ; ..for input call BDOS or a jp z,GETCH0 pop bc pop de pop hl and 7FH ; Strip MSB if there UPPER: cp 'a' ; ..Convert to Uppercase ret c cp 'z'+1 ret nc and 5FH ret ; ;..... ; Get a character, and terminate if Control-C ; TERM: push bc push de push hl ld c,TRMIO ld e,0FFH ; Check console call BDOS pop hl pop de pop bc cp 'C'-40H jp z,EXIT jp UPPER ; ;..... ; Gets a character from the keyboard while sensing for Command ; character indicators. ; CMDIN: call CRTINT ; console read with time update cp 'L'-40H ; Log MAST.CAT Drive ? jp z,CMDMST cp 'O'-40H ; Output Change ? jp z,CMDOUT cp 'F'-40H ; Change Database Format ? jp z,CMDFMT cp 'S'-40H ; Change Search criteria ? jp z,CMDSCH cp 'C'-40H ; Abort Request ? jp z,EXIT cp 'Z'-40H ; Redraw screen request ? jp z,DRWAGN RET ; PRMPYN: defb ' Ready? (Y/N) : ',0 ; ;..... ; Read Console direct while sensing and updating clock. ; CRTINT: ld a,(LEADIN) or a ; No time if can't address cursor jp z,CRTIN TIMLOP: xor a ; Set clock timer to 256 counts ld (TIMER),a call RDTIM ; ..Read clock and display ld a,(SCRLIN) push hl push de ld d,a ld e,54 ; ..in right column call SETCUR ; ..and Set It. pop de pop hl TIMLO1: call TERM ; See if character ready or a jp nz,CRTIM ; Jump to process if present ld b,0 ; ..Do a little pause TIML02: dec b jp nz,TIML02 ld a,(TIMER) ; Time to read yet ? dec a ld (TIMER),a jp nz,TIMLO1 jp TIMLOP ; CRTIM: and 7FH ; Do preprocess of char jp CRTIN0 ; ..now finish ; ;..... ; Get a character from the keyboard. ; CRTIN: call GETCH ; Basic console read CRTIN0: CP 'C'-40H ;CTL-c? ret Z ;if yes, abort CP 'X'-40H ;CTL-x? ret nz ; ..return if not ld a,'N' ; Show 'N' on exit for other chars RET ; ;..... ; Input a character string to memory in uppercase deleting cntl chars ; INLINE: call GETCH cp BS ; Process backspace jp z,INBKSP cp DEL ; ..also Delete jp z,INBKSP ld (hl),0 ; In case of end cp CR ; End..? ret z cp ' ' ; Check control chars jp c,INLINE ld (hl),a ; save char call CRTOUT ; ..and Echo inc hl ld a,(CBUFF) inc a ; Bump char count ld (CBUFF),a jp INLINE ; INBKSP: ld a,(CBUFF) ; Already at start ? or a jp z,INLINE dec a ld (CBUFF),a dec hl ld a,BS call CRTOUT ld a,' ' call CRTOUT ld a,BS call CRTOUT jp INLINE ; ;..... ; Handle a backspace character while entering a file name ; BCKSP: LD A,B ;get position on line OR A JP NZ,BCKSP1 ;exit if at initial column LD A,' ' ;delete the character JP BCKSP3 ; BCKSP1: DEC B ;show one less column used DEC HL ;decrease buffer location LD A,' ' LD (HL),A ;replace to original CALL CRTOUT ;backspace the CRT ; BCKSP2: LD A,BS ;reset the CRT again ; BCKSP3: CALL CRTOUT ;write to CRT RET ; ;-------------------- End Console Input ------------------------ ;..... ; Quit with Ending Message ; OKEXIT: call PRMSG9 ; Print ending message and quit jp EXIT ; ;..... ; Exit here on Error ; ERXIT: call SCROLL ; Add CRLF POP hl ; Get message address call HLPRT ; ..and print it call SCROLL xor a ; On error, return to Menu mode ld (IMMED),a jp AGAIN ; ..and resume execution. ; EXIT: CALL ILPRNL defb '--- Good-Bye ---',0 call SCROLL EXIT1: ld a,(CUSER) ; Reset user to entry ld e,a call SETUSR ld a,(CDRIVE) ; Reset entry drive ld e,a call SELECT EXIT2: ld hl,(STACK) ; Get old Stack Pointer ld sp,hl ; ..back to stack ret ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Console Output routines consolidated here for convenience. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; CRLF: CALL ILPRT ;carriage ret - line feed DEFB CR,LF,0 RET ; ;..... ; Do screen Scroll followed by Inline Print. ; ILPRNL: call SCROLL ; ..and fall thru... ; ;..... ; Inline print subroutine ; ILPRT: EX (SP),HL ;get starting address of string to 'HL' call HLPRT inc hl ; Bump past ending 0 ex (sp),hl ; ..return addr to top of stack ret ; ; Print Zero-terminated string addressed in HL register pair ; HLPRT: LD A,(HL) OR A ret z call CRTOUT ; Show character on CRT INC HL jp HLPRT ; ;..... ; Displays one character on the CRT ; CRTOUT: PUSH AF ;save the character push bc push de push hl LD C,TRMIO LD E,A ;get the character into 'E' reg. CALL BDOS ;show the character on the crt pop hl pop de pop bc POP AF ;get the character back RET ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Full-Screen oriented routines, and terminal attribute procs. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; Print Horizontal line across full screen width. ; HLINE: ld a,(TWIDTH) ; Get defined width dec a ; ..-1 ld b,a HLINLP: ld hl,HCSTR ; Get char (or string) push bc call HLPRT ; ..print it pop bc dec b jp nz,HLINLP ret ; ; Set Cursor to row = 'D', Column = 'E' registers ; Checks for valid screen addressing. ; SETCUR: ld a,(LEADIN) ; See if cursor cntls present or a ret z ; ..Exit here if not ; push hl ; Save HL ld hl,LEADIN ; Send lead string call HLPRT ld a,(FASTFLG) or a jp nz,FSETDE ; ld a,(ROWFIRST) or a ld hl,ROWBIAS jp nz,ROW1 inc hl ; Point at col bias ld a,d ; Exchange order of coordinates ld d,e ; ..make D = col.. ld e,a ; ..E = row. ROW1: push de ; Save coordinate values ld a,d ; A = 1st coord to send call PUTCOORD ; ..send it. ; ld hl,MIDSTR ; Mid string call HLPRT ; ; Now the 2nd coordinate. pop de ; Restore coordinates ld a,(ROWFIRST) or a ld hl,COLBIAS jp nz,ROW2 dec hl ; Row Bias ROW2: ld a,e ; ..A = 2nd coord to send call PUTCOORD ; ld hl,TAILSTR ; Tail String call HLPRT ; ..output it pop hl ret ; Exit.. ; ; A = Binary value of coordinate to send ; HL --> Bias to be added ; PUTCOORD: add a,(HL) ; Add the bias ld e,a ; Save result in E ld a,(BINARY) or a jp z,PUTASCII ld a,(COMPFLG) ; Complement if needed xor e jp CRTOUT ; ; Put coordinates as ASCII digit(s) ; PUTASCII: ld a,e ; Get value back DECOUT: push bc ; ..Save BC ld b,0 ; Tens digit counter PLP: sub 10 jp c,PDONE inc b jp PLP ; PDONE: add a,10 ; Add back for underflow push af ; ..Save low digit ld a,b ; ..Get tens or a call nz,OUTASC pop af ; Retrieve digits call OUTASC pop bc ; Restore BC ret ; OUTASC: add a,'0' ; Make ASCII jp CRTOUT ; ; Fast toutine when row, col order, binary, no complementing, ; no MID and TAIL strings. ; (Kaypro, Heath, etc.) ; FSETDE: ld a,(ROWBIAS) add a,d call CRTOUT ld a,(COLBIAS) add a,e call CRTOUT pop hl ; Restore HL saved at beginning ret ;..... ; Insert Line on screen. ; ILINE: ld hl,INSLINSTR jp HLPRT ; ;..... ; Delete a Line on the screen. ; DLINE: ld hl,DELLINSTR jp HLPRT ; ;..... ; Start Highlighting area of the screen. ; HILIT: ld hl,HILITSTR jp HLPRT ; ;..... ; End Highlighting area of the screen. ; UHILIT: ld hl,UNHILITSTR jp HLPRT ; ;..... ; Clear to End-Of-Line ; CLEOLN: ld hl,CLREOLSTR jp HLPRT ; ;..... ; Clear to End-Of-Screen ; CLEOSCR: ld hl,CLREOSSCR jp HLPRT ; ;..... ; Check for cursor addressing, and CRLF if none. ; CHKCRLF: ld a,(LEADIN) ; If null in leadin, then no screen or a ; installation has been performed.. ret nz jp CRLF ; ..so do CRLF ; ;..... ; Simulate scroll on center of screen ; SCROLL: ld a,(THEIGHT) ; Compare to last line on screen push bc push de ld b,a ld a,(SCRLIN) ; See if on last line inc a ld (SCRLIN),a cp b jp c,SCROL0 ; OK..bypass clear call RDTIM ; Read clock and print time ld a,6 ld (SCRLIN),a ld d,a ld e,0 call SETCUR ld hl,CLREOSSTR ; Clear to end-of-screen call HLPRT ld d,5 ; Set cursor to end of line.. ld a,(TWIDTH) ; ..above top available. dec a ld e,a call SETCUR SCROL0: pop de pop bc jp CRLF ; Roll up a new line and quit ; ;..... ; Highlight command tails in On-line Help when active. ; Unhighlight on exit. Enter with Command + 2 address in DE ; which is stored in HSADR for use in exit routine. ; SHOCMD: ld a,(LEADIN) ; Only do if can address cursor or a ret z ; ex de,hl ; Move to HL for save ld (HSADR),hl ex de,hl ; ..now back SHOCM1: push hl ; ..and save string addr call SETCUR call HILIT pop hl ; Retrieve string addr call HLPRT ; ..and print jp UHILIT ; ; Exit routine. Re-draw screen if terminal installed. ; ENDCMD: ld a,(LEADIN) ; Do only if can address cursor or a jp z,AGAIN push hl ; Save ending string ld hl,(HSADR) ; Get start address ex de,hl call SETCUR call UHILIT ; ..turn it off.. pop hl ; Get ending string back call HLPRT jp DRWAG0 ; ..and exit back to main loop ; ;+ + + + + + + + + + + End Screen Interface + + + + + + + + + + + ;..... ; Spell out answers for space bar and Return key depressions ; SHOW$Y: call ILPRT defb 'YES',0 ; Spell YES on the CRT ret ; SHOW$N: call ILPRT defb 'NO',0 ; Spell NO on the CRT ret ; ;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; Screen draw routines. ;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; Introduce program on first line - 0. ; DRAWSCR: ld de,0000H ; Position Line 0, Col 0 call SETCUR call ILPRT ; Print sign-on message defb 'Catalog X-Ref Pgm v5.',versno,revno,0 ; ld a,(DSFLAG) ; See if DateStamper installed or a jp z,NODSTP call ILPRT defb ' - for - ',0 ; call ILPRT defb 'DateStamper',0 ; NODSTP: call CLEOLN call CRLF ; ; Now print On-line Help (Second line - 1) ; ld de,1*256+0 ; Position cursor where we are push de ; ..get set for later call CMDS00 defb '^S',0 CMDS00: pop hl call SHOCM1 call ILPRT CMDS: defb 'earch ',0 pop de push de ld e,16 call CMDZ00 defb '^Z',0 CMDZ00: pop hl call SHOCM1 call ILPRT defb '-Redraw ',0 pop de push de ld e,32 call CMDO00 defb '^O',0 CMDO00: pop hl call SHOCM1 call ILPRT CMDO: defb 'utput ',0 pop de push de ld e,48 call CMDL00 defb '^L',0 CMDL00: pop hl call SHOCM1 call ILPRT CMDL: defb 'og MAST.CAT ',0 pop de ld e,64 call CMDF00 defb '^F',0 CMDF00: pop hl call SHOCM1 call ILPRT CMDF: defb 'ormat (DU) ',0 ; ; Draw separation line (third line - 2) ; call CHKCRLF ; Do CRLF if no screen installation ld de,2*256+0 ; Position cursor call SETCUR call HLINE ; Draw a horizontal line ; ; Finish drawing screen boundaries ; ld de,3*256+32 call SETCUR ld a,(VCSTR) ; Print vertical separator call CRTOUT ld de,4*256+32 call SETCUR ld a,(VCSTR) ; ..and another call CRTOUT call CRLF ; Down one line for.. call HLINE ; ..bottom horiz line ; ; Print remianing status information on screen (lines 3 & 4) ; call STUPD1 call STUPD2 call STUPD3 STUPFN: ld a,(SCRLIN) ; Restore saved cursor line ld d,a ld e,0 jp SETCUR ; ..and quit ; ;..... STUPD1: call CHKCRLF ; Give CRLF if no cursor addressing ld de,3*256+0 call SETCUR call ILPRT defb 'MAST.CAT on : ',0 ld a,(MDRIVE) add a,'A' call CRTOUT ; Print drive letter.. ld a,(MUSER) call DECOUT ; ..and user area ld hl,SPAC14 ; Blank remainder call HLPRT ld de,3*256+16 ; ..reposition cursor call SETCUR call ILPRT defb ' (',0 ; Show implemented options ld a,(USER) or a jp z,AGAIN0 ; Jump if no USER call ILPRT defb 'User ',0 AGAIN0: ld a,(DATES) or a jp z,AGAIN1 ; Jump if no DATES call ILPRT defb 'Date',0 AGAIN1: ld a,')' call CRTOUT ; Print closing parens ret ; ;..... STUPD2: call CHKCRLF ; New line if no screen installed ld de,3*256+34 call SETCUR ; Position cursor call ILPRT defb 'Search for ---> ',0 ld hl,SRNAM call NAMOUT call ILPRT ; Print seperator defb ' / .',0 ld hl,SRDISK ld b,3 jp NAM0 ; ..and Disk ID type ; ;..... STUPD3: call CHKCRLF ; New line if no screen installed ld de,4*256+0 call SETCUR call ILPRT defb 'Output to --> ',0 ld hl,SPAC18 ; Blank remainder of entry call HLPRT ld de,4*256+14 call SETCUR ; ..and reset cursor ld a,(OUTFLG) ; Print current destination cp 'C' jp nz,STUP3A call ILPRT defb 'Console',0 ret ; STUP3A: cp 'P' ; Printer ? jp nz,STUP3B call ILPRT defb 'Printer',0 ret ; STUP3B: ld a,(ODRIVE) ; Disk putput, show DU & name add a,'A' call CRTOUT ld a,(OUSER) call DECOUT ld a,':' call CRTOUT ld a,' ' call CRTOUT ld hl,DEFLT+1 jp NAMOUT ; ..and output file name. ; ;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; DateStamper (TM) Support routines ;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; ; Convert BCD digit to two ASCII digits ; DODIGIT: ld a,(de) ; Get BCD digit rrca ; ..rotate Hi to low rrca rrca rrca call DODIG1 ; Do first nybble.. ld a,(de) ; ..fall thru to second. DODIG1: call MAKHEX ; Convert low Nybble to Hex digit call CRTOUT ld (hl),a ; store it.. inc hl ; ..and go to next digit ret ; ;..... ; Print Date to CRT and H/C banner in the form of DD MMM YY from BCDBUF. ; DATLIN: ld hl,HEAD2 ld de,BCDBUF+2 call DODIGIT dec de ; Down to Month push de ld a,(de) and 0F0H ; Mask hi nybble ld b,0 ; ..assume it is 0 jr z,DATL0 ld b,10 ; ..it is 10 if not 0 DATL0: ld a,(de) ; Reget digit and 0FH ; ..Mask off Low nybble add a,b dec a ; Decrement for indexing cp 13 ; Is it valid ? jp c,DATOK ; ..jump if OK ld a,13 ; ..else show invalid DATOK: ld c,a ld b,0 push hl ; Save Banner address ld l,c ld h,b add hl,hl ; Mult by 3 add hl,bc ex de,hl ld hl,MONTHS add hl,de ; Now month address ex de,hl ; ..and put in DE pop hl ; Retrieve Banner address ld a,' ' call CRTOUT ld (hl),a inc hl ld b,3 ; Months have 3 chars DATL1: ld a,(de) ld (hl),a call CRTOUT inc hl inc de dec b jp nz,DATL1 ; ..Loop til done ld a,' ' call CRTOUT ld (hl),a inc hl ld a,'1' ld (hl),a inc hl call CRTOUT ld a,'9' ld (hl),a inc hl call CRTOUT pop de ; Restore BCDBUF dec de ; ..down to Year field call DODIGIT jp SCROLL ; ..and quit ; ;..... ; Execute routine to get Current date from operator. ; CURDAT: call ILPRNL ; No clock so enter Current date defb ' The year has been set to 19',0 ld a,(CURYR) call CRTDIG ; Print BCD digit on screen ; ; Get date input with BELL prompt. Also Bell on retries. ; call SCROLL TRYMOR: call ILPRT defb CR,BELL,' Enter date to set : -- ' defb 'mo/da : __/__',BS,BS,BS,BS,BS,0 ld hl,BCDBUF ; Get Date buffer address ld a,(CURYR) ; Get static year ld (hl),a inc hl ; Point to month ld (hl),0 ; ..and zero to start call GETNIB call GETNIB ld a,(hl) ; Get month or a ; ..Zero is not allowed jp z,TRYMOR cp 13H ; Test range jp nc,TRYMOR ld (MONTH),a ; Save for days check push hl ld a,'/' call CRTOUT ; Print seperator pop hl inc hl ; Now point to Day ld (hl),0 ; ..and zero to start call GETNIB call GETNIB ld a,(hl) ; Get days input or a ; ..again, no zero jp z,TRYMOR ld c,a ld a,(MONTH) ld hl,DAYS add a,l ld l,a jp nc,NNCC inc h ; Now pointing to max days NNCC: ld a,c dec a ; N - 1 cp (hl) ; Test if bigger than max jp nc,TRYMOR jp SCROLL ; New line for formatting..Exit ; ;..... ; Manual date entry support code ; GETNIB: push hl RETRY: call GETCH ; Use direct console IO cp BS ; Is char Backspace ? jp c,CANCEL cp 07FH ; ..or DELete ? jp z,CANCEL call NUMCK ; Check for number in range jp c,BDIN call CRTOUT ; Now echo the character pop hl ; Return HL pointer and 0FH ; Crunch HI Nybble ld c,a ld a,(hl) ; Get byte add a,a add a,a add a,a add a,a ; ..shift to HI nybble or c ; ..OR in Lo byte ld (hl),a ret ; BDIN: ld a,BELL ; Ring BELL on error call CRTOUT jp RETRY ; ..Try again ; CANCEL: pop hl pop hl ; Clear stack.. jp TRYMOR ; ..and back for more ; ; Pad impossible HEX offsets ; DAYS: defb 00H,31H,29H,31H,30H,31H,30H defb 31H,31H,30H,00H,00H,00H,00H defb 00H,00H,31H,30H,31H ; ;..... ; Read clock and print on upper-right of screen ; RDTIM: ld a,(LEADIN) or a ret z ; Forget it if no screen addressing.. ld a,(DSFLAG) or a ret z ; ..or DateStamper not installed ld a,(RELCLK) ; Check for Relative clock.. or a ret nz ; ..and quit if so. ld a,(BCDBUF+3) ; If "Relative" clock, Don't.. or a ; ..read again call p,GTDATE ; Read the clock ld a,(TWIDTH) ; OK, so position cursor sub 10 ld e,a ld d,2 ; On third line call SETCUR call HILIT ; Do it Highlighted ld hl,BCDBUF+3 ld a,(hl) rla ld a,(hl) jp c,RELTIM ; MSB set means Relative time call CRTDIG ; Do hours inc hl ld a,':' call CRTOUT ld a,(hl) call CRTDIG jp UHILIT ; RELTIM: sub 80H ; Strip bias push af inc hl ; Get Low order byte ld l,(hl) pop af ; ..and Hi one ld h,a ld a,'+' ; RELCHAR call CRTOUT ld de,-1000 ; Print 1000's call RDIGIT ld de,-100 ; ..100's call RDIGIT ld de,-10 ; ..10's call RDIGIT ld a,l ; ..and Ones add a,'0' call CRTOUT ld a,TRUE ; Show that Relative clk read once. ld (RELCLK),a jp UHILIT ; Turn off highlighting and quit ; RDIGIT: ld b,'0' ; Start with ASCII 0 DIGLP: push hl ; Save current remainder add hl,de ; ..subtract jp nc,DIGEX ; Quit on overflow pop af ; ..Throw away remainder inc b ; ..bump digit jp DIGLP ; ..and loop til overflow ; DIGEX: pop HL ; Restore remainder ld a,b jp CRTOUT ; Print digit and quit ; ;..... ; Print BCD digit in A-register as two digits on CRT. ; CRTDIG: push af ; Save digit rrca ; Rotate BCD digits rrca rrca rrca call MAKHEX ; Convert to ASCII.. call CRTOUT ; ..and Print pop af ; Restore original call MAKHEX jp CRTOUT ; Print and return ; ;..... ; Error mesage text if attempting to catalog under CP/M versions other ; than 2.2 with DateStamper selected. ; BADVR1: call ERXIT defb BELL,CR,LF defb '++ FATAL ERROR - DateStamper requires CP/M 2.2 ++' defb CR,LF,CR,LF,0 ; ;..... ; ckclkz.asm 6/26/85 Z80 mnemonics ;=========================================== ; Exit: HL = 0, Z set if no clock ; HL = DateStamper clock entry, Z reset if clock present ; CLKADD is also set, so DSCLK can be called hereafter ; ; The logic for finding the clock is as follows: ; ; 1. Use BDOS version number call to check for DateStamper version >= 2.0 ; Call with E = 'D'. ; If DateStamper is installed, function returns H = 'D', L = 22H ; and DE = address of clock. ; ; 2. If version number test fails, check for DateStamper version 1. ; The DateStamper clock address is located from the ; bdos patch at LOGDR1+1 and is (LOGDR1+1) - 49H. ; ; The checks must be done in this order to maintain compatibility ; with all DateStamper versions and non-standard BDOS systems. ; GETVFN equ 12 ; BDOS get version function DSID equ 'D' ; DateStamper ID for getversion call ; CKCLK: ld e,DSID ; Special parameter for ld c,GETVFN ; ..getversion call call BDOS cp 22H ; Must be 2.2 jp nz,NOCLK ld a,h cp DSID ; If H == DSID, ex de,hl ; ..then clock addr was in DE jp z,CLKA ; Set it & return HL = CLKADD, NZ ; ; else test for BDOS patch ; ; Exit: NZ if test satisfied, HL = clock addr ; Z, HL = 0 if not ; ld hl,(0001H) ; Start at wb ptr ld a,l ; Test for BIOS jmp vector cp 3 ; Aligned on page boundary jp nz,NOCLK ; If not, can't find BDOS ; ; Enter: H = page of presumed BIOS base ; ; Internal BDOS addresses relative to base of BDOS ; LOGDR1 EQU 0C42H ; 'jmp 06A3' in standard CP/M 2.2 HILOGD EQU 0CH LOLOGD EQU 042H BITMAP EQU 06A3H ; Addresses to be checked LOBITM EQU 0A3H HIBITM EQU 06H DELTAP equ HILOGD-HIBITM ; GETVER equ 0C7EH ; 'mvi a,022H' in standard CP/M 2.2 ; CLKOFF EQU 42H+7H ; Offset to DateStamper clock from (LOGDR1+1) ; BIOSWB EQU 0E03H ; BIOS warmboot address ; ; TSTCLK: ; ; Test for version 1 BDOS patch in standard 2.2 BDOS ; ld b,h ; Save B = BIOS base page ld de,GETVER+1-BIOSWB ; Check for CP/M 2.2 vers byte add hl,de ld a,(hl) cp 22H jp nz,NOCLK ; Not standard CP/M 2.2 BDOS ; ; Version byte shows 2.2. Check for DateStamper patch at LOGDR1 ; ; Unpatched 2.2 std BDOS: JMP BITMAP ; Patched Std BDOS : JMP DSADDRESS ; Other : unknown ; LD DE,LOGDR1+1-GETVER-1 ADD HL,DE ; Point at addr word LD E,(HL) ; DE = D/S addr, if resident ld a,e cp LOBITM ; Check low byte INC HL LD D,(HL) jp nz,CHECK2 ld a,d ; Check HI byte add a,DELTAP ; Page difference in rel. addresses cp h jp nz,CHECK2 ; NOCLK: ld hl,0 ; Standard, unpatched 2.2 BDOS ==> No clock jp CLKA ; ; Address differs from std. 2.2 BDOS. ; Check whether it is internal to the BDOS. ; CHECK2: ld a,b ; Base page of BIOS sub d ccf jp nc,STDCLK ; External addr above BDOS sub 0EH ; Page length of BDOS jp c,NOCLK ; Addr is within BDOS ; STDCLK: LD HL,-CLKOFF ;calc. entry to DateStamper clock ADD HL,DE ; CLKA: LD (XCLKADD+1),HL ;set addr in ram for clock calls ld a,h or l ; Z if no clock RET ; ; Read the DateStamper clock ; ; Enter : HL -> 6-byte buffer for date/time ; Exit : If no clock : HL = 0, No CY (Clear) ; If Clock : HL = Entering HL, CY Set ; Current time at (hl) ...(hl+5) ; DSCLK: ex de,hl ; Buffer ptr to DE ld hl,(XCLKADD+1) ;do we have a resident clock? ld a,h or l ret z ; Return HL = 0, Z set ex de,hl ; Buffer ptr to HL XCLKADD: call 0000 ;call DateStamper clock scf ;cy is a clock ret ; ; get bcd date&time ; ; exit: hl = 0, Z set if no DateStamper clock ; hl = bcd buffer, Z reset if DateStamper clock ; GTDATE: ld hl,(XCLKADD+1) ; Check presence of clk ld a,h or l ret z ;return hl = 0 (no clock) ld hl,BCDBUF push hl call DSCLK pop hl ;return ptr to bcd buffer ld a,h or l ;nz ret ; ;----------- End DateStamper Code ---------------------- ; ; Heading line for hard copy/disk output ; HEAD: DEFB CR,LF,LF,LF,CR,LF HEAD1: DEFB SI,SI,SI,SI,SI,SI,SI,SI,SI,0 HEAD1A: defb 'Master Catalog as of ',0 HEAD2: DEFB ' ',0 HEAD2A: defb ' Page ' HEAD3: DEFB ' 1',CR,LF,LF,LF,0 QUIT: DEFB CR,LF,LF,LF,0 ; DHEAD: defb 'Disk -.' DHEAD1: defb ' as of ',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 when printer selected. ; (None needed if your printer has ; adjustable margins.) ; PRBUF: DEFB SI,SI,SI,SI,SI,SI,SI,SI,SI;to augment left margin ; OBUF: DEFB ' ' ;output buffer, 80 columns max. DEFB ' ' DEFB ' ' DEFB ' ' ; ;..... ; A single-record buffer is used for converting the compressed- ; format data from MAST.CAT into the fixed-length format used ; by the various parts of XCAT. ; RECNAM: defb ' ' ; Space for Name.Typ RECDSK: defb ' ' ; Space for Disk ID RECUSR: defb ' ' ; Space for User area RECDAT: defb ' / / ' ; Space for Date info ; IBUF: defb ' ' ; Name & ID buffer for comparisons ; ;..... ; FCB for reading MAST.CAT ; FCB: DEFB 0,'MAST CAT',0 ;2nd 0 = extent # DEFB ' ' DEFB ' ' ;rest of 'FCB' for 32 bytes DEFB 0 ;nr field ; ;..... ; Table for Months in year. ; MONTHS: defb 'JanFebMarAprMayJunJulAugSepOctNovDecXXX' ; SEPSTR: defb ' | ' ; Separator for Dir listing ;..... ; Misc storage locations ; DASH: DEFB ' - ' ;used to format printout ; SPAC18: defb ' ' ; Space strings used for screen formatting SPAC14: defb ' ',0 ; defs 80 ; Area for stack STACK: defs 2 ; Place to hold stack pointer ; CNT: defs 1 ;number of diskid'S ON LINE ALLNAM: defs 1 ; TRUE if search .eq. all Name.typ ALLDSK: defs 1 ; TRUE if search .eq. all Disk IDs LCNT: defs 1 ;line count for hard copy XDONE: defs 1 ;use last name file ; DBDATE: defs 1 ; Database Date flag (From Ignore list) DBUSER: defs 1 ; Database User flag (from Ignore list) DIFF: defs 1 ; Difference from above 2 and defaults ; TIMER: defs 1 ; Misc location for timer function ; CMDPTR: defs 2 ; Pointer to command line arguments HSADR: defs 2 ; Misc place to store comd addr hilite ; IDLEN: defs 1 ; Chars per disk entry NUMPRL: defs 1 ; Disk entries per line ; CBUFF: defs 32 ; Move location for command line args ; TMPSEP: defs 1 ; Temp storage for separator ; ;----------- End of cleared memory on each pass --------- ; BUFLEN: defs 2 ; Calculated buffer length MEMTOP: defs 2 ; Top of useable memory INADR: defs 2 ; Input buffer address INLEN: defs 2 ; Input buffer length INPTR: defs 2 ; Input buffer pointer OUTADR: defs 2 ; Output buffer address OUTLEN: defs 2 ; Output buffer length OUTPTR: defs 2 ; Output buffer pointer DIRFLG: defs 1 ; Flag set true if Directory form of output ; CCP: defs 1 ; 'CCP' page of memory ; IMMED: defs 1 ; Flag for immediate execution SCRLIN: defs 1 ; Line counter for main window ; CDRIVE: defs 1 ;drive for disk to be cataloged MDRIVE: defs 1 ;drive for MAST.CAT must follow CDRIVE ODRIVE: defs 1 ; Drive for Output file ; TDRIVE: defs 1 ; General purpose drive storage ; CUSER: defs 1 ; Place to save current user on entry MUSER: defs 1 ; User area for MAST.CAT OUSER: defs 1 ; Output File User Area ; TUSER: defs 1 ; General purpose user storage ; OUTFLG: defs 1 ; Output device - C, F, P HWFFD: defs 1 ; Flag for Hardware FormFeed ; DEFLT: defs 9 ; Leading zero and output file name DEF1: defs 3 ; ..Output file type ; ; Default Search parameters. (future expansion) ; SRNAM: defs 11 ; File name/type for search SRDISK: defs 3 ; Disk Criteria for search ; ; DateStamper variables ; BCDBUF: defs 6 ; Buffer for reading clock DSFLAG: defs 1 ; Flag for presence of clock MONTH: defs 1 ; Temporary store for Date entry routine TMPDAY: defs 2 ; Temporary hold for days digits MYEAR: defs 2 ; Place to store master year RELCLK: defs 1 ; Flag showing relative clock ;..... ; FNT: DEFS 0 ; IO Buffers start HERE... ; ;..... End of Storage ........ ; ; HELP code and text overlays the data area. If Help is requested, ; the information is presented, and the program exits to CP/M. If ; execution is selected, the HELP text and code is overwritten. ; ORG CNT ; Start here. ; ;------------------------------------------------------------------ ; HELP: call CRLF ; Give a new line.. ld hl,HELPM ; Set starting address ld a,(THEIGHT) ; Get lines per screen cp 7 ; Must have at least 8 lines jp nc,HELP1 ; ..jump if OK ld a,7 HELP1: ld e,a ; Save it in E HELP2: ld d,1 ; Start at the beginning HELP3: call HLPRT inc hl ; ..Point past ending 0 ld a,(hl) ; If next char = 0.. or a jp z,EXIT2 ; ..then quit push de push hl call CRLF pop hl pop de inc d ; Printed 1 line, bump counter ld a,d cp e jp c,HELP3 call ILPRT ; Print prompt defb '[more]',0 call GETCH ; Wait for any character ld a,CR call CRTOUT ; ..overwrite prompt jp HELP2 ; ..and loop ; HELPM: defb 'X-Ref Program Version 5.',0 defb ' ',0 defb ' XCAT accepts a Master Catalog of file names' defb ' (MAST.CAT)',0 defb 'produced by the Catalog Update program, MCAT. ' defb 'Compatability',0 defb 'with previous catalogs is retained with only the ' defb 'addition',0 defb 'of a special header field (see MCAT501.DOC).',0 defb ' ',0 defb ' XCAT can operate in line-oriented or full-screen' defb ' ''window'' ',0 defb 'mode. Screen-oriented mode is selected by adding' defb ' cursor',0 defb 'commands to the program. See source code or use',0 defb 'Plu*Perfect Systems'' SETTERM.COM utility.',0 defb ' ',0 defb 'OPERATION:',0 defb ' ',0 defb ' XCAT Runs program from current drive/user' defb ' with',0 defb ' default MAST.LST put on current' defb ' drive/user.',0 defb ' XCAT A10:MAST.PRN',0 defb ' Loads MAST.CAT from drive B, user 4' defb ' and puts',0 defb ' MAST.PRN on Drive A, user 10.',0 defb ' XCAT -C Loads MAST.CAT from current drive/user' defb ' and',0 defb ' outputs X-ref to Console device.',0 defb ' XCAT afn Loads MAST.CAT from current drive/user' defb ' and',0 defb ' puts X-ref names matching "afn" to ' defb 'default',0 defb ' output device',0 defb ' XCAT *.MAC,814 $U - Outputs special Directory' defb ' form',0 defb ' of all .MAC files on disk -.814 with' defb ' only',0 defb ' Filename.Typ and USER areas.',0 defb ' ',0 defb ' If parameters are passed on the command line after' defb ' XCAT,',0 defb 'immediate execution will occur and return to CP/M ' defb 'when',0 defb 'finished unless an error occurs. If errors are' defb ' detected,',0 defb 'operation returns to the menu mode so the user can' defb ' correct',0 defb 'and re-execute the command.',0 defb ' ',0 defb ' XCAT V.5 is compatible with Plu*Perfect''s' defb ' DateStamper(tm)',0 defb 'programs. Date stamping info cataloged by the com' defb 'panion MCAT',0 defb 'V.5 with DateStamper can be displayed in either US' defb ' (mm/dd/yy)',0 defb 'or European (dd.mm.yy) formats.',0 defb ' ',0 defb ' Normal operation of XCAT is Menu-driven and default' defb ' settings',0 defb 'can be changed from within the program. Variables' defb ' are:',0 defb ' ^L - Location of MAST.CAT (drive/user)',0 defb ' ^O - Output (Console/Printer/Disk File)',0 defb ' ^F - Format of MAST.CAT entries (FN.FT/User/Dates)',0 defb ' ^S - Selective search criteria (Name.Typ,Disk)',0 defb ' ^Z - Redraw the entire screen',0 defb ' ',0 defb 0 ; ;---- End Of Program ---- ; ; BDOS commands ; LISTC equ 5 ; Write char to List device TRMIO equ 6 ; Direct Console/Terminal IO CPMVER equ 12 ; Return CP/M Version Number RESET equ 13 ; Reset Disk System SELDSK equ 14 ; Select Disk Drive OPENF equ 15 ; Open File CLOSF equ 16 ; Close file ERASF equ 19 ; Delete File READF equ 20 ; Read Sequential WRITEF equ 21 ; Write Sequential MAKEF equ 22 ; Make File CURDSK equ 25 ; Query Current Logged Disk SETDMA equ 26 ; Set 'DMA' address G$SUSR equ 32 ; Get/Set User Area ; BDOS equ 0005H ; BDOS entry location TFCB equ 005CH ; Default File Control Block TBUF equ 0080H ; Default 128 Byte Buffer ; ; END START