home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
RCPM
/
LUX100.LBR
/
LUX100.ZZ0
/
LUX100.Z80
Wrap
Text File
|
2000-06-30
|
49KB
|
1,904 lines
; LUX - A Library extension system - Version 100 as of 03/05/87
;
; Supports CPM v2.2 and CPM v3.0
;
; Allows the user to peer into .ARC, .ARK and .LBR file groups. With
; appropriate peripheral files which accompany this program (or are
; already on most RCPM systems) can type .LBR member files whether
; crunched, squeezed or normal. Can also type files in .ARC or .ARK
; libraries. If using KMD or a comparable program, can easily extract
; member files from .ARC, .ARK or .LBR groups. Options included to use
; KMD clones such as MBKMD and NUKMD.
;
;-----------------------------------------------------------------------
;
; 03/05/87 This is LUX77 renamed to LUX100. It has numerous features
; v100 which make it far more desireable for many RCPM operators
; than Tom Brady's versions called LUX54, LUX75 and LUX80,
; all of which are virtually identical and none of which work
; on CPM v3.0 systems that many of us have. LUX70, LUX77 and
; this LUX100 work great on CPM v3.0 as well as on CPM v2.2
; systems. Irv had version LUX54 ready in October of 1986 but
; never released it while waiting for Bob Freed to finish NOAH
; since LUX52 already supported both .LBR and .ARC files.
; Tom Brady put out his version called LUX54 so Irv didn't have
; much choice except to skip to LUX70 for his version in a
; courteous way to allow Tom Brady to continue developing his
; LUX54 with LUX55 - should any additional things of merit be
; added. Such has not been the case. Tom has taken a personal
; vendetta to prevent the rest of us from using Irv's version
; which took me all of 5 minutes to install on my CPM v3.0
; system. This was the first I had been able to even use LUX
; on my system and I for one greatly appreciate what Irv has
; contributed to this excellent program. I don't care for Tom
; Brady trying to play God and dictate to me what I should use
; on my system. I know many of you will agree with me. Tom
; also included UNARC142 in his version, without permission
; from Bob Freed. He specifically distributed that with the
; distinct admonition that it was a beta test version for sysops
; use only. Tom Brady totally ignored this warning and made the
; program public as though it were his to do with as he wished.
; This has upset Bob Freed to the point he may never issue any
; source code to any of his programs, again. He was already
; upset with Tom Brad's stealing the copyrighted routines he
; had given to Irv for exclusive use in KMD. If you never see
; NOAH for CPM it may well be because of Tom Brady's antics.
; (I got some of this information from direct personal calls.
; The rest was already well known in many parts of the country.)
; - Earl Crocket
; Earl's Corner RCPM
;
; 03/04/87 (By Tom Brady, who again totally substituted his version of
; v80 LUX54 in place of LUX77 then put an .ARK extention on it.
; It is an obvious effort to again totally discredit the efforts
; of Irv Hoff to simpifly and adapt the LUX program to use
; normal programs already on most RCPM systems.)
;
; 03/01/87 NOTICE TO TOM BRADY: LEAVE YOUR FINGERS OFF THIS PROGRAM.
; v77 IF YOU WANT TO CONTINUE MUCKING WITH LUX, SUGGEST YOU USE
; THE NUMBER LUX55 TO FOLLOW YOUR OWN LUX54. I INTENTIONALLY
; SKIPPED TO LUX70 SO AS TO NOT PROHIBIT YOU FROM DOING JUST
; THAT, BUT WILL NOT TOLERATE YOUR USING THIS SERIES IN AN
; OBVIOUS ATTEMPT TO PREVENT ME FROM CONTRIBUTING TO THE DE-
; VELOPMENT OF THIS PROGRAM.
;
; Restored LUX v77 to the original intent of the LUX 7x ver-
; sion. I had already skipped to LUX70 to not place Tom Brady
; in a position where he could not continue working with his
; LUX54, calling any subsequent version LUX55. Instead he
; elected to try to totally obliterate any work I had put into
; this program. I will not allow that to occur. Many people
; prefer my version to his, since it can be installed on any
; RCPM as fast as you can extract the files from the libaray.
; - Irv Hoff
;
; 02/28/87 (Tom Brady totally replaced everything in the LUX70A version
; v75 including all auxiliary programs in the library with his own
; LUX54 version. He further decided to jump to LUX75. This
; was done in an obvious attempt to force people to use only
; his version.)
;
; 02/27/87 Added an equate to select MBKMD120 which came out about the
; v70A same time that LUX70 was being released. LUX70A supports
; KMD, MBKMD and NUKMD. Be sure to make the proper selection.
; - Irv Hoff
;
; 02/22/87 MAJOR CHANGE... Rewrote program to use conventional files
; v70 normally found on A0:
;
; LCHEK.COM (Current is LCHEK11.COM)
; DIR.COM (Renamed SD.COM with $L option)
; TYPE.COM (Should handle both squeezed and crunched)
; UNARC.COM (Combination DIR and TYPE for .ARC/.ARK files)
;
; Special files such as LUXCHK, LUXDIR, LUXTYPE, etc. on
; a special drive/user area (usually A15:) no longer needed.
; This greatly simplifies the installation and use of LUX.
; Wheel byte, MAXDRV and MAXUSR bytes no longer used or even
; needed - LUX can be only be called up in whatever drive/user
; area you are currently in, which in itself is the limiting
; factor. This is a radical departure from previous versions
; so the version number has been significantly advanced. This
; allows additional updates of conventional versions if others
; want an additional choice. This makes one universal version
; possible for any size system from small floppies to immense
; hard drives of 100 Mb and more.
;
; Option added to support KMD, MB-KMD or NUKMD added as the
; latter two must have must have both 'A' and 'L' capability
; for various functions. (KMD needs only the 'A', however it
; accepts 'L' interchangeably since versions prior to .ARC or
; .ARK files used 'L' for .LBR files.) Can now exit LUX with
; CTL-C, CTL-K or CTL-X. This standardizes exit with other
; similar programs. - Irv Hoff
;
; 09/09/86 None of the previous LUX files protected its start address,
; v54 allowing long programs to overrun LUX itself. It would then
; lock up the system until reset by the Sysop. This happened
; most often when using the TYPE command to look at lengthy
; .DOC files but was not limited to such files. Reformatted
; and simplified. - Irv Hoff
;
; 08/25/86 Modified for .ARK file support in addition to .ARC and .LBR.
; v53 - Norman Beeler
;
; 06/02/86 Modified for .ARC file support, using UNARCxx for DIR and
; v52 TYPE commands....fully automatic determination of .ARC or
; .LBR file extents, (extent not necessary). Supports .ARC
; member transfer. - Norman Beeler
;
; 06/26/85 Modified for KMD support throughout. Other cosmetic changes.
; v51 KMD offers total automatic protocol detect. (It also offers
; YMODEM-type batch transfers but this is not used with LUX.)
; - Tom Brady
;
; 07/21/85 Added SENDK and SK options for use with 1k blocks which are
; v50 needed for MEX114 and MS-DOS program with YMODEM protocol.
; (1k blocks are fully automatic with IMP. The 'SK' need not
; be manually inserted for 1k protocol.)
; - Steve Sanders
;
; 11/26/83 Original release. Adapted from ATTACH program.
; v12B - Steven Holtzclaw
;
;-----------------------------------------------------------------------
;
.Z80 ; Needed for M80, otherwise ignore
;
YES EQU 0FFH
NO EQU 0
;
KMD EQU YES
MBKMD EQU NO
NUKMD EQU NO
;
;-----------------------------------------------------------------------
;
; Equates
;
CR EQU 0DH
LF EQU 0AH
;
;-----------------------------------------------------------------------
;
;
; If RCPM is Yes, change the BYECMD equate at end of this file if your
; logoff program is not called BYE.COM.
;
RCPM EQU YES ; Yes, if being used with a RCPM system
HLPMSG EQU YES ; Yes, if helpful messages are wanted
AUTODR EQU YES ; Yes, if initial auto-directory wanted
HLPERS EQU 2 ; Give auto-help after this many errors
;
;
;-----------------------------------------------------------------------
;
; The following files are normally on A0: and are for general purpose as
; well as for use with LUX.
;
; NOTE: The DIR.COM file must be a SD-xx.COM type
; having the $L option (to show library member
; contents). This is normally placed on A0:
; for general use in displaying the directory.
; When choosing a drive, use: 0=A, 1=B, etc.
;
CHKDRV EQU 0 ; Drive number for LCHEK.COM (LCHEK11.COM)
CHKUSR EQU 0 ; User number for LCHEK.COM
;
DIRDRV EQU 0 ; Drive number for DIR.COM (SD.COM)
DIRUSR EQU 0 ; User number for DIR.COM (SD.COM)
;
KMDRV EQU 0 ; Drive number for KMD, MB-KMD or NUKMD
KMDUSR EQU 0 ; User number for KMD, MB-KMD or NUKMD
;
TYPDRV EQU 0 ; Drive number for TYPE.COM
TYPUSR EQU 0 ; User number for TYPE.COM
;
UNADRV EQU 0 ; Drive number for UNARC.COM
UNAUSR EQU 0 ; User number for UNARC.COM
;
;-----------------------------------------------------------------------
;
BDOS EQU 0005H ; Jumper vector for BDOS calls
TPA EQU 0100H ; CP/M program area
FCB1 EQU 005CH ; First file control block
FCB2 EQU 006CH ; Second file control block
REBOOT EQU 0000H ; Cold reboot address
TBUFF EQU 0080H ; Default command buffer
;
;
; Macros used
;
DRVUSR MACRO DRIVNO,USERNO,FNCNAM,RTN1,RTN2,RTN3,RTN4
CALL FILTYP
DEFB DRIVNO+'A'
;
USERN1 DEFL USERNO
;
IF USERN1 GT 9
DEFB (USERN1 /10)+'0'
;
USERN1 DEFL USERN1-10
ENDIF ; USERN1 GT 9
;
DEFB USERN1+'0'
DEFB ':'
DEFB FNCNAM
DEFB 0
;
IF NOT NUL RTN1
CALL RTN1
ENDIF ; NOT NUL RTN1
;
IF NOT NUL RTN2
CALL RTN2
ENDIF ; NOT NUL RTN2
;
IF NOT NUL RTN3
CALL RTN3
ENDIF ; NOT NUL RTN3
;
IF NOT NUL RTN4
CALL RTN4
ENDIF
JP PROCES ; NOT NUL RTN4
ENDM
;
DVUS MACRO DRIVNO,USERNO,FNCNAM,RTN1,RTN2,RTN3,RTN4
CALL FILTYP
DEFB DRIVNO+'A'
;
USERN2 DEFL USERNO
;
IF USERN2 GT 9
DEFB (USERN2 /10)+'0'
USERN2 DEFL USERN2-10
ENDIF ; USERN2 GT 9
;
DEFB USERN2+'0'
DEFB ':'
DEFB FNCNAM
DEFB 0
ENDM
;
CMDJMP MACRO VERB,VECTOR
CALL ILCMP
DEFB VERB
DEFB 0
JP NC,VECTOR
ENDM
;
;=======================================================================
;
; Program starts here
;
;=======================================================================
;
START: LD SP,SSTACK ; Starting stack
CALL ILPRT
DEFB CR,LF,'LUX v100'
DEFB CR,LF,0
;
;
; Check for a blank or null command line
;
LD A,(TBUFF+1) ; Get byte from default command buffer
OR A ; If non-zero then there is a possible
JP NZ,GTDVUS ; File specified
;
SPCERR: CALL ILPRT ; Print the error message
DEFB CR,LF
DEFB '++ Examples of valid LUX commands ++',CR,LF,LF
DEFB ' LUX HELLO.ARC',CR,LF
DEFB ' LUX HELLO.ARK',CR,LF
DEFB ' LUX HELLO.LBR',CR,LF,LF
DEFB ' The extent is not needed if no other ',CR,LF
DEFB ' library files have a similar name.'
DEFB CR,LF,0
JP REBOOT ; Reboot since we have overwritten CCP
;.....
;
;
GTDVUS: LD HL,TBUFF+2 ; Index default key buffer
CALL DRUSR ; Get requested drive/user
JP C,SPCERR
;
;
; Test for drive/user within range
;
LD (RQDDRV),BC ; Set the requested drive/user
EX DE,HL ; DE is source address to create new FCB
LD HL,FCB1 ; Index FCB
CALL SCANR1 ; Create the new FCB
;
;
; Force the default file type
;
LD HL,'RA' ; Set 'AR' into first two bytes of file type
LD (FCB1+9),HL
LD A,'K' ; Set 'K' into last byte of file type
LD (FCB1+11),A
;
;
; Get the library name from the FCB and store it
;
LD HL,FCB1 ; Source for move
LD DE,LBRNAM-1 ; Destination for move
LD BC,9 ; Max 8 character filename
LDIR ; Move to local name
LD HL,FCB1+1 ; First byte of filename
LD A,'?' ; Character to look for
LD BC,11 ; Search thru 11 bytes
CPIR ; Do search
JR NZ,LOOKUP ; No ? found - continue
CALL ILPRT ; Print the error message
DEFB CR,LF
DEFB '++ Ambiguous filenames are not allowed ++',CR,LF,0
JP SPCERR
;.....
;
;
; Look for the filename on directory
;
LOOKUP: CALL GETOLD ; Get the current drive/user
CALL SETNEW ; Set requested drive/user
LD DE,080H ; Default DMA address
LD C,26
CALL BDOS ; Set the DMA address
LD DE,FCB1 ; Index filename specified
LD C,17
CALL BDOS ; Search for first
INC A ; Does file exist?
JP NZ,SETARK ; Jump to start of LUX
LD HL,'RA' ; Try .ARC file
LD (FCB1+9),HL
LD A,'C' ; Set .ARC
LD (FCB1+11),A
LD DE,FCB1
LD C,17 ; See if it exists
CALL BDOS
INC A
JP NZ,SETARC ; Yes so go
LD HL,'BL' ; Try .LBR file
LD (FCB1+9),HL
LD A,'R' ; Set .LBR
LD (FCB1+11),A
LD DE,FCB1
LD C,17 ; See if it exists
CALL BDOS
INC A
JP Z,NOFILE ; No, error off
JP PRESTR
;.....
;
;
SETARC: LD A,0FFH ; Yes, set ARCFLG
LD (ARCFLG),A
JP PRESTR
;.....
;
;
SETARK: LD A,7FH ; Yes, set ARCFLG and .ARK
LD (ARCFLG),A
;
PRESTR: LD HL,FCB1
LD DE,LBRNAM-1 ; Update library name (.ARC)
LD BC,12
LDIR
JP PGMSTR ; Go do it
;.....
;
;
NOFILE: CALL SETOLD
CALL ILPRT ; Print the error message
DEFB CR,LF,'Can''t find ',0
CALL DVUPRT
CALL NAMPRT ; Print the filename
CALL ILPRT
DEFB ' - check the DIR',CR,LF,0
JP 0000H ; Reboot since we have destroyed the ccp
;.....
;
;
DEFS 64 ; 32 level stack for here
;
SSTACK EQU $
;
FINIS EQU $ ; Finish of program loader
;
LODLEN EQU FINIS-START ; Length of loader
; Keep the program in line
DEFS 300H-LODLEN ; Add extra bytes here to make
; 'PGMSTR' start on a 100h byte boundary
;
;-----------------------------------------------------------------------
; This is the start of the relocated program - all of the code from
; 'START' to here is thrown away once LUX begins execution.
;-----------------------------------------------------------------------
;
; set up the BDOS and BIOS patches
;
PGMSTR: JP INIT ; Jump to start of this module
DEFB 'LUX v100' ; The name 'LUX' is a clue to other
; programs that enables them to deter-
; mine if LUX is resident. 'L' is at
; BDOS+3 when LUX is resident.
;
; This is the LUX removal routine, jumped to by the BYE command. It is
; accessable to external programs and is defined to exist at LUX+12
; (looks like BDOS+12 when LUX is resident).
;
REMOVE:
IF RCPM
LD SP,TPA+100H ; Use the TPA for a stack
LD BC,0 ; First select A0:
CALL RESET
LD DE,80H ; Clear the DMA buffer
PUSH DE
PUSH DE
LD B,128 ; Bytes to clear
XOR A ; Easy way to make A=0
;
RZRLP: LD (DE),A ; Null the location
INC DE ; Next address
DJNZ RZRLP ; Loop until 'B' is zero
;
LD A,BYELEN ; Store away the length of the command
LD HL,BYECMD ; Now move the commands to the DMA
LD (HL),A
POP DE ; Restore the DMA address
LD BC,BYELEN
LDIR
;
POP DE ; Restore it again
LD C,26 ; Reset the DMA
CALL BDOS
LD DE,SUBFCB ; Address the .SUB file FCB
LD C,22 ; Make the file
CALL BDOS
INC A ; Check for errors
JR Z,EXITER ; Oops, no directory space
LD DE,SUBFCB ; Else write the data
LD C,21
CALL BDOS
INC A
JR Z,EXITER ; Oops, no space left
LD DE,SUBFCB
LD C,16 ; Now close the file
CALL BDOS
LD HL,0 ; Now make the exit routine go to A0:
LD (OLDDRV),HL
ENDIF ; RCPM
;
JP UNPATH ; Unpatch the jump table, and warm boot
;.....
;
;
; Error handler for REMOVE routine
;
IF RCPM
EXITER: CALL ILPRT ; An error when making the .SUB file
DB CR,LF,'+ Error: Can''t remove LUX! Please +'
DB CR,LF,'+ type CTRL-C to exit LUX, +'
DB CR,LF,'+ then type BYE to logoff. +',0
LD SP,STACK
JP GETCMD
ENDIF ; RCPM
;.....
;
;
; This is the LUX intialization
;
INIT: LD HL,(0005H+1) ; Get BDOS start
LD (PGMSTR+1),HL ; Set new jump to BDOS
LD HL,PGMSTR ; Get local bdos vector
LD (0005H+1),HL ; Set it in low memory
LD SP,STACK ; Reset stack
LD HL,(0000H+1) ; Get BIOS warm boot vector
LD (BIOS3),HL ; Save old warm boot vector
;
;
; Save the old BIOS vectors
;
LD HL,(BIOS3) ; BIOS warm boot address
LD DE,OWBOOT ; Local warm boot address
LD BC,12 ; 12 bytes to move
LDIR ; Move the block
;
;
; Set up the new BIOS vectors
;
LD HL,WBOOT ; Source is local table
LD DE,(BIOS3) ; Destination is old BIOS
LD BC,12 ; 12 bytes to move
LDIR ; Move the block
LD A,0FFH ; Set the auto-directory byte
LD (DOADIR),A
XOR A ; Reset the error count
LD (HLPCNT),A ;
JP ENTRY ; Initialize
;.....
;
;
OWBOOT: DEFB 0,0,0 ; Old WBOOT vector is moved to here
OCONST: DEFB 0,0,0 ; Old CONSTAT vector is moved to here
OCONIN: DEFB 0,0,0 ; Old cONIN vector is moved to here
OCONOU: DEFB 0,0,0 ; Old CONOUT vector is moved to here
;
WBOOT: JP ENTRY ; Vector warm boot to entry
CONST: JP VCONST ; Check for carrier
CONIN: JP VCONIN ; Vector conin to CONIN
CONOU: JP VCONOU ; Vector to CONOUT
;
VCONST: JP OCONST ; Jump to old CONSTAT routine
;
VCONOU: JP OCONOU ; Jump to old CONOUT routine
;
VCONIN: CALL OCONIN ; Get a byte
CP 'C'-40H ; CTL-C?
JR Z,VCON1
CP 'K'-40H ; CTL-K?
JR Z,VCON1
CP 'X'-40H ; CTL-X?
RET NZ ; Nope - let BIOS have it
;
VCON1: LD A,(ACTIVE) ; Is LUX segment active?
OR A
LD A,3
RET Z ; Not active - let BIOS have it
;
LD SP,TPA ; Re initialize the stack
CALL ILPRT ; Print the following
DEFB ' Exiting LUX',CR,LF,0
;
UNPATH: LD HL,OWBOOT ; Index old warm boot vector
LD DE,(BIOS3) ; BIOS jump table
LD BC,12 ; 12 bytes to move
LDIR ; Move the old table back
CALL SETOLD ; Set old drive/user
JP 0000H ; Warm boot - end of program
;.....
;
;
; This is the LUX entry point
;
ENTRY: LD SP,STACK ; Set up local stack
LD HL,PGMSTR ; Dummy BDOS vector
LD (6),HL ; Set it
LD HL,(BIOS3) ; BIOS warm boot vector
LD (1),HL ; Set it
LD A,0C3H ; (JMP)
LD (0),A ; Reset warm boot jump
LD (5),A ; And BDOS jump
CALL OCONST ; See if character waiting
OR A ; Test result
JR Z,ENTR1 ; If no character is waiting
CALL OCONIN ; Get the console character
; This is done to gobble any
; Possible garbage character
;
ENTR1: LD A,0FFH
LD (ACTIVE),A ; Set LUX active
;
GETCMD: CALL SETNEW ; Reset drive/user
LD IX,TBUFF+1 ; Place to put command string
LD IY,TBUFF+0 ; Length of command
XOR A
LD (IY+0),A
;
IF AUTODR
LD A,(DOADIR) ; Shall we do a directory?
OR A
JR Z,PROMPT ; Guess not
XOR A ; Else zap the byte
LD (DOADIR),A
LD A,3 ; Fake a DIR command
LD (CMDLEN),A
LD HL,'ID'
LD (CMDLIN+2),HL
LD L,'R'
LD H,0
LD (CMDLIN+4),HL
JP GOCNV ; And do it
ENDIF ; AUTODR
;.....
;
;
PROMPT:
IF HLPMSG
CALL ILPRT ; Print the entry message
DEFB CR,LF,'LUX v70 - ^C, ^K or ^X to exit, ? for menu'
DEFB CR,LF,0
ENDIF ; HLPMSG
;
PRMPT2: CALL CRLF
CALL DVUPRT ; Print the LUX prompt
CALL NAMPRT ; Drive/user, library name
CALL ILPRT
DEFB ' -->',0
LD DE,CMDLIN ; Index command line
LD C,10
CALL BDOS ; Read console buffer
LD A,(CMDLEN) ; Get command length
OR A ; Test it
JR Z,GETCMD ; If null command
LD A,(CMDLIN+2) ; Get first character
CP ';' ; Semicolon ok
JP Z,PRMPT2
;
GOCNV: CALL CNVBUF ; Convert the command line to upper case
LD DE,CMDLIN+2 ; Index data from the command line
LD A,(ARCFLG) ; Are we looking at .ARC files?
OR A
JR Z,LBRCMD ; Nope, do .LBR commands
BIT 7,A
JR Z,ARKFL
CMDJMP 'FILES',ACFILES
JR REST
;
ARKFL: CMDJMP 'FILES',AKFILES
;
REST: CMDJMP 'TYPE',ATYPE
CMDJMP 'DIR',UNARC
CMDJMP 'D',UNARC
CMDJMP 'SD',UNARC
CMDJMP 'CHEK',NOARC1
JR HLP
;
LBRCMD: CMDJMP 'TYPE',TIPE ; File type command process
CMDJMP 'DIR',DIR ; Directory command process
CMDJMP 'D',DIR ; Alternate for DIR
CMDJMP 'SD',DIR ; Alternate for DIR
CMDJMP 'FILES',FILES ; Run DIR.COM in "$L" (.LBR) mode
CMDJMP 'CHEK',LCHEK ; Run LCHEK
;
HLP: CMDJMP '?',QKHELP ; Alternate for HELP
CMDJMP 'LUX',LUX ; LUX command process
;
;
; If there are other commands a user may use on your system, and you
; want to tell him to exit LUX first, then enter below:
;
; CMDJMP 'CMD',NOGOT.
;
; Place your command in 'CMD' and it will tell the user that that com-
; mand is only available outside of LUX.
;
IF RCPM AND KMD
CMDJMP 'KMD',KKMD ; KMD command process
ENDIF ; RCPM AND KMD
;
IF RCPM AND MBKMD
CMDJMP 'MBKMD',KKMD ; NUKMD command process
ENDIF ; RCPM and MBKMD
;
IF RCPM AND NUKMD
CMDJMP 'NUKMD',KKMD ; NUKMD command process
ENDIF ; RCPM and NUKMD
;
IF RCPM
CMDJMP 'SEND',SEND ; Synonym for KMD S, MBKMD S or NUKMD S
CMDJMP 'SENDK',SENDK ; Synonym for KMD SK, MBkMD SK or NUKMD SK
CMDJMP 'CHAT',NOGOT ; Tell user NOGOT here
CMDJMP 'BYE',NOGOT ; Tell user NOGOT here
ENDIF ; RCPM
;
;
; This will actually print the command in error like this
;
; ERROR, DUR is not a valid LUX command.
;
CALL ILPRT
DEFB CR,LF,LF,'ERROR, ',0 ; Point at command error
CALL PRTERR ; Print the command just entered
LD A,' ' ; And a space
CALL CTYPE
LD HL,HLPCNT ; Address the error count
INC (HL) ; Bump it
LD A,HLPERS ; Have we reached the limit?
CP (HL) ;
JR NZ,KPTRYN ; No, jump around the rest
LD (HL),0 ; Else reset the count
JP QKHELP ; And give him help anyway
;.....
;
;
KPTRYN: CALL ILPRT ; Tell them it's no good
DEFB ' is not a valid LUX command.',CR,LF,0
JP GETCMD
;.....
;
;
PRTERR: LD HL,CMDLIN+2 ; Index command just entered
LD A,(CMDLEN) ; Get the length
LD B,A ; Into 'B'
;
GETCM5: LD A,(HL) ; Get a byte
CP 020H ; Space ?
JR Z,GETCM6 ; Yes - dont print it
CP 000H ; Null
JR Z,GETCM6 ; Yes - all done
CALL CTYPE ; Print the character
INC HL ; Next character
DJNZ GETCM5 ; Loop for the rest
;
GETCM6: RET
;
;
; 'COMMAND TRANSLATION VECTORS
;
; 'SUMMARY OF AUX ROUTINES:
;
; 'FILTYP' installs the following 'DEFB' into new command line
; specify the drive and user area for each command as in
; the vectors below. remember each 'DEFB' must end with a
; zero.
;
; 'FILNAM' installs the current .LBR name into the new command line
;
; 'FILSPC' installs a space character into the new command line
;
; 'FILMEM' installs the requested member name into the new command line
;
;
ACFILES:DRVUSR DIRDRV,DIRUSR,'DIR *.ARC'
AKFILES:DRVUSR DIRDRV,DIRUSR,'DIR *.ARK'
FILES: DRVUSR DIRDRV,DIRUSR,'DIR *.LBR'
;
ATYPE: DRVUSR UNADRV,UNAUSR,'UNARC ',FILNAM,FILSPC,FILMEM
DIR: DRVUSR DIRDRV,DIRUSR,'DIR ',FILNAM,FILDIR,FILMEM
LCHEK: DRVUSR CHKDRV,CHKUSR,'LCHEK ',FILNAM,FILSPC,FILMEM
TIPE: DRVUSR TYPDRV,TYPUSR,'TYPE ',FILNAM,FILSPC,FILMEM
UNARC: DRVUSR UNADRV,UNAUSR,'UNARC ',FILNAM
;
IF RCPM AND KMD
SEND: DRVUSR KMDRV,KMDUSR,'KMD A ',FILNAM,FILSPC,FILMEM
SENDK: DRVUSR KMDRV,KMDUSR,'KMD AK ',FILNAM,FILSPC,FILMEM
SENDA: DRVUSR KMDRV,KMDUSR,'KMD A ',FILNAM,FILSPC,FILMEM
SENDAK: DRVUSR KMDRV,KMDUSR,'KMD AK ',FILNAM,FILSPC,FILMEM
ENDIF ; RCPM AND KMD
;
IF RCPM AND NUKMD OR MBKMD
SEND: LD A,(ARCFLG) ; Are we in an .ARC file?
OR A
JP NZ,SENDA ; Yes, use 'A' for .ARC
JP SEND1 ; No, use 'L' for .LBR
;
SENDK: LD A,(ARCFLG) ; Are we in an .ARC file?
OR A
JP NZ,SENDA ; Yes, use 'A' for .ARC
JP SENDK1 ; No, use 'L' for .LBR
ENDIF ; RCPM AND MBKMD OR NUKMD
;
IF RCPM AND MBKMD
SEND1: DRVUSR KMDRV,KMDUSR,'MBKMD L ',FILNAM,FILSPC,FILMEM
SENDK1: DRVUSR KMDRV,KMDUSR,'MBKMD LK ',FILNAM,FILSPC,FILMEM
SENDA: DRVUSR KMDRV,KMDUSR,'MBKMD A ',FILNAM,FILSPC,FILMEM
SENDAK: DRVUSR KMDRV,KMDUSR,'MBKMD AK ',FILNAM,FILSPC,FILMEM
ENDIF ; RCPM AND MBKMD
;
IF RCPM AND NUKMD
SEND1: DRVUSR KMDRV,KMDUSR,'NUKMD L ',FILNAM,FILSPC,FILMEM
SENDK1: DRVUSR KMDRV,KMDUSR,'NUKMD LK ',FILNAM,FILSPC,FILMEM
SENDA: DRVUSR KMDRV,KMDUSR,'NUKMD A ',FILNAM,FILSPC,FILMEM
SENDAK: DRVUSR KMDRV,KMDUSR,'NUKMD AK ',FILNAM,FILSPC,FILMEM
ENDIF ; RCPM AND NUKMD
;
;
; Quick help summary
;
QKHELP: CALL ILPRT
DEFB CR,LF,LF
DEFB 'You are using the LUX utility to work with an archive '
DEFB CR,LF
DEFB 'or library file. These are the available commands:'
DEFB CR,LF,LF
DEFB 'CHEK HELLO.EXT - Runs LCHEK on requested member '
DEFB 'file',CR,LF
DEFB 'DIR - Display member files '
DEFB 'in this library',CR,LF
DEFB 'FILES - Display other .ARC/.ARK/.LBR '
DEFB 'files available',CR,LF
DEFB 'LUX NEWNAME - Attach to another '
DEFB 'LBR/ARC file ',CR,LF
;
IF RCPM AND KMD
DEFB CR,LF
DEFB 'KMD S HELLO.EXT - Sends member file '
DEFB 'via auto-protocol detect',CR,LF
DEFB 'KMD SK HELLO.EXT - Sends member file '
DEFB 'with manual 1k setting',CR,LF
ENDIF ; RCPM AND KMD
;
IF RCPM AND MBKMD
DEFB 'MBKMD S HELLO.EXT - Sends member file '
DEFB 'via auto-protocol detect',CR,LF
DEFB 'MBKMD SK HELLO.EXT - Sends member file '
DEFB 'with manual 1k setting',CR,LF
ENDIF ; RCPM AND MBKMD
;
IF RCPM AND NUKMD
DEFB 'NUKMD S HELLO.EXT - Sends member file '
DEFB 'via auto-protocol detect',CR,LF
DEFB 'NUKMD SK HELLO.EXT - Sends member file '
DEFB 'with manual 1k setting',CR,LF
ENDIF ; RCPM AND NUKMD
;
IF RCPM
DEFB 'SEND HELLO.EXT - Same as ''S'' command',CR,LF
DEFB 'SENDK HELLO.EXT - Same as ''SK'' command',CR,LF
ENDIF ; RCPM
;
DEFB CR,LF
DEFB 'TYPE HELLO.EXT - Display ASCII file contents'
DEFB CR,LF,CR,LF
DEFB '? - Displays this menu'
DEFB CR,LF,LF,'(Abort to CP/M with ^C, ^K or ^X)',CR,LF
DEFB 0
JP GETCMD
;.....
;
;
; Tried entering CHAT - tell him to exit LUX first. Add other commands
; as you wish.
;
NOGOT: CALL CRLF
CALL CRLF
CALL PRTERR ; Print the command
CALL ILPRT ; And then this
DEFB ' <<== Exit LUX with ^C, ^K or ^C',CR,LF,0
JP GETCMD ; Go back for another command
;.....
;
;
NOARC1: CALL CRLF
CALL CRLF
CALL ILPRT
DEFB 'Use DIR command for CRC values',CR,LF,0
JP GETCMD
;.....
;
;
; KMD is a special case since the 'A' and 'R' options are invalid here
;
IF RCPM
KKMD: CALL ADVANC ; Go to next character
LD A,(HL) ; Get the character
CP 'S' ; If 'S' check for
JR Z,KKMD1 ; Following 'K'
CP 'R' ; Not legal here
JR Z,KKMD2 ; Execute error routine
CP 'A' ; Not legal here
JR Z,KKMD3 ; Execute error routine
CP 'L' ; Not legal here
JR Z,KKMD3 ; Execute error routine
ENDIF ; RCPM
;
IF RCPM AND KMD
DRVUSR KMDRV,KMDUSR,'KMD'
ENDIF ; RCPM AND KMD
;
IF RCPM AND MBKMD
DRVUSR KMDRV,KMDUSR,'MBKMD'
ENDIF ; RCPM AND MBKMD
;
IF RCPM AND NUKMD
DRVUSR KMDRV,KMDUSR,'NUKMD'
ENDIF ; RCPM AND NUKMD
;
IF RCPM
KKMD1: INC HL ; Get next chacter
LD A,(HL)
CP 020H ; Is it a space?
JR Z,KKMD1A
CP 'K' ; Or packet request?
JR Z,KKMDK
;
KKMD1A: CALL NXTSPC
LD A,(ARCFLG) ; Are we in an .ARC file?
OR A
JP Z,SEND ; Nope, send regular
JP SENDA ; Yes, send .ARC
;.....
;
;
KKMDK: CALL NXTSPC
LD A,(ARCFLG) ; Are we in an .ARC file?
OR A
JP Z,SENDK ; Nope, send regular
JP SENDAK ; Yes, send .ARC
;.....
;
;
KKMD2: CALL CRLF
CALL PRTERR ; Print the command
CALL ILPRT ; Print the following
DEFB ' can''t (R)eceive while in LUX',CR,LF,0
JP GETCMD ; Return to command
;.....
;
;
KKMD3: CALL CRLF
CALL PRTERR ; Print the command
CALL ILPRT ; Print the following
DEFB ' uses S or SK options while in LUX',CR,LF,0
JP GETCMD
ENDIF ; RCPM
;.....
;
;
; 'LUX' command process
;
LUX: LD A,(CMDLEN) ; Get the length of the command line
CP 3 ; Was input only 'LUX'
JP Z,LUX04 ; Error...
CALL FNDSPC ; Find a space in command line
JP C,LUX05 ; Error if no space found
CALL ADVANC ; Search for the next non-blank character
JP C,LUX05 ; Error if no more characters left
CALL DRUSR ; Get drive/user
JP C,LUX05 ; If drive/user specification error
LD (TMPDRV),BC ; Save the temporary drive/user
EX DE,HL ; De is source address to create new fcb
LD HL,TMPFCB ; Index temporary fcb
CALL SCANR1 ; Create the new fcb
LD HL,'BL' ; Set 'LB' into first two bytes of file type
LD (TMPFCB+9),HL
LD A,'R' ; Set 'R' into last byte of file type
LD (TMPFCB+11),A
CALL SETTMP ; Log into the requested drive/user
LD DE,080H
LD C,26 ; BDOS set DMA function
CALL 5 ; Set DMA address to 80h
LD DE,TMPFCB ; Index temporary FCB
LD C,17 ; Bdos search first function
CALL 5
INC A ; Test for existence
JR NZ,LUX01 ; OK, go
LD HL,'RA' ; Check for .ARC file
LD (TMPFCB+9),HL
LD A,'C'
LD (TMPFCB+11),A
LD DE,080H
LD C,26
CALL 5
LD DE,TMPFCB
LD C,17
CALL 5
INC A
JR NZ,SETFLG ; Set ARCFLG
LD HL,'RA' ; Check for .ARK file
LD (TMPFCB+9),HL
LD A,'K'
LD (TMPFCB+11),A
LD DE,080H
LD C,26
CALL 5
LD DE,TMPFCB
LD C,17
CALL 5
INC A
JR Z,LUX05 ; Cant find file
LD A,07FH
LD (ARCFLG),A ; Set .ARK flag true
JR LUX02
;
SETFLG: LD A,0FFH ; Set .ARC flag true
LD (ARCFLG),A
JP LUX02
;.....
;
;
LUX01: LD A,0 ; Set .ARC flag false
LD (ARCFLG),A
;
LUX02: LD HL,(TMPDRV) ; Get temporary drive/user
LD (RQDDRV),HL ; Set new drive/user
LD HL,TMPFCB+1 ; Source address of new name
LD DE,LBRNAM ; Current .lbr name
LD BC,12 ; 8 character file name
LDIR ; Move it
CALL ILPRT ; For display neatness
DEFB CR,LF,0
LD A,0FFH ; Set the auto-directory flag
LD (DOADIR),A
JP GETCMD
;.....
;
;
LUX04: CALL ILPRT
DEFB CR,LF,'++ Invalid drive/user number ++',CR,LF,0
JP GETCMD
;.....
;
;
LUX05: CALL ILPRT
DEFB CR,LF,LF,'Can''t find ',0
CALL DVUPR1
LD B,8
LD HL,TMPFCB+1
CALL NAMPR1 ; Print the file name
CALL ILPRT
DEFB ' - check your spelling',CR,LF,0
JP GETCMD
;.....
;
;
PROCES: XOR A ; Zero last byte of new command line
LD (IX+0),A
LD HL,TBUFF+1
LD (HLPCNT),A ; Reset the error count
CALL DRUSR ; Get drive/user
LD (COMDRV),BC ; Set the .COM drive/user
EX DE,HL ; De is source address to create new FCB
CALL SCANER ; Create the new FCB
EX DE,HL ; Into 'HL'
LD DE,TBUFF+1 ; Start of command buffer
PUSH HL
PUSH DE
OR A ; Clear any carry
SBC HL,DE ; Calculate length of move
LD A,(TBUFF) ; Get command line length
SUB L ; Calculate new length
LD (TBUFF),A ; Put new length
LD A,07EH ; Calculate length of block move
SUB L
LD C,A ; Set into C
LD B,0 ; 'B' gets zero
POP DE ; Restore destination
POP HL ; And source
LDIR ; Move the block down
LD HL,FCB1 ; Set up first FCB
LD DE,TBUFF+1
CALL SCANR1
LD HL,FCB2 ; Set up second FCB
CALL SCANR1
;
;
; Force the default file type (.COM)
;
LD HL,'OC' ; 'CO'
LD (DEFFCB+9),HL
LD A,'M' ; 'M'
LD (DEFFCB+11),A
XOR A ; Zero the record count and
LD (DEFFCB+15),A ; the extent number
LD (DEFFCB+32),A
CALL SETCOM ; Set .COM drive/user
LD DE,TPA
LD C,01AH
CALL BDOS ; Set DMA to TPA
LD DE,DEFFCB
LD C,011H
CALL BDOS ; Search for first
INC A
JR NZ,PROCE1 ; File found
CALL ILPRT
DEFB CR,LF,'Can''t find ',0
LD B,8
LD HL,DEFFCB+1
CALL NAMPR1 ; Print the file name
CALL ILPRT ; CR/LF
DEFB CR,LF,0
JP ENTRY ; Go for more commands
;.....
;
;
PROCE1: LD DE,TPA
LD C,01AH
CALL BDOS ; Set DMA to TPA
LD DE,DEFFCB
LD C,00FH
CALL BDOS ; Open file
INC A
JR NZ,PROCE2
CALL ILPRT
DEFB CR,LF,'.COM File error - notify SYSOP',CR,LF,0
JP ENTRY
;.....
;
;
; Load the .COM file into memory at 100h and call it
;
PROCE2: LD HL,080H
LD DE,080H
;
LODCOM: ADD HL,DE ; Add record size offset
EX DE,HL ; Get DMA address into 'DE'
PUSH DE ; Save 'DE' and 'HL'
PUSH HL
LD C,01AH
CALL BDOS ; Set DMA
LD DE,DEFFCB ; Index .com file name
LD C,014H
CALL BDOS ; Read a record
POP HL ; Restore 'DE' and 'HL'
POP DE
EX DE,HL ; 'HL' is dma address again
OR A ; End of file ?
JR Z,LODCOM ; No - read another record
LD C,13
CALL BDOS ; Reset drive system
CALL SETNEW ; Set new drive/user
XOR A
LD (ACTIVE),A ; Clear command mode active
CALL CRLF
CALL TPA ; Call the loaded file @100h
LD DE,35 ; Zero out FCB1
LD HL,FCB1
;
ZEROFCB:LD (HL),0
INC HL
DJNZ ZEROFCB
JP ENTRY ; Go for more commands
;.....
;
;
NAMPRT: LD B,8 ; 8 character file name
LD HL,LBRNAM ; Index .LBR name
;
NAMPR1: LD A,(HL) ; Get a byte
CP 020H ; Space?
JR Z,NAMPR2 ; Yes - dont print
CALL CTYPE ; Else print the character
;
NAMPR2: INC HL ; Next character
DJNZ NAMPR1 ; Process 8 characters
LD A,'.' ; Print a seperator
CALL CTYPE
LD B,3 ; 3 character file type
;
NAMPR3: LD A,(HL) ; Get a character
CALL CTYPE ; Print it
INC HL ; Next character
DJNZ NAMPR3 ; Process 3 characters
RET
;.....
;
;
; Write a string of characters to the crt
;
ILPRT: EX (SP),HL ; Save return address/get character pointer
;
ILPRT1: LD A,(HL) ; Get a byte
OR A ; Test it
JR Z,ILPRT2 ; Null - end of string
CALL CTYPE ; Else type the character
INC HL ; Next character
JR ILPRT1 ; Loop for more
;
ILPRT2: INC HL
EX (SP),HL ; Restore return address
RET ; Return to caller
;.....
;
;
; Write a string of characters to the command line
;
; (works like ILPRT above)
;
FILTYP: EX (SP),HL
;
FILTY1: LD A,(HL)
OR A
JR Z,FILTY2
CALL PUTIN
INC HL
JR FILTY1
;
FILTY2: EX (SP),HL
RET
;.....
;
;
; Puts ' $L' on command line
;
FILDIR: CALL FILSPC
LD A,'$'
CALL PUTIN
LD A,'L'
CALL PUTIN
;
;
; Fill command line with a space
;
FILSPC: LD A,20H ; Space character
JP PUTIN ; Fill in
;.....
;
;
; Fill command line with .LBR name
;
FILNAM: LD B,8 ; 8 character file name
LD HL,LBRNAM ; Index .LBR name
;
FILNA1: LD A,(HL) ; Get a character
CP 020H ; Space ?
JR Z,FILNA2 ; Yes - dont add to command line
CALL PUTIN ; Put character into command line
;
FILNA2: INC HL ; Next character
DJNZ FILNA1 ; Process 8 characters
LD A,'.' ; Put in a seperator character
CALL PUTIN
LD B,3 ; 3 character file type
;
FILNA3: LD A,(HL) ; Get a character
CALL PUTIN ; Put in command line
INC HL ; Next character
DJNZ FILNA3 ; Process 3 characters
RET ; Return to caller
;.....
;
;
; Fill command line with member name
;
FILMEM: CALL PARSER ; Parse member name
LD HL,MEMBER ; Index member name
LD B,12 ; 12 character max
;
FILME1: LD A,(HL) ; Get a byte
OR A ; End of input
RET Z ; Yes - return
CALL PUTIN ; Fill in one character
INC HL ; Next character
DJNZ FILME1 ; Continue looping
RET ; Done
;
PUTIN: LD (IX+0),A ; Stuff the character into command line
INC IX ; Get ready for next character
INC (IY+0) ; Bump command line length
RET ; Return to caller
;.....
;
;
; Parse out a member name
;
PARSER: LD HL,MEMBER ; Index member name
LD B,12 ; Max 12 character filename
;
PARSE1: LD (HL),0 ; Zero character
INC HL ; Next character
DJNZ PARSE1 ; Clear the entire member name
CALL ADVANC ; Advance to the next non blank character
RET C ; If at the end of the line
LD DE,MEMBER ; DE is index to member, HL set by ADVANC
LD HL,(NXTWRD)
;
PARSE2: LD A,(HL) ; Get source byte
OR A ; End of input line ?
RET Z ; Yes - return
;
LD (DE),A ; Put byte
INC HL ; Next source
INC DE ; Next destination
JR PARSE2 ; Continue looping
;.....
;
;
; Advance the word at NXTWRD to the next non-blank address of the com-
; mand line. Set carry if no more characters available.
;
ADVANC: LD HL,(NXTWRD) ; Get pointer to next word
;
ADVAN1: LD A,(HL) ; Get a byte
OR A ; Test flags
JR Z,ADVAN3 ; Error - null character
CP 020H ; Space ?
JR NZ,ADVAN2 ; Yes - done
INC HL
LD (NXTWRD),HL ; Put pointer back
JR ADVAN1 ; Loop for more
;
ADVAN2: OR A ; Clear any carry
RET
;
ADVAN3: SCF ; Set error condition
RET
;.....
;
;
FNDSPC: LD HL,CMDLIN+2 ; Index command line
;
FND01: LD A,(HL) ; Get a byte from command line
OR A ; Eol ?
JP Z,FNDER ; Error...
CP 020H ; Space?
JP Z,FNDEX ; Yes - go find requested file name
INC HL ; Next character
JR FND01 ; Else continue the search
;
FNDER: SCF ; All chars. scanned and no space found
RET
;
FNDEX: LD (NXTWRD),HL ; Set character location
OR A ; Assure carry reset
RET ;
;
NXTSPC: LD HL,(NXTWRD) ; Get pointer to next word
;
NXTSP1: LD A,(HL) ; Get a byte
OR A ; Is it a null?
JR Z,NXTSP2 ; Yes - return
CP 020H ; If at a space?
JR Z,NXTSP2 ; Yes - return
INC HL ; Next character
JR NXTSP1 ; And continue looking
;
NXTSP2: LD (NXTWRD),HL
RET
;.....
;
;
; In-line compare. Compares string addressed by 'DE' to string after
; call (ends with zero). Return with carry set means strings not the
; same. All registers except 'A'-reg are unaffected.
;
ILCMP: EX (SP),HL
PUSH DE
;
ILCMP1: LD A,(HL) ; Get a byte from source
OR A ; Null
JR Z,SAME1 ; Yes - same so far - test next char
LD A,(DE) ; Get a byte from command string
CP (HL) ; Same as source
JR NZ,NOTSAM ; No - not the same
INC HL ; Next source
INC DE ; Next compare
JR ILCMP1 ; Loop again
;
NOTSAM: XOR A ; Zero for the test
;
NSLP: INC HL ; Next immediate byte
CP (HL) ; Null yet ?
JR NZ,NSLP ; No - continue
;
SAME2: SCF ; Set error condition
;
SAME: EX DE,HL ; Get command string pointer
LD (NXTWRD),HL ; Store it
EX DE,HL ; Restore return address
POP DE ; Restore source address
INC HL ; Adjust to stack
EX (SP),HL ; Replace return address
RET ; Return
;
SAME1: LD A,(DE) ; Get the next byte from command line
OR A ; Null ?
JR Z,SAME ; Yes - its ok
CP 20H ; Space ?
JR Z,SAME ; Yes - thats ok too...
JR SAME2 ; Not ok- must be another character
;.....
;
;
CTYPE: PUSH AF ; Save all registers
PUSH BC
PUSH DE
PUSH HL
AND 7FH ; Be sure its ASCII
LD E,A ; Into 'E'
LD C,2 ; Cpm console function
CALL BDOS
POP HL ; Restore all registers
POP DE
POP BC
POP AF
RET ; Return to caller
;.....
;
;
CRLF: LD A,13
CALL CTYPE
LD A,10
JR CTYPE
;.....
;
;
; Get the drive and user number for a file from command string index by
; 'HL'
;
; On entry:
;
; 'HL' points to first byte of the command string
;
; on exit:
;
; 'HL' points to the byte following ':' in the command string if
; the ':' was found in the first 4 character positions.
; -or-
; 'HL' points to the first byte of the command string if no ':'
; was found.
;
; 'C' contains the requested drive number (0-15)
;
; 'B' contains the requested user number (0-15)
;
; 'AF' the number of characters thru the ':' in the command string.
;
; 'CY' is set if drive or user number is out of range (0-15)
;
;-----------------------------------------------------------------------
;
DRUSR: LD (TEMPHL),HL ; Save the pointer address
LD IX,(TEMPHL) ; 'IX' get the pointer address
LD BC,5 ;
LD A,':'
CPIR ; Search for the ':'
LD A,C ; Get 'B' result from 'CPIR' instruction
LD (LENGTH),A ; Keep for possible adjust
EX DE,HL ; De points to the byte following ':'
LD HL,VTABLE ; Index address table
ADD HL,BC ; Add word offset
ADD HL,BC
LD A,(HL) ; Get routine lsb
INC HL
LD H,(HL) ; Get routine msb
LD L,A
LD BC,0 ; Set up drive/user storage
JP (HL) ; Execute
;.....
;
;
VTABLE: DEFW DRUS0 ; B=0 - FILENAME.EXT
DEFW DRUS1 ; B=1 - A15:FILENAME.EXT
DEFW DRUS2 ; B=2 - A1:FILENAME.EXT
DEFW DRUS3 ; B=3 - A:FILENAME.EXT
DEFW DRUS4 ; B=4 - :FILENAME.EXT
;
;
; Format was - FILENAME.EXT
;
DRUS0: CALL GETDFU ; Get the default user
CALL GETDFD ; Get the default drive
LD HL,(TEMPHL) ; Get old buffer pointer back
XOR A ; Zero move length
RET ; All done
;.....
;
;
; Format was - DUU:FILENAME.EXT
;
DRUS1: CALL GETDRV ; Get the drive parameter
LD A,(IX+0)
CP '0'
JR C,ERROR
CP '9'+1
JR NC,ERROR
SUB '0'
LD B,A ; Put in drive number
SLA B ; * 2
SLA B ; * 4
SLA B ; * 8
ADD A,A ; A * 2
ADD A,B ; + c
LD B,A
INC IX ; Skip the tens digit
JR GETUSR ; Get the user number
;.....
;
;
; Format was - DU:FILENAME.EXT
;
DRUS2: CALL GETDRV ; Get the drive parameter
JR GETUSR ; Get the user number
;.....
;
;
; Format was - D:FILENAME.EXT
;
DRUS3: CALL GETDRV ; Get the drive parameter
CALL GETDFU ; Get the default user
;
;
; Format was - :FILENAME.EXT
;
DRUS4: JR DRUS5
;
GETDRV: LD A,(IX+0)
CP 'A'
JR C,ERROR1
CP 'Q'
JR NC,ERROR1
SUB 'A'
LD C,A ; Put in drive number
INC IX
RET
;.....
;
;
GETUSR: LD A,(IX+0)
CP '0'
JR C,ERROR
CP '9'+1
JR NC,ERROR
SUB '0'
ADD A,B
LD B,A
;
;
; Adjust the byte in 'LENGTH'
;
DRUS5: EX DE,HL ; Hl points to byte following ':' if any
LD A,(LENGTH) ; Get length of move
OR A ; Test it
RET Z ; Return if null/ clear carry
LD E,A
LD A,5
SUB E
LD (LENGTH),A
OR A ; Clear any error
RET
;.....
;
;
ERROR1: POP DE ; Kill return address from subroutine
ERROR: SCF ; Set error condition
RET
;.....
;
;
; Get default user
;
GETDFU: PUSH BC
PUSH DE
PUSH HL
LD C,020H
LD E,0FFH
CALL BDOS
POP HL
POP DE
POP BC
LD B,A ; Set 'B' register to current user
RET
;.....
;
;
; Get default drive
;
GETDFD: PUSH BC
PUSH DE
PUSH HL
LD C,19H
CALL BDOS
POP HL
POP DE
POP BC
LD C,A ; Set 'C' register to current drive
RET
;.....
;
;
; Extract token from command line and place it into DEFFCB;
; format DEFFCB FCB if token resembles file name and type
; (FILENAME.TYP);
; on input, CIBPTR points to character at which to start scan
; on output, CIBPTR points to character at which to continue
; and zero flag is reset if '?' is in token
;
; Entry points:
; scaner - load token into first FCB
; scanr1 - load token into FCB poibted to by HL
;
;
SCANER: LD HL,DEFFCB ; Point to DEFFCB
;
SCANR1: XOR A ; Set temporary drive number to default
LD (TEMPDR),A
CALL ADVNCE ; Skip to non-blank or end of line
LD (CIPTR),DE ; Set pointer to non-blank or end of line
LD A,(DE)
OR A
JR Z,SCANR2
SBC A,'A'-1
LD B,A
INC DE
LD A,(DE)
CP ':'
JR Z,SCANR3
DEC DE
;
SCANR2: LD A,(TDRIVE) ; Set 1st byte of deffcb as default drive
LD (HL),A
JR SCANR4
;
SCANR3: LD A,B
LD (TEMPDR),A
LD (HL),B
INC DE
;
SCANR4: XOR A ; A=0
LD (QMCNT),A ; Init count of # of question marks in FCB
LD B,8 ; Max of 8 characters in file name
CALL SCANF ; Fill FCB file name
;
;
; Extract file type from possible FILENAME.TYP
;
LD B,3 ; Prepare to extract type
CP '.' ; If (de) delimiter is a '.', we have a type
JR NZ,SCANR5 ; Fill file type bytes with <sp>
INC DE ; Pt to char in command line after '.'
CALL SCANF ; Fill FCB file type
JR SCANR6 ; Skip to next processing
;
SCANR5: CALL SCANF4 ; Space fill
;
;
; Fill in ex, s1, s2, and rc with zeroes
;
SCANR6: LD B,4 ; 4 bytes
;
SCANR7: INC HL ; Point to next byte in DEFFCB
LD (HL),0
DJNZ SCANR7
;
;
; Scan complete -- DE points to delimiter byte after token
;
LD (CIBPTR),DE
;
;
; Set zero flag to indicate presence of '?' in FILENAME.TYP
;
LD A,(QMCNT) ; Get number of question marks
OR A ; Set zero flag to indicate any '?'
RET
;
;
; Scan token pointed to by DE for a maximum of B bytes; place it into
; file name field pointed to by HL; expand and interpret wild cards of
; '*' and '?'; on exit, DE points to terminating delimiter
;
SCANF: CALL SDELM ; Done if delimiter encountered - <sp> fill
JR Z,SCANF4
INC HL ; Pt to next byte in deffcb
CP '*' ; Is (de) a wild card?
JR NZ,SCANF1 ; Continue if not
LD (HL),'?' ; Place '?' in deffcb and dont advance de if so
CALL SCQ ; Scanner count question marks
JR SCANF2
;
SCANF1: LD (HL),A ; Store filename char in deffcb
INC DE ; Pt to next char in command line
CP '?' ; Check for question mark (wild)
CALL Z,SCQ ; Scanner count question marks
;
SCANF2: DJNZ SCANF ; Decrement char count until 8 elapsed
;
SCANF3: CALL SDELM ; 8 chars or more - skip until delimiter
RET Z ; Zero flag set if delimiter found
INC DE ; Pt to next char in command line
JR SCANF3
;
;
; Fill memory pointed to by HL with spaces for B bytes
;
SCANF4: INC HL ; Pt to next byte in deffcb
LD (HL),' ' ; Fill filename part with <sp>
DJNZ SCANF4
RET
;.....
;
;
; Increment question mark count for scanner - this routine increments
; the count of the number of question marks in the current FCB entry
;
SCQ: LD A,(QMCNT) ; Get count
INC A ; Increment
LD (QMCNT),A ; Put count
RET
;.....
;
;
; Check to see if DE points to delimiter; if so, return with zero flag
; set.
;
SDELM: LD A,(DE)
OR A ; 0=delimiter
RET Z
CP ' ' ; Error if < <sp>
RET Z ; <sp>=delimiter
CP '=' ; '='=delimiter
RET Z
CP 5FH ; Underscore=delimiter
RET Z
CP '.' ; '.'=delimiter
RET Z
CP ':' ; ':'=delimiter
RET Z
CP ';' ; ';'=delimiter
RET Z
CP '<' ; '<'=delimiter
RET Z
CP '>' ; '>'=delimiter
RET
;.....
;
;
; Advance input pointr to first non-blank and fall through to SBLANK
;
ADVNCE: LD (CIBPTR),DE
;
; Skip string pointed to by DE (string ends in 0) until end of string
; or non-blank encountered (beginning of token)
;
SBLANK: LD A,(DE)
OR A
RET Z
CP ' '
RET NZ
INC DE
JR SBLANK
;.....
;
;
; Capitalize string (ending in 0) in cmdlin and set pointr for parsing
;
CNVBUF: LD HL,CMDLIN+1 ; Point to users command
LD B,(HL) ; Character count in 'B'
INC B ; Add 1 in case of zero
;
CNVBF1: INC HL ; Point to 1st valid character
LD A,(HL) ; Capitalize command character
CALL UCASE
LD (HL),A
DJNZ CNVBF1 ; Continue to end of command line
;
CNVBF2: LD (HL),0 ; Store ending <null>
LD HL,CMDLIN+2 ; Set command line pointer to 1st char
LD (CIBPTR),HL
RET
;.....
;
;
; Convert character in 'A' to upper case
;
UCASE: CP 61H ; Lower-case a
RET C
CP 7BH ; Greater than lower-case z?
RET NC
AND 5FH ; Capitalize
RET
;.....
;
;
GETOLD: CALL GETDFU ; Get current user into 'B'
CALL GETDFD ; Get current drive into 'C'
LD (OLDDRV),BC ; Get the parameters
RET
;.....
;
;
SETTMP: LD BC,(TMPDRV)
JR RESET
;.....
;
;
SETOLD: LD BC,(OLDDRV)
JR RESET
;.....
;
;
SETNEW: LD BC,(RQDDRV) ; Get the old drive number
JR RESET
;.....
;
;
SETCOM: LD BC,(COMDRV) ; Get the old drive number
;
RESET: PUSH BC ; Save drive/user
PUSH BC
LD E,C ; Get selected drive
LD C,14 ; Bdos function
CALL BDOS
POP BC ; Restore drive/user
LD E,B ; Get selected user
LD C,32 ; Bdis set user function
CALL BDOS
;
;
; Set up byte at 0004h - some programs may look at it
;
POP BC
LD A,B ; Get user number
RLA
RLA
RLA
RLA
AND 0F0H
OR C
LD (4),A
RET
;
DVUPR1: LD A,(TMPUSR)
PUSH AF
LD A,(TMPDRV)
JR DVUPR3
;
DVUPRT: LD A,(RQDUSR) ; Get requested drive
PUSH AF
LD A,(RQDDRV) ; Get the requested user
;
DVUPR3: ADD A,'A'
CALL CTYPE ; Print the drive 'A'-'P'
POP AF
CP 10 ; Less that 10?
JR C,DVUPR2 ; Yes - dont print the '1'
PUSH AF
LD A,'1'
CALL CTYPE
POP AF
SUB 10
;
DVUPR2: ADD A,'0'
CALL CTYPE
LD A,':'
JP CTYPE
;.....
;
;
IF RCPM
SUBFCB: DEFB 0 ; Use current drive
DEFB '$$$ SUB'
DEFB 0,0,0,0,0,0,0,0 ; Rest of the FCB
DEFB 0,0,0,0,0,0,0,0 ;
DEFB 0,0,0,0,0
DEFB 0,0,0,0 ; RFU
;
;
; Edit this to contain the console commands necessary to execute the
; logoff sequence for your system.
;
BYECMD: DEFB 0 ; <====== do not touch
DEFB 'BYE',CR,LF ; <====== put any number of cmds here
DEFB 'Z'-40H ; <====== do not touch
;
BYELEN EQU $-BYECMD-1
ENDIF ; RCPM
;
;
ARCFLG: DEFB 0
DOADIR: DEFB 0
HLPCNT: DEFB 0
BIOS3: DEFW 0
TEMPDR: DEFB 0
CIPTR: DEFW 0
TDRIVE: DEFB 0
QMCNT: DEFB 0
CIBPTR: DEFW 0
TEMPHL: DEFW 0
LENGTH: DEFB 0
OLDDRV: DEFB 0
OLDUSR: DEFB 0
RQDDRV: DEFB 0 ; Requested drive
RQDUSR: DEFB 0 ; Requested user
COMDRV: DEFB 0 ; Drive to load .COM file
COMUSR: DEFB 0 ; User to load .COM file
TMPDRV: DEFB 0 ; Temporary drive number
TMPUSR: DEFB 0 ; Temporary user number
ACTIVE: DEFB 0 ; Attach command mode active
NXTWRD: DEFW 0
DEFW 0
CMDLIN: DEFB 79
CMDLEN: DEFB 0
DEFS 79
DEFB 0
;
MEMBER: DEFB ' '
DEFB 0
DEFB 0
LBRNAM: DEFB ' ' ; Library file name
DEFB 'LBR'
;
TMPFCB: DEFS 36
DEFFCB: DEFS 36
;
DEFS 80 ; Area for stack
;
STACK EQU $
;
;
END