.Z80 ;************************************************************************* ; ZLUX by J. POPLETT ;************************************************************************* ; VERS EQU 25 ; ; Z3ENV DEFL 0F1A0H ; No big deal, Z3INS will fix it anyway ; COPR MACRO DEFB 'Copyright (C) 1986 by John H. Poplett. All Rights Reserved.' ENDM ; ;---------------------- ; Version 2.5 12/4/86 ; Fixed a bug in the inline routine that has been plagueing ; ZLUX since V2.2. The original inline routine expanded tabs with ; spaces but placed a single tab character in the line buffer. ; Attempts to backspace after a tab would hang the system. ; NEW with 2.5 is an optional internal directory function. ; Although an internal directory runs slightly counter to the ; original intention of ZLUX, i.e. to make maximum use of external ; utilities, the internal directory is a great deal faster than, ; say, SDXX, and therefore, warranted. Purists can of course stick ; to the original and use an external program for display of ; library directories. Importantly, Bruce Morgen's fix to the ; SYSLIB SLUDIR module, SLUDIR11.Z80 was/is used for assembling ; ZLUX25 w/the internal directory option. ; Joubert Berger contributed an improvement to the CTRL-E ; function; Harris Edelman helped again w/beta testing; thanks also ; to Norman Beeler, Al Hawley, Steve Kitahata and Bruce Morgen. ; -J. Poplett, the PPR MBBS (213) 382-2213 ; ;------------------------- ; Version 2.4 5/24/86 ; Incorporated .ARC file capability into ZLUX, using UNARC utility ; for DIR and TYPE commands. Fully automatic determination of LBR/ARC ; file presence. No syntax differences in the commands. No KMD/XMODEM ; transfer at present time (although its being worked). ; Shortened and re-worded internal ascii statements to keep code less ; than 4k. This is an "OFFICIAL" release, approved by J. Poplett. ; Just install, (compile if changing options), rename LUX.COM, and ; locate LUX.COM and UNARC.COM on A0: ; ; -Norman Beeler ; ZeeMachine Z-Node #35 ; (408)735-0176/(408)245-1420 ; Multi-user/RAS ;------------------------ ; ; define TRUE and FALSE ; FALSE EQU 0 TRUE EQU NOT FALSE ; ; ASCII characters and constants ; CMDLEN EQU 60 CR EQU 0DH ; Carriage return LF EQU 0AH ; Line feed DEL EQU 7FH ; Delete NULL EQU 0 ; NULL BEL EQU 7 ; BELL BS EQU 8 ; BACKSPACE TAB EQU 9 ; TAB CTRLC EQU 'C'-40H ; CTRL-C CTRLE EQU 'E'-40H ; CTRL-E CTRLR EQU 'R'-40H ; CTRL-R CTRLU EQU 'U'-40H ; CTRL-U CTRLX EQU 'X'-40H ; CTRL-X ; ; ; Base page address equates ; FCB EQU 5CH ; CCP file control block DMAADR EQU 80H ; Default DMA buffer address (DBUF) PARM EQU DMAADR+2 ; Location of parameter in DMA ; ; Conditional assembly equates ; ; The comment equate allows one to opt for either the semicolon as a comment ; delimiter or to have an instant help key (the '?'). The option is given ; because otherwise a '?' on a comment line would give a help screen. Set ; to true if semicolon delimiter is desired; set to false if instant help ; key desired. (NOTE- an initial '?' will still give a help screen with the ; comment option enabled.) ; COMMENT EQU TRUE ; TRUE, if recognize semicolon as comment KMDM EQU TRUE ; TRUE, if KMD in use; FALSE, if XMODEM PASSCMD EQU TRUE ; TRUE, if non-LUX commands passed to CCP BYECLR EQU TRUE ; TRUE, if BYE clears Z3 shell stack EXTHLP EQU FALSE ; TRUE, if ZLUX.HLP help file on-line ; ; the following equate adds a library directory function that is internal ; to ZLUX. Although this option increases the programs code size, overall ; operation is speedier. ; INTDIR EQU TRUE ; TRUE, if use internal directory code ; ; Z3LIB & SYSLIB external references ; ; IF INTDIR EXTRN CAPS,CODEND,CONDIN,LUINIT,LUDIR EXTRN FNAME,PFN3,PHLDC,PHL4HC ENDIF ; IF PASSCMD EXTRN PUTCST ENDIF ; EXTRN Z3INIT,Z3LOG,CLRCL,PUTCL EXTRN GETSH1,DIRTDU,ZPRSFN,PARSER EXTRN GETMDISK,GETMUSER,GETDUOK,GETMSG EXTRN QSHELL,SHFULL,SHPUSH,SHPOP EXTRN COUT,CIN,EPRINT,CRLF,SKNSP EXTRN CAPSTR,EPSTR,RETUD,F$EXIST ; JP BEGIN ; Jump Z3 header DB 'Z3ENV' ; Z3 program type DB 1 ; External environment descriptor Z3EADR: DW Z3ENV ; Arbitrary environment address, ; Z3INS will fix it later ; set up stack, Z80-style ; BEGIN: LD (STACK),SP ; Save Z3's stack pointer LD SP,STACK ; Set new stack pointer ; ; initialize Z3 environment ; LD HL,(Z3EADR) ; Get env ptr CALL Z3INIT ; Inform Z3LIB ; ; begin by clearing Z3 CL buffer and setting pointer to LBR's name ; CALL CLRCL ; Check for & clear Z3 command line buffer JP Z,ERR3 ; Might as well quit now if no buffer LD DE,LBRNAM-SHNAME; Offset to LBR name from our shell name CALL GETSH1 ; Shell Stack address in HL (DE preserved) JP Z,SHERR ; Oops, no Shell Stack ADD HL,DE ; Add in the offset LD (LFNAME),HL ; Store for later use LD DE,15 ; Z3msg offset for Shell scratch byte CALL GETMSG ; Z3MSG address in HL JP Z,ERR2 ; NO Z3MSG space ADD HL,DE ; Add the offset LD (ARCFLG),HL ; Store for later use ; ; are we already a shell? ; RESHEL: CALL QSHELL ; Test the command status byte JP Z,GETCMD ; Don't reinvoke if we're a shell ; ; check for filename parameter and append to shell name if found ; RSTRT: LD A,(DMAADR) ; 1st byte of DMA contains length of parameter OR A ; Is it null? if so, no parameter specified JP Z,ERR1 ; Exit with error msg if null DEC A ; Or just a space? JP Z,ERR1 ; Exit with error msg if one-byte tail LD HL,PARM LD A,(HL) ; What's the first character? CP '/' ; These are trapped on restarts JP Z,Z3HLP ; Branch if it's a Z3 help query CALL GETMDISK ; Max disk in A LD D,A ; To D INC D ; Bump it for CP/JP NC CALL GETMUSER ; Max user in A LD E,A ; To E INC E ; Bump it for CP/JP NC CALL GETDUOK ; Will we accept DU: form? JR NZ,DUISOK ; Good, skip a CALL CALL DIRTDU ; See if a valid NDR entry JR Z,CURDIR ; If not, try current directory only DUISOK: LD A,(FCB) ; FCB drive byte into A OR A ; Current disk? JR NZ,GOTDRV ; Otherwise A has it CURDIR: CALL RETUD ; Get current DU: from SYSLIB LD A,B ; Disk into A INC A ; Bump it to 1=A, etc. GOTDRV: CP D ; Compare to max drive + 1 JP NC,DIRERR ; A register must be smaller ADD A,'A'-1 ; ASCII the drive LD HL,LBRNAM ; Point at our shell tail LD (HL),A ; Plant it LD A,(FCB+13) ; Get user number from FCB CP E ; Compare to max user + 1 JP NC,DIRERR ; A register must be smaller INC HL ; Bump to user spot in our buffer ; ; Convert hexadecimal user area number to 1- or 2-digit ASCII ; LD B,'0'-1 ; Preset for two-digit calculation later CP 10 ; See if single digit JR NC,TWODIG ; If not, print two digits ADD A,'0' ; Else convert to ASCII LD (HL),A ; And plant it JR PUTCLN ; Then do colon TWODIG: INC B ; Count tens digit in B SUB 10 ; Keep subtracting 10 until carry is set JR NC,TWODIG ADD A,10 ; Get remainder (units digit) back LD C,A ; Save it in C LD A,B LD (HL),A INC HL LD A,C ADD A,'0' LD (HL),A ; PUTCLN: INC HL LD (HL),':' INC HL ; PUTNAM: LD DE,FCB+1 ; DE points to FCB filename LD B,8 ; Maximum filename length NLOOP: LD A,(DE) ; Get character from FCB CP ' ' ; End of filename? JR Z,CLAPND ; Go append .LBR LD (HL),A ; Character to LBRNAM INC HL ; Bump HL INC DE ; And DE DJNZ NLOOP ; Count down CLAPND: CALL APND ; ; make `LBR' the FCB filetype and see if the file exists ; PUSH HL ; Save for possible ARC file LD HL,FCB+9 ; Point at FCB filetype CALL APND1 ; Plug in L and B and R LD DE,FCB ; Point at FCB for the LIBs CALL Z3LOG ; Log in via Z3LIB CALL F$EXIST ; Check via SYSLIB JP NZ,CHSH ; Lbr file, so go POP HL ; Retrive lbr type DEC HL DEC HL DEC HL DEC HL CALL APND2 ; Try again LD HL,FCB+9 ; Do it again for ARC CALL APND3 ; Plug in A and R and C LD DE,FCB ; Point at FCB for the ARCS CALL Z3LOG CALL F$EXIST JP Z,ERR4 ; No file, no ZLUX JR CHSH1 ; check for shell stack full, become a shell if there's room ; CHSH: POP HL ; Just to be sure CHSH1: CALL SHFULL ; All clear? JP Z,SHERR ; Let's not play if not LD HL,SHNAME ; Time to play ball CALL SHPUSH ; Install us on shell stack ; ; Insures that internal directory code will display a full directory on ; restarts. ; IF INTDIR LD HL,AFNSTR ; point to wild-card str (*.*) in HL LD DE,CMDLN+4 ; point to command line buffer CALL STRCP ; copy it ENDIF ; JP DIR ; Give our directory and exit, and ; Z3 will get back to us (trust me) ; ;========================================================================= ; subroutines start here ;========================================================================= ; Z3HLP: CALL EPRINT ; Polite, Z3-style help DB CR,LF,'ZLUX V' DB (VERS/10)+'0','.',(VERS MOD 10)+'0' DB CR,LF,LF DB 'Syntax:' DB CR,LF DB 0 JR ERRZ ; To syntax message ; ERR1: CALL EPRINT ; Print error message DB CR,LF DB 'No file specified',CR,LF,LF DB 'Syntax:' DB CR,LF DB 0 ; ERRZ: CALL EPRINT DB TAB,'LUX [DIR: or DU:]ufn[.lbr/arc]',CR,LF DB TAB,'(DIR: & DU: is system-dependent)' DB 0 JP EXIT1 ; ERR2: CALL EPRINT DB CR,LF DB 'No Z3MSG Buffer' DB 0 JP EXIT1 ; ERR3: CALL EPRINT DB CR,LF DB 'No Z3CL Buffer' DB 0 JP EXIT1 ; SHERR: CALL EPRINT DB CR,LF DB 'Shell Stack full or not supported' DB 0 JP EXIT1 ; DIRERR: CALL EPRINT DB CR,LF DB 'Directory not available' DB 0 JP EXIT1 ; TPAERR: CALL EPRINT DB CR,LF DB 'Insufficient memory for library directory.' DB 0 JP EXIT1 ; ERR4: CALL EPRINT DB CR,LF,LF DB 'Lbr/Arc file not found, check directory.' DB CR,LF,0 JP EXIT1 ; ERR5: CALL EPRINT DB CR,LF,LF DB 'ARC file transfer not available' DB CR,LF,0 RET ; EXIT1: CALL CRLF EXIT: LD HL,(STACK) ; Get old Z3 stack LD SP,HL ; Restore it RET ; Return to CPR ; ; print ZLUX shell prompt and get user command ; GETCMD: ; ; print command line prompt ; PROMPT: CALL EPRINT DB CR,LF DB '[ in ZLUX, ^C to quit, ? for help ]' DB CR,LF,LF,0 HLFPRT: LD HL,(LFNAME) CALL EPSTR LD A,'>' CALL COUT ; ; Command Line Editor (like ZRDOS's, but no ctrl chars printed) ; ------------------------------------------------------------- ; MAIN INLINE (MODIFIED FROM SYSLIB) ENTRY POINT ; original author: Richard Conn INLINE: ; ; INLINE RESTART LOOP ; ; added code here so that the CMDLIN buffer is cleared on each restart ; this is critical (not to mention safer) because a comment line or use ; of the one-key, instant ? help can leave the buffer full of schmutz ; JHP 04/26/86 ; INL0: LD HL,CMDLN ; GET START OF STRING LD B,CMDLEN ; length of command line in B XOR A ; null in accumulator CLRLLP: LD (HL),A ; put null in command line byte INC HL ; increment pointer DJNZ CLRLLP ; loop til command line initialized (nulled) LD HL,CMDLN ; start of command line in HL LD C,A ; SET CHAR COUNT ; MAIN LOOP INL1: CALL CIN ; GET INPUT CHAR CP NULL ; DO NOT PERMIT JR Z,INL1 CP CTRLC JP Z,CCABRT CP BS ; BACKSPACE? JP Z,INBS CP DEL ; DELETE? JP Z,INBS CP TAB ; TABULATE? JP Z,INTAB CP CR ; CARRIAGE RETURN? JP Z,INCR CP LF ; LINE FEED? JP Z,INCR CP CTRLR ; CTRL-R JR Z,PRNLIN CP CTRLU ; CTRL-U? JR Z,RESTRT CP CTRLX ; CTRL-X? JR Z,REXSTRT CP CTRLE ; CTRL-E? JR Z,NEWLINE CP ' ' JR C,INL1 LD (HL),A ; STORE CHAR INC HL ; PT TO NEXT CALL COUT IF NOT COMMENT ; moved check for help to after the call to CP '?' ; COUT so user can see character. JP Z,HELP ; JHP 04/26/86 ENDIF INC C ; INCR CHAR CNT LD A,CMDLEN ; MAX CHAR CNT CP C ; COMPARE JR NC,INL1 ; NO OVERRUN, LOOP LD A,BEL ; load ASCII bell into A CALL COUT ; sound bell JR INBS ; print backspace & loop ; ; ; ** INLINE MODULES ** ; ; ; NEWLINE -- ECHO AND CONTINUE ; ; improvement of CTRL-E function provided by Joubert Berger ; NEWLINE: ld a,c ; count into A or a ; NULL test jr z,newln2 ; if NULL skip backup routine ld b,c ; count into b reg ld a,BS ; ASCII backspace char in acc newln: call cout ; backup for count in b reg djnz newln ; loop til b = 0 newln2: ld a,lf ; ASCII linefeed in acc call cout ; print LF ld c,0 ; 0 in cursor position counter ld hl,CMDLN ; hl points to working cmd line buffer jr inl1 ; return to main edit loop ; TAB -- TABULATE TO NEXT TAB STOP ; ; lowercase code modifies tab expansion to allow backspacing. A backspace ; following a tab was causing some remote systems to freeze up (mine included) ; jhp 06/31/86 ; INTAB: ld a,c ; get count into a ld b,8 ; 8 into B add a,b ; add 8 to accumulator cp cmdlen ; compare against max length jr nc,inl1 ; return, if a + 8 > max len ld c,a ; get new "expanded" count in c ld a,' ' tablp: call cout ld (hl),a inc hl djnz tablp JR INL1 ; ; PRNLIN -- PRINT HASH, AND LINE BUFFER PRNLIN: CALL HASH LD B,C LD A,BS PRNLP: CALL COUT DJNZ PRNLP PUSH HL LD HL,CMDLN CALL EPSTR POP HL JP INL1 ; ; CTRL-U -- ERASE LINE AND RESTART RESTRT: CALL HASH ; PRINT HASH CHAR ; FALL THRU ; START UP AGAIN VIA REXSTRT ; CTRL-X -- ERASE (AND BACKSPACE) LINE AND RESTART REXSTRT: CALL ERALIN ; ERASE LINE JP INL0 ; STARTOVER ; ERALIN: LD A,C ; CHECK FOR EMPTY LINE OR A ; 0 CHARS? RET Z CALL EXBS ; JR ERALIN ; ; BACKSPACE -- DELETE PREVIOUS CHAR AND BACK UP CURSOR INBS: CALL EXBS ; EXECUTE JP INL1 ; BACKSPACE ROUTINE EXBS: CALL BOL ; BEGINNING OF LINE? RET Z ; CONTINUE IF SO DEC C ; DECR COUNT DEC HL ; BACK UP ld (hl),0 ; null character in buffer for ^R JHP 5/86 LD A,BS ; PRINT CALL COUT LD A,' ' ; CALL COUT LD A,BS ; JP COUT ; CARRIAGE RETURN -- DONE; STORE ENDING ZERO INCR: CALL CRLF CALL BOL JP Z,GETCMD LD (HL),0 ; STORE ENDING ZERO JR GOTCMD ; ; ** SUPPORT ROUTINES ** ; BOL -- RETURNS W/ZERO FLAG SET IF USER AT BEGINNING OF LINE BOL: EX DE,HL ; DE=HL LD HL,CMDLN ; GET START ADR EX DE,HL ; HL RESTORED LD A,D ; CHECK FOR MATCH CP H ; MATCH? RET NZ ; NO MATCH LD A,E ; CHECK FOR COMPLETE MATCH CP L RET ; ; ; HASH -- PRINT HASH MARK FOLLOWED BY & HASH: LD A,'#' ; PRINT HASH CHAR CALL COUT LD A,LF CALL COUT LD A,BS JP COUT ; CCABRT: CALL ERALIN ; ERASE LINE JP CABORT ; PRINT CONTROL-C ABORT MESSAGE & QUIT ; ; Capitalize and parse line editor buffer, call scanner ; GOTCMD: LD HL,CMDLN IF COMMENT LD A,(HL) ; get first byte into A CP ';' ; is it a comment line? JP Z,HLFPRT ; yez, go back fo mo CP '?' ; a request for help? JP Z,HELP ; if help char, go get help ENDIF CALL CAPSTR LD DE,FCB CALL ZPRSFN CALL CMDSER ; ; if command not recognized print error ; message & return to ZLUX cmdln prompt ; OR pass command to CCP ; JR NZ,NOTCMD JP (HL) ; Jump to routine from scanner ; NOTCMD: IF NOT PASSCMD CALL EPRINT DB CR,LF,LF DB 'Invalid command. Use ? or HELP' DB CR,LF,0 JP GETCMD ELSE ; ; PUTCST insures that the shell will recover if a bad command spec is ; given ; XOR A ; 0 in A CALL PUTCST ; tell ZCPR3 next is a normal command LD HL,CMDLN ; addr of non-ZLUX command in HL CALL PUTCL ; setup Z3 command buffer JP EXIT ; give it a shot ENDIF ; ; table of valid ZLUX command keys (only the CMDTBL: ; label is really needed) for programmer's convenience ; CMDTBL: HKEY: DB 'HELP ' DW HELP ; IF (NOT PASSCMD) OR (NOT BYECLR) BKEY: DB 'BYE ' DW BYE ENDIF ; CATKEY: DB 'CAT ' DW CAT ; IF NOT PASSCMD CHTKEY: DB 'CHAT ' DW CHAT ENDIF ; DKEY: DB 'DIR ' DW DIR FKEY: DB 'FILES ' DW FILES LKEY: DB 'LUX ' DW LUX SKEY: DB 'SEND ' DW SEND SKKEY: DB 'SENDK ' DW SENDK TKEY: DB 'TYPE ' DW TYPE XKEY: DB 'XMODEM' DW XMODEM KKEY: DB 'KMD ' DW KMD ; IF NOT PASSCMD PKEY: DB 'PWD ' DW PWD ENDIF ; DB 0 ; Marks end of table ; IF (NOT PASSCMD) OR (NOT BYECLR) BYE: CALL SHPOP LD HL,CSTR1 CALL PUTCL JP EXIT ENDIF ; CAT: LD HL,CSTR2 CALL ARCTST JR Z,CAT1 LD HL,CSTR2A CAT1: CALL PUTCL JP EXIT ; IF NOT PASSCMD CHAT: LD HL,CSTR3 CALL PUTCL JP EXIT ENDIF ; DIR: IF NOT INTDIR LD HL,CSTR4 ; DIR (SDxxx) CALL ARCTST JR Z,DIR2 LD HL,CSTR4A ; UNARC (UNARCxx) ELSE LD HL,CSTR4A CALL ARCTST JP NZ,DIR2 CALL CODEND ; get codend for library buffers LD (LUBUFF),HL ; stash it LD HL,(LFNAME) ; address of token into HL LD DE,LUDFCB ; address of LUD FCB in DE CALL FNAME ; parse token into FCB LD DE,LUD ; point at syslib library structure CALL LUINIT ; init w/SYSLIB routine LD HL,CMDLN+4 ; address of dir spec, if any LD DE,LMBRN ; CALL FNAME LD HL,LMBRN+1 LD BC,(LUBUFF) ; start address in heap for dir buffers LD DE,LUD ; address of LU descriptor CALL LUDIR ; get directory (array of 17 byte elements) JP NZ,TPAERR ; jump on error CALL EPRINT DEFB CR,LF,'ZLUX directory for ',0 LD HL,(LFNAME) CALL EPSTR CALL CRLF CALL CRLF LD B,2 LDHDR: CALL EPRINT DEFB 'Filename Recs Size CRC ',0 DJNZ LDHDR CALL CRLF XOR A LD (LBRFLG),A LD HL,(LUBUFF) ; get start address of array PRLIBM: CALL CONDIN ; see if user typed anything JR Z,PRLBM1 ; no, continue CP CTRLC ; yes, was it control-C? JP Z,LDONE ; if Z, quit PRLBM1: LD A,(HL) ; get first byte into A OR A ; check for end of array delimiter (null) JP Z,LDONE ; if null, quit printing loop CP ' ' ; is it the first element in the library? JR NZ,N1STEL ; no, go print LD DE,17 ; yes, offset in DE ADD HL,DE ; add offset to ptr JR PRLIBM ; go get next array element N1STEL: PUSH HL ; else, save HL on stack EX DE,HL ; put filename ptr into DE for call to PFN3 CALL PFN3 ; print the name of the library member LD A,' ' ; ASCII space into accumulator CALL COUT ; print it POP HL ; restore address of array LD DE,13 ; offset to rec size in DE ADD HL,DE ; add it EX DE,HL ; put address of lib member rec size in DE CALL GETWD ; get word pointed to by DE into HL PUSH DE ; save ptr CALL PHLDC ; print rec size LD A,' ' ; print space CALL COUT LD DE,8 ; div by 8 to get size in Kbytes CALL DIVHD ; HL = HL / DE JR Z,NRMNDR ; check for remainder INC HL ; if remainder, bump up a Kbyte NRMNDR: LD A,L ; put LSB into accumulator OR H ; OR it with MSB JR NZ,NOZERO ; is it zero? INC HL ; yes, increment NOZERO: CALL PHLDC ; print result LD A,'K' ; K into accumulator CALL COUT ; print it LD A,' ' ; space into acc CALL COUT ; print it CALL COUT ; print it again POP DE ; restore ptr into array element CALL GETWD ; get word pointed to by DE into HL PUSH DE ; save ptr CALL PHL4HC ; print CRC value in hex LD A,'H' CALL COUT LD A,(LBRFLG) OR A JR NZ,NXTLIN CALL EPRINT DEFB ' | ',0 LD A,0FFH JR UNIRET NXTLIN: CALL CRLF XOR A UNIRET: LD (LBRFLG),A POP HL JP PRLIBM ; GETWD: LD A,(DE) ; get LSB of rec size LD L,A ; put it in L INC DE ; increment pointer into array element LD A,(DE) ; get MSB LD H,A ; put it in H INC DE ; increment ptr into array element RET ; ; DIVHD -> HL = HL / DE. On entry, HL = dividend, DE = divisor; on return, ; result in HL, remainder in DE. Zero flag reset if remainder ; DIVHD: LD A,D ; put LSB of divisor in A OR E ; or w/MSB RET Z ; return if null LD A,H ; get dividend in AC LD C,L CALL DIV16 ; divide EX DE,HL ; put remainder in DE LD H,A ; put quotient in HL LD L,C ; LD A,D ; reset flag if remainder OR E RET DIV16: LD HL,0 LD B,16 LOOP16: RL C RLA ADC HL,HL SBC HL,DE JR NC,$+3 ADD HL,DE CCF DJNZ LOOP16 RL C RLA RET ; LDONE: CALL CRLF JP GETCMD ENDIF DIR2: LD DE,MCMDLN ; Command line scratch PUSH DE ; Save it for PUTCL CALL STRCP ; Move HL to DE LD HL,(LFNAME) ; Our LBR's full name CALL STRCP ; Move it CALL ARCTST JR NZ,TAILT3 ; Skip the "L" is ARC file LD HL,CSTR5 ; "$L" JR TAILT2 ; Share some code ; FILES: LD HL,CSTR4 ; DIR again LD DE,MCMDLN ; Scratch PUSH DE ; Save it CALL STRCP ; Move LD HL,(LFNAME) ; get library name address into HL FILELP: LD A,(HL) ; get first byte of DU: into A LD (DE),A ; put it into MCMDLN INC DE ; increment ptrs INC HL CP ':' ; have we reached the delimiter yet? JR NZ,FILELP ; no, loop LD HL,CSTR6 ; *.LBR CALL ARCTST ; Is it an ARC file? JR Z,FILEL2 ; Zero = no LD HL,CSTR6A ; ARC file, so change string FILEL2: JR TAILT2 ; Exit via shared code ; LUX: LD A,(CMDLN+4) ; Check for Z3 help query CP '/' JP Z,HELP ; Give internal menu, else LD HL,(LFNAME) ; old LFNAME addr in HL LD DE,FCB ; FCB in DE CALL ZPRSFN ; parse it for auld lang syne CALL Z3LOG ; log into old lib's DU: LD HL,CMDLN ; Point to buffer CALL PARSER ; Parse ala' Z3 CALL SHPOP ; Deshell us JP RSTRT ; Restart LUX ; SEND: CALL ARCTST ; Is it an ARC file? JR Z,SEND1 ; No, go send it CALL ERR5 ; Can't send ARC members yet JP GETCMD ; Go get new command SEND1: LD HL,CSTR7 ; Gets us XMODEM S or KMD S TAILIT: LD DE,MCMDLN ; Our scratchpad buffer PUSH DE ; Save that for PUTCL CALL STRCP ; Move HL to DE LD HL,(LFNAME) ; The LBR's full name CALL STRCP ; Move that LD HL,CMDLN ; INLINE's buffer TAILT1: CALL SKNSP ; SHOULD put us at the right 20H TAILT2: CALL STRCP ; And trailing parm w/null TAILT3: POP HL ; Get back MCMDLN CALL PUTCL ; Give it to Z3 JP EXIT ; And boogie ; SENDK: CALL ARCTST ; Is it an ARC file? JR Z,SENDK1 ; No, go send it CALL ERR5 ; Can't send ARC members yet JP GETCMD ; Go try again SENDK1: LD HL,CSTR8 ; XMODEM/KMD SK JR TAILIT ; Same stuff follows ; TYPE: LD HL,CSTR9 ; TYPE (Sigi's TYPEL3x) CALL ARCTST JR Z,TYPE1 LD HL,CSTR9A TYPE1: JR TAILIT ; Same old stuff ; KMD: LD HL,CMDLN+4 ; KMD's parm #1 JR KMDIN ; Skip to parm tests XMODEM: LD HL,CMDLN+7 ; XMODEM's parm #1 KMDIN: LD A,(HL) ; Get first parm char CP 'S' ; Only S is kosher JP NZ,NOTCMD ; Or it's not a command INC HL ; Next char LD A,(HL) ; Into A CP 'K' ; Packet send? JR Z,XMDMK ; Branch and do that LD HL,CSTR7 ; XMODEM S or KMD S JR XMDM ; Skip and do that XMDMK: LD HL,CSTR8 ; (whatever...) SK XMDM: LD DE,MCMDLN ; Our scratchpad buffer PUSH DE ; Save that for PUTCL CALL STRCP ; Move HL to DE LD HL,(LFNAME) ; The LBR's full name CALL STRCP ; Move that LD HL,CMDLN ; INLINE's buffer CALL SKNSP ; SHOULD put us at first 20H INC HL ; Set up next SKNSP call JR TAILT1 ; Go to some shared code ; IF NOT PASSCMD PWD: LD HL,CSTR0 CALL PUTCL JP EXIT ENDIF ; ARCTST: PUSH HL LD HL,(ARCFLG) ; Point to ARC flag LD A,(HL) ; Get contents OR A ; Returns Z for no ARC POP HL RET ; IF (NOT PASSCMD) OR (NOT BYECLR) CSTR1: DB 'BYE',0 ENDIF ; CSTR2: DB 'DIR *.LBR $AD',0 CSTR2A: DB 'DIR *.ARC $AD',0 ; IF NOT PASSCMD CSTR3: DB 'CHAT',0 ENDIF ; CSTR4: DB 'DIR ',0 CSTR4A: DB 'UNARC ',0 CSTR5: DB ' $L',0 CSTR6: DB '*.LBR',0 CSTR6A: DB '*.ARC',0 ; IF KMDM CSTR7: DB 'KMD L ',0 CSTR8: DB 'KMD LK ',0 ELSE CSTR7: DB 'XMODEM L ',0 CSTR8: DB 'XMODEM LK ',0 ENDIF ;KMDM ; CSTR9: DB 'TYPE ',0 CSTR9A: DB 'UNARC ',0 ; IF NOT PASSCMD CSTR0: DB 'PWD',0 ENDIF IF EXTHLP CSTR10: DB 'TYPE A0:ZLUX.HLP',0 ENDIF ; ; ; CMDTBL (COMMAND TABLE) SCANNER (adapted from ZCPR3.Z80) ; ON RETURN, HL CONTAINS ADDRESS OF COMMAND, IF FOUND ; ON RETURN, ZERO FLAG SET MEANS VALID COMMAND ; original author: Richard Conn ; CMDSER: LD HL,CMDTBL ; Pt to command table ; CMDSCAN: LD B,6 ; Get size of command text CMS1: LD A,(HL) ; Check for end of table OR A JR Z,CMS5 LD DE,FCB+1 ; Pt to stored command FCB PUSH BC ; Save size of command text CMS2: LD A,(DE) ; Compare stored against table entry CP (HL) JR NZ,CMS3 ; No match INC DE ; Pt to next char INC HL DJNZ CMS2 ; Count down LD A,(DE) ; Next char in input command must be CP ' ' JR NZ,CMS4 POP BC ; Clear stack LD A,(HL) ; Get address from table into hl INC HL LD H,(HL) LD L,A ; Hl contains address XOR A ; Zero flag set for command found RET ; Command is resident (zero flag set) CMS3: INC HL ; Skip to next command table entry DJNZ CMS3 CMS4: POP BC ; Get size of command text INC HL ; Skip address INC HL JR CMS1 CMS5: XOR A ; Set nz DEC A ; Command not found if nz RET ; ; print help message ; HELP: IF EXTHLP LD HL,CSTR10 CALL PUTCL JP EXIT ; ELSE ; LD HL,HLPMSG CALL EPSTR JP GETCMD ENDIF ; CABORT: CALL EPRINT ; Print exit message DB 'Control-C entered. Returning to ZCPR3.',0 ; ; pop ZLUX from shell stack/restore stack/return to CPR ; CALL SHPOP JP EXIT1 ; ; Append LBR extension to HL-pointed command string ; APND: LD (HL),'.' INC HL APND1: LD (HL),'L' INC HL LD (HL),'B' INC HL LD (HL),'R' INC HL LD (HL),0 ; 'cause we might be changing LBRs PUSH HL XOR A LD HL,(ARCFLG) ; Point to Arc flag LD (HL),A ; Set it false POP HL RET ; ; Append ARC extension to HL-pointed command string ; APND2: LD (HL),'.' INC HL APND3: LD (HL),'A' INC HL LD (HL),'R' INC HL LD (HL),'C' INC HL LD (HL),0 ; 'cause we might be changing LBRs PUSH HL LD A,0FFH LD HL,(ARCFLG) ; Point to Arc flag LD (HL),A ; Set ARC flag true POP HL RET ; ; COPY HL TO DE up to null terminator ; STRCP: LD A,(HL) OR A ; have we copied null terminator JR Z,STCPRT ; yes, return LDI ; (HL) -> (DE), ++HL, ++DE JR STRCP ; loop til null terminator copied STCPRT: LD (DE),A ; put null (terminate str) RET ; return ; IF NOT EXTHLP HLPMSG: DB CR,LF,LF DB TAB,TAB,' Available LUX commands' DB CR,LF,LF,LF DB TAB,'BYE logoff computer' DB CR,LF DB TAB,'CAT display all lbr/arc files on system' DB CR,LF DB TAB,'CHAT page system operator' DB CR,LF DB TAB,'DIR display members of current lbr/arc file' DB CR,LF DB TAB,'FILES display lbr/arc files on default drive/user' DB CR,LF DB TAB,'HELP display this message' DB CR,LF DB TAB,'LUX attach to another lbr/arc file' DB CR,LF DB TAB,'SEND send a library member' DB CR,LF DB TAB,'SENDK send a library member in 1K packets' DB CR,LF DB TAB,'TYPE type an ASCII (text) lbr/arc member' DB CR,LF DB TAB,'PWD list available named directories' DB CR,LF,LF DB TAB,' Exit LUX with Control-C' DB CR,LF,LF DB ' ZLUX V' DB (VERS/10)+'0','.',(VERS MOD 10)+'0',' ' COPR DB CR,LF DB 0 ENDIF ; IF INTDIR ; allocate necessary variables for INTDIR AFNSTR: DEFB '*.*',0 ; use to insure full display of library dir LBRFLG: DB 0 LUBUFF: DW 0000H LMBRN: DS 36 DB 0 LUD: DS 6 ; data for LU troutines DS 11 ; name of current file LUDFCB: DS 36 ; FCB of library file ENDIF ; LFNAME: DW 0000H ; Pointer to lib/arc fname string ; (in Z3 Shell Stack) ARCFLG: DW 0000H ; Pointer to Arcflg byte in Z3MSG ; ; ZLUX installs SHNAME in ZCPR3's shell stack with LBRNAM as tail ; SHNAME: DB 'A00:LUX ' LBRNAM: DS 32-(LBRNAM-SHNAME) DB 0 ; Lots of room in case SHNAME is ; patched to include DIR: form ; MCMDLN: DS 48 ; Scratch buffer for Z3 command lines DB 0 ; CMDLN: DS CMDLEN+2 ; Buffer for command line editor DB 0 ; DS 64 ; Room for 32 level stack STACK: DW 0000H ; Old system stack saved here ; END