; Program: MEX+2Z ; Author: Bruce Morgen and Jay Sage ; Version: 1.3 ; Date: 23 Mar 89 ; Previous Versions: 1.2 (9 Feb 89) ; * * * IMPORTANT NOTE * * * ; ; This program is copyrighted 1989 by NAOG/ZSIG. It may be copied and ; modified freely for personal use but may not be sold or distributed ; for a fee. Modified versions must be submitted to and approved by ; NAOG/ZSIG before they may be distributed. See the file ZSIGPOL1.DOC ; on Z-Nodes for the ZSIG policy on signing out and modifying programs. ; ;______________________________________________________________________ ; ; MEX+2Z: MEX-to-ZCPR3 Chaining Program ; ; This program was derived from Bruce Morgen's MEX2Z and is designed ; to work with either MEX114 or Mex-Plus. The functions supported are ; slightly different -- hence the different name. NOTE: There are some ; significant differences from version 1.1. Please read carefully. This ; version must be assembled and run as a type-3 program. It inspects the ; byte at location 107H in the MEX that was running to determine the current ; data rate. It then restores that rate when it chains back to MEX. ; ; This program gives the MEX command 'CPM' a shell capability like that in ; the 16-bit version's SHELL command. ; ; 1) Set the real MEX.COM file so that it will not be invoked by a command ; of the form "MEX". This is done by renaming it to REALMEX.COM. ; 2) Rename your MEX2+2Z13.CIM to MEX.COM ; 3) Put both files in a directory along the ZCPR3 search path. ; On exit from MEX, MEX+2Z runs and looks for the MEX command line left in ; memory. It scans for the command "CPM", takes anything in the command after ; that, and puts it into the ZCPR3 command line with ";MEXRR" after it so that ; the MEX alias will be run again after the other commands are finished. With ; version 1.2, the baud rate constant will be passed to MEXRR as a parameter so ; that it can poke it into place so that MEX will come back at its old rate. ; If you leave MEX with the command "CPM CRUNCH FN.FT", the file will be ; crunched and then you will return to MEX. ; ;============================================================================= ; ; R E V I S I O N H I S T O R Y ; ;============================================================================= VERSION EQU 14 ; Version 1.4 December 24, 1990, Bruce Morgen ; Allow the single-character MEX command "/" as a synonym for "CPM." ; This can be implemented by patching the MEX command table or by a ; MEX read file called "/.MEX" with the single command "CPM" (or the ; undocumented "ABORTCPM" to exit MEX+ without a screen message), ; placed in the MEX "SEARCH" directory. "/.MEX" will only work if ; you have STAT EXTEND ON, of course. ;VERSION EQU 13 ; Version 1.3 March 23, 1989, Bruce Morgen ; Eliminated the need for alias or ARUNZ support. Just rename ; your actual MEX to REALMEX.COM and MEX+2Z to MEX.COM, make ; sure both are available on your Path and you're all set. ; Eliminated need for separate MEX and MEX-Plus versions -- ; one program now handles both! ;VERSION EQU 12 ; Version 1.2 February 9, 1989, Jay Sage ; I have set this up now as a type-3 program. By loading at 200H, it ; can save MEX's current baud rate and restore it when it chains back ; to MEX. ; ; If you do not want this feature, go back to version 1.1. This version ; must run as a type-3 program (recommended at an address of 200H). ; VERSION EQU 11 ; Version 1.1 December 11, 1986, Jay Sage ; Improved processing of the MEX command line to make it more reliable ; and make it work with multiple commands in MEX-PLUS. The code makes ; use of the way MEX-PLUS maintains the command line. With MEX114 the ; command line length is not stored at the beginning of the command ; line; a value of zero is stored there. Bruce's original technique of ; scanning for the terminating carriage return must be used. The MEXPLUS ; equate takes care of this. ; Version 1.0 December 8. 1986, Bruce Morgen ; Original version for MEX114. ;============================================================================= ; ; C O N F I G U R A T I O N S E C T I O N ; ;============================================================================= NO EQU 0 YES EQU NOT NO BIHELP EQU YES ; YES to include built-in help facility MEXPCL EQU 2295H ; Mex-Plus 1.65 command buffer address MEXPPTR EQU 2214H ; Address of pointer to command buffer MEXCL EQU 5A39H ; Mex 1.14 command buffer address MEXPTR EQU 5390H ; Address of pointer to command buffer CR EQU 0DH ; ASCII characters LF EQU 0AH TAB EQU 9 BELL EQU 7 TBUFF EQU 80H ; CCP Command Tail Buffer FCB EQU 5CH ; CCP Default File Control Block ;============================================================================= ; ; E X T E R N A L R E F E R E N C E S ; ;============================================================================= EXTRN EPSTR,CAPS,Z3INIT,PUTCL,$MEMRY ;============================================================================= ; ; C O D E ; ;============================================================================= ; TYP3HDR.Z80, Version 1.1 ; This code has been modified as suggested by Charles Irvine so that it will ; function correctly with interrupts enabled. ; This is header code that can be used at the beginning of a type-3-environment ; program so that it will abort with an error message when not loaded to the ; correct address (such as when a user tries to run it under CP/M or Z30). entry: jr start0 ; Must use relative jump defb 0 ; Filler db 'Z3ENV',3 ; Type-3 environment z3env: dw 0 ; Filled in by Z33 dw entry ; Intended load address start0: ld hl,0 ; Point to warmboot entry ld a,(hl) ; Save the byte there di ; Protect against interrupts ld (hl),0c9h ; Replace warmboot with a return opcode rst 0 ; Call address 0, pushing RETADDR onto stack retaddr: ld (hl),a ; Restore byte at 0 dec sp ; Get stack pointer to point dec sp ; ..to the value of RETADDR pop hl ; Get it into HL and restore stack ei ; We can allow interrupts again ld de,retaddr ; This is where we should be xor a ; Clear carry flag sbc hl,de ; Subtract -- we should have 0 now jr z,start ; If addresses matched, begin real code add hl,de ; Otherwise restore value of RETADDR ld de,notz33msg-retaddr ; Offset to message add hl,de ex de,hl ; Switch pointer to message into DE ld c,9 jp 0005h ; Return via BDOS print string function notz33msg: defb 'Not Z33+$' ; Abort message if not Z33-compatible ; --------------------------------------------------------------------------- START: JP RSTART MEXNAM: DB ';' ; Separator db 'GET 100 REALMEX.COM;POKE 107 ' BAUDPAT: DB '6' ; This will be filled in by program DB ';GO' TAILPT: DB ';MEX !!',0 DS 120 NAMELEN EQU $ - MEXNAM ENDOFN: DB ';MEX !!',0 ENDLEN EQU $ - ENDOFN RSTART: LD (STACK),SP LD SP,$MEMRY+64 ; Establish stack (so we can be sloppy later) LD HL,(Z3ENV) CALL Z3INIT ; Initialize Z3LIB. LD A,(FCB+2) ; ------------------------- Display built-in help if requested IF BIHELP ; Built-in help enabled CP '/' ; If nonzero, display built-in help JP Z,HELP ENDIF ; BIHELP ; ------------------------- Check for MEX command line in memory LD HL,(MEXPTR) ; Get pointer to command line (MEX) LD (POINTR),HL LD DE,MEXCL ; Correct value of pointer (MEX) SUB '!' ; Check for re-invocation JR NZ,FSTONE ; If not, pointer doesn't matter SBC HL,DE ; Test for MEX JR Z,FSTONE ; Proceed if we have a MEX image LD HL,(MEXPPTR) ; Get pointer to command line (MEX+) LD (POINTR),HL LD DE,MEXPCL ; Correct value of pointer (MEX+) OR A SBC HL,DE ; Test for MEX+ JR Z,FSTONE ; Proceed if we have a MEX+ image LD DE,MEXERR1 JP ENDIT ; No MEX or MEX+ image, abort FSTONE: EX DE,HL JR Z,FIRST PUSH HL ; This code executes the first time LD HL,TBUFF ; only, not on "!!" re-invocations. DEC (HL) JR Z,NOTAIL ; One character means no tail INC (HL) JR Z,NOTAIL ; Zero characters means no tail LD C,(HL) ; C has length of tail LD B,H ; H = B = 0, so BC has length INC HL ; Bump to leading blank LD DE,TAILPT ; Overlay default command line LDIR ; Do it LD HL,ENDOFN ; Point to re-invocation command LD C,ENDLEN ; We know that B = 0 from above LDIR ; Move command to buffer NOTAIL: POP DE ; Get back buffer start PUSH DE ; Save it again JR FSTINV ; Share code to finish up FIRST: ; ------------------------- Get current baud rate from address 107H LD A,(107H) ADD A,'0' ; Convert to character for POKE command CP '9'+1 ; Check for value bigger than 9 JR C,SETBAUD ADD A,'A'-'0'-10 SETBAUD: LD (BAUDPAT),A ; Save in command string ; ------------------------- Scan for exit command in the MEX command line LD A,H CP HIGH MEXPCL JR Z,GOTMEXP LD BC,126 ; Maximum command line length LD A,CR ; Search for terminating carriage return LD D,H ; Save pointer to start of command buffer LD E,L ; (in DE) CPIR ; Scan for the carriage return JR NZ,DONE ; If CPIR failed, quit OR A SBC HL,DE ; Get number of characters in command line DEC HL ; Correct by 2 DEC HL EX DE,HL LD (HL),E ; Put count into place in buffer GOTMEXP: LD B,(HL) ; Put character count into B INC HL ; Point to first character of command line LD DE,EXITCMD ; Point to exit command to scan for EX DE,HL ; Outer loop: look for initial character SCAN1: LD A,(DE) ; Get character from command line CP '/' JR Z,FOUND CALL CAPS ; Capitalize it CP (HL) ; See if it matches exit command first char JR Z,SCAN3 ; Go to check for rest of characters SCAN2: INC DE ; Point to next character in command line DJNZ SCAN1 ; Continue scan JR DONE ; If not found, we are done ; Inner loop: check rest of characters SCAN3: PUSH HL ; Save registers PUSH DE PUSH BC LD B,EXITLEN-2 ; Characters in exit command less one SCAN4: INC HL ; Bump pointers INC DE LD A,(DE) CALL CAPS CP (HL) JR NZ,SCAN5 ; Commands do not match DJNZ SCAN4 JR FOUND ; Exit command found SCAN5: POP BC ; Restore the registers POP DE POP HL JR SCAN2 ; Resume outer scan loop FOUND: EX DE,HL ; Get pointer to start of command into HL ; ------------------------- Build ZCPR3 command line ; Skip to any tail after exit command SETPTR: INC HL ; Point to next character LD A,(HL) ; Get it CP CR ; If CR, we are at end of line JR Z,DONE ; Nothing for ZCPR3 to run CP ' '+1 ; Skip over any other control characters JR C,SETPTR PUSH HL ; Save pointer for PUTCL call LD HL,(POINTR) ; Point to command line again LD C,(HL) ; Get length into BC LD B,0 INC HL ; Point to first character in command line ADD HL,BC ; Increment to termininating CR LD A,(HL) ; Verify it CP CR LD DE,MEXERR2 ; Prepare for possible error message JR NZ,ENDIT ; Report error ; Add MEX reinvocation command to end of existing ; command in MEX command buffer EX DE,HL ; To DE as destination pointer. FSTINV: LD HL,MEXNAM ; Source pointer to HL. LD BC,NAMELEN ; Length of line as counter to BC. LDIR ; Move 'em out. POP HL ; Get back command line start. CALL PUTCL ; Stuff command line via Z3LIB. JR NZ,DONE ; Trap command line failures. LD DE,MCLERR ; Point at cmd line error msg. ; ------------------------- ENDIT: EX DE,HL ; Switch string pointer into HL CALL EPSTR ; Print string pointed to by HL DONE: LD SP,(STACK) ; Restore incoming stack pointer. RET ; All done, go to Z3. IF BIHELP ; Built-in help enabled HELP: LD DE,HELPMSG ; Point to help message JR ENDIT ENDIF ; BIHELP ; ------------------------- Messages EXITCMD: DB 'CPM',0 EXITLEN EQU $ - EXITCMD MEXERR1: DB LF DB 'Can''t find MEX v1.14 or MEX-Plus v1.65 memory image!' DB cr,lf,bell,0 MEXERR2: DB LF DB 'Defect in MEX command line!' DB cr,lf,bell,0 MCLERR: DB 'ZCPR3 command line error!',cr,lf,bell,0 IF BIHELP ; Built-in help enabled HELPMSG: DB LF DB TAB,'MEX+2Z Version ' DB VERSION/10+'0','.',VERSION MOD 10 +'0' DB ' [ZSIG]' DB CR,LF,LF DB 'For MEX v1.14 or MEX-Plus v1.65.' DB CR,LF DB 'Gives a virtual shell capability' DB CR,LF DB 'to the exit commands CPM and /.' DB CR,LF,LF DB 'Any tail after the MEX command "CPM" or "/" will be' DB CR,LF DB 'detected by MEX+2Z and run as a command by ZCPR3. Then' DB CR,LF DB 'MEX will be reinvoked at its current baud rate.' DB CR,LF,LF DB 'To use MEX+2Z you must rename your MEX.COM to REALMEX.COM' DB CR,LF DB 'and rename this program to MEX.COM, with both files on the' DB CR,LF DB 'ZCPR3 Command Path. The availability of the GET and POKE' DB CR,LF DB 'commands is assumed.' DB 0 ENDIF ; BIHELP DSEG POINTR: DS 2 STACK: DS 2 END