How can I create a program that is bigger than 24K and works on AMS 2.xx?

Previous Miscellaneous Next

Q: How I can make a program which does not need any kernel, but which is greater than 8K and which works on AMS 2.03 as well (or greater than 24K and which works on AMS 2.04 and AMS 2.05 as well)?
A: In fact, you need to make a short program (a so-called "launcher") which will call the main program, bypassing the TIOS (to skip the software protection). If the main program is "example.c", I recommend the following "launcher":
// Launcher for program called "example"

#define USE_TI89
#define USE_TI92PLUS
#define USE_V200

#include <tigcclib.h>

#define fatal(s) ({ST_showHelp (s); return;})

void _main (void)
{
  char *fptr, *cptr;
  unsigned short plen;
  SYM_ENTRY *SymPtr = DerefSym (SymFind (SYMSTR ("example")));
  HANDLE h;
  if (!SymPtr) fatal ("Program not found");
  h = SymPtr->handle;
  if (HeapGetLock (h))
    {
      cptr = fptr = HeapDeref (h);
      h = 0;
    }
  else
    {
      cptr = fptr = HLock (h);
    }
  plen = *(short*)(cptr) + 3;
  if (SymPtr->flags.bits.archived)
    {
      if (!(cptr = malloc (plen)))
        {
          if (h) HeapUnlock (h);
          fatal ("Out of memory");
        }
      memcpy (cptr, fptr, plen);
    }
  enter_ghost_space ();
  EX_patch (cptr + 0x40002, cptr + plen + 0x3FFFE);
  ASM_call (cptr + 0x40002);
  if (h) HeapUnlock (h);
  if (cptr != fptr) free (cptr);
}
If you are not an expert, use this program as-is.

For anybody who wants to know more about the 8K limit: on HW1 calcs it is a pure software limit which can be broken by intercepting some error traps (used in DoorsOS and UniOS), or by making a short launcher which relocates the called program and jumps to it bypassing the TIOS check. This is what I used. But, yet another problem must be solved: HW2. Namely, it has built-in a hardware device which does not allow that PC can be out of certain zone, so the launcher itself will not help. This device can't be turned off normally by software, but Julien Muchembled found a "hole" in the protection system which allows turning out this device (this is what his HW2 patch does): this is a very nasty method, and I don't want to explain this here. But, this protection device can be fooled in a simple way: it protects only the "normal" RAM address space (i.e. the first 256K of RAM). As RAM is partially decoded, address x and x+256K are the same for TI-89, but if you jump to x+256K instead of x, the protection will not be activated! Look at the launcher to see how it works, and you now can understand why I added 0x40000 (i.e. 256K) to the address in two places. First, I relocate the called program as it is located on x+256K instead of x, then I call the subroutine on x+256K instead of x.

AMS 2.04 and AMS 2.05 introduce yet another level of protection (which existed before, but caused problems very seldomly): on these AMS versions, even jumping to the "ghost address space" (above 256K) is not possible if the program counter is out of a certain area. (This caused the so-called "second launch crash"; if you have AMS 2.05 with any longer program like TI-Chess, you probably know what I am talking about.) That's why I introcuced a new function called enter_ghost_space: its only purpose is to smoothly bypass this new protection. Note that enter_ghost_space is deprecated now; you should use the EXECUTE_IN_GHOST_SPACE directive instead in most cases.