22RSX: a Resident System Extension facility for CP/M 2.x Copyright (C) 1984 by James H. Whorton All rights reserved ***************************************************************** * This documentation and all files included in this system * * (see list in Introduction) may be freely exchanged provided * * that such exchange is non-commercial and that the copyright * * notice is wholly retained. No commercial use of this * * document or any of the files listed is permitted without * * the express written permission of the author. * * Anyone wishing to modify this system for re-release should * * contact the author before doing so. * ***************************************************************** The author may be contacted by one of the following methods... Mail: James H. Whorton PSC #1 Box 36 Offutt AFB, NE 68113 Modem: OBBS Remote CP/M Facility (402) 346-4206 Leave message or comment to SYSOP. QX-10 Remote System (402) 393-5246 Leave message addressed to James Whorton 1. Introduction 22RSX is a facility to allow the installation and removal of Resident System Extensions. Briefly, an extension is an addition to BDOS that can monitor, trap, alter or process any BDOS call made from an applications program. This came about after I had worked a bit with CP/M 3.0. It's RSX facility impressed me with the fact that it made it relatively easy to 'patch' the operating system to add things such as remote consoles, print spoolers, etc. Since I had some experience with CP/M, I decided to write a similar system for CP/M 2.2. Note: I realize that there is an RSX manager written by Jim Lopushinsky for CP/M 2.2. I have never used it, but from what I have seen and read, it seems to require a fair amount of work with DDT, M80, etc. This system, on the other hand, takes care of all installation. All you have to do is write a module, insert it in the driver, assemble, load and run! And your finished product will, assuming that it uses standard CP/M calls and procedures, run on any other CP/M system without modification. This system, as distributed, consists of the following files: 22RSX.OBJ -------> The RSX manager module. 22INSTA.ASM -------> The main driver file. 22INSTB.ASM -------> The second driver file. 22REMOVE.OBJ -------> The module removal program. 22RSX.DOC -------> Documentation. LASM.OBJ -------> Linking assembler needed by system. EXPTABS.ASM -------> A demonstration module. CONSOLE.ASM -------> Another demonstration module. CONSTAT.ASM -------> The companion access program for CONSOLE.ASM. MAKE.SUB -------> Submit file for assembling RSX modules. 22RSX.NOT -------> Short version of this file list. 2. Theory of operation When 22RSX is run, assuming that it has not been previously installed, it loads itself into high memory, storing some addresses and pacthing itself in. The manager remains resident for as long as any RSX modules are present, intercepting warm boots and doing other housekeeping chores. More on it's functions later. Let's say that you have assembled an RSX module following the directions given in section 4. You now run the assembled file. The driver code checks to see if the manager is present. If so, it proceeds to add the RSX to the environment. First the module is relocated to a point just underneath the last module or manager. This is done a byte at a time. When the code is moved, a second routine goes through it and checks for addresses. Each address that falls within the module code is adjusted to compensate for the relocation. Once that is done, there are several addresses that must be patched. First the PREV field of the module last installed (before this one) is loaded with the address of our new module. Then the NEXT field of the current module is loaded with the address of the next module. Now the BDOS vector at location 0005 is patched with the new module address, making it the first in line. WMLOC, the address in the warm boot routine that we found earlier, is patched with the new module address to our new BDOS vector from being overwritten by the next warm boot. Now that the patches are finished, a brief summary of what has occured is printed, then the program returns to CP/M. Modules may be removed by using the 22REMOVE program, or by utilizing the manager call (see section 3 for details.) The 22REMOVE program may selectively remove modules one at a time, or it may remove the manager and all modules, restoring the system to the condition that we found it in. When it removes one module, if the module was the last to be installed (first in line) then when the BDOS and WMLOC addresses are patched the portion of the TPA previously used by the now deleted module will be freed up for user programs. The BDOS vector is simply changed to the address of the NEXT module and everything is fine. If the module is inside the chain (not top or bottom) then the previous module NEXT field is loaded with the current module NEXT address and the next module PREV field is loaded with the current module PREV address. The module is now effectively deleted from the chain. Note that the TPA used by the module is not reclaimed until all modules preceeding it have also been removed, or the entire environment (manager and modules) have been deleted. 3. RSX modules This section deals with how to write an RSX module for use with this system. A section on using Manager calls follows the RSX formulation discussion. An RSX must follow a specified format in order to work properly. Each RSX consists of two(2) major parts. Prefix This system accepts RSX's written in the standard DRI format, which includes the prefix. This header MUST preface every RSX module. The format is as follows: serial: db 0,0,0,0,0,0 ;Space for CP/M 3.0 serial # (not ;used by this system.) start: jmp rsxstrt ;This is the jump to the beginning ;of the module itself (skips past ;the rest of the prefix. next: jmp $-$ ;This address is patched by the ;loader and points to another RSX ;or the BDOS jump table. prev: dw 0 ;The loader will patch in the address ;of the previous module or BDOS. remove: db 0 ;Remove flag (0=remain resident, ;0FFh=remove at next warm boot.) nonbank: db 0 ;Flag for CP/M 3.0 (not used). name: db 'RSXNAME ' ;This is the name of the RSX ;module. It MUST be 8 characters in ;length. Pad with spaces as needed. loader: db 0 ;Flag for CP/M 3.0 (not used). db 0,0 ;Reserved for system use. Code The module code comes next. At present the loader routine will only recognize 8080 instructions, so your module must be written in 8080 code. Generally the first thing you will want to do on entry is to check for whatever function(s) you wish to work with. If the function being called is not one you are interested in, you can simply pass the call along with a JMP NEXT. If you didn't pass out of the routine then the function must be one you're looking for. Before doing any processing it is a good idea to save the stack pointer and registers and . A illustration of this is shown below. lxi h,0 dad sp shld userstk ;save stack pointer push d ;save regs. push b Now do whatever processing you wish to. The most important thing to remember is to use NEXT to access BDOS calls from inside the module. Example (outputs char to the console): mvi e,'X' ;load regs mvi c,02 call next If you call location 05 (the BDOS vector) instead of calling NEXT your call will be intercepted again and... There are several ways to exit a module. If you wish the trapped function call to execute, then restore the stack pointer, and and do a JMP NEXT. Example: lhld userstk ;restore stack sphl pop b ;resore regs pop d jmp next ;continue with the call If you have provided alternate processing in place of the function and wish to return directly to where you came from, restore the stack and regs as above, set the result regs as desired and do a RET instead of a JMP NEXT. Still not sure about something? Check out the two sample modules included with this package. They should provide some helpful ideas. Manager Calls Version 2.0 offers four(4) manager functions that may be called from an application or RSX module. To use the calls, load with 59, Call RSX Manager, then load according to the following specifications: -->>DE=0 Remove inactive RSX's, that is, those whose REMOVE flags have been set to 0FFh. See next function description to see how to do this. (This functions the same as CP/M 3.0. It is called automatically called on every warm boot.) -->>DE=1 This request causes the manager to place WMLOC in DE and return it to the user. (The install- ation driver uses this.) This function should be used to check to see if the manager is resident. -->>DE=(address) Set the remove flag of the RSX whose name is pointed to by DE. DE must be an 8-byte block corresponding to the NAME field of the RSX mod- ule. If found, the remove flag will be set to 0FFh causing the RSX to be removed at the next warm boot. (Note: 22RSX, which is the name reserved for the RSX manager, may not be used.) -->>DE=0FFFFh This signals the manager to remove itself and any RSX's installed, restoring the system to the condition it was found in. Now execute a normal CALL BDOS(0005). On entry, should be set to zero. The result code for the called function is then returned in . A value of 0FFh signals a successful operation, while a value of 00h indicates an error has occurred or that the manager has not been installed. 4. Implementation Software needed: -> A text editor. -> LASM.COM (supplied) -> LOAD.COM -> SUBMIT.COM -> MAKE.SUB (supplied) -> 22INSTA.ASM, 22INSTB.ASM (supplied) -> An RSX source code module. The procedure to implement a properly written module is fairly simple. a. Using an editor, such as WORDSTAR, call up the RSX module file. Go to the end of the file. Now type in a line that reads... LINK '22INSTB' This line MUST be the last line in the module file. Ensure that there is not an END statement there. If so, delete it or comment(;) it out. Now save the file and exit. b. Ensure that the .SUB file and all source files are on the proper drive. (The .SUB file as configured specifies A. This may be adjusted as desired.) Now run the MAKE.SUB file, which will automate the process somewhat. The syntax is... SUBMIT MAKE module-name You should now have a .COM file ready to run. c. First run 22RSX to install the RSX manager, then run the file. It will anounce itself, install the RSX into the system and present a few vital statistics. The RSX is now part of the system environment and will remain so until removed. And that's all there is to it, folks. You don't have to know a thing about your particular CP/M setup (CCPLOC, BDOS vector, size) unless you want to do something in the module that requires a certain parameter. 5. Thoughts For those of you who are unfamiliar with the RSX concept and want to learn more, I recommend the following articles: "Resident System Extensions Under CP/M Plus" Gary M. Silvey Dr. Dobbs Journal #93 July '84 "Resident System Extensions (RSX)" Ronald G. Fowler Microsystems Vol. 5/# 2 February '84 Please direct any bug reports to me via one of the methods mentioned on the title page. And if you write any modules and release them I'd appreciate it if you could upload a copy. That way I can keep an up-to-date library for downloading. I hope that you enjoy using this system. I feel that it is useful and should provide a conveinent way to add utilities and features to any CP/M system. James H. Whorton October 13, 1984