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
/
LUXI80.LBR
/
LUXI80.MZC
/
LUXI80.MAC
Wrap
Text File
|
2000-06-30
|
51KB
|
2,026 lines
; LUXI80 - A Library extension system - Version 10 as of 03/22/88
;
; 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/22/88 This is LUXI80. It is basically LUX100 rewritten for the
; v10 Intel 8080 processor. You must use M80, L80 and MAKELUX.COM
; to assemble it. I decided to rename it to LUXI80 and start
; out with version 10 inorder to separate it from other
; versions of LUX being done by Irv Hoff and Tom Brady.
; This code is basically Irv's LUX100 code slightly modified
; for the 8080. LUX100 is a fine piece of software and we all
; owe Irv a large debt of gratitude for it. I'd also like to
; thank Donald Phillips and Douglas Coatney for writing LUX43.
; It was from LUX43 that I got most of the inspiration for
; doing this revision.
; -- Bill Weinel
; Capitol RCP/M
;
; 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
;
;-----------------------------------------------------------------------
;
;
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
DB DRIVNO+'A'
;
USERN1 SET USERNO
;
IF USERN1 GT 9
DB (USERN1 /10)+'0'
;
USERN1 SET USERN1-10
ENDIF ; USERN1 GT 9
;
DB USERN1+'0'
DB ':'
DB FNCNAM
DB 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
JMP PROCES ; NOT NUL RTN4
ENDM
;
DVUS MACRO DRIVNO,USERNO,FNCNAM,RTN1,RTN2,RTN3,RTN4
CALL FILTYP
DB DRIVNO+'A'
;
USERN2 SET USERNO
;
IF USERN2 GT 9
DB (USERN2 /10)+'0'
USERN2 SET USERN2-10
ENDIF ; USERN2 GT 9
;
DB USERN2+'0'
DB ':'
DB FNCNAM
DB 0
ENDM
;
CMDJMP MACRO VERB,VECTOR
CALL ILCMP
DB VERB
DB 0
JNC VECTOR
ENDM
;
; Z80 DJNZ code replacement macro
;
DJNZ MACRO DJADR
DCR B ; DJNZ replacement
JNZ DJADR
ENDM
;
; Z80 CPIR replacement macro
;
CPIR MACRO nm
Cp&nm: cmp m ; CPIR replacement code begins
push psw
inx h
dcr c
jnz C1&nm
pop psw
jmp C2&nm
C1&nm: pop psw
jnz Cp&nm ;; CPIR replacement code ends
C2&nm equ $
ENDM
;
;
;=======================================================================
;
; Program starts here
;
;=======================================================================
;
START: LXI SP,SSTACK ; Starting stack
CALL ILPRT
DB CR,LF,'LUXI80 v10'
DB CR,LF,0
;
;
; Check for a blank or null command line
;
LDA TBUFF+1 ; Get byte from default command buffer
ORA A ; If non-zero then there is a possible
JNZ GTDVUS ; File specified
;
SPCERR: CALL ILPRT ; Print the error message
DB CR,LF
DB '++ Examples of valid LUX commands ++',CR,LF,LF
DB ' LUX HELLO.ARC',CR,LF
DB ' LUX HELLO.ARK',CR,LF
DB ' LUX HELLO.LBR',CR,LF,LF
DB ' The extent is not needed if no other ',CR,LF
DB ' library files have a similar name.'
DB CR,LF,0
JMP REBOOT ; Reboot since we have overwritten CCP
;
;.....
;
;
GTDVUS: LXI H,TBUFF+2 ; Index default key buffer
CALL DRUSR ; Get requested drive/user
JC SPCERR
;
;
; Test for drive/user within range
;
;
push h ; save command line pointer
push b ; save drive/user spec
pop h
shld rqddrv ; set the requested drive/user
pop h
XCHG ; DE is source address to create new FCB
LXI H,FCB1 ; Index FCB
CALL SCANR1 ; Create the new FCB
;
;
; Force the default file type
;
LXI H,'RA' ; Set 'AR' into first two bytes of file type
SHLD FCB1+9
MVI A,'K' ; Set 'K' into last byte of file type
STA FCB1+11
;
;
; Get the library name from the FCB and store it
;
LXI H,FCB1 ; Source for move
LXI D,LBRNAM-1 ; Destination for move
LXI B,9 ; Max 8 character filename
call LDIRs ; Move to local name
LXI H,FCB1+1 ; First byte of filename
MVI A,'?' ; Character to look for
LXI B,11 ; Search thru 11 bytes
CPIR 1 ; Do search macro
JNZ LOOKUP ; No ? found - continue
CALL ILPRT ; Print the error message
DB CR,LF
DB '++ Ambiguous filenames are not allowed ++',CR,LF,0
JMP SPCERR
;.....
;
;
; Look for the filename on directory
;
LOOKUP: CALL GETOLD ; Get the current drive/user
CALL SETNEW ; Set requested drive/user
LXI D,080H ; Default DMA address
MVI C,26
CALL BDOS ; Set the DMA address
LXI D,FCB1 ; Index filename specified
MVI C,17
CALL BDOS ; Search for first
INR A ; Does file exist?
JNZ SETARK ; Jump to start of LUX
LXI H,'RA' ; Try .ARC file
SHLD FCB1+9
MVI A,'C' ; Set .ARC
STA FCB1+11
LXI D,FCB1
MVI C,17 ; See if it exists
CALL BDOS
INR A
JNZ SETARC ; Yes so go
LXI H,'BL' ; Try .LBR file
SHLD FCB1+9
MVI A,'R' ; Set .LBR
STA FCB1+11
LXI D,FCB1
MVI C,17 ; See if it exists
CALL BDOS
INR A
JZ NOFILE ; No, error off
JMP PRESTR
;.....
;
;
SETARC: MVI A,0FFH ; Yes, set ARCFLG
STA ARCFLG
JMP PRESTR
;.....
;
;
SETARK: MVI A,7FH ; Yes, set ARCFLG and .ARK
STA ARCFLG
;
PRESTR: LXI H,FCB1
LXI D,LBRNAM-1 ; Update library name (.ARC)
LXI B,12
call LDIRs
JMP PGMSTR ; Go do it
;.....
;
;
NOFILE: CALL SETOLD
CALL ILPRT ; Print the error message
DB CR,LF,'Can''t find ',0
CALL DVUPRT
CALL NAMPRT ; Print the filename
CALL ILPRT
DB ' - check the DIR',CR,LF,0
JMP 0000H ; Reboot since we have destroyed the ccp
;.....
;
;
DS 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
DS 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: JMP INIT ; Jump to start of this module
DB 'LUXI80 v10' ; 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
LXI SP,TPA+100H ; Use the TPA for a stack
LXI B,0 ; First select A0:
CALL RESET
LXI D,80H ; Clear the DMA buffer
PUSH D
PUSH D
MVI B,128 ; Bytes to clear
XRA A ; Easy way to make A=0
;
RZRLP: STAX D ; Null the location
INX D ; Next address
DJNZ RZRLP ; Loop until 'B' is zero
;
MVI A,BYELEN ; Store away the length of the command
LXI H,BYECMD ; Now move the commands to the DMA
MOV M,A
POP D ; Restore the DMA address
LXI B,BYELEN
call LDIRs
;
POP D ; Restore it again
MVI C,26 ; Reset the DMA
CALL BDOS
LXI D,SUBFCB ; Address the .SUB file FCB
MVI C,22 ; Make the file
CALL BDOS
INR A ; Check for errors
JZ EXITER ; Oops, no directory space
LXI D,SUBFCB ; Else write the data
MVI C,21
CALL BDOS
INR A
JZ EXITER ; Oops, no space left
LXI D,SUBFCB
MVI C,16 ; Now close the file
CALL BDOS
LXI H,0 ; Now make the exit routine go to A0:
SHLD OLDDRV
ENDIF ; RCPM
;
JMP 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
LXI SP,STACK
JMP GETCMD
ENDIF ; RCPM
;.....
;
;
; This is the LUX intialization
;
INIT: LHLD 0005H+1 ; Get BDOS start
SHLD PGMSTR+1 ; Set new jump to BDOS
LXI H,PGMSTR ; Get local bdos vector
SHLD 0005H+1 ; Set it in low memory
LXI SP,STACK ; Reset stack
LHLD 0000H+1 ; Get BIOS warm boot vector
SHLD BIOS3 ; Save old warm boot vector
;
;
; Save the old BIOS vectors
;
LHLD BIOS3 ; BIOS warm boot address
LXI D,OWBOOT ; Local warm boot address
LXI B,12 ; 12 bytes to move
call LDIRs ; Move the block
;
;
; Set up the new BIOS vectors
;
LXI H,WBOOT ; Source is local table
lhld bios3 ; destination is old bios
xchg
LXI B,12 ; 12 bytes to move
call LDIRs ; Move the block
MVI A,0FFH ; Set the auto-directory byte
STA DOADIR
XRA A ; Reset the error count
STA HLPCNT ;
JMP ENTRY ; Initialize
;.....
;
;
OWBOOT: DB 0,0,0 ; Old WBOOT vector is moved to here
OCONST: DB 0,0,0 ; Old CONSTAT vector is moved to here
OCONIN: DB 0,0,0 ; Old cONIN vector is moved to here
OCONOU: DB 0,0,0 ; Old CONOUT vector is moved to here
;
WBOOT: JMP ENTRY ; Vector warm boot to entry
CONST: JMP VCONST ; Check for carrier
CONIN: JMP VCONIN ; Vector conin to CONIN
CONOU: JMP VCONOU ; Vector to CONOUT
;
VCONST: JMP OCONST ; Jump to old CONSTAT routine
;
VCONOU: JMP OCONOU ; Jump to old CONOUT routine
;
VCONIN: CALL OCONIN ; Get a byte
CPI 'C'-40H ; CTL-C?
JZ VCON1
CPI 'K'-40H ; CTL-K?
JZ VCON1
CPI 'X'-40H ; CTL-X?
RNZ ; Nope - let BIOS have it
;
VCON1: LDA ACTIVE ; Is LUX segment active?
ORA A
MVI A,3
RZ ; Not active - let BIOS have it
;
LXI SP,TPA ; Re initialize the stack
CALL ILPRT ; Print the following
DB ' Exiting LUX',CR,LF,0
;
UNPATH: LXI d,OWBOOT ; Index old warm boot vector
lhld bios3 ; bios jump table
xchg
LXI B,12 ; 12 bytes to move
call LDIRs ; Move the old table back
CALL SETOLD ; Set old drive/user
JMP 0000H ; Warm boot - end of program
;.....
;
;
; This is the LUX entry point
;
ENTRY: LXI SP,STACK ; Set up local stack
LXI H,PGMSTR ; Dummy BDOS vector
SHLD 6 ; Set it
LHLD BIOS3 ; BIOS warm boot vector
SHLD 1 ; Set it
MVI A,0C3H ; (JMP)
STA 0 ; Reset warm boot jump
STA 5 ; And BDOS jump
CALL OCONST ; See if character waiting
ORA A ; Test result
JZ ENTR1 ; If no character is waiting
CALL OCONIN ; Get the console character
; This is done to gobble any
; Possible garbage character
;
ENTR1: MVI A,0FFH
STA ACTIVE ; Set LUX active
;
GETCMD: CALL SETNEW ; Reset drive/user
lxi h,tbuff+1 ; Place to put command string
shld cptrix
XRA A ; Length of command
sta tbuff
;
IF AUTODR
LDA DOADIR ; Shall we do a directory?
ORA A
JZ PROMPT ; Guess not
XRA A ; Else zap the byte
STA DOADIR
MVI A,3 ; Fake a DIR command
STA CMDLEN
LXI H,'ID'
SHLD CMDLIN+2
MVI L,'R'
MVI H,0
SHLD CMDLIN+4
JMP GOCNV ; And do it
ENDIF ; AUTODR
;.....
;
;
PROMPT:
IF HLPMSG
CALL ILPRT ; Print the entry message
DB CR,LF,'LUXI80 v10 - ^C, ^K or ^X to exit, ? for menu'
DB CR,LF,0
ENDIF ; HLPMSG
;
PRMPT2: CALL CRLF
CALL DVUPRT ; Print the LUX prompt
CALL NAMPRT ; Drive/user, library name
CALL ILPRT
DB ' -->',0
LXI D,CMDLIN ; Index command line
MVI C,10
CALL BDOS ; Read console buffer
LDA CMDLEN ; Get command length
ORA A ; Test it
JZ GETCMD ; If null command
LDA CMDLIN+2 ; Get first character
CPI ';' ; Semicolon ok
JZ PRMPT2
;
GOCNV: CALL CNVBUF ; Convert the command line to upper case
LXI D,CMDLIN+2 ; Index data from the command line
LDA ARCFLG ; Are we looking at .ARC files?
ORA A
JZ LBRCMD ; Nope, do .LBR commands
ani 10000000b
ora a
JZ ARKFL
CMDJMP 'FILES',ACFILES
JMP REST
;
ARKFL: CMDJMP 'FILES',AKFILES
;
REST: CMDJMP 'TYPE',ATYPE
CMDJMP 'DIR',UNARC
CMDJMP 'D',UNARC
CMDJMP 'SD',UNARC
CMDJMP 'CHEK',NOARC1
JMP 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
DB CR,LF,LF,'ERROR, ',0 ; Point at command error
CALL PRTERR ; Print the command just entered
MVI A,' ' ; And a space
CALL CTYPE
LXI H,HLPCNT ; Address the error count
INR M ; Bump it
MVI A,HLPERS ; Have we reached the limit?
CMP M ;
JNZ KPTRYN ; No, jump around the rest
MVI M,0 ; Else reset the count
JMP QKHELP ; And give him help anyway
;.....
;
;
KPTRYN: CALL ILPRT ; Tell them it's no good
DB ' is not a valid LUX command.',CR,LF,0
JMP GETCMD
;.....
;
;
PRTERR: LXI H,CMDLIN+2 ; Index command just entered
LDA CMDLEN ; Get the length
MOV B,A ; Into 'B'
;
GETCM5: MOV A,M ; Get a byte
CPI 020H ; Space ?
JZ GETCM6 ; Yes - dont print it
CPI 000H ; Null
JZ GETCM6 ; Yes - all done
CALL CTYPE ; Print the character
INX H ; 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: LDA ARCFLG ; Are we in an .ARC file?
ORA A
JNZ SENDA ; Yes, use 'A' for .ARC
JMP SEND1 ; No, use 'L' for .LBR
;
SENDK: LDA ARCFLG ; Are we in an .ARC file?
ORA A
JNZ SENDA ; Yes, use 'A' for .ARC
JMP 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
DB CR,LF,LF
DB 'You are using the LUX utility to work with an archive '
DB CR,LF
DB 'or library file. These are the available commands:'
DB CR,LF,LF
DB 'CHEK HELLO.EXT - Runs LCHEK on requested member '
DB 'file',CR,LF
DB 'DIR - Display member files '
DB 'in this library',CR,LF
DB 'FILES - Display other .ARC/.ARK/.LBR '
DB 'files available',CR,LF
DB 'LUX NEWNAME - Attach to another '
DB 'LBR/ARC file ',CR,LF
;
IF RCPM AND KMD
DB CR,LF
DB 'KMD S HELLO.EXT - Sends member file '
DB 'via auto-protocol detect',CR,LF
DB 'KMD SK HELLO.EXT - Sends member file '
DB 'with manual 1k setting',CR,LF
ENDIF ; RCPM AND KMD
;
IF RCPM AND MBKMD
DB 'MBKMD S HELLO.EXT - Sends member file '
DB 'via auto-protocol detect',CR,LF
DB 'MBKMD SK HELLO.EXT - Sends member file '
DB 'with manual 1k setting',CR,LF
ENDIF ; RCPM AND MBKMD
;
IF RCPM AND NUKMD
DB 'NUKMD S HELLO.EXT - Sends member file '
DB 'via auto-protocol detect',CR,LF
DB 'NUKMD SK HELLO.EXT - Sends member file '
DB 'with manual 1k setting',CR,LF
ENDIF ; RCPM AND NUKMD
;
IF RCPM
DB 'SEND HELLO.EXT - Same as ''S'' command',CR,LF
DB 'SENDK HELLO.EXT - Same as ''SK'' command',CR,LF
ENDIF ; RCPM
;
DB CR,LF
DB 'TYPE HELLO.EXT - Display ASCII file contents'
DB CR,LF,CR,LF
DB '? - Displays this menu'
DB CR,LF,LF,'(Abort to CP/M with ^C, ^K or ^X)',CR,LF
DB 0
JMP 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
DB ' <<== Exit LUX with ^C, ^K or ^C',CR,LF,0
JMP GETCMD ; Go back for another command
;.....
;
;
NOARC1: CALL CRLF
CALL CRLF
CALL ILPRT
DB 'Use DIR command for CRC values',CR,LF,0
JMP GETCMD
;.....
;
;
; KMD is a special case since the 'A' and 'R' options are invalid here
;
IF RCPM
KKMD: CALL ADVANC ; Go to next character
MOV A,M ; Get the character
CPI 'S' ; If 'S' check for
JZ KKMD1 ; Following 'K'
CPI 'R' ; Not legal here
JZ KKMD2 ; Execute error routine
CPI 'A' ; Not legal here
JZ KKMD3 ; Execute error routine
CPI 'L' ; Not legal here
JZ 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: INX H ; Get next chacter
MOV A,M
CPI 020H ; Is it a space?
JZ KKMD1A
CPI 'K' ; Or packet request?
JZ KKMDK
;
KKMD1A: CALL NXTSPC
LDA ARCFLG ; Are we in an .ARC file?
ORA A
JZ SEND ; Nope, send regular
JMP SENDA ; Yes, send .ARC
;.....
;
;
KKMDK: CALL NXTSPC
LDA ARCFLG ; Are we in an .ARC file?
ORA A
JZ SENDK ; Nope, send regular
JMP SENDAK ; Yes, send .ARC
;.....
;
;
KKMD2: CALL CRLF
CALL PRTERR ; Print the command
CALL ILPRT ; Print the following
DB ' can''t (R)eceive while in LUX',CR,LF,0
JMP GETCMD ; Return to command
;.....
;
;
KKMD3: CALL CRLF
CALL PRTERR ; Print the command
CALL ILPRT ; Print the following
DB ' uses S or SK options while in LUX',CR,LF,0
JMP GETCMD
ENDIF ; RCPM
;.....
;
;
; 'LUX' command process
;
LUX: LDA CMDLEN ; Get the length of the command line
CPI 3 ; Was input only 'LUX'
JZ LUX04 ; Error...
CALL FNDSPC ; Find a space in command line
JC LUX05 ; Error if no space found
CALL ADVANC ; Search for the next non-blank character
JC LUX05 ; Error if no more characters left
CALL DRUSR ; Get drive/user
JC LUX05 ; If drive/user specification error
push h ; save command pointer
mov h,b
mov l,c
shld tmpdrv ; save the temporary drive/user
pop h ; get cmd pointer back
XCHG ; De is source address to create new fcb
LXI H,TMPFCB ; Index temporary fcb
CALL SCANR1 ; Create the new fcb
LXI H,'BL' ; Set 'LB' into first two bytes of file type
SHLD TMPFCB+9
MVI A,'R' ; Set 'R' into last byte of file type
STA TMPFCB+11
CALL SETTMP ; Log into the requested drive/user
LXI D,080H
MVI C,26 ; BDOS set DMA function
CALL 5 ; Set DMA address to 80h
LXI D,TMPFCB ; Index temporary FCB
MVI C,17 ; Bdos search first function
CALL 5
INR A ; Test for existence
JNZ LUX01 ; OK, go
LXI H,'RA' ; Check for .ARC file
SHLD TMPFCB+9
MVI A,'C'
STA TMPFCB+11
LXI D,080H
MVI C,26
CALL 5
LXI D,TMPFCB
MVI C,17
CALL 5
INR A
JNZ SETFLG ; Set ARCFLG
LXI H,'RA' ; Check for .ARK file
SHLD TMPFCB+9
MVI A,'K'
STA TMPFCB+11
LXI D,080H
MVI C,26
CALL 5
LXI D,TMPFCB
MVI C,17
CALL 5
INR A
JZ LUX05 ; Cant find file
MVI A,07FH
STA ARCFLG ; Set .ARK flag true
JMP LUX02
;
SETFLG: MVI A,0FFH ; Set .ARC flag true
STA ARCFLG
JMP LUX02
;.....
;
;
LUX01: MVI A,0 ; Set .ARC flag false
STA ARCFLG
;
LUX02: LHLD TMPDRV ; Get temporary drive/user
SHLD RQDDRV ; Set new drive/user
LXI H,TMPFCB+1 ; Source address of new name
LXI D,LBRNAM ; Current .lbr name
LXI B,12 ; 8 character file name
call LDIRs ; Move it
CALL ILPRT ; For display neatness
DB CR,LF,0
MVI A,0FFH ; Set the auto-directory flag
STA DOADIR
JMP GETCMD
;.....
;
;
LUX04: CALL ILPRT
DB CR,LF,'++ Invalid drive/user number ++',CR,LF,0
JMP GETCMD
;.....
;
;
LUX05: CALL ILPRT
DB CR,LF,LF,'Can''t find ',0
CALL DVUPR1
MVI B,8
LXI H,TMPFCB+1
CALL NAMPR1 ; Print the file name
CALL ILPRT
DB ' - check your spelling',CR,LF,0
JMP GETCMD
;.....
;
;
PROCES: XRA A ; Zero last byte of new command line
lhld cptrix
mov m,a
LXI H,TBUFF+1
STA HLPCNT ; Reset the error count
CALL DRUSR ; Get drive/user
push h
mov h,b
mov l,c
shld comdrv
pop h
XCHG ; De is source address to create new FCB
CALL SCANER ; Create the new FCB
XCHG ; Into 'HL'
LXI D,TBUFF+1 ; Start of command buffer
PUSH H
PUSH D
ORA A ; Clear any carry
mov a,h
sbb d
mov h,a
mov a,l
sbb e
mov l,a ; Replace Z80 SBC HL,DE
LDA TBUFF ; Get command line length
SUB L ; Calculate new length
STA TBUFF ; Put new length
MVI A,07EH ; Calculate length of block move
SUB L
MOV C,A ; Set into C
MVI B,0 ; 'B' gets zero
POP D ; Restore destination
POP H ; And source
call LDIRs ; Move the block down
LXI H,FCB1 ; Set up first FCB
LXI D,TBUFF+1
CALL SCANR1
LXI H,FCB2 ; Set up second FCB
CALL SCANR1
;
;
; Force the default file type (.COM)
;
LXI H,'OC' ; 'CO'
SHLD DEFFCB+9
MVI A,'M' ; 'M'
STA DEFFCB+11
XRA A ; Zero the record count and
STA DEFFCB+15 ; the extent number
STA DEFFCB+32
CALL SETCOM ; Set .COM drive/user
LXI D,TPA
MVI C,01AH
CALL BDOS ; Set DMA to TPA
LXI D,DEFFCB
MVI C,011H
CALL BDOS ; Search for first
INR A
JNZ PROCE1 ; File found
CALL ILPRT
DB CR,LF,'Can''t find ',0
MVI B,8
LXI H,DEFFCB+1
CALL NAMPR1 ; Print the file name
CALL ILPRT ; CR/LF
DB CR,LF,0
JMP ENTRY ; Go for more commands
;.....
;
;
PROCE1: LXI D,TPA
MVI C,01AH
CALL BDOS ; Set DMA to TPA
LXI D,DEFFCB
MVI C,00FH
CALL BDOS ; Open file
INR A
JNZ PROCE2
CALL ILPRT
DB CR,LF,'.COM File error - notify SYSOP',CR,LF,0
JMP ENTRY
;.....
;
;
; Load the .COM file into memory at 100h and call it
;
PROCE2: LXI H,080H
LXI D,080H
;
LODCOM: DAD D ; Add record size offset
XCHG ; Get DMA address into 'DE'
PUSH D ; Save 'DE' and 'HL'
PUSH H
MVI C,01AH
CALL BDOS ; Set DMA
LXI D,DEFFCB ; Index .com file name
MVI C,014H
CALL BDOS ; Read a record
POP H ; Restore 'DE' and 'HL'
POP D
XCHG ; 'HL' is dma address again
ORA A ; End of file ?
JZ LODCOM ; No - read another record
MVI C,13
CALL BDOS ; Reset drive system
CALL SETNEW ; Set new drive/user
XRA A
STA ACTIVE ; Clear command mode active
CALL CRLF
CALL TPA ; Call the loaded file @100h
LXI D,35 ; Zero out FCB1
LXI H,FCB1
;
ZEROFCB:MVI M,0
INX H
DJNZ ZEROFCB
JMP ENTRY ; Go for more commands
;.....
;
;
NAMPRT: MVI B,8 ; 8 character file name
LXI H,LBRNAM ; Index .LBR name
;
NAMPR1: MOV A,M ; Get a byte
CPI 020H ; Space?
JZ NAMPR2 ; Yes - dont print
CALL CTYPE ; Else print the character
;
NAMPR2: INX H ; Next character
DJNZ NAMPR1 ; Process 8 characters
MVI A,'.' ; Print a seperator
CALL CTYPE
MVI B,3 ; 3 character file type
;
NAMPR3: MOV A,M ; Get a character
CALL CTYPE ; Print it
INX H ; Next character
DJNZ NAMPR3 ; Process 3 characters
RET
;.....
;
;
; Write a string of characters to the crt
;
ILPRT: XTHL ; Save return address/get character pointer
;
ILPRT1: MOV A,M ; Get a byte
ORA A ; Test it
JZ ILPRT2 ; Null - end of string
CALL CTYPE ; Else type the character
INX H ; Next character
JMP ILPRT1 ; Loop for more
;
ILPRT2: INX H
XTHL ; Restore return address
RET ; Return to caller
;.....
;
;
; Write a string of characters to the command line
;
; (works like ILPRT above)
;
FILTYP: XTHL
;
FILTY1: MOV A,M
ORA A
JZ FILTY2
CALL PUTIN
INX H
JMP FILTY1
;
FILTY2: XTHL
RET
;.....
;
;
; Puts ' $L' on command line
;
FILDIR: CALL FILSPC
MVI A,'$'
CALL PUTIN
MVI A,'L'
CALL PUTIN
;
;
; Fill command line with a space
;
FILSPC: MVI A,20H ; Space character
JMP PUTIN ; Fill in
;.....
;
;
; Fill command line with .LBR name
;
FILNAM: MVI B,8 ; 8 character file name
LXI H,LBRNAM ; Index .LBR name
;
FILNA1: MOV A,M ; Get a character
CPI 020H ; Space ?
JZ FILNA2 ; Yes - dont add to command line
CALL PUTIN ; Put character into command line
;
FILNA2: INX H ; Next character
DJNZ FILNA1 ; Process 8 characters
MVI A,'.' ; Put in a seperator character
CALL PUTIN
MVI B,3 ; 3 character file type
;
FILNA3: MOV A,M ; Get a character
CALL PUTIN ; Put in command line
INX H ; Next character
DJNZ FILNA3 ; Process 3 characters
RET ; Return to caller
;.....
;
;
; Fill command line with member name
;
FILMEM: CALL PARSER ; Parse member name
LXI H,MEMBER ; Index member name
MVI B,12 ; 12 character max
;
FILME1: MOV A,M ; Get a byte
ORA A ; End of input
RZ ; Yes - return
CALL PUTIN ; Fill in one character
INX H ; Next character
DJNZ FILME1 ; Continue looping
RET ; Done
;
Putin: push h ; Stuff the character into command line
lhld cptrix
mov m,a
inx h ; Get ready for next character
shld cptrix
lxi h,tbuff ; Bump command line length
inr m
pop h
RET ; Return to caller
;.....
;
;
; Parse out a member name
;
PARSER: LXI H,MEMBER ; Index member name
MVI B,12 ; Max 12 character filename
;
PARSE1: MVI M,0 ; Zero character
INX H ; Next character
DJNZ PARSE1 ; Clear the entire member name
CALL ADVANC ; Advance to the next non blank character
RC ; If at the end of the line
LXI D,MEMBER ; DE is index to member, HL set by ADVANC
LHLD NXTWRD
;
PARSE2: MOV A,M ; Get source byte
ORA A ; End of input line ?
RZ ; Yes - return
;
STAX D ; Put byte
INX H ; Next source
INX D ; Next destination
JMP 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: LHLD NXTWRD ; Get pointer to next word
;
ADVAN1: MOV A,M ; Get a byte
ORA A ; Test flags
JZ ADVAN3 ; Error - null character
CPI 020H ; Space ?
JNZ ADVAN2 ; Yes - done
INX H
SHLD NXTWRD ; Put pointer back
JMP ADVAN1 ; Loop for more
;
ADVAN2: ORA A ; Clear any carry
RET
;
ADVAN3: STC ; Set error condition
RET
;.....
;
;
FNDSPC: LXI H,CMDLIN+2 ; Index command line
;
FND01: MOV A,M ; Get a byte from command line
ORA A ; Eol ?
JZ FNDER ; Error...
CPI 020H ; Space?
JZ FNDEX ; Yes - go find requested file name
INX H ; Next character
JMP FND01 ; Else continue the search
;
FNDER: STC ; All chars. scanned and no space found
RET
;
FNDEX: SHLD NXTWRD ; Set character location
ORA A ; Assure carry reset
RET ;
;
NXTSPC: LHLD NXTWRD ; Get pointer to next word
;
NXTSP1: MOV A,M ; Get a byte
ORA A ; Is it a null?
JZ NXTSP2 ; Yes - return
CPI 020H ; If at a space?
JZ NXTSP2 ; Yes - return
INX H ; Next character
JMP NXTSP1 ; And continue looking
;
NXTSP2: SHLD NXTWRD
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: XTHL
PUSH D
;
ILCMP1: MOV A,M ; Get a byte from source
ORA A ; Null
JZ SAME1 ; Yes - same so far - test next char
LDAX D ; Get a byte from command string
CMP M ; Same as source
JNZ NOTSAM ; No - not the same
INX H ; Next source
INX D ; Next compare
JMP ILCMP1 ; Loop again
;
NOTSAM: XRA A ; Zero for the test
;
NSLP: INX H ; Next immediate byte
CMP M ; Null yet ?
JNZ NSLP ; No - continue
;
SAME2: STC ; Set error condition
;
SAME: XCHG ; Get command string pointer
SHLD NXTWRD ; Store it
XCHG ; Restore return address
POP D ; Restore source address
INX H ; Adjust to stack
XTHL ; Replace return address
RET ; Return
;
SAME1: LDAX D ; Get the next byte from command line
ORA A ; Null ?
JZ SAME ; Yes - its ok
CPI 20H ; Space ?
JZ SAME ; Yes - thats ok too...
JMP SAME2 ; Not ok- must be another character
;.....
;
;
CTYPE: PUSH PSW ; Save all registers
PUSH B
PUSH D
PUSH H
ANI 7FH ; Be sure its ASCII
MOV E,A ; Into 'E'
MVI C,2 ; Cpm console function
CALL BDOS
POP H ; Restore all registers
POP D
POP B
POP PSW
RET ; Return to caller
;.....
;
;
CRLF: MVI A,13
CALL CTYPE
MVI A,10
JMP 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: SHLD TEMPHL ; Save the pointer address
shld cptrix ; 'IX' get the pointer address
LXI B,5 ;
MVI A,':'
CPIR 2 ; Search for the ':' macro
MOV A,C ; Get 'B' result from 'CPIR' instruction
STA LENGTH ; Keep for possible adjust
XCHG ; De points to the byte following ':'
LXI H,VTABLE ; Index address table
DAD B ; Add word offset
DAD B
MOV A,M ; Get routine lsb
INX H
MOV H,M ; Get routine msb
MOV L,A
LXI B,0 ; Set up drive/user storage
PCHL ; Execute
;.....
;
;
VTABLE: DW DRUS0 ; B=0 - FILENAME.EXT
DW DRUS1 ; B=1 - A15:FILENAME.EXT
DW DRUS2 ; B=2 - A1:FILENAME.EXT
DW DRUS3 ; B=3 - A:FILENAME.EXT
DW DRUS4 ; B=4 - :FILENAME.EXT
;
;
; Format was - FILENAME.EXT
;
DRUS0: CALL GETDFU ; Get the default user
CALL GETDFD ; Get the default drive
LHLD TEMPHL ; Get old buffer pointer back
XRA A ; Zero move length
RET ; All done
;.....
;
;
; Format was - DUU:FILENAME.EXT
;
DRUS1: CALL GETDRV ; Get the drive parameter
push h
lhld cptrix
mov a,m
pop h
CPI '0'
JC ERROR
CPI '9'+1
JNC ERROR
SUI '0'
MOV B,A ; Put in drive number
ADD B
MOV B,A
push h ; Skip the tens digit
lhld cptrix
inx h
shld cptrix
pop h
JMP GETUSR ; Get the user number
;.....
;
;
; Format was - DU:FILENAME.EXT
;
DRUS2: CALL GETDRV ; Get the drive parameter
JMP 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: JMP DRUS5
;
Getdrv: push h
lhld cptrix
mov a,m
pop h
CPI 'A'
JC ERROR1
CPI 'Q'
JNC ERROR1
SUI 'A'
MOV C,A ; Put in drive number
push h
lhld cptrix
inx h
shld cptrix
pop h
RET
;.....
;
;
Getusr: push h
lhld cptrix
mov a,m
pop h
CPI '0'
JC ERROR
CPI '9'+1
JNC ERROR
SUI '0'
ADD B
MOV B,A
;
;
; Adjust the byte in 'LENGTH'
;
DRUS5: XCHG ; Hl points to byte following ':' if any
LDA LENGTH ; Get length of move
ORA A ; Test it
RZ ; Return if null/ clear carry
MOV E,A
MVI A,5
SUB E
STA LENGTH
ORA A ; Clear any error
RET
;.....
;
;
ERROR1: POP D ; Kill return address from subroutine
ERROR: STC ; Set error condition
RET
;.....
;
;
; Get default user
;
GETDFU: PUSH B
PUSH D
PUSH H
MVI C,020H
MVI E,0FFH
CALL BDOS
POP H
POP D
POP B
MOV B,A ; Set 'B' register to current user
RET
;.....
;
;
; Get default drive
;
GETDFD: PUSH B
PUSH D
PUSH H
MVI C,19H
CALL BDOS
POP H
POP D
POP B
MOV 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: LXI H,DEFFCB ; Point to DEFFCB
;
SCANR1: XRA A ; Set temporary drive number to default
STA TEMPDR
CALL ADVNCE ; Skip to non-blank or end of line
xchg ; Set pointer to non-blank or end of line
shld ciptr
xchg
LDAX D
ORA A
JZ SCANR2
SBI 'A'-1
MOV B,A
INX D
LDAX D
CPI ':'
JZ SCANR3
DCX D
;
SCANR2: LDA TDRIVE ; Set 1st byte of deffcb as default drive
MOV M,A
JMP SCANR4
;
SCANR3: MOV A,B
STA TEMPDR
MOV M,B
INX D
;
SCANR4: XRA A ; A=0
STA QMCNT ; Init count of # of question marks in FCB
MVI B,8 ; Max of 8 characters in file name
CALL SCANF ; Fill FCB file name
;
;
; Extract file type from possible FILENAME.TYP
;
MVI B,3 ; Prepare to extract type
CPI '.' ; If (de) delimiter is a '.', we have a type
JNZ SCANR5 ; Fill file type bytes with <sp>
INX D ; Pt to char in command line after '.'
CALL SCANF ; Fill FCB file type
JMP SCANR6 ; Skip to next processing
;
SCANR5: CALL SCANF4 ; Space fill
;
;
; Fill in ex, s1, s2, and rc with zeroes
;
SCANR6: MVI B,4 ; 4 bytes
;
SCANR7: INX H ; Point to next byte in DEFFCB
MVI M,0
DJNZ SCANR7
;
;
; Scan complete -- DE points to delimiter byte after token
;
xchg
shld cibptr
xchg
;
;
; Set zero flag to indicate presence of '?' in FILENAME.TYP
;
LDA QMCNT ; Get number of question marks
ORA 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
JZ SCANF4
INX H ; Pt to next byte in deffcb
CPI '*' ; Is (de) a wild card?
JNZ SCANF1 ; Continue if not
MVI M,'?' ; Place '?' in deffcb and dont advance de if so
CALL SCQ ; Scanner count question marks
JMP SCANF2
;
SCANF1: MOV M,A ; Store filename char in deffcb
INX D ; Pt to next char in command line
CPI '?' ; Check for question mark (wild)
CZ SCQ ; Scanner count question marks
;
SCANF2: DJNZ SCANF ; Decrement char count until 8 elapsed
;
SCANF3: CALL SDELM ; 8 chars or more - skip until delimiter
RZ ; Zero flag set if delimiter found
INX D ; Pt to next char in command line
JMP SCANF3
;
;
; Fill memory pointed to by HL with spaces for B bytes
;
SCANF4: INX H ; Pt to next byte in deffcb
MVI M,' ' ; 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: LDA QMCNT ; Get count
INR A ; Increment
STA QMCNT ; Put count
RET
;.....
;
;
; Check to see if DE points to delimiter; if so, return with zero flag
; set.
;
SDELM: LDAX D
ORA A ; 0=delimiter
RZ
CPI ' ' ; Error if < <sp>
RZ ; <sp>=delimiter
CPI '=' ; '='=delimiter
RZ
CPI 5FH ; Underscore=delimiter
RZ
CPI '.' ; '.'=delimiter
RZ
CPI ':' ; ':'=delimiter
RZ
CPI ';' ; ';'=delimiter
RZ
CPI '<' ; '<'=delimiter
RZ
CPI '>' ; '>'=delimiter
RET
;.....
;
;
; Advance input pointr to first non-blank and fall through to SBLANK
;
Advnce: xchg
shld cibptr
xchg
;
; Skip string pointed to by DE (string ends in 0) until end of string
; or non-blank encountered (beginning of token)
;
SBLANK: LDAX D
ORA A
RZ
CPI ' '
RNZ
INX D
JMP SBLANK
;.....
;
;
; Capitalize string (ending in 0) in cmdlin and set pointr for parsing
;
CNVBUF: LXI H,CMDLIN+1 ; Point to users command
MOV B,M ; Character count in 'B'
INR B ; Add 1 in case of zero
;
CNVBF1: INX H ; Point to 1st valid character
MOV A,M ; Capitalize command character
CALL UCASE
MOV M,A
DJNZ CNVBF1 ; Continue to end of command line
;
CNVBF2: MVI M,0 ; Store ending <null>
LXI H,CMDLIN+2 ; Set command line pointer to 1st char
SHLD CIBPTR
RET
;.....
;
;
; Convert character in 'A' to upper case
;
UCASE: CPI 61H ; Lower-case a
RC
CPI 7BH ; Greater than lower-case z?
RNC
ANI 5FH ; Capitalize
RET
;.....
;
;
GETOLD: CALL GETDFU ; Get current user into 'B'
CALL GETDFD ; Get current drive into 'C'
push h
mov h,b ; Get the parameters
mov l,c
shld olddrv
pop h
RET
;.....
;
;
Settmp: push h
lhld tmpdrv
mov b,h
mov c,l
pop h
JMP RESET
;.....
;
;
Setold: push h
lhld olddrv
mov b,h
mov c,l
pop h
JMP RESET
;.....
;
;
Setnew: push h
lhld rqddrv ; get the old drive number
mov b,h
mov c,l
pop h
JMP RESET
;.....
;
;
Setcom: push h
lhld comdrv ; Get the old drive number
mov b,h
mov c,l
pop h
;
RESET: PUSH B ; Save drive/user
PUSH B
MOV E,C ; Get selected drive
MVI C,14 ; Bdos function
CALL BDOS
POP B ; Restore drive/user
MOV E,B ; Get selected user
MVI C,32 ; Bdis set user function
CALL BDOS
;
;
; Set up byte at 0004h - some programs may look at it
;
POP B
MOV A,B ; Get user number
RAL
RAL
RAL
RAL
ANI 0F0H
ORA C
STA 4
RET
;
DVUPR1: LDA TMPUSR
PUSH PSW
LDA TMPDRV
JMP DVUPR3
;
DVUPRT: LDA RQDUSR ; Get requested drive
PUSH PSW
LDA RQDDRV ; Get the requested user
;
DVUPR3: ADI 'A'
CALL CTYPE ; Print the drive 'A'-'P'
POP PSW
CPI 10 ; Less that 10?
JC DVUPR2 ; Yes - dont print the '1'
PUSH PSW
MVI A,'1'
CALL CTYPE
POP PSW
SUI 10
;
DVUPR2: ADI '0'
CALL CTYPE
MVI A,':'
JMP CTYPE
;.....
;-----------------------------------------------------------------------
;
; This subroutine is a substitute for the Z80 LDIR instruction.
; Borrowed from ZCMD8080.ASM
;
LDIRS: PUSH PSW ; Save flags
LDIR1: MOV A,M ; Fetch the byte
STAX D ; Poke it
INX H ; Increment pointers
INX D
DCX B ; Decrement counter
MOV A,B ; Check the counter to
ORA C ; see if we are done
JNZ LDIR1 ; Not done?
POP PSW ; Finished
RET ; End of LDIR replacement subroutine
;
;-----------------------------------------------------------------------
;
;
IF RCPM
SUBFCB: DB 0 ; Use current drive
DB '$$$ SUB'
DB 0,0,0,0,0,0,0,0 ; Rest of the FCB
DB 0,0,0,0,0,0,0,0 ;
DB 0,0,0,0,0
DB 0,0,0,0 ; RFU
;
;
; Edit this to contain the console commands necessary to execute the
; logoff sequence for your system.
;
BYECMD: DB 0 ; <====== do not touch
DB 'BYE',CR,LF ; <====== put any number of cmds here
DB 'Z'-40H ; <====== do not touch
;
BYELEN EQU $-BYECMD-1
ENDIF ; RCPM
;
;
ARCFLG: DB 0
DOADIR: DB 0
HLPCNT: DB 0
BIOS3: DW 0
TEMPDR: DB 0
CIPTR: DW 0
TDRIVE: DB 0
QMCNT: DB 0
CIBPTR: DW 0
TEMPHL: DW 0
LENGTH: DB 0
OLDDRV: DB 0
OLDUSR: DB 0
RQDDRV: DB 0 ; Requested drive
RQDUSR: DB 0 ; Requested user
COMDRV: DB 0 ; Drive to load .COM file
COMUSR: DB 0 ; User to load .COM file
TMPDRV: DB 0 ; Temporary drive number
TMPUSR: DB 0 ; Temporary user number
ACTIVE: DB 0 ; Attach command mode active
NXTWRD: DW 0
DW 0
CMDLIN: DB 79
CMDLEN: DB 0
DS 79
DB 0
;
MEMBER: DB ' '
DB 0
DB 0
LBRNAM: DB ' ' ; Library file name
DB 'LBR'
;
Cptrix: ds 2 ; <IX> points to command line
;
TMPFCB: DS 36
DEFFCB: DS 36
;
DS 80 ; Area for stack
;
STACK EQU $
;
;
END