RSXMAKERDOCRSX COMRSXTEM ASM AYRSXINFO TXTMX RSXMAKER User's Guide Copyright (c) 1986 by AutoSoft Incorporated This software may be used for non-commercial purposes only. No commercial use may be made of RSXMAKER or any utilties produced by RSXMAKER without the express written permission of AutoSoft Incorporated. AutoSoft Incorporated 166 Santa Clara Avenue Oakland, CA 94610 (415) 658-2881 For assistance with this or other AutoSoft products, use the AutoSoft Customer Service ModemMail BBS at (408) 336-8080. Post mail to SYSOP. 1 INTRODUCTION 1.1 WHAT IS AN RSX? RSX stands for "Resident System Extension". What this means is that an RSX is an extension to the operating system (in this case CP/M-80) that resides in memory along with the operating system. Usually an RSX is used to provide a facility or capability which the operating system lacks in such a way that transient programs are unaware of the change. Facilities that might be added to CP/M-80 through the use of an RSX include print spoolers, keyboard macros, remote consoles, access control to disks/user areas, etc. RSX's operate by relocating themselves in memory to a location just below CP/M's CCP (Console Command Processor), which allows other programs to run in the normal way without interfering with the RSX. Some other utility programs operate in this way, co-residing with a transient program and the operating system in memory. Usually, these utilities do not tolerate the presence of another such utility very well. An RSX, however, is specifically designed to allow many RSX-based utilities to be present in memory together, and either cooperate or ignore each other, as required. Thus, an access control RSX can be combined with a remote console RSX, for example, to create a secure remote CP/M system. If the access control is not needed, that RSX is simply not loaded. 1.2 RSX MEMORY MANAGEMENT RSX's are loaded just under the CCP, each succeeding installation loading its RSX just under the previous one. Thus, as more RSX's are installed, the available TPA (Transient Program Area), the space available for normal programs, gets smaller and smaller. The RSXMAKER, when it removes an RSX, reclaims the memory used by that RSX by shuffling the remaining RSX's up in memory after the removal. This is unlike other RSX-type systems, which merely mark an RSX for removal, waiting until all those below it in memory are also marked for removal before removing the whole lot. 1.3 RSX CONTROL FLOW An RSX's code executes by intercepting BDOS calls from transient programs, effectively "hitching a ride" on the operating system. The last-installed RSX always gains control first, and when it is done, passes control either back to the transient program or on to the next RSX between it and the BDOS. If all the RSX's allow control to pass upward, eventually the BDOS will get the request. This allows RSX's to modify system behavior independent of the transient program being executed. 1.4 WHAT IS IN THIS PACKAGE? This package includes a utility program to allow easy construction of RSX's of your own, and to manage a collection of RSX's in memory. The program RSX.COM allows you to install and remove RSX's as well as show information about currently resident RSX's. It also allows you to create self-installing RSX's of your own so that you needn't use the RSX.COM program to use the RSX. Also included is a template RSX source file with all the standard routines already coded so that you can devote your efforts to the function of the RSX you are building rather than the details of the RSX implementation. 2 THE RSXMAKER UTILITY (RSX.COM) 2.1 RSX COMMANDS The RSXMAKER, RSX.COM, accepts arguments on the command line as shown below. All of the commands may be shortened to a single character (e.g. SHOW can be entered as S). A>RSX No arguments - displays a help screen A>RSX SHOW Displays information about the RSX's currently resident in memory. Information includes the base address, name, description, and control flags for each RSX. A>RSX INSTALL filename Installs the RSX contained in the file specified. The file must have a filetype of .RSX, and must have been prepared as described in the section on creating an RSX. A>RSX REMOVE rsxname Removes the specified RSX from memory, relocating any remaining RSX's so as to reclaim the memory space used by the removed RSX. A>RSX MAKE filename Creates a .COM file which, when executed, installs the RSX contained in the specified file. The file must have a filetype of .RSX, and must have been prepared as described in the section on creating an RSX. The .COM file's filename is derived from the RSX NAME string contained in the RSX header. 2.2 FILE NAMING CONVENTIONS It is not necessary that the file containing an RSX have the same name as the RSX. It is, however, advisable to make them the same in order to avoid confusion. Since the RSX name is a maximum of eight characters and so it a CP/M filename, this recommendation should place little hardship on the implementor. The filetype .RSX is reserved for RSX files to be used as input to the RSXMAKER. They would otherwise be .COM files, being the product of LOAD. The renaming is required to help avoid the incidence of installing a .COM file which is not an RSX -- this usually crashes the system. 3 CREATING AN RSX An RSX consists of two major pieces: the RSX header and the RSX code. 3.1 THE RSX HEADER The header contains information required by the RSXMAKER for installation and relocation of the RSX. The majority of the header need not be altered from that found in the template RSX RSXTEM.ASM. Those fields which are of interest to the RSX creator are discussed below. 3.1.1 THE RSX HEADER FLAGS The RFLAGS word contains bit flags used by the RSXMAKER. Depending on the purpose of your RSX, you may want to include or leave out some or all of the flags. The flags and their functions are listed below. FIRST This flag is set by the RSXMAKER in the RSX residing in the highest memory location. It is cleared by the RSXMAKER in RSX's residing in other locations. LAST This flag is set by the RSXMAKER to mark the RSX residing in the lowest memory location. It is cleared by the RSXMAKER in RSX's residing in other locations. NOREMOV If this flag is included in the RFLAGS word, the RSXMAKER will not remove the RSX even if it is commanded to do so. This might be desirable, for example, in an RSX performing password control. MULTI If this flag is included, the RSXMAKER will load additional copies of an existing RSX on subsequent install requests. If this flag in not included, multiple install requests of the same RSX will not result in additional copies being placed in memory. REINIT If this flag is set, each install request for an existing RSX causes the initialization routines of those already in memory to be executed. NOMORE If this flag is set, the RSXMAKER will not load any more RSX's after this one. This might be useful in a situation where the RSX is performing vital security functions which could be compromised by another RSX. NORELO If this flag is set, the RSX will not be relocated in the event of an RSX in upper memory being removed. This will result in the memory used by the removed RSX not being reclaimed. This might be needed in an RSX which is referenced by other software which could lose track of the RSX if it moved in memory. RELINI This flag is an alternative, although not a required one, to the NORELO flag. If this flag is set, after relocation, the RSX's initialization will be called, allowing the RSX to adjust to its new location, if required. OVRLAY This flag causes the RSX to overlay the CP/M CCP if it is the first one installed. This might be useful in applications where a maximum amount of memory is needed. Note that no commands may be issued after RSX installation, since the CCP is no longer in memory. The flags are inserted in the RFLAGS word by specifying them in a series separated by "+" signs. For example, if I wished my RSX to be re-initialized upon subsequent install attempts and when relocated, I would edit the RFLAGS declaration to be as shown below. RFLAGS: DB REINIT+RELINI ; Init on install and relocate 3.1.2 THE RNAME AND RDESC FIELDS The RNAME string is the name by which the RSXMAKER will recognize the RSX. This string *must* be eight characters long, must be padded with spaces on the right, must be uppercase, and may not contain any embedded spaces. The following list of valid and invalid RSX names exemplifies these constraints. Valid RSX Names Invalid RSX Names "REMOTE " "remote " lowercase not allowed "MYRSX " "MY RSX " no embedded spaces "SECURITY" "SECURITYRSX" too long "ACCESS " " ACCESS" spaces on left "THERSX " "THERSX" no padding to 8 chars The RDESC string may be of any length, although a maximum of about 16 characters is probably a practical limit. This description string is displayed by the RSXMAKER's SHOW command. The RDESC string is null-terminated, meaning it must end with a byte of zero. An example is shown below. RDESC: DB 'This is the description',0 ; Note null terminated 3.2 RSX CODE SECTION The code of an RSX consists of four routines, which are called at various times throughout the life of the RSX. o The Initialization Routine o The Termination Routine o The BDOS Intercept Routine o The WBOOT Intercept Routine Depending on the purpose of your RSX, one or more of these routines may be altered from the default routines provided in the template RSX. 3.2.1 THE INITIALIZATION ROUTINE The initialization routine is called after the RSX is loaded, if the REINIT flag is set, on subsequent installs of the same RSX, and, if the RELINIT flag is set, whenever the RSX is relocated in memory. In the template RSX, the initialization routine just writes a message to the console indicating that the RSX has been successfully installed. A print spooler RSX might use the initialization routine to locate the filename in the CP/M default FCB at 5CH and open the file. 3.2.2 THE TERMINATION ROUTINE The termination routine is called just before the RSXMAKER removes the RSX from memory. In the template RSX, the termination routine merely issues a message stating that the RSX is terminating. If your RSX altered any CCP, BDOS, or BIOS addresses, this routine could be used to undo the alterations. 3.2.3 THE BDOS INTERCEPT ROUTINE This routine gains control whenever a transient program issues a CP/M BDOS call. The function number is contained in C, and the parameter, if any in E or DE. This routine allows you to alter or monitor the behavior of BDOS functions, and to add new functions of your own. Note that in returning from a new function, you should obey the CP/M BDOS conventions for register usage described in the CP/M 2.2 Interface Guide. The template BDOS intercept routine switches to a local stack and then passes the call on to the next RSX, or the BDOS, using a JMP NEXT, taking no action. Note that you should never CALL 0005 from within an RSX, but rather use CALL NEXT instead, giving the RSX's higher in memory a chance to intercept the function also. Generally, passing the function through location 0005 will result in an endless loop as the RSX repeatedly traps the call and passes it back through location 0005. This is perhaps the most potentially useful routine in the RSX code section. 3.2.4 THE WBOOT INTERCEPT ROUTINE This routine is called whenever a BDOS function zero is passed to the BDOS, and whenever control is passed through the warm boot vector at location 0000. The template routine, if the RSX is FIRST (i.e. it is the last in the RSX chain), issues a disk reset and reloads some addresses in low memory, mimicking the expected BIOS warm boot activity. You might find it useful, in a hard-disk environment, to dipense entirely with the disk reset, which will markedly speed up the warm boot function. Note that the BIOS warm boot code is never called; control is merely passed back to the CCP after all the RSX;s have had a chance. 3.3 CODING NOTES A number of items must be kept in mind by the RSX programmer. 3.3.1 USE OF THE 8080 INSTRUCTION SET The relocation system currently does not recognize Z80 opcodes. Thus, RSX's must be written entirely in 8080 assembly code. 3.3.2 USE OF THE LXI INSTRUCTION Since it is impossible for the relocation code to determine whether the operand of an LXI instruction is a value or an address, assuming that the value lies within the address range being relocated, the RSX programmer should never load a value into a register pair with the LXI instruction. Only addresses should be loaded using the LXI instruction. Instead of the LXI instruction, use two MVI instructions as shown below. ; LXI D,035AH ; Don't use LXI to load values MVI E,5AH ; Instead, use two MVI's MVI D,03H ; Thusly 3.3.3 USE CALL NEXT FOR BDOS ACCESS Never use CALL 0005 to issue BDOS calls. Use instead CALL NEXT, which obeys the RSX chaining rules. 3.3.4 ALWAYS USE A LOCAL STACK Always switch to an RSX-local stack before doing any processing. Use the code shown in the template RSX to do this. 3.3.5 DO NOT MIX CODE AND DATA The RSXMAKER's relocation routines will not properly relocate data which is embeeded within a code segment. Thus in-line print routines which require the text to be printed to follow the CALL to the print routine may not be used within an RSX. Only code is allowed between the labels RSXCODE and RSXDATA in the RSX template, and only data is allowed between the labels RSXDATA and RSXEND. 3.4 BUILDING THE RSX 3.4.1 STEP BY STEP Follow the steps described below in building your RSX. 1. Make a copy of the RSXTEM.ASM template file with the name you plan to use for your RSX. 2. Edit the new template file to accomplish the functions required of your RSX. 3. Assemble the .ASM RSX source file. 4. Create a .COM file from the assembler's output using LOAD.COM. 5. Change the filetype of the .COM file to .RSX using the REN command. 6. Install the RSX with RSXMAKER and test its function. 7. Repeat steps 2 through 6 until the RSX is functioning properly. 8. User RSXMAKER's MAKE command to create a self-installing RSX. 3.4.2 EXAMPLE USING RSXTEM The following is an example using the supplied RSXTEM template RSX to demonstrate steps 3 through 8 above. A>ASM RSXTEM Assemble the template source CP/M ASSEMBLER - VER 2.0 0205 002H USE FACTOR END OF ASSEMBLY A>LOAD RSXTEM Create .COM file from .HEX FIRST ADDRESS 0100 LAST ADDRESS 0204 BYTES READ 00F5 RECORDS WRITTEN 03 A>REN RSXTEM.RSX=RSXTEM.COM Rename the .COM to .RSX A>RSX INS RSXTEM Install using RSXMAKER Template RSX initialized. Initialization message A>^C Warm boot Template RSX active. Warm boot message A>RSX SHO Show installed RSX's Base Name Description ---------------------------------------------------------------- D200 RSXTEM AutoSoft RSX Template (first last reinit multi) A>RSX REM RSXTEM Remove the RSX Template RSX terminated. Termination message. A>RSX SHO Show installed RSX's There are no RSX's installed. A>RSX MAKE RSXTEM Make self-installing RSXTEM RSXTEM.COM created. A>RSXTEM Test self-installing RSXTEM Template RSX initialized. Initialization message. A>RSX REM RSXTEM Remove it Template RSX terminated. Termination message. "u1!l\[!~ʋ O#~ ) ʋ I@SR~MË p*u>2o*! µ#^#V+ ʏ)~@P2oP)~OG:o2oyʱPyÃ:o¿e"*"!*j}$L*! *:2 . )~w":2|g"m*"#~2#~2y*m*#*m }|*m"*meé RSX!hw#v!he[\ File not found. e*k"k\ʭ\ɯ2}*"{*{! :}#~2{#~2| + 3ͭ ()~O#G first yV last yg reinit yw multi yʉ noremov y ʚ ovrlay y@ʫ nomore yʼ norelo Ny relini ) :}© There are no installed RSX's. é Base Name Description -------------------------------------------------------------------------- >2}*"!"*! **s#r#"#~2#~2+] ˆ)~O o is non-removable.   )~Oy¿) ~3* ~w ^#V* s#r #^#V* #s#r #^#V* #s#r *)~O|2y¥* * #s#r** #s#r>2*#*" }| #^#V")~w#^#V*#s#rN#F*#q#p #~2#~2é 2*+V+^+"!^#V}+$.*F+N+"! ^#Vj."y2x2*~2+~2*j:*BK**)#~ʏ*:*. RSX not found in memory. ""!q#p* #^#V"*"*#^#V"*#~22#~22* #^#V*j*"**j*"*"""*#~2#~2* #^#V"*"*":2*"!1&.6>**j"**j"**j"***MD*+ ~{1*MD*~#{1$*"*}!# F!j# T*+"*w*++"*##"8*+++"*#"og""*j*j|ʹú***s#r#"*8*##"*8p*!yj}$.|G>2!C"!hw# !][! e[\ o .COM already exists. Replace (y/n)? Yʪ N  No RSX Make aborted. é  o Yes \\ No directory space available e!"k*k"k\?  \ o .COM created. é Insufficient space available on disk. é !]~ _#t COM RSXMAKER V1.00 for CP/M-80 V2.2 Copyright (c) 1986 by AutoSoft Incorporated This software may be used for non-commercial purposes only. No commercial use of RSXMAKER or utilities produced using RSXMAKER may be made without the express written permission of AutoSoft Incorporated. RSXMAKER COMMANDS Text enclosed within brackets ([]) is optional. RSX I[nstall] filespec Install an RSX in memory. The filespec must have a filetype of ".RSX". RSX R[emove] rsxname Remove the named RSX. RSX S[how] Display a list of all RSX's currently installed. RSX M[ake] filespec Create an self-installing RSX from the given .RSX file. *u~ _#ð  # ^# ~#_ |-}-#~-~-GG6xƐ'@'_h ~#^{/_z/W RSX from the given .RSX file. *u~ _#ð  # ^# ~# |-}-#~-~-GG6xƐ'@'_h ~#^{/_z/W AutoSoft12345678;++ ; RSXTEM - RSXMAKER RSX Template ; ; Copyright (c) 1986 by AutoSoft Incorporated ; ; See RSXMAKER.DOC for information. ; ;-- ;+ ; RSX Header RFLAGS Flag bit definitions ;- FIRST EQU 1 ; First RSX installed LAST EQU 2 ; Last RSX installed NOREMOV EQU 4 ; RSX may be removed REINIT EQU 8 ; Re-initialize on subsequent installation requests MULTI EQU 16 ; Install another copy on subsequent installs OVRLAY EQU 32 ; Overlay CCP if first RSX installed NOMORE EQU 64 ; No more RSX's may be installed NORELO EQU 128 ; Do not relocate this RSX RELINI EQU 256 ; Call INIT routine after relocation ;+ ; RSX Header Section begins here ;- ORG 100H ; Origin *must* be at 100H ;+ ; Do not modify these 14 fields ;- RSX: JMP RSTART ; Jump to real code (jumped to from 0005) RSXRST: JMP RESET ; Reset handler RINIT: JMP INIT ; Initialization code RTERM: JMP TERM ; Termination code RELST: JMP RSXCODE ; Start of relocatable code DATAST: JMP RSXDATA ; Start of data section (copied as is) RELEND: JMP RSXEND ; End of RSX code and data to be relocated NXTWB: JMP $-$ ; WBOOT path (filled in by RSXMAKER) NEXT: JMP $-$ ; BDOS path (filled in by RSXMAKER) WBADR: DW $-$ ; Filled in by RSXMAKER WBJMP: DW $-$ ; Filled in by RSXMAKER RSIZE: DW RSXEND-RSX ; Size of RSX code and data RSXID: DB 'AutoSoft' ; ID - Must be 'AutoSoft' ;+ ; The next three fields may be modified by the RSX programmer ;- RFLAGS: DW MULTI+REINIT ; RSX flags (combine with +) RNAME: DB 'RSXTEM ' ; Name - must be 8 bytes - pad on rt w/spaces RDESC: DB 'AutoSoft RSX Template',0 ; Description (null terminated) ;+ ; RSX Code Section begins here ;- RSXCODE EQU $ ; Executable code *only* between here ; and RSXDATA (no in-line prints allowed) ;+ ; Initialization Routine (end with RET) ;- INIT: ; This *must* be the label MVI C,9 ; Just write a message to the console LXI D,INITMSG ; CALL NEXT ; RET ; And return ;+ ; Termination Routine (end with RET) ;- TERM: ; This *must* be the label MVI C,9 ; Just write a message to the console LXI D,TERMMSG ; CALL NEXT ; RET ; And return ;+ ; BDOS Intercept Routine (end with JMP NEXT or RET) ;- RSTART: ; This *must* be the label LXI H,0 ; Clear HL DAD SP ; Get current stack pointer SHLD USRSTK ; Save it LXI SP,LOCSTK ; Switch to local stack PUSH D ; Save environment PUSH B ; PUSH PSW ; ;******************************************************************** ; Insert function-specific code here ;******************************************************************** POP PSW ; Restore environment POP B ; POP D ; LHLD USRSTK ; And stack pointer SPHL ; JMP NEXT ; Pass control to next RSX ;+ ; WBOOT Intercept Routine (end with JMP NXTWB) ;- RESET: LXI SP,LOCSTK ; Local stack MVI C,9 ; Write a message LXI D,WBMSG ; CALL NEXT ; LHLD RFLAGS ; HL = flags word MOV A,L ; Low byte ANI FIRST ; First? JZ NOT1ST ; If Z, no MVI C,13 ; Disk system reset CALL NEXT ; (you might want to comment this and the ; previous line out to speed up warm boots) NOT1ST: MOV A,L ; Get flags ANI LAST ; Last? JZ NOTLST ; If Z, no LXI H,RSX ; Else reload BDOS vector SHLD 0006 ; LHLD WBJMP ; HL -> WBOOT vector in BIOS jump table SHLD 0001 ; Insert WBOOT vector INX H ; Point past JMP LXI D,RSXRST ; Our WB address MOV M,E ; Copy it into BIOS jump table INX H ; MOV M,D ; NOTLST: JMP NXTWB ; And pass control to next RSX (or CCP) ;+ ; RSX Data Section ;- RSXDATA EQU $ ; Data *must* start here - no data ; allowed before this point; no executable ; code beyond. WBMSG: DB 13,10,'Template RSX active.$' TERMMSG: DB 'Template RSX terminated.',13,10,'$' INITMSG: DB 'Template RSX initialized.',13,10,'$' DS 16 ; 16-byte stack LOCSTK: ; Initial SP USRSTK: DW 0 ; Caller's SP RSXEND EQU $ ; No code or data allowed beyond this label RSXMAKER Information 22-Feb-86 RSXMAKER is an internal tool of AutoSoft Incorporated, the creators of the ModemMail CP/M BBS/Email/Gateway communications program. RSXMAKER was created to allow the easy creation of memory-resident utilities to be used in remote-access ModemMail applications. The tool is so generally useful that we decided to release it for non-commercial use. AutoSoft will be releasing for non-commercial use a set of remote-access utilities as well as other utilities in the near future as examples of RSXMAKER's capabilities. AutoSoft's Customer Service ModemMail BBS is alive 24-hrs/7days at (408) 336-8080. The BBS regularly collects USENET news relating to CP/M, data communications, and data encryption. The BBS system is powered down between calls , so be patient when you call while it boots up and gets going. We hope you find RSXMAKER a useful tool. AutoSoft Incorporated