Difference between revisions of "83Plus:OS:Hooks"

From WikiTI
Jump to: navigation, search
 
Line 43: Line 43:
 
     ld bc, hook_end-hook_start
 
     ld bc, hook_end-hook_start
 
     ldir
 
     ldir
   pop de
+
   pop hl
  ld a, 1
+
 
   bcall(__SetGetKeyHook)
 
   bcall(__SetGetKeyHook)
 
   ret
 
   ret

Latest revision as of 07:34, 11 July 2016

Description

Hooks are a hidden feature of the TI OS that were originally included for the official TI flash apps to use. The hooks allow a program or app to gain control at different times during the operating system to modify values or add additional features. Although the hooks were designed to be used by flash apps, they also work for programs in ram.

Usage

  • The first step to using a hook is to decide which one you need. The list of hooks can help you decide which one to use. Just be sure that the hook you pick won't interfere with other OS processes.
  • Next, you must find an area of memory for your hook that won't get destroyed during the life of the hook. Typically hooks are saved in flash apps so this is not a problem as you can't overwrite an app. However, if you must put your hook in ram, try to find an unusual place if you want your hook to survive. AppBackUpScreen is definitely not the place to put a long-term hook.
  • Once you have your location figured out. Put the address in HL and the page in A. If the hook is in ram, the page is 1. And then call the specific bcall for that hook.
  • For the actual hook, it is imperative that the first line is .db $83. The OS uses this as a marker for hooks. It is a safety check so that the OS doesn't jump to a hook that has been destroyed.
  • When you are done with your hook. Just call the specific disable bcall for that hook.

Memory

  • Each hook has 3 bytes of memory and a flag
    • The first two bytes are the address of the hook. The third byte is the page it is on.
    • The flag is as simple as 1 is on 0 is off.

Restoring and Chaining

Since the hooks are so useful, many different programs make use of them. This can create problems when two different programs want to use the same hook at the same time. There are three options in this case: either ignore the first hook, save the first hook and restore later, or chain the hooks.

Restoring

Restoring the hook is the easier of the two options.

  • The first task is to save the hook's three bytes and its active flag to somewhere where they won't get destroyed.
  • Next install your hook and let it run its course.
  • When it is time to uninstall your hook, just restore the three bytes and the active flag.

Chaining

This is much harder than restoring, but the benefits of having one hook occur after the other can be worth the hassle.

  • Just like restoring the hook, the first step is to save the hook's three bytes and it's active flag.
  • Install your hook like normal.
  • When your hook is finished, it now needs to jump to the address you saved in the first step. When this jump is made, care should be taken to put the calculator in exactly the same state that you found it when the hook was called. Remember: the other hook thinks it is being called by the OS.

A few notes:

  • Watch out for double chaining. Say program A lays a hook. Program B sees A's hook and chains with it. So the current order is B->A. But now program A gets run again. It sees that program B's hook and chains to it. Program A has no idea that it is already being chained to. So now the order is A->B->A. Program A's hook gets called twice. While the situation is not completely avoidable, remember that if you chain hooks, it is a possibility.
  • When chaining hooks. If you need to return a value directly back to the OS, depending on the situation, it is probably safe the skip the jump to the other hook and just return to the OS. If you have to return a value, you don't have much of a choice anyways.

Install

This is an example to install a hook

#define hook_addr $1234

Install_hook:
  ld hl, hook_start
  ld de, hook_addr
  push de
    ld bc, hook_end-hook_start
    ldir
  pop hl
  bcall(__SetGetKeyHook)
  ret
hook_start:
  .db 83h
  ...
hook_end:

See also