* remove all use of the 0x40000 ghost space,
* use a special trick to make interrupt handlers work (see below for details).
A patched version of SMQ is available here.
Here are the details:
TitaniK (Titanium Kernel) 0.12 by Kevin Kofler==============================================This is a fork of Patrick Pélissier's PreOs which targets the TI-89 TitaniumWITHOUT any patches (HW2Patch or the like). It is NOT a TSR, but a launcher. Italso adds code to (temporary copies of) the programs it executes, so it won'twork for programs which are excessively close to the file size limit (more than56 KB in this implementation).Usage: titanik("yourprog") See PreOs.txt for details about PreOs.List of known unsupported PreOs features in TitaniK 0.12:* Support for non-Titanium calculators* Everything requiring a TSR: SHIFT+ON support, AMS error intercepting, automatic nostub crash protection, ...* Crash protection* Passing command-line parameters to the programs. (I need to add more estack handling to the auto-exec feature.)* Running _nostub programs through kernel::exec.* Programs >56 KB.* Programs/libraries which would require >8 KB of stubs/callers/receivers.* Programs which require all the RAM. (The stubs take away part of it.)* Programs which require all the stack. (The stubs need lots of it.)* The (un)reloc(2) functions won't work if you don't reserve enough room for the stubs at the end of the handle (NOT counted in the file size). (Note that you also have to account for the execution protection if you want to use (un)reloc(2)...)* Read-only libraries. (The relocation code currently adds at least a receiver to all libraries. For read-only libraries to work, this has to be skipped for them.)* Indirect function calls (lea ...,%a0;jsr (%a0)) to libraries or to RAM_CALLs.* Nonstandard (e.g. huge structure by-value returns) or excessive (>60 bytes) stack parameters to libraries or RAM_CALLs.* Archive packs. (Uncompressed files need to be copied to add the stubs, compressed ones need TitaniK to call the uncompressor through a receiver.)* Custom interrupt handlers that survive over a libcall or return-from-lib. Anything using such interrupt handlers needs to be ported to use the graphlib hack.* Programs relying on libcalls keeping the keyboard mask instact. (AMS interrupt handlers used by the unprotection clobber it. Could be fixed by saving/restoring it in the stubs.)List of programs known to work with TitaniK:* Empty test program ;-)* Patched version of SMQTechnical:All non-internal function calls (including the call to _main in kernel::exec)have to go through a client-side stub, a client-side caller and a server-sidereceiver. The stubs look like: pea [target] pea [server_receiver] pea [server_base] bra callerThe callers and receivers are copied from stubs.h.Unlike PreOs, kernel::exec calls kernel programs through a direct call tokernel::start_kernel_prgm, not through a stub call to $34.The problem is that library references and RAM_CALLs can be to both variablesand functions. TitaniK uses a simple (improvable) heuristic to detect functioncalls: a jsr or jmp is a function call, everything else is a variable reference.Interrupt handlers are even more annoying: they can move the control flow fromone file to another completely unpredictably. One solution that wouldtheoretically work would be to update the interrupt vectors whenever the controlchanges from one file to another, and route them through the caller/receivermechanism. However, this is way too slow and makes the interrupt handler consumeall the CPU and crash the calculator. So the solution we actually implement isdifferent:* Remember the TI-89 Titanium is a TI-89. This means it is not using the last 850 bytes of LCD_MEM at all.* Remember where the always-execution-unprotected zone lives: 0x5000-0x5fff.* See how nicely they intersect! The unused screen portion is actually a subset of the always-unprotected zone.* Moreover, while some routines might write there, in grayscale, NOTHING is supposed to write to LCD_MEM, since this area is usually clobbered by the grayscale routine anyway. (Well, if only SMQ respected that. I actually to patch it to reduce its screen inversion loop from 3840 bytes to 3000 bytes. It actually shouldn't invert LCD_MEM at all, that's what the grayscale planes are for...)* So I have modified the grayscale routine to only update 3000 bytes instead of 3840, and used the last 840 bytes of LCD_MEM to store the grayscale routine itself. :-)* The hack is included in the TitaniK version of graphlib. I also changed userlib::lockcalc to use a similar hack.Of course, programs using their own custom interrupt handlers still need to bemodified to implement this trick. Depending on the function of the interrupthandler, there are 2 ways to fix this:* If it is non-essential, we can just remove it. That's what I did with SMQ's AI6 redirect to a DUMMY_HANDLER.* If it is essential, then it has to be executed from LCD_MEM as well. That's what I did with SMQ's AI1.History:0.10 Kevin Kofler 2004-02-14* First release. Forked from PreOs 0.67. All files modified.0.11 Kevin Kofler 2004-04-07* Changed version number identifier from $FF00 to $0011 (PreOs.asm).* Updated graphlib and userlib with a hack to make interrupt handlers work.0.12 Kevin Kofler 2004-04-11* Updated version number identifier (PreOs.asm).* Using ROM_CALL instead of hack to get tios::Heap (PreOs.asm). Using another hack to put it into an address which fits in a word (!"§$%&/()=? SMQ ...).* Removed the error frame saving/restoring hack (Preos.asm, exec.asm). Using ER_success instead.Last minute release note: Programs that throw errors (and don't catch them themselves) are also known unsupported. (This includes ENABLE_ERROR_RETURN.)
You can get TitaniK here, the corresponding libraries can be found here (do not try to use the libraries from DoorsOS or the PreOs stdlib pack, they will most likely not work).
Note that I have not touched TitaniK in the last few weeks. I wanted to polish up some stuff, but I decided to rush it instead.
[EDIT: Updated title.]
