Description of kernel-supoorted swapping of FreeCOM -- 2001/01/21 ska ===> Please also read VSPAWN.TXT. This sort of swap is incompatible with XMS-Only swap! === Preface This technique is an experimental implementation of a general purpose swap technique applyable to FreeCOM that does not require any special support of the kernel. It will therefore not support swapping in any circumstances and is intended to work as a "boot-through" shell for memory hungry programs, which normally don't require no function of a resident shell. === Supported Swappings The swapping is activated via the CALL command in this way: C> CALL /S prg [{ args }] The /S switch forces the swapping mechanism to be activated on executation of the next command. Swapping is NOT supported in: - secondary shells or other programs, - pipes, e.g. CALL /S prg1 | prg2, nor prg1 | CALL /s prg2 , - conjunction with redirections, e.g. CALL /s prg shut down computer. The argument structure is made known to the system via an interrupt call, here are the specs: DOS-4B-FD: Set Segment of Argument Structure AH = 0x4B AL = 0xFD BX = segment DX = 0x4446 == 'FD' (magic number) Return: Carry == 1 on error (see below) Carry == 0 on success BX := _previous_ segment DOS-4B-FE: Get Segment of Argument Structure AH = 0x4B AL = 0xFE DX = 0x4446 == 'FD' (magic number) Return: Carry == 1 on error (see below) if AX == 5 (Access Denied) --> BX := current segment Carry == 0 on success BX := current segment Note: If DEBUG was enabled during compilation of KSSF && Carry == 0, AX := PID of KSSF Only one process may use these functions, any other process gets the error 1 (invalid function). Therefore the primary shell MUST invoke DOS-4B-F? to lock this function for other processes. Secondary shells may use DOS-4B-FE/Carry/AX==5 to detect a context of the primary shell and re-use it's critical error handler. If segment == 0, no segment has been assigned so far. The kernel interpretes this situation as prg == NULL && shell == NULL. FreeCOM performs a swap-out request as follows: + Parse a "CALL /S prg argument" as "CALL prg arguments", but enable the flag swapOnExec. + Eventually the interpreter reaches the "exec()" function, that executes an external command. At this point all the remaining command line has been broken into the external program's name and it's command line. If at this point the flag "swapOnExec" is true, the argument structure is prepared and FreeCOM terminates with a DOS-4C API command. + Whenever FreeCOM is to read "the next input line" from whichever media is currently active, the flag is deactived, thus unless the CALL/S command is immediately followed by an external program, this switch is ignored completely. Because the shell provides two core functions, the Critical Error handler and the ^Break handler, which are not always included within every program, both handlers must be installed residently even if the primary copy of FreeCOM unloads on a swap request. That's why both handlers are installed when FreeCOM loads the first time and FreeCOM's own previous handlers are settings are tweaked in such way that when FreeCOM terminates for swapping, the addresses of the installed handlers are copied back into the system and, thus, furtherly re-used for both the external program and the re-invoked shell. FreeCOM knows two variants of the Critical Error handler: Type 1: displays the known menu Abort/Retry/Ignore/Fail. Type 2: is installed when the primary copy had been invoked with the /F switch == AutoFail. In this case the handler will automatically return "Fail" for all and any Critical Error. This variant is much smaller (about 5 bytes rather than approx. 390 bytes), but may cause unexpected and unretraceable behaviour. FreeCOM installs a ^Break handler, that will always "Abort" the program. This is required in order to make the handler independed on the context, in which it is triggered, aka if within FreeCOM or a spawned program. In most circumstances the external program spawned by a swaped-out FreeCOM will get the same PID as FreeCOM itself.