Name: Parser Hook
Hook Pointer Block Address: 9BAC
Hook Enable BCALL: 5026
Hook Disable BCALL: 5029
Hook Call BCALL: (none known)
Hook Active Flag: 1, (iy + 36h)
This hook allows you to change the behavior of the TI-BASIC parser and functions.
Using the Hook
These different values, passed in A, determine what the hook should do.
- 0: The parser has just been restarted. This happens when the calculator begins parsing a variable, as well as after some control statements. Do not assume that OP1 is the name of the variable being parsed!
- parseVar = name of variable being parsed
- (begPC), (curPC), and (endPC) are set to the start, current location and end of the variable respectively
- These variables, if done logically, can be set to parse anywhere in RAM without negative side effects.
- Return Z if the parser should continue parsing this variable.
- 1-3: A BASIC function has been encountered. The various types are described below.
- BC identifies the particular function within the class. For many 1-byte tokens, B is the token itself; for many others, B is the OP-number given in ti83plus.inc (although some of these are incorrect.)
- Return Z to run the standard function.
Class 1 Functions
Class 1 tokens all take some positive number of arguments (zero arguments is a syntax error.) These are separated by commas, or in the case of binary operators, by the operator itself. All of the arguments are evaluated before the function is.
The arguments are placed on the FPS in "reverse" order. That is to say, the earliest argument read is deepest in the stack. The final argument is in OP1. The total number of arguments is passed in HL.
Any of the following data types may be used (except where prohibited by syntax rules): Real, List, Matrix, Equation, String, Complex, Complex List. Real numbers are stored on the stack as floating-point. Complex numbers are stored as two consecutive stack entries or in OP1 and OP2 (see the SDK documentation for Push/Pop OP1/3/5.) Other data types are stored as variable names.
A hook may do any of the following:
- Leave all arguments as is, and return Z.
- Modify arguments, or add or remove them while updating HL appropriately, and return Z.
- Remove all arguments from the FPS, place the result of your computation in OP1, and return NZ.
- Remove all arguments from the FPS, reset numOP1,(iy+ParsFlag2), and return NZ. (This is generally preferable if you are not returning a useful value, as it will preserve Ans.)
Class 2 Functions
These include most "programming" commands. No arguments are parsed.
You may, if you are prepared to face the consequences, attempt to read the arguments yourself. The undocumented B_CALL IncFetch can be useful in doing so.
If you return Z, the parser will run the function normally. If you return NZ, the parser will continue execution from where you left off.
Class 3 Functions
If very little is known about class 2, less is known about class 3. Tenatively, it looks like the class 2 functions that you would expect to be class 1 have class 3 secondary callbacks.
It looks like the parameters are stored in OP1 and the FPS as in class 1 and the number of arguments is stored at 9661. HL is the same as (OPS) and should be saved.
Prevent running prgmEXEC
ParserHook: .db 83h ; Required for all hooks or a ; Which condition? jr nz,ReturnZ ld hl,EXECStr ; Check whether our string ld de,parseVar+1 ; matches the name to be run. call CompStrs ; Will return NZ if they don't match jr nz,ReturnZ or 1 ret ReturnZ: cp a ret EXECStr: .db "EXEC",0 CompStrs: ld a,(de) cp (hl) ret nz inc de inc hl or a jr nz,CompStrs ret
Random sin function
ParserHook: .db 83h ; Required for all hooks or a ; Which condition? ret z push hl ld hl,0C2C2h ; Is it the sin( token? sbc hl,bc pop hl jr nz,ReturnZ dec hl B_CALL _DeallocFPS ; free unused parameters B_CALL _Random or 1 ; set NZ ret ReturnZ: cp a ret
Credits and Contributions
- Brandon Sterner: Analysis, and the Symbolic source code.
- Michael Vincent: The Omnicalc source code.