83Plus:OS:Small Edit Buffers
The TI-OS offers a number of undocumented B_CALLs and B_JUMPs that allow for input to be performed using the small font. Perhaps the best example of these functions is TI's Conics app, which uses them for inputting the variables for the relations. You can use the small edit routines for either one-line input (which scrolls left to right), or multi-line input (which will scroll up/down, wrapping text like on the homescreen.)
The following entry points are used with the small editing routines:
_InitSmallEditBox EQU 4CDBh _InitSmallEditBoxOP1 EQU 4D38h _InitSmallEditBoxVar EQU 4D35h _InitSmallEditLine EQU 4CA5h _InitSmallEditLineOP1 EQU 4D32h _InitSmallEditLineVar EQU 4D2Fh _ReleaseSEdit EQU 4CA2h _SmallEditCxErrorEP EQU 4CC6h _SmallEditCxMain EQU 4CABh _SmallEditCxPPutaway EQU 4CC3h _SmallEditCxPutaway EQU 4CC0h _SmallEditCxRedisp EQU 4CBAh _SmallEditCxSizeWind EQU 4D2Ch _StartSmallEdit EQU 4CA8h _StartSmallEditReturn EQU 4E1Fh
Customization of the small edit buffer occurs by setting up certain areas of the RAM, with their equates listed below. Interestingly, all of these equates fall between ramCode and ramCodeEnd.
SmallEditCancelParse EQU 8194h SmallEditColumnLeft EQU 8177h SmallEditColumnRight EQU 8179h SmallEditRow EQU 8178h SmallEditRowCount EQU 81B7h SmallEditPromptString EQU 81CCh
To begin an edit session, you first must setup some of the settings in RAM. All of the small edit routines require the following to be set:
SmallEditCancelParse: Set to 03h if you do not want the small edit routines to parse the string typed, set to anything else for automatic parsing. This will be discussed later.
SmallEditColumnLeft: The leftmost column for the small edit buffer.
SmallEditColumnRight: The rightmost column. If the text would extend past this point, the edit routines will automatically handle scrolling.
SmallEditRow: The row (in pixels, from the top of the screen) for the first row of the edit buffer.
SmallEditPromptString: The string to display. This is analogous to the first string argument for the Input command in TI-BASIC. SmallEditPromptString should contain the length, in characters, and SmallEditPromptString + 1 should contain the actual string. If you don't want a string, simply set SmallEditPromptString to zero.
Also, if you are doing multi-line input ("box" input), then you must also set SmallEditRowCount, which is the number of rows to use for editing.
Once the various settings in RAM are setup, you must then B_CALL one of the Init entrypoints. There are six of them, with their names describing exactly what behaviors should occur, the format being _InitSmallEdit[Type][WhatToEdit]. Type is either line, which is for one line input, or Box, which does multi-line. WhatToEdit describes what should appear in the edit buffer by default. If WhatToEdit isn't there (either _InitSmallEditLine or _InitSmallEditBox), then the edit buffer is initially empty. If WhatToEdit is Var, the contents of the variable given in OP1 is used. If WhatToEdit is OP1, then OP1 is treated as a real and converted to a string, the resulting string then is placed in the edit buffer.
The following actions are taken by the _InitSmallEdit entry points:
- An edit buffer is opened on the "text_buf" equation, with the contents requested (if any) placed inside.
- The prompt string and contents of the edit buffer are displayed based on the settings in RAM and the form of InitSmallEdit called.
- Monitor vectors are installed to prepare for the editing. The previous monitor vectors are backed up. I believe appFlags is not touched.
Once the small edit buffer is open, you perform the actual editing by B_CALLing _StartSmallEdit. This entrypoint saves the return page / address combination for the B_CALL to RAM, and then passes control to Mon, and editing starts.
Editing is completed by pressing Enter or 2nd+Quit, and if you are doing line input, then also up or down. _StartSmallEdit returns with A being the key pressed that caused the edit session to complete. If you didn't disable parsing, parsing will occur (a system error is thrown if a parse error occurs), with OP1 (and maybe OP2 in the case of complex results) containing the result. Otherwise, OP1 contains the name of "text_buf", which is:
Notes about _StartSmallEdit:
- appBackUpScreen is used when backing up the image during a cxPPutAway for restoration during cxRedisp.
- Switching to other contexts (say by doing 2nd+Mem, 2) can cause unexpected behaviors. TI's Conics app uses a keyhook to disable various keys that open menus that contain problematic items (the memory, stat and program menus are blocked entirely, for example.)
- 2nd-Off also causes problems. Conics handles this by installing it's own monitor vectors, as mentioned later.
- If a parse error occurs, you can call this again to continue input, but it appears some internal states are messed up, so errors are always thrown (at least if we're asking it to parse for us.) If anyone can clear this up, tell me!
Once you are done with the edit buffer, B_CALL ReleaseSEdit. This closes the edit buffer, and restores the original monitor vectors. You must do this under all conditions.
There is an extra B_CALL _StartSmallEditReturn, which is a very odd and not very useful routine. When you B_CALL _StartSmallEdit, the top three items on the stack (placed there by the B_CALL routine itself) are popped off (and stored at 818Bh for the curious), and the SP is then saved (saved to 9D88h.) This is used so StartSmallEdit can actually return (the sp is restored, the values are pushed back, and the OS then does ret.) _StartSmallEditReturn basically restores the SP to what it was before you B_CALLed _StartSmallEdit. Incidently, this also changes the same pieces of RAM where _StartSmallEdit saved the return location, so if you were to call _StartSmallEditReturn in a hook (key hook for example), the edit session may continue, but when it's done, _StartSmallEdit will return to the op-code after where you B_CALLed _StartSmallEditReturn!
Notes about Conic's use of the small edit routines:
- A _GetKey hook is used for disabling various keys that open uneeded menus. Also, the softkeys are also implemented with this hook. If the user presses Graph for example, the hook sets an internal flag and changes the key to kEnter. This causes the small edit to finish (_StartSmallEdit returns), at which point the app then checks the internal flag to see if extra actions should be taken.
- Conics installs it's own monitor vectors before calling _StartSmallEdit (but after it calls one of the _InitSmallEdit routines.) This allows it to get putaway notification to cleanly handle 2nd+Off. It's cxMain, cxPPutaway and cxRedisp handlers simply B_JUMP to _SmallEditCxMain, _SmallEditCxPPutaway, and _SmallEditCxRedisp for handling. _SmallEditCxErrorEP and _SmallEditCxSizeWind can also be used for the same purpose. (thanks to mmartin for this info!) _SmallEditCxPutaway loads SP from 9D88h, pushes three saved items on the stack and does a ret. Which is the routine used to return in the _StartSmallEdit B_CALL.
- Conics parses text_buf manually by setting the SmallEditCancelParse byte, and then calling ParseInp with an error handler.
Credits and Contributions
- mmartin: For helping figure out some of the extra B_JUMPs