home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-10-10 | 54.9 KB | 2,007 lines |
- title LT31 Types/Extracts/Uncrunch/USQ/UNLZH LBR/Files (15 Dec 1991)
- ;
- ver equ 31; Current version number
- ;
- ; LT types normal, lzh-encoded, crunched or squeezed files, either directly
- ; or from .LBR members. Wild cards access a series of library members.
- ;
- ; Recommended Assembler/Linker - SLRMAC and SLRNKP. Others will work,
- ; but normally require a two pass link operation and file truncation
- ; to avoid generating useless uninitialized data space in the code file.
- ;
- ; SLRMAC LTxx/R
- ; SLRNKP LTxx/N,/A:100,/J,LTxx,UNLZH,UNC,/E
- ;
- ; For other linkers see the documentation in BUFFERS. To check your
- ; methods first assemble and link this release and compare the object
- ; files. If they are different you do not have the full technique.
- ;
- ;---------------------------------------------------------------------
- ; updates
- ;
- ; 15 Dec 91 Modified as follows to enable assembly with ancient (about 1979)
- ; v31 version of M80 by changing the names of the following symbols which
- ; exceeded 6 characters. (This will not effect assembly with any
- ; other assembler.)
- ; OLD LABEL NEW LABEL OLD LABEL NEW LABEL OLD LABEL NEW LABEL
- ; setnam2 setnm2 setfld1 setfd1 setfld2 setfd2
- ; setfld3 setfd3 setfld4 setfd4 setfld5 setfd5
- ; Also modified routine labelled start: to fix a bug dating from v25
- ; that prevented LT from accepting USER specifications as a SOURCE
- ; of data. (Many thanks to Roger Warren, Sysop, Elephant's Graveyard
- ; San Diego, California for the suggestions for fixing this problem.)
- ; Modified by Brian Murphy (BCM)
- ; Vancouver Kaypro Users Group
- ; Richmond, British Columbia, Canada
- ; BBS phone: (604) 271-5934
- ;
- ; 17 Jul 91 Incorporated version 2.0 of LZH encoding. This program is
- ; v30 necessary to decode files encoded with version 2.0 of LZH
- ; compression, but will AUTOMATICALLY handle files encoded with
- ; version 1.x LZH encoding. Added appropriate documentation changes.
- ; Added instruction to reset MSB in output FCBs.
- ; Corrected error message pointer for UNC & UNL errors
- ; (sent garbage to screen).
- ; -R Warren
- ; Sysop, Elephant's Graveyard
- ; San Diego, CA (619)270-3148
- ;
- ; 02 Sep 89 Added ability to handle LZH-encoded files (extensions
- ; v29 of the form .?Y?). Added appropriate docs. No functional
- ; changes to the program, otherwise.
- ; -R Warren
- ; Sysop, Elephant's Graveyard
- ; San Diego, CA (619)270-3148
- ;
- ;
- ; **** DIATRIBE ****
- ; 18 May 88 Reformatted again, and repaired. If Mr Hoff wishes to
- ; v28 to reformat this source I wish he would retain such for
- ; his own benefit, and not foul the distributed version.
- ; He ingeniously makes it virtually impossible to detect the
- ; changes made using a text comparator. If this request is
- ; a problem to him he is welcome to call me at the number
- ; below. V27 had totally lost any indication of what file
- ; was being typed, and without a convenient comparison I
- ; had to restore from V25. Thus V26 changes have been lost.
- ; and I do not know whether V26 or V27 was the problem.
- ; I also request that Mr. Hoff refrain from removing my
- ; comments in the future (I have restored my comments to
- ; version 25 below). Will all modifiers kindly refrain from
- ; altering the file dates of modules that have not changed.
- ; For example, UNC.REL and UNC.SLR are still the '86 versions.
- ; LBR distributions can use LSETDATE, and ARCs are automatic.
- ; The gain from a large value of REC is miniscule and prevents
- ; use on systems with limited memory. V28 does not produce
- ; extra lines between extractions to file now, and this was
- ; done with less, not more, code.
- ;
- ; THINGS to be done: Incorporate checksum testing of results;
- ; slave ZCPR linkages to Z3ENV if on ZCPR system (signal
- ; is non-zero environment pointer). I hope to have a
- ; DOS+/CCP+ version that respects the ENV for wheel/user
- ; levels some time.
- ;
- ; If I am mistaken as to the culprit, I apologize for the
- ; vented spleen. - C.B. Falconer
- ;
- ; 05/11/88 Rewrote display section when extracting files to disk. Was
- ; v27 triple spacing with no tabulation. Was unsightly if library
- ; had more than 1-2 files. (Still under 5k.) If TPA is under
- ; 48k, might need to change "REC" from 128 to 96 or even 64.
- ; - Irv Hoff, Sysop
- ; PRACSA Sysop RCPM
- ;
- ; 04/15/88 When typing a crunched file with a comment attached, it was
- ; v26 running off the end of the screen, to display the uncrunched
- ; file name with comment. - Ed Minton
- ; Columbus, OH
- ;
- ; 10 Apr 88 Reformatted to my original system, which shows the action
- ; v25 of conditionals clearly. Someone had reformatted the
- ; entire source, and I suspect the promulgator of a certain
- ; reformatting program. There is no need to keep conditionals
- ; un-nested, since linking requires a reasonable assembler
- ; (not ASM) anyhow. Added .OVR type prohibition.
- ; Wheel control is now unified, with a single patch point.
- ; Now organized so that all options are patchable - Set maxusr
- ; to 0ffh to use the ZCPR mxusr value. Pausecheck on every
- ; character is now an option (useful for Braille). The
- ; conditionals should be used only where a smaller object
- ; file is required for some reason, not for configuration.
- ; Space has been reserved for ZCPR addicts (environment).
- ; ** PATCH POINTS HAVE CHANGED (for the last time??!!).
- ; I have also restored some of the "regs affected" comments
- ; which had been removed. Please update and maintain them,
- ; they greatly ease future modifications.
- ; I have attached a slightly later version of UNC, functionally
- ; identical, but 5 bytes shorter.
- ; I am glad to see many people actively enhancing this. When
- ; originally released I did not expect it to attain such
- ; popularity. Too bad it grew over 4k. Now should add the
- ; checksum tests.
- ; - C.B. Falconer (203) 281-1438
- ;
- ; 02/18/88 Fixed bug in PARSE4 routine. If no USER AREA specified for
- ; v24 disk output then it defaulted to input file user area rather
- ; than the CURRENT user area. Modified to allow abort during
- ; disk output. Added $U command line option to allow disk
- ; output of squeezed/crunched files WITHOUT unsqueeze/uncrunch.
- ; (see the NOUQZ byte added to the patch area at 103H).
- ; Added REC equate to allow more than one sector in the file
- ; output buffer to reduce wear and tear on floppy drives.
- ; - Tom Head
- ;
- ; 08/12/87 Fixed to properly handle 0-length files. Modified to
- ; v23 check for pause and abort from console after every typed
- ; character rather than at the end of each line. This was
- ; necessary to prevent loss of data on some very slow
- ; terminals such as the one I use, and to enable the typing
- ; of a file with no linefeeds to be aborted. Also fixed the
- ; tab expansion routine to work correctly with files con-
- ; taining unusual control characters such as backspace, and
- ; made the "turn up one line" feature more foolproof.
- ; - Howard Goldstein
- ;
- ; 07/30/87 Added the long needed ZCPR/ZCMD support of maximum user
- ; v22 area. When the UZCPR option is set, the page 0 value
- ; will be examined to determine if the requested user area
- ; is within the allowable range. This is primarily useful
- ; on RCP/M's (but I suspect that is where LT is primarily
- ; used). Added code to allow overriding the line counter
- ; and user area restrictions when the wheel is active.
- ; - Gary Inman, Sysop
- ; West Los Angeles RCP/M
- ;
- ; 07/21/87 When at a [more] pause, the space bar now turns up one
- ; v21 line at a time. LTxx is often used on RCPM systems as
- ; their general purpose TYPE.COM program. This makes it
- ; compatible with UNARC16. These two programs are used
- ; in the popular LUX program to type ASCII files in ARC,
- ; ARK or LBR files. I have always liked this feature in
- ; UNARC16 and decided to add it to LT20. I believe most
- ; users will find this quite useful and hope CB Falconer
- ; does not mind my adding this feature. This version is
- ; a little over 4k. If this makes any problem, just use
- ; an earlier version. - Irv Hoff, Sysop
- ; PRACSA RCPM
- ;
- ; 07/17/87 Able to use wheel byte in conjunction with OUTFLG flag.
- ; v20 One byte added in ddt modifiable area at program start.
- ; WHLFLG and/or WHEEL now tested in conjunction with the
- ; OUTFLG flag eliminating need for two copies of program
- ; when used on a remote system. Found that it would not
- ; assemble properly using M80/L80 because of YES/NO, now
- ; corrected. Restored program name, version number, and
- ; author credit. Other minor mods to keep code size <4k.
- ; - G.F. Reding [72436,45]
- ;
- ; 06/10/87 Change to only display characters between "[" and "]" in
- ; v19 the header of crunched files as other characters in this
- ; area are reserved. Removed the redundant "IF NOT UNCR"
- ; (marked ";;;;") following an "ELSE" which prevented LT18
- ; from being assembled in its distributed form. Slight text
- ; changes to keep <4k. - Steven Greenberg
- ;
- ; 12/28/86 Allows access to .LBR files > 512k. Was using CPM 1.4
- ; v18 variety of direct access. Mods to keep under 4k total.
- ; Should CP/M v1.4 check and refusal.
- ; - C.B. Falconer
- ;
- ; 12/13/86 Prevent junk file names on "LT fn.t d:" where fn.t is not
- ; v17 squeezed or crunched. Thanks to Bill Duerr for calling my
- ; attention to this. Set default "drvsup" to all drives.
- ; Fixed OUTFLF usage when extract false, per Frank Whitman.
- ; - C.B. Falconer
- ;
- ; 11/24/86 Using UNC module, executable on 8080. Can extract all
- ; v16 files to disk. Needed because NULU 1.51 cannot uncrunch
- ; during extractions. Disk extraction ignores "BADTBL".
- ; For RCPM use, assemble with the "extract" equate set to
- ; NO. Clean-ups. - C.B. Falconer
- ;
- ; 11/17/86 Added ability to extract to a file with "LT lbr d:fn.ft",
- ; v15 where the "d:" signifies extraction. 01Ah is EOF, so not
- ; suitable for binary files. The code has become a mess to
- ; preserve the ability to generate minimum version.
- ; - C.B. Falconer
- ;
- ; 86/11/15 Added hooks to include Steve Greenbergs UNCR system. These
- ; v14 are guarded by 'UNCR' equate to setup options. Use requires
- ; linking and creation of relocatable object. Any uncrunching
- ; requires a Z80 cpu. - C.B. Falconer
- ;
- ; 02/12/86 Added expansion of UCSD style "dle/code" indentation codes.
- ; v13 These also appear in the PASCALP system.
- ; - C.B. Falconer
- ;
- ; 12/05/84 Stole some features from TYPELxx '?' for forbidden file
- ; v12 type table, list output enable on du version, location of
- ; BADTBL for patching. Checked "LIMITT" and "LMITL" options
- ; functioning with wild cards. Version display shows options
- ; enabled. Added bit vector for drives available. Added du
- ; option under "DUSPEC" conditional. The minimum version
- ; remains under 0500h bytes, with options disabled. If an
- ; operator is already logged into a drive/user area then that
- ; drive/user area remains available even though the configured
- ; restrictions should prevent it. This allows for privileged
- ; users. John Doe can't get there at all.
- ; - C.B. Falconer
- ;
- ; 12/04/84 Deleted unused variables and labels, also variables that
- ; v11 are better kept on the stack. Arranged for LBRFCB to be
- ; fully initializable via parameter, for straight type.
- ; Thus:
- ; A>LT fname.typ
- ;
- ; will type/unsqueeze FNAME, while "LT LBRFILE component"
- ; extracts as before. - C.B. Falconer
- ;
- ; 10/02/84 Adapted from Steven R. Holtzclaw's "LUXTYP (06/10/83)"
- ; v10 for independent use without the complete LUX system.
- ; Eliminated Z80-only opcodes. Added file searches. Added
- ; simple usage message, assembly time constants to eliminate
- ; limits on lines and file types, ^Z stops pauses. CRT lines
- ; measured acrossfiles.
- ; - C.B. Falconer
- ;
- ; ---------------------------------------------------------------------
- ;
- aseg ; Needed for M80, ignored by SLRMAC, else ignore error
- ;
- no equ 0; For conditional assembly
- yes equ not no; (Some assemblers don't like 0FFh)
- ;
- ; -------- Configuration -------
- ; Assembly time configurable areas. Each increases COM file size.
- extract equ yes; *File extraction ability, wheel controllable
- rec equ 32; Sectors in file output buffer. DO NOT make
- ; too large, else uncruncher wont work
- ;
- limitl equ yes; Yes allows output line limits
- limitt equ yes; Yes allows file type restriction
- duspec equ yes; Use DU style drive/user specifications
- xpnd equ yes; Expand UCSD style "DLE/code" indentation codes
- paws equ no; Check pause/abort on each output char (braille)
- ;
- ; Next is used with EXTRACT so that 1 copy only needed for RCPM systems
- ; Note: the wheel also over-rides the line count restriction, if any
- whlat equ 0; Location of wheel byte, 0 disables wheel check
- ; (usually 03eh, patch into option area)
- ; Value only used to set this word (1 place)
- ;
- ; For added security on RCP/M's to prevent access to files outside
- ; the callers permitted drive user areas. See whlat above also
- mxdrv equ 03dh; Location of max drive byte
- mxusr equ 03fh; Location of max user byte
- ;
- ; Configurable values. Also see "DRVSUP" configurable vector
- pagsz equ 20; Default lines per CRT page
- lnmax equ 0; 0 for no limit, else max file size (to 255)
- noctrl equ yes; Yes to prevent control char. output
- usrmax equ 15; Maximum user area accessible
- ; 0-15 for CP/M 3, 0-31 for CP/M 2.2 or DOSPLUS
- ; ZCPR . . SPECIAL VALUE - 0ffh causes ZCPR mxusr to be
- ; loaded into maxusr.
- ; ------- END configuration equates --------
- ;
- ; Ascii control chars
- bell equ 07h
- bs equ 08h
- tab equ 09h
- lf equ 0ah
- cr equ 0dh
- dle equ 010h
- eof equ 01ah
- sqzdle equ 090h; special in squeezed/crunched files
- ;
- ; CP/M-DOS+ system values
- bdos equ 0005h
- fcb1 equ 05ch
- fcb2 equ 06ch
- cmdln equ 080h
- ;
- ; BDOS calls
- cio equ 6; Direct console I/O
- setdrv equ 14
- open equ 15
- close equ 16
- srchf equ 17
- delete equ 19
- fread equ 20
- fwrt equ 21
- make equ 22
- getdrv equ 25
- setdma equ 26
- gsuser equ 32; Get/set user
- frdran equ 33; Read random record
- ;
- cseg
- ;
- ; Linkages to unc module
- extrn unc, endu
- entry getbyt, out
- ;
- ; Linkages to UNLZH module
- extrn unl
- entry glzhun,plzhun
- ;
- ; --------------
- ; PROGRAM BEGINS
- ; --------------
- begin: jmp start; past configuration area
- ;
- ; Unused, but space reserved to fix patch locations
- db 'Z3ENV'; Special signature
- db 1; External environment
- @env: dw 0; And ZCPR can patch this location
- ;
- ; Configuration values, even if unused via "limit" options
- ; These may be patched to configure the COM file at installation
- whladr: dw whlat; Non-zero if wheel controlled
- pagsiz: db pagsz; Lines per page, 0 = no pauses
- maxlin: db lnmax; Max lines to type, 0 = unlimited
- typflg: db limitt; 0 for all file types, else selective
- pawsfg: db paws; To check pause on each output char.
- ctlflg: db noctrl; Non zero allows control char print
- altdrv: db 0; Alternate drive to search, 0 = none
- maxusr: db usrmax; Max accessible user, for du entries
- ; Set 0ffh to use ZCPR mxusr value
- drvsup: dw 1111111111111111b; Vector of available drives
- ; ABCDEFGHIJKLMNOP-; Drive ids (No N..P under PascalP)
- ; (example) 1100000000001000B; (shown set for A, B and M drives)
- nouqz: db 0; 0 to allow unsqueezing/uncrunching
- ; of files during disk output. The $U
- ; command line option will toggle this.
- xpdle: db NOT noctrl; Set NO = 0 to suppress DLE expansion.
- ; Useful if noctrl is set NO.
- db 0; spare for future use
- ;
- ; '?' matches any character. Alpha order for convenience only,
- ; a complete sequential scan is done. An existing name can be
- ; made to disappear by setting its high order bit somewhere.
- if limitt; Table of invalid file types
- badtbl: db 'ABS'; Intended to disable
- db 'ARC'; ===================
- db 'ARK'
- db 'BAD'
- db 'CRL'
- db 'C?M'; COM, CQM, CZM, CPM (v20 executes on PCs)
- db 'E?E'; EXE, EQE, EZE (MSDOS executable)
- db 'IRL'
- db 'I?T'; INT, IQT, IZT
- db 'LBR'
- db 'O??'; OBJ, OQJ, OZJ, OVL, OVR etc
- db 'P?D'; PCD, PQD, PZD (executable by RUNPCD)
- db 'TX#'
- db 'RBM'
- db 'R?L'; REL, RQL, RZL
- db 'S?R'; SLR, SQR, SZR (SLR format rel files)
- db 'SYS'
- db 0,0,0
- db 0,0,0; Spares, for user configuration
- db 0,0,0
- db 0; Table end marker
- endif; limitt
-
- start: lxi h,0; Set up HL for add to stack
- shld memcnt; Zero the memory count
- dad sp; Add stack pointer
- shld stack; Keep stack contents
- lxi sp,stack; Set up local stack
- lda maxusr
- inr a; Special 0ffh max causes
- lda mxusr; revision to mxusr
- jnz start1; (Changed from jz to fix bug BCM 15/12/91)
- sta maxusr; Revise if ZCPR user system
- start1: lxi d,lbrbuf
- mvi a,setdma; Do all I/O thru this buffer
- call sys
- ; " "
- if extract
- mvi a,' '
- sta outfcb+1; Default none
- endif; extract
- ; " "
- if duspec; Parse the command line
- call parse
- lda savusr
- call sguser; Set the user access
- endif; duspec
- ; " "
- call lbropn; Set up the library name buffer
- push psw; Save extract/type flag
- jnz start2; Type only
- lhld memcnt; Get member count
- mov a,l; Get member count lsb
- ora h; Any members?
- lxi d,nfound
- jz exeunt; No - exit
- ; " "
- start2: lxi d,sign1; Give name, version, credit
- call tstrc
- pop psw
- jnz dump; Type only
- ; " "
- ; Per component loop
- next: call initlp; Initialize the "next" loop
- call getmem; Get next member FCB
- jc exit; All done...
- call lbrset; Set up to read the library file
- ; " "
- ; Input setup, do the extraction and/or unsqueezing
- dump: if limitt; Test the type of file
- call tsttyp
- endif; limitt
- ; " "
- call get2hl; Get the first 2 bytes from the file
- jnz zerprt; Special processing for 0-length file
- ; " "
- ; This allows disk output WITHOUT any unsqueezing or uncrunching.
- push h
- lxi h,outflg; File output flag
- lda nouqz; No unsq/uncr flag
- ana m; If (no unsq/uncr) AND (disk output)
- pop h
- jnz asprt; Then skip uncompression routines.
- ; " "
- mvi a,076h
- cmp l
- jnz asprt; Not squeezed - print an ascii file
- mvi a,0ffh
- cmp h
- jz dumpsq; Squeezed, dump it
- dcr a; To 0feh
- cmp h
- jz dumpcr; Crunched, dump it
- dcr a; To 0fdh
- cmp h
- jnz asprt; Not compressed - print an ascii file
- ; " "
- ; Output from a LZH compressed file
- call nmshow; Show actual name etc, absorb header
- lhld namptr; Free memory area, above names
- call unl; UNLZH.REL. Uncompress
- lxi d,badfile
- jc donem; something went wrong
- jmp done
- ; " "
- ; Output from a crunched file
- dumpcr: call nmshow; Show actual name etc, absorb header
- lhld namptr; Free memory area, above names
- call unc; UNC.REL. Uncrunch
- lxi d,badfile
- jc donem; something went wrong
- jmp done
- ;
- ; Output from a squeezed component
- dumpsq: call get2hl; Get and discard the next 2 bytes
- call nmshow; Actual name, and absorb header
- call sqsetu; Setup the squeezed file
- ; " "
- ; List a squeezed component
- sqloop: call getsqb; Get a byte from the file
- jc done; Eof - get next file name in queue
- call crtype; Else print the char
- jmp sqloop; And loop for more
- ;
- ; Show UNSQ/UNCR member name, etc. Optionally revise output name.
- ; This has the side function of absorbing the sqz/crn header.
- ; a,f,b,d,e,h,l
- nmshow: lxi d,ffsep
- call tstr; Make the file-file seperator
- ; " "
- if extract
- lxi h,outfcb+1
- mvi b,11
- nmshw1: mvi m,' '; Pre-blank the output name
- inx h
- dcr b
- jnz nmshw1
- mov m,b
- lxi d,outfcb+1
- mvi b,8; Size of name field
- endif; extract
- ; " "
- ; This section types the filename to the console and puts it into
- ; "OUTFCB". A null character terminates all header processing. Other
- ; characters after filename are ignored, unless they follow a "["
- ; character. These will be echoed to the console, until either a null
- ; character is detected (terminate processing) or a "]" character is
- ; detected (start scanning for null again).
- nmshw2: push d; Filename area of OUTFCB
- call lbrget; Get character from the file
- pop d; Restore pointer
- ora a; Check for null
- jz nmshw9; If found, terminate header processing
- cpi '['
- jz nmshw7; "[", go display "stamp" text
- cpi '.'; Was the character a "."?
- jnz nmshw3; If not update cnt, display char, put in FCB
- call ctype; "." is displayed, but not put into FCB
- mvi b,3; set filename char counter to "3"
- ; " "
- if extract;
- lxi d,outfcb+9; adv filename dest pointer accordingly
- endif; extract
- ; " "
- jmp nmshw2; Continue processing filename ext chars
-
- nmshw3: inr b; Check filename character limit
- dcr b;
- jz nmshw6; If down to zero, exit this section
- ani 07fh; Strip MS bit before placing in FCB
- call ctype; Else display char
- ; " "
- if extract;
- stax d; put char in the FCB if appropriate
- endif; extract
- ; " "
- inx d; Bump filename dest pntr
- dcr b; Count it
- jmp nmshw2; Continue filename processing
- ;
- ; Filename has been fully processed. Continue header analysis.
- nmshw4: call ctype; (entry here to display extra char)
- ; " "
- nmshw5: call lbrget
- ora a; Loop swallows characters until either
- jz nmshw9; a null or a "[" char is detected
- ; " "
- nmshw6: cpi '['
- jnz nmshw5
- ; " "
- nmshw7: mvi a,' '; "[" found. Insert blank for aesthetics
- call ctype
- mvi a,'['; But display the "[" char as well
- nmshw8: call ctype
- call lbrget
- cpi ']'; Loop to display characters to the con-
- jz nmshw4; sole until a null or a "]" is found
- ora a
- jnz nmshw8
- ; " "
- ; All paths to here have a=0 and z flag set
- nmshw9: if extract
- call outtst; Test if output to disk
- cnz opnout; If to file, create it (outfcb), set nz
- endif; extract
- ; " "
- cz crlflf; only when typing
- ret
- ;
- ; Output an unsqueezed file/component.
- ;
- zerprt: sta zerlen; Save zero length file flag
- ; " "
- asprt: if extract
- push h
- lda outfcb+1; Kludge to prevent file copying
- sui ' '
- jnz asprt0
- lxi h,nouqz
- ora m; If we override unsq/uncr
- jnz abort; we would trash the screen.
- sta outflg; i.e. a zero, following fails
- asprt0: call outtst; Test if output to disk
- cnz opnout; If to file, create it (outfcb), sets nz
- pop h
- cz crlflf; if typing. Opened output has set nz
- else; not extract
- call crlflf; we are typeing
- endif; not extract
- ; " "
- lda zerlen
- ora a
- jnz done; Don't type anything for 0-length file
- mov a,l; Print
- push h
- call crtype; First
- pop h; (file out clobbers hl)
- mov a,h; Two
- ; " "
- asprt1: call crtype; Bytes
- call lbrget; Get a byte from the file
- jz asprt1; Not eof, print and get more
- jmp done
- ;
- ; Done, send message
- donem: call tstr
- ; " '
- ; Done, no message
- done: lxi sp,stack; SP uncertain here - reset the stack
- ; " "
- if extract
- call outtst; Test if output to disk
- cnz fclose; close file if so
- endif; extract
- ; " "
- jmp next
- ;
- ; Initialize the "next" loop
- ; a,f,b,h,l
- initlp: lda paglns
- ora a
- jnz initl1; Paging was not stopped
- sta lincn1; Else clear for fresh start
- lda pagsiz
- sta paglns; Restart any page pauses
- initl1: lxi h,zeros; Fill flag area with zeros
- mvi b,lastz-zeros; Count of zeroes to load
- xra a; Fill (HL) up for (B) with zeroes
- initl2: mov m,a; Put a byte
- inx h; Next location
- dcr b
- jnz initl2; Fill all 11 bytes
- ret
- ;
- ; Open the FILENAME.LBR file and the MEMBER.EXT files, returns Z-flag
- ; for library extraction, NZ for pure type
- ;
- lbropn: mvi b,12; Field size for .LBR file
- lxi h,fcb1; Move first file FCB
- lxi d,lbrfcb; To LBRFCB
- call move
- xra a; Set ext & rec # to 0 for proper open
- sta lbrext
- sta lbrsno
- lxi h,fcb2+1; Source is member FCB name, no drive
- mov a,m; First member character
- cpi ' '; Is it a space or control ?
- jc helper; Control, exit with help
- jz tfile; Space, type one file only
- lxi d,memnam; Move FCB2 to MEMNAM
- mvi b,11; Bytes to move
- call move; Member name to local area
- ; " "
- ; Open the .LBR file
- lxi h,'BL'
- shld lbrtyp; Force .LBR type
- mvi a,'R'
- sta lbrtyp+2
- call fopnlb; Open .LBR file
- inr a; Open ok?
- jz nofile; Failure, abort with help
- ; " "
- ; Read the first record of the library directory
- call lbread; Read a sector
- lhld lbrbuf+14; Get directory size
- ; " "
- ; Test for a valid library file
- lda lbrbuf
- ora a; Test first byte
- lxi d,corrpt
- jnz exeunt; Non-zero, bad .LBR file
- ; " "
- ; Read the next library directory record
- lbrop5: push h; Save DIRSIZE
- cnz lbread; Read a sector, except 1st pass
- ; " "
- ; Search for the member name in the library directory
- lxi h,lbrbuf; Process first entry
- call addmem; To memory buffer
- lxi h,lbrbuf+20h; Process second entry
- call addmem; To memory buffer
- lxi h,lbrbuf+40h; Process third entry
- call addmem; To memory buffer
- lxi h,lbrbuf+60h; Process fourth entry
- call addmem; To memory buffer
- pop h; Count of dir entries
- dcx h; -1
- mov a,h; Zero directory entries left ?
- ora l
- jnz lbrop5; Now read another directory sector
- ret
- ;
- ; The second parameter is missing, just type the main file,
- ; returns NZ flag to signal no library extraction
- ;
- tfile: lxi d,lbrfcb+1
- ldax d
- dcx d
- cpi ' '
- jz helper
- call fopenf
- inr a
- jz nofile
- ; " "
- if limitt
- inx d
- xchg
- lxi d,memfcb
- mvi b,11
- call move; Name to memnam for checking
- endif; limitt
- ; " "
- call initlp; Other one pass initializers
- ori 0ffh; Set NZ flag
- jmp initpt; Set up pointers, leave NZ flag
- ;
- ; Setup access to the library component
- ; a,f,b,d,e,h,l
- lbrset: lxi d,mbrmsg
- call tstrc
- lxi h,memfcb; Index member FCB
- ; " "
- if extract
- push h
- lxi d,outfcb+1
- mvi b,11; Set default output file name
- call move; (will revise if squeezed/crunched)
- xra a
- stax d; And clear extent field
- pop h
- endif; extract
- ; " "
- call fname
- mov e,m; Get member starting record LSB
- inx h
- mov d,m; And MSB
- push d; Save
- inx h
- mov e,m; Get member size LSB
- inx h
- mov d,m; And MSB
- xchg; Into 'HL'
- inx h; +1
- shld rcnt; Save it in record count
- pop h; Restore starting record number
- shld lbrrno
- xra a
- sta lbrrno+2; Set random rcd no
- sta lbrext
- call fopnlb; Open the LBR file again
- inr a
- jz preeof; Should not happen
- mvi a,frdran
- call sys; Do a random read to put in sequential
- ora a
- jnz preeof; No such record
- ; " '
- ; Initialize pointers to read from LBRFCB
- ; a,h,l (flags preserved)
- initpt: mvi a,080h
- sta chrcnt; Set char count to force read
- lxi h,lbrbuf-1
- shld bufptr
- ret
- ;
- ; Get a byte from the .LBR member. GETBYT for UNCREL. GLZHUN for UNLZH use
- ; a,f,d,e,h,l
- glzhun:
- getbyt:
- lbrget: lda chrcnt; Get pointer
- inr a; Point to next position
- sta chrcnt; Put pointer back
- jp lbrge1; Buffer not empty
- call zbuff; Empty, reset pointers, read sector
- lhld rcnt; Get record count
- dcx h; -1
- shld rcnt; Set new record count
- mov a,l
- ora h
- jz lbrge2; If all records read
- call lbread; Read a sector
- ora a
- jnz lbrge2; If read was unsuccessful
- ; " "
- lbrge1: lhld bufptr
- inx h
- shld bufptr
- mov a,m; No - get the next byte
- cmp a; Set zero - no error
- ret
- ;
- lbrge2: mvi a,0ffh
- ora a
- ret; Return non-zero for error
- ;
- ; Zero the buffer pointers (for reaccess from start)
- ; a,f,h,l
- zbuff: xra a; Empty, read another record
- sta chrcnt; Clear the character count
- lxi h,lbrbuf-1
- shld bufptr
- ret
- ;
- ; Read a sector from library file
- ; a,f,d,e
- lbread: mvi a,fread
- lxi d,lbrfcb; .LBR FCB
- jmp sys; Read a block, and exit
- ;
- ; Get 2 bytes from input file into HL
- ; a,f,d,e,h,l
- get2hl: call lbrget; Get a byte from the input file
- rnz; May be an empty component
- push psw
- call lbrget; Get a byte from the input file
- mov h,a
- pop psw; first byte of the pair
- mov l,a
- ret
- ;
- nofile: lxi d,nofmsg
- jmp exeunt
- ;
- helper: lxi d,signon; Give name, version, credit
- call tstr
- lxi d,usage; Give help menu
- call tstrc
- call qwhl
- lxi d,whlusg
- cnz tstrc; Added help when wheel enabled
- jmp exit; without wasting CRT space.
- ;
- preeof: lxi d,eofmsg
- ; " "
- ; Error exit, crlf and message (DE)^
- exeunt: call tstrc; Print message
- ; " "
- exit: if duspec; Restore entry conditions
- call restor
- endif; duspec
- ; " "
- lhld stack
- sphl; Restore original stack
- ret; --exit-- to cp/m
- ;
- if extract
- ; Close any output file
- ; a,f,d,e,h,l
- fclose: lda bytes; Get bytes in current sector
- ora a
- jz fcls2; None
- lhld outptr; Get buffer pointer
- fcls1: mvi m,eof; Put in EOF
- inx h; Bump pointer
- inr a; And byte count
- jp fcls1; Fill out sector with EOF
- lda sector
- inr a
- sta sector; Bump sector count
- fcls2: call fput; Write buffer, maybe
- lda outusr; Shift to output user
- call sguser
- lxi d,outfcb
- mvi a,close
- call sys
- lda inuser
- jmp sguser; Restore and exit
- ;
- ; Put character (TOS) to file. Unclean hook for CRTYPE.
- ; a,f,h,l
- fputch: pop psw; Get char. to ACC.
- lhld outptr; Pointer
- mov m,a; Put char in buffer
- inx h
- shld outptr; Update pointer
- lda bytes
- inr a
- sta bytes; Update bytes in this sector
- rp; Exit if not full sector
- xra a
- sta bytes; Init. byte count
- lda sector
- inr a
- sta sector; Update sectors in buffer
- cpi rec; Buffer full?
- rnz; Exit if not
- ; " "
- ; Write output buffer to file
- ; a,f,h,l
- fput: push d
- lda outusr; User for output file
- call sguser
- call pbuf; Write the sectors
- lxi d,lbrbuf
- mvi a,setdma; Back to input buffer
- call sys
- lda inuser; Restore input user
- call sguser
- ; " "
- ; This code allows aborting a disk file output
- call cistat; Check for console input
- jz fput2; Continue if none
- cpi 'C'-40h
- jz abort; Abort on CTL-C
- fput2: pop d; Else continue
- ret
- ;
- ; Unload the stored buffer (up to rec sectors long)
- ; a,f,d,e,h,l
- pbuf: lda sector; Get sector count
- inr a; Prepare for upcomming DCR A
- lxi h,outbuff; Start of output buffer
- shld outptr; Init. byte pointer
- pbuf1: shld dmaadd; and write address
- dcr a
- sta sector; Update sector count
- rz; Exit if none left to write
- push psw; Save sector count
- xchg; Setup DE
- mvi a,setdma; Write address
- call sys
- lxi d,outfcb
- mvi a,fwrt; Now write it
- call sys
- ora a
- jnz fullup; Write error, abort everything
- lhld dmaadd
- lxi d,128; Get next write address
- dad d
- pop psw; Get sector count
- jmp pbuf1; And loop
- endif; extract
- ;
- ; Output to CRT or file. Entry name "out" for UNC or UNCREL, 'plzhun' for
- ; UNLZH or UNL use
- ; CRT output tracks column and line.
- ; a,f,e,h,l
- plzhun:
- out:
- crtype: if extract
- push psw
- call outtst; Test if output to disk
- jnz fputch
- pop psw
- endif; extract
- ; " "
- ; Not creating a file, this char goes to the console.
- cpi eof
- jz done; EOF on 01Ah for ASCII output
- ; " "
- if xpnd
- push psw
- lda dleflg
- ora a
- jnz crtyp6
- pop psw
- cpi dle
- jnz crtyp1
- lda xpdle
- ora a
- jnz crtyp5
- mvi a,dle
- endif; xpnd
- ; " "
- crtyp1: ani 7fh; Make sure its ASCII
- push psw; Save the character
- call cout
- lda pawsfg
- ora a
- cnz pauser; For slow terminals (Braille, etc)
- pop psw; Restore character
- cpi lf; Was it a line feed
- rnz; No - continue
- call qwhl; Load wheel byte if enabled
- jnz crtyp2; Bypass line count tests on wheel
- ; " "
- if limitl; Check for too many lines typed
- lda lincnt; Advance line counter
- inr a
- sta lincnt
- mov b,a; Line number in 'B'
- lda maxlin; Max number of lines to type
- ora a; Test flag
- jz crtyp2; If null function
- cmp b; Else compare to max lines
- lxi d,excess
- jz donem; Announce too much
- endif; limitl
- ; " "
- crtyp2: lda lincn1; Get line counter
- mov b,a; Keep in 'B'
- lda paglns; Number of lines per page
- dcr a; Decrement and test flag
- jm pauser; Function is null
- cmp b; Compare to lines per page
- jnc pauser; If not at maximum count
- xra a; Clear lines counter
- sta lincn1
- lxi d,more
- call tstr; Announce the pause
- call pause; Get input from console
- cpi ' '-eof; Space for line at a time?
- jnz crtyp3
- mov a,b; Get original line count back
- dcr a; And set to "one line left"
- sta lincn1
- crtyp3: lxi d,clean
- call tstr; Clear out the "[more]"
- ; " "
- ; Check for user pause or abort
- ; a,f,e (unless aborted)
- pauser: call cistat; Check the keyboard
- call pschk
- cpi 'S'-40h; CTL-S to pause?
- jz pause
- ani 5fh
- cpi 'S'
- rnz; Not CTL-S, return
- ; " "
- ; Returns input-01Ah. Aborts on c,C,^C or k,K,^K - next on CTL-X, etc.
- ; a,f,e
- pause: call cistat; Check the keyboard
- jz pause; Nothing yet so wait
- call pschk
- sui eof
- rnz; Not ^Z
- sta paglns; End pauses permanently on ^Z
- ret
- ;
- if xpnd
- crtyp6: xra a; Indentation expansion
- sta dleflg
- pop psw
- sui ' '
- rc
- rz; Else 'A' is count of spaces to send
- crtyp7: sta dlecnt
- mvi e,' '
- call cout3
- lda dlecnt
- dcr a
- jnz crtyp7
- crtyp5: sta dleflg
- ret
- endif; xpnd
- ;
- ; Console status
- ; a,f,e
- cistat: mvi a,cio; BDOS function
- mvi e,0ffh
- call sys; Direct console in call
- ora a; Was a key entered ?
- ret
- ;
- ; Pause check for special characters
- ; a,f (unless aborted)
- pschk: cpi 'C'-40h; Want to abort?
- jz abort; If yes, quit
- cpi 'K'-40h
- jz abort
- cpi 'X'-40h; Jumping to next file?
- jz pschk1
- cpi ' '; Space for "line at a time"?
- rz
- ani 5fh; Insure in upper case
- cpi 'C'
- jz abort
- cpi 'K'
- jz abort
- cpi 'X'
- rnz; If not, keep going
- pschk1: call crlf
- jmp done; Next file on CTL-X
- ;
- ; Abort the run with message
- abort: lxi d,abrmsg
- jmp exeunt
- ;
- ; Output char a to console, expanding tabs, tracking column
- ; a,f,e
- cout: mov e,a; Save output character
- cpi tab
- jz tabber; Expand a tab
- cpi cr; Carriage return
- jnz cout1
- xra a; CR sets COLUMN to 0
- jmp cout4
-
- cout1: cpi bs; Is char a backspace?
- jnz cout2
- lda column; Backspace sets COLUMN back one
- dcr a
- rm; Ignore if at column 0 already
- jmp cout4
-
- cout2: cpi ' ';
- jc coute; Other controls don't affect COLUMN
- ; " "
- ; Callable entry point here to display e
- cout3: lda column; Advance column counter
- inr a
- cout4: sta column
- ; " "
- ; Output e to console if printable
- coute: call qctl; Test control
- mov a,e; Get char back
- jz ctype; no suppression, print the char
- ret; absorb it, Return to caller
- ;
- ; Expand a tab, at least one space emitted
- tabber: mvi e,' '
- call cout3; Print a space
- lda column
- ani 7; At next tab stop ?
- jnz tabber; Yes, continue
- ret
- ;
- ; Test for control char output (from e). Z flag for no suppression.
- ; a,f
- qctl: lda ctlflg; Get controls active
- ora a; Test flag
- rz; Return if not
- mov a,e; Get output char
- cpi ' '
- jnc qctl1; Not control, clear flags
- cpi cr
- rz
- cpi bs
- rz
- cpi bell
- rz
- cpi lf
- rnz; Non-typable control char
- qctl1: cmp a; Set Z-flag, typable
- ret
- ;
- if limitt; Test for typable file
- ; Test for typeable file, abort with message to "DONE" if not
- ; a,f,b,d,e,h,l
- tsttyp: lda typflg; Get test flag
- ora a; Test it
- rz; Return if ok to type all types
- ; " "
- if extract; AND limitt
- call outtst; Test if output to disk
- rnz; Return if outputting to disk
- endif; extract AND limitt
- ; " "
- mvi b,3
- lxi h,badtbl-3; Index bad file type table
- tstty1: inx h; Next table address pointer
- dcr b; Bump loop counter
- jnz tstty1; Do until at next table entry
- mov a,m; Get a byte
- ora a
- rz; end of table - ok to type this one
- mvi b,3; 3 char extension
- lxi d,memfcb+8; Index file name extension
- tstty2: ldax d; Get a byte from extension
- ani 7fh; Strip any file attribute bits
- cmp m
- jz tstty3; Match, continue scan
- mov a,m
- cpi '?'; '?' in table matches all
- jnz tstty1; No match, next entry
- tstty3: inx h; Bump table address pointer
- inx d; Bump extent pointer
- dcr b; Bump counter
- jnz tstty2; Continue for 3 chars
- lxi h,memfcb+8; User name
- lxi d,cant
- call tstr; "CAN't type a '"
- mvi b,3; 3 byte file type
- tstty5: mov a,m; Get byte
- call ctype; Give a chance to abort here
- inx h; Next byte
- dcr b
- jnz tstty5; Type all 3 bytes
- lxi d,cant2; "' FILE ",CR,LF
- jmp donem; And do next file
- endif; limitt
- ;
- ; This part is adapted from TYPE109 by David Rand
- ; a,f,b,c,d,e,h,l
- getsqb: lda rptcnt; Get repeat flag
- ora a; Any chars to repeat ?
- jnz getsq1; Yes - get and count
- call nxtch; Get a character
- rc; Eof
- cpi sqzdle; Repeat byte flag
- jnz getsq3; No -
- call nxtch; Yes - get another character
- rc; EOF
- ora a; If null
- jnz getsq2
- mvi a,sqzdle; Dle is encoded as dle,0
- ret; Return with it, carry clear
- ;
- getsq2: dcr a; Bump counter twice
- jz getsqb; 1 repeat is a null event
- getsq1: dcr a
- sta rptcnt; Set repeat count
- lda rptchr; Return repeat character
- getsq3: sta rptchr; Set repeat char
- ora a; Clear any carry, not EOF
- ret
- ;
- ; Next decoded byte from file, ignoring repeat characters
- ; a,f,b,c,d,e,h,l
- nxtch: lxi d,0; Pointer @ star of text
- lda char
- mov c,a
- nxtch1: lda numflt
- ora a
- jnz nxtch2
- push d; Save 'DE'
- call lbrget; Get a byte from the input file
- jnz preeof; Not expecting an eof here
- pop d; Restore 'DE'
- mov c,a
- mvi a,8; 'A' is counter
- nxtch2: dcr a; Bump count
- sta numflt; Save it
- mov a,c; Get character
- rrc; Shift right
- mov c,a; Save character
- push psw; Save character
- lxi h,xlatbl; Index ram area
- dad d; HL=HL+(4*DE)
- dad d
- dad d
- dad d
- pop psw; Restore char
- jnc nxtch3; If no carry
- inx h
- inx h
- nxtch3: mov e,m
- inx h
- mov d,m
- mov a,d
- ani 80h
- jz nxtch1
- mov a,c
- sta char
- mov a,d
- cpi 0feh; Special end of file ?
- mvi a,eof; Yes - return with EOF character
- stc
- rz; And carry for EOF
- mov a,e
- cmc
- cma
- ret; With carry clear, not EOF
- ;
- ; Set up the translation table for the squeezed file
- ; a,f,d,e,h,l
- sqsetu: call get2hl; Get 2 bytes from input file into HL
- lxi d,xlatbl; Index ram area
- sqset1: mov a,h; Get MSB
- ora l; Test LSB
- rz
- push h; Save table size counter
- push d; Save ram area index
- call get2hl; Get 2 bytes from input file into HL
- pop d; Restore ram area index
- xchg; Into 'HL'
- mov m,e; Save the LSB byte
- inx h
- mov m,d; And MSB byte
- inx h
- push h; Bump & save pointer
- call get2hl; Get 2 bytes from input file into HL
- xchg; Into DE
- pop h; Restore pointer
- mov m,e; Save the LSB byte
- inx h
- mov m,d; And the MSB byte
- inx h; Bump pointer
- xchg; Restore pointer to 'DE'
- pop h; Restore table size counter
- dcx h; Decrement it the byte count
- jmp sqset1; And loop for more
- ;
- ; Add a library member to the name queue buffer if a match to MEMNAM
- ; a,f,b,d,e,h,l
- addmem: mov a,m; Get first byte of member entry
- ora a
- rnz; Non zero - must be deleted or null entry
- inx h; Go to the second byte
- push h; Save source address for coming 'LDIR'
- push h; Save it again
- mvi b,11; 11 byte filename
- addme0: mov a,m; Get byte
- cpi ' '
- jnz addme1; Not space - continue
- inx h; Next char
- dcr b
- jnz addme0; Continue searching for spaces
- pop h; Must be the directory
- jmp addme4; So abort this one
- ;
- addme1: pop h
- lxi d,memnam; Index member FCB name
- mvi b,11; 11 byte compare
- addme2: ldax d; Get byte from member name FCB
- cpi '?'; '?' matches all entries
- jz addme3; Match
- cmp m; Same as member entry?
- jnz addme4; No - abort this process
- addme3: inx h
- inx d
- dcr b
- jnz addme2; Compare all 11 bytes
- lhld namptr; Get destination address
- xchg
- pop h; Get source address back again
- mvi b,15
- call move; Move 15 byte block into memory
- xchg
- shld namptr; Save name pointer
- lhld memcnt; Get member number count
- inx h; Bump it up one
- shld memcnt; Set next member memory address
- ret
-
- addme4: pop h; Balance stack
- ret
- ;
- ; Get the next member name from the memory name queue buffer,
- ; return carry set if no more members left
- ; a,f,b,d,e,h,l
- getmem: lhld memcnt; Get member count
- mov a,l
- ora h
- stc
- rz; Zero count - set error condition
- dcx h; Bump count down
- shld memcnt; And reset member count
- lhld nampt1; Get source address for move
- lxi d,memfcb; Get destination for move
- mvi b,15; 11 byte filename + 4 byte file info
- call move; The block
- shld nampt1; Reset the next source address
- ora a; Clear any cy
- ret
- ;
- ; Double CRLF to console
- ; a
- crlflf: call crlf
- ; " "
- ; CR and LF to console
- ; a
- crlf: mvi a,cr
- call ctype
- mvi a,lf
- ; " "
- ; Character to console, preserve all registers, track lines
- ctype: push psw
- push d
- mov e,a
- cpi lf
- jnz ctype1
- lda lincn1
- inr a
- sta lincn1
- ctype1: mvi a,cio; Direct console output
- call sys
- pop d
- pop psw
- ret
- ;
- ; CRLF, then fall through to TSTR
- ; a,f
- tstrc: call crlf
- ; " "
- ; Output string (DE)^
- ; a,f
- tstr: push d
- tstr1: ldax d
- ora a
- jz tstrx
- call ctype
- inx d
- jmp tstr1
- ;
- tstrx: pop d
- ret
- ;
- if extract
- ; Query for file purge
- ; a,f
- query: push d
- lxi d,exists
- call tstr
- call pause
- pop d
- adi eof; Correct output
- ani 05fh; Upshift
- call ctype; And echo
- ; push psw
- ; call crlf
- ; pop psw
- cpi 'Y'
- ret; Purge wanted if z flag
- ;
- ; Open (create) file OUTFCB^. Returns NZ when all well
- ; a,f,d,e
- opnout: lda outusr
- call sguser
- lxi d,outfcb
- mvi a,open
- call sys
- inr a
- ora a; Ensure carry reset
- cnz query; When file already exists
- jnz done; Abort if not to be purged
- xra a
- sta bytes; Reset byte count
- sta sector; and sector count
- sta outfcb+32; Reset output record number
- mvi a,delete
- call sys; Remove any old file
- mvi a,make
- call sys; And create a new one
- inr a
- push psw
- lda inuser
- call sguser; Go back to input access
- pop psw
- rnz; All well
- ; " "
- ; Fullup message and abort
- fullup: lxi d,noroom
- jmp exeunt; Abort everything
- endif; extract
- ;
- ; Open LBRFCB file
- ; a,f
- fopnlb: lxi d,lbrfcb
- ; " "
- ; Open file (DE)^, doing any searches, return BDOS response
- ; a,f
- fopenf: call fopen
- cpi 0ffh
- rnz; Success
- ldax d
- ora a
- mvi a,0ffh; Failure flag
- rnz; Because a drive was specified
- lda altdrv; Set system drive and retry
- stax d; (a zero value causes useless retry)
- ; " "
- ; Open file (DE)^, return BDOS response in (A),
- ; assumes DMA is preset to LBRBUF.
- ; a,f
- fopen: if limitt; Ensure non-ambiguous name
- mvi a,srchf
- call sys; Search for openee
- cpi 0ffh
- rz; Failure, not found
- push h
- push d
- push b
- lxi h,lbrbuf+1; Copy the non-ambiguous name
- add a
- add a; 4*
- add a
- add a; 16*
- add a; 32*
- add l
- mov l,a; Index into the DMA area
- adc h
- sub l
- mov h,a; Point to the "found" file
- mvi b,11
- inx d
- call move; Exact name into FCB
- pop b
- pop d
- pop h
- endif; limitt
- ; " "
- mvi a,open
- ; " '
- ; Execute BDOS function (A), preserve registers
- ; a,f
- sys: push h
- push d
- push b
- mov c,a
- call bdos
- pop b
- pop d
- pop h
- ret
- ;
- ; Move (B) bytes from (HL)^ to (DE)^
- ; a,f,b,d,e,h,l
- move: mov a,m
- stax d
- inx h
- inx d
- dcr b
- jnz move
- ret
- ;
- ; List filename from FCB (HL)^
- ; a,f,h,l
- fname: push b
- mvi b,8; Size of name field
- fname1: mov a,m; Get a byte
- ani 07fh
- cpi ' '
- cnz ctype; print non-space
- inx h; Next char
- dcr b
- jnz fname1; Continue name
- mvi a,'.'
- call ctype; Print seperator
- mvi b,3; 3 character extent
- fname2: mov a,m; Get byte
- ani 07fh
- cpi ' '
- cnz ctype; print non-space
- inx h; Next char
- dcr b
- jnz fname2; Continue ext
- pop b
- ret
- ;
- ; This must parse the command line into FCB1 and FCB2, setting the
- ; appropriate drives and user values, and saving old values. Note that
- ; this routine should NOT assume that the command line is upshifted, to
- ; allow use with CCPLUS when the noupshift option is selected, and thus
- ; enabling use of Software Tools etc. This routine does not deny
- ; access to the currently logged in drive or user, so that a privileged
- ; operator can always use the program on his own area, even though
- ; normally restricted. Note that the fact of logging in establishes
- ; the existance of the drive unit.
- if duspec; Parse command line
- parse: mvi a,getdrv; Save entry drive
- call sys
- sta olddrv
- call getusr; and user values
- sta oldusr; first so any error restores
- lxi h,cmdln
- mov a,m; Line length
- push h
- inr a
- add l
- mov l,a
- mvi m,0; Mark line end
- ; " "
- ; Check for command line option $U to toggle unsq/uncr flag
- mvi a,' '
- parse1: dcx h
- cmp m
- jz parse1; ignore trailing blanks
- mov a,m
- ani 05fh
- cpi 'U'
- jnz parse4; not $U option
- dcx h; Backup 3 chars.
- mov a,m
- cpi '$'
- jnz parse4; not $U option
- dcx h
- mov a,m
- cpi ' '
- jnz parse4; not delimited, may be part of fname
- mvi m,0; Found " $U" at end, remove from line
- lda nouqz; Get flag
- cma; Toggle it
- sta nouqz; And put it back
- ; " "
- parse4: pop h; line beginning ptr
- lxi d,fcb1
- call skipbl; Skip any leading blanks
- call setdu
- jc helper; Bad specification
- mov b,a
- lda oldusr
- cmp b
- jz parse6; User ok if already logged on to it
- lda maxusr; Load maximum user value
- parse5: cmp b
- jc noacc; Illegal on system
- parse6: push d
- mov a,b
- ; " "
- if extract
- sta inuser; Preserve for output flipping
- endif; extract
- ; " "
- sta savusr; Save for later
- pop d
- ldax d
- call chkdv
- jc noacc; No access or no such drive
- inx d; Drive is already set
- call setnam; Setup first file name
- cnz skipbl; Dont skip past eol marker
- lxi d,fcb2
- xra a
- stax d; Kill the 2nd drive spec.
- ; " "
- if extract
- sta outflg; Default no output file created
- endif; extract
- ; " "
- call setdu; To skip over any du spec
- jc helper
- ; " '
- if extract
- jz parse7; No DU specified
- mov a,b
- sta outusr
- ldax d
- sta outfcb
- xra a
- stax d; Reset drive field.
- dcr a; To 0ffh
- sta outflg; Flag doing output
- else ; NOT extract
- jnz helper
- endif; NOT extract
- ; " "
- parse7: inx d
- ; " "
- ; Parse filename from (HL)^ into FCB at (DE)^
- ; Z-flag if end of line reached
- ; a,f,b,d,e,h,l
- setnam: mvi b,8
- call setfld
- cpi '.'
- jnz setnm2; No extension specified
- inx h
- setnm2: mvi b,3
- ; " "
- ; Set field length (B) in (DE)^ from (HL)^ up, blank padding, Z- flag
- ; for end of line. Leave HL pointing to delimiter. (a) := delimiter.
- ; Truncate any fields longer than expected.
- ; a,f,b,d,e,h,l
- setfld: call qdelim; Load and upshift char
- jz setfd4; Delimiter, go blank pad
- cpi '*'
- jnz setfd1
- mvi a,'?'; Expand '*' to '?'s
- jmp setfd2; Without advancing input pointr
-
- setfd1: inx h
- setfd2: stax d
- inx d
- dcr b
- jnz setfld
- setfd3: call qdelim; Skip to first delimiter
- jz setfd5; At a delimiter
- inx h; Else truncate
- jmp setfd3
-
- setfd4: mvi a,' '; Blank pad
- stax d
- inx d
- dcr b
- jnz setfd4
- setfd5: mov a,m
- ora a; Z flag for eol only
- ret
- ;
- ; (A) := (HL)^ upshifted. Z flag if a delimiter for file names
- ; a,f
- qdelim: mov a,m
- ani 07fh; Just in case
- call upshft
- cpi 07fh
- rz; A rubout is a delimiter
- cpi '='
- rz
- cpi ','
- rz
- cpi '_'
- rz
- cpi '.'
- rz
- cpi ':'
- rz
- cpi ';'
- rz
- cpi '<'
- rz
- cpi '>'
- rz
- cpi '['
- rz
- cpi ']'
- rz
- cpi ' '
- rz
- rnc;
- cmp a; All controls are delimiters
- ret; Including EOL
- ;
- ; Skip to non-blank in (hl)^. Z-flag if EOL reached.
- ; At entry (HL) points to byte previous to first testee.
- ; a,f,h,l
- skipbl: inx h
- mov a,m
- ora a
- rz; Empty line, Z-flag
- cpi ' '
- jz skipbl; Skip leading blanks
- ret; Nz, found something
- ;
- ; No access exit
- noacc: lxi d,illegl
- jmp exeunt
- ;
- ; Parse drive/user from line (HL)^ return user in (A), set drive in (DE)^
- ; At exit (HL) points past any drive/user specification. Drive/user
- ; validity is not checked here. Carry for any error, z-flag for no entry
- ; a,f,b,c,h,l
- setdu: mvi a,':'; Scan for ':'
- call scan; Returns (A) = position
- jc setdu2; No drive/user specified
- cpi 4
- jnc setdu2; Not in 1st 4 characters, not du spec
- mov c,a; Save position
- mov a,m
- call upshft
- sui '@'
- rc; Illegal, catches initial ':'
- stax d; Preventing any searches unless '@'
- inx h
- call getusr; Default, if none specified
- mov b,a
- dcr c; Range 0...2
- jz setdu1; No user spec
- mvi b,0
- call decin
- rc; Illegal character
- dcr c; Range 0..1
- jz setdu1; One char in user spec only
- call decin
- rc; Illegal character
- setdu1: ori 1; Reset Z-flag, have values
- mov a,b
- inx h; Now point past the ':'
- ret
-
- setdu2: call getusr; No spec, set z flag & default usr
- cmp a; Set z flag
- ret
- ;
- ; Return current user in (A)
- ; a,f
- getusr: mvi a,0ffh
- ; " "
- ; Set current user to (A)
- ; a,f
- sguser: push d
- mov e,a
- mvi a,gsuser
- call sys
- pop d
- ret
- ;
- ; Check for valid drive specification (A). Carry for invalid value.
- ; Uses global "DRVSUP" value and "OLDDRV" values
- ; a,f
- chkdv: ora a
- rz; Default is always ok
- push h
- lhld olddrv
- cmp l
- pop h; Specific reference to
- rz; Logged in drive is ok
- push h
- lhld drvsup
- chkdv2: dad h
- dcr a
- jnz chkdv2; Shift access bit into carry
- pop h; Carry for access at this point
- cmc
- ret
- ;
- ; Incorporate character (HL)^ into the value (E) (decimal).
- ; Carry for llegal character, else advance (HL).
- ; a,f,b
- decin: mov a,m
- sui '0'
- rc; Illegal
- cpi 9+1
- cmc
- rc; Illegal
- inx h
- push psw
- mov a,b
- add a; 2*
- add a; 4*
- add b; 5*
- add a; 10*
- mov b,a
- pop psw
- add b
- mov b,a
- ret
- ;
- ; Scan (HL) up for (A) or to EOL (marked by null).
- ; Return (A) = relative position (0 based), carry if not found.
- ; a,f
- scan: push b
- push h
- mvi c,-1
- dcx h
- scan1: inx h
- inr c
- cmp m
- jz scan2; Found, carry clear
- push b; Check for end of string
- mov c,m; This test occurs after the char test
- inr c; So that a null will be found. Else
- dcr c; A null signifies end of string.
- pop b; Don't play with memory, may be ROM.
- jnz scan1; Not EOS, continue
- stc; End of line, not found
- scan2: mov a,c
- pop h
- pop b
- ret
- ;
- ; This restores the entry drive/user value
- ; a,f,e
- restor: lda oldusr
- call sguser
- lda olddrv
- mov e,a
- mvi a,setdrv
- call sys
- ret
- ;
- ; Upshift (A)
- ; a,f
- upshft: cpi 'a'
- rc
- cpi 'z'+1
- rnc
- ani 05fh
- ret
- endif; duspec
- ;
- if extract
- ; See if we use wheel test. If so, test wheel byte.
- ; Returns Z set if wheel not set, or no file output,
- ; else returns with Z not set for output to file.
- ; a,f
- outtst: call qwhl
- rz; wheel not set
- lda outflg; Get output flag
- ora a; True for output to file
- ret
- endif; extract
- ;
- ; Cheek wheel status. WHLADR = 0 acts as if wheel on, else checks
- ; NZ flag for priviledged operation
- ; a,f
- qwhl: push h
- lhld whladr
- mov a,m; Gets 0c3 or 0cd at lcn 0 if whladr=0
- pop h
- ora a; Non-zero means priviledged
- ret
- ;
- nfound: db 'Member '
- nofmsg: db 'Not found',cr,lf,lf,0
-
- signon: db cr,lf,'LT',ver/10+'0',ver mod 10+'0'
- db ' [d[u]:]lbr/filename [d[u]:][component] [$u]'
- db ' by C.B. Falconer',cr,lf
- sign1: db '^S pause, ^C abort, ^X next'
- db ' file, ^Z stops paging',0
-
- usage: db cr,lf,' Type/uncrunch/unsqueeze/unLZH '
- db 'files or LBR members',cr,lf
- db ' Drive/user after lbr/filename '
- db 'causes file output.',cr,lf
- db ' $U at end disables unsq/uncr/unlzh '
- db 'of compressed files',cr,lf
- db ' (wildcards permitted)'
- db cr,lf,lf
- db 'Examples:',cr,lf
- db ' B>LT A3:HELLO SOURCE.AZM '
- db ' [console] (defaults to HELLO.LBR)',cr,lf
- db ' A>LT LZHENCOD.DYC '
- db ' [console] (handles LZH encoding)',cr,lf
- db ' A>LT SQUEEZE.DQC '
- db ' [console]',cr,lf
- db ' A>LT HELLO *.* '
- db ' [console, all typable]',0
- ;
- ; 2nd part when wheel set or disabled
- whlusg: db ' B>LT B:HELLO A4:SOURCE.AQM '
- db ' [file]',cr,lf
- db ' B>LT B:HELLO A4:SOURCE.AQM $U'
- db ' [file with no unsqueeze]',cr,lf
- db ' A>LT B:CRUNCH.AZM A: '
- db ' [file]',0
-
- abrmsg: db cr,lf,'++ ABORTED ++',cr,lf,0
- clean: db cr,' ',cr,0; Erase the "more"
- eofmsg: db 'Early EOF, aborted',0
- exists: db ' exists, purge (y/n)? ',0
- ffsep: db ' =>> ',0; File-file separator
- corrpt: db 'LBR file corrupt',0
- mbrmsg: db 'Member: ',0
- more: db '[more] ',0
- badfile:db cr,lf,lf,bell,'Corrupt or unknown format file',cr,lf,0
-
- if limitt
- cant: db bell," ...Can't type a '",0
- cant2: db "' file",cr,lf,0
- endif; limitt
-
- if extract
- noroom: db cr,lf,lf,bell,'No space, aborting',0
- endif; extract
-
- if limitl
- excess: db bell,'Too long, transfer with KMD',cr,lf,0
- endif; limitl
-
- if duspec
- illegl: db bell,'Access denied',cr,lf,0
- endif; duspec
- ;
- ; -------------------------------------------------------------------
- ;
- dseg
- ; Link the data segment after the code. Use 2 passes if necessary.
- ;
- ; Temporary storage area
- bufptr: dw 0
- chrcnt: db 0
- db 0
- lincn1: db 0; Lines printed since [more]
- paglns: db 0; Ln/page before pause, 0 causes setup
-
- nampt1: dw endu; NAMBUF
- namptr: dw endu; NAMBUF
- rcnt: dw 65535; Maximum. record count for type
-
- outptr: dw outbuff; File output buffer
- ; It is helpful to ensure that the LAST initialized data item
- ; is NON-ZERO. Eases any final truncation, ensures CCITCRC can run.
- ;;
- ; This (uninitialized) portion takes up no space in the code file
- ; (with reasonable linkers - l80 zero fills)
- bytes: ds 1; in current outbuff sector
- sector: ds 1; no. in outbuff filling
- memcnt: ds 2; members in current library
- lbrfcb: ds 9
- lbrtyp: ds 3
- lbrext: ds 20; Lbrfcb+12; file extent
- lbrsno: ds 1; Lbrfcb+32; sector #
- lbrrno: ds 3; Lbrfcb+33; random rcd no.
- memfcb: ds 16
- memnam: ds 16
-
- oldusr: ds 1
- olddrv: ds 1
- savusr: ds 1
-
- if extract
- inuser: ds 1; To restore after file output
- outflg: ds 1; Do file output if true
- outusr: ds 1; Output FCB usr
- outfcb: ds 33; Output file FCB
- dmaadd: ds 2; Write address
- outbuff: ds 128*rec; Output buffer
- endif; extract
- ;
- ; Mark start of zeroed area, per component loop
- zeros:
-
- numflt: ds 1
- char: ds 1
- rptchr: ds 1; Char to repeat
- rptcnt: ds 1; Count of repeat characters
- lincnt: ds 1; Number of lines printed total
- column: ds 1; Crt column position
- zerlen: ds 1
- if xpnd
- dleflg: ds 1; Flag a dle just received
- dlecnt: ds 1; Count of blanks to emit
- endif; xpnd
- lastz: ds 64; Mark end of zeroed area, stack space
-
- stack: ds 2; Store entry stack pointer
- lbrbuf: ds 128; Member read buffer
- xlatbl: ds 258*4
-
- end begin
- , stack space
-
-