83Plus:OS:Recall Queue

From WikiTI
Jump to: navigation, search

Recall Queue

The recall queue is TI's internal mechanism for storing long sequences of tokens to be entered into an edit buffer. It can be used to output on the homescreen after quitting an application or inside a hook. The tokens will be inserted into an edit buffer as soon as possible (with some caveats, explained below.)

It is important to note that the recall queue is implemented by the app itself -- specifically, by the cxMain vector -- and not by the system monitor. Thus its exact behavior will depend on the app currently running, which may have some undesired effects.

Two flags control the recall queue:

  • 7, (iy+0Eh): This flag is set to enable the recall queue itself.
  • 2, (iy+33h): This flag controls which of two modes the recall queue operates in.
    • Flag reset ("internal") mode: This is the mode used most often by TIOS. It is used to implement standard recall operations. In this mode the tokens to be inserted are placed directly in the buffer gap, and subsequently read and displayed, one by one. This mode is implemented by all TIOS apps which use edit buffers.
    • Flag set ("external") mode: This mode is more useful for applications, as it can be set up before the edit buffer is actually opened. In this mode the tokens to be inserted can be placed anywhere in RAM, and will be copied into the next edit buffer to be opened. This mode is implemented by some, but not all, TIOS apps. In particular, the program editor does not implement this mode.

Internal mode

Internal mode requires the tokens to be inserted directly into the buffer gap -- which in turn means that it can only be used when the app has already been loaded. In this mode, tokens are read starting at (editCursor) and continuing up to (rclQueue)-1. So in this case (rclQueue) indicates the end of the data in the queue.

Note that tokens are actually read and "typed" one by one, which means that to get the usual "recall" behavior, insert mode needs to be enabled first. (The insert flag is usually saved in (promptIns) during recall operations, and that will be used to restore the insert flag once the recall operation finishes.) If insert mode is not enabled, the "recalled" tokens will overwrite the existing tokens instead -- which may be considered a feature.

Finally, remember that the recall queue is implemented by the cxMain vector, and therefore if you are inserting recalled data from a key hook, you will still need to simulate a keypress in order to start the recalling process. The easiest way to do this is to return the key corresponding to the first token to be recalled; this key will be pressed, the token inserted (advancing editCursor by one or two) and then the rest of the queued tokens will be added.

As an example, suppose we are using a Raw Key hook and want to insert the string "HELLO". (This example will not deal with the added complexity of overlaying a menu; imagine that we want to bind this directly to a TI-Keyboard function and we have intercepted the key at the homescreen.)

  • Test to make sure an edit buffer is open, and that there is enough memory available. In our example we need 7 bytes.
  bit editOpen,(iy+editFlags)
  jr z,NotInEditor
  or a
  ld hl,(editTail)
  ld de,(editCursor)
  sbc hl,de
  ld de,7
  sbc hl,de
  jr c,NotEnoughMemory
  • Copy our string into the edit buffer. Note that it's not actually necessary to copy the initial quote token -- since that will actually be typed normally -- but the 'H' must still be placed at (editCursor)+1 since the initial quote will be inserted before the recall queue is activated. (Confused yet?)
  ld hl,String
  ld de,(editCursor)
  ld bc,7
  ldir
  • Set the rclQueue pointer so that we know when to stop.
  ld (rclQueue),de
  • Set the recall flags.
  set 7, (iy+0Eh)
  res 2, (iy+33h)
  • Save and set the insert mode flag.
  ld a,(iy+textFlags)
  and 1<<textInsMode
  ld (promptIns),a
  set textInsMode,(iy+textFlags)
  • Return the quote key, which must be typed normally.
  ld a,kQuote
  or a
  ret z

String: .db tQuote, "HELLO", tQuote

External mode

External mode copies tokens from some other place in RAM -- such as a saferam buffer -- into the edit buffer. It can be used similarly to internal mode, with edit buffers that are already open, but this is clearly not an intended feature, as external mode recalling is not even implemented in some apps (notably the program editor.) So this is generally not the mode to use for key hooks.

This mode is intended for apps such as TI's Periodic Table which have data that needs to be copied to the homescreen. In this case what you want is to quit, let the homescreen initialize itself, and then copy the tokens into the edit buffer. Luckily the homescreen can do all of that for you -- including the ugly memory management issues.

In this mode, (rclQueue) indicates the start of the data to be inserted, and (rclQueueEnd)-1 the end. Simply set these pointers and the flags, and let TIOS take care of everything else!

As an example, suppose our app wants to exit and copy the string "HELLO" onto the homescreen.

  • Copy the data into a saferam area that won't be erased before you return to the home screen.
  ld hl,String
  ld de,appBackUpScreen
  ld bc,7
  ldir
  • Put the location of the first byte of data in rclQueue. (Remember, if you're being a fool and using this in a key hook, that the first token still has to be typed manually!)
  ld hl,appBackUpScreen
  ld (rclQueue),hl
  • Put the location of the last byte of data + 1 in rclQueueEnd.
  ld (rclQueueEnd),de
  • Set the recall flags, and return to TIOS.
  set 7, (iy+0Eh)
  set 2, (iy+33h)
  B_JUMP JForceCmdNoChar