A while ago, I asked about how to implement hooks on the TI-84 plus, and I got some clarification, but I still don't understand quite enough to use them.
This page explained quite a bit about how key hooks work, but when I tried the example program, I got ERR: INVALID. I did this in Mimas, and something to note that might be the cause of this problem is that I could not type ".end" into Mimas, like there is as the end of the example. (I couldn't find it in the command list. I tried with and without the period, but it always told me "Unknown Instruction.")
However, even if I do get this to work, the hook would be stored in ram, not archive. How would I put it in either an app or appvar, preferably on-calc using Mimas? With it in archive, what do I have to do differently to install the hook, and how do I know its adress and flash page? (I believe I need those.)
Edit: I also have Axe on my calc, I have no idea if that would help, maybe just to be able to create a new application? (Can you do that in assembly?)
CamelCode wrote:
A while ago, I asked about how to implement hooks on the TI-84 plus, and I got some clarification, but I still don't understand quite enough to use them.
This page explained quite a bit about how key hooks work, but when I tried the example program, I got ERR: INVALID. I did this in Mimas, and something to note that might be the cause of this problem is that I could not type ".end" into Mimas, like there is as the end of the example. (I couldn't find it in the command list. I tried with and without the period, but it always told me "Unknown Instruction.")
However, even if I do get this to work, the hook would be stored in ram, not archive. How would I put it in either an app or appvar, preferably on-calc using Mimas? With it in archive, what do I have to do differently to install the hook, and how do I know its adress and flash page? (I believe I need those.)
Edit: I also have Axe on my calc, I have no idea if that would help, maybe just to be able to create a new application? (Can you do that in assembly?)
".end" is a label. Type it in as text
.end is not a label, it's a directive for old assemblers telling them to stop assembling. You shouldn't need it.
If you want to store your code in an appvar (if an app, you need to make an app which doesn't require this kind of messing about anyway), you'd have to create the appvar with the code, then archive it and do the usual _ChkFindSym dance to find its location in the archive.
Where that becomes harder is then you can't predict where your code will actually be executing from, so you need to be careful that it's all relocatable- no jp allowed, no calls to other parts of the hook, etc. Probably even worse, it's possible that you'd be placed in archive such that the hook code spans multiple pages which would mean you could fall off the end of the mapped Flash page in the 0x4000-0x7FFF range and start executing whatever happens to be at the bottom of RAM at the time. So.. you shouldn't do that. Be an app, stash things in some saferam and stop working randomly or crash without warning are basically your options.
Tari makes some excellent points regarding hooks. This is why typically coders have used APPS.
It is possible to locate a hook somewhere else, but there are a lot of factors to keep track of to ensure stability. Page boundaries, garbage collection, unknown entry point etc.
So how would I create the app with the hook, and how would I point to it? Can I create it somehow on-calc?
I'm not too familiar with mimas, but I doubt that it supports building and installing an APP oncalc as standard. There are ways to do this however - I'll have a look around.
Mateo could perhaps assist with this process.
Yeah, Mimas can only create programs, not applications. Axe is the only software that I know of that can create an application on-calc, so I was wondering if I could either program the code for the hook in Axe, or somehow use assembly to edit a blank application created by Axe. I'm still not sure how I would actually install the hook with its code in archive, and how I would know it's address, though.
Edit: Now that I come to think of it, I can insert asm into Axe programs in the form of hex, in case I do it with Axe, but need to do something that cannot be done directly with axe code. Relating to this, I've been looking for a tool to convert Assembly code to hex online. Can source coder 3 do this?
Does anyone know about this? All I really need to know is how to install the hook if it’s in archive, and if anyone knows, what I would have to do specifically in axe to make the application created by axe work for a hook.
Installing a hook in archive is the same process as you would in RAM, just you need to ensure you pass the right flash page as well as address. For instance:
Code: ld hl, hook_code
; Get the currently-mapped Flash page that we're executing from
; because we're an app
in a, (6)
bcall(_EnableGetCSCHook)
; ...
hook_code:
.db $83
; ...
So it’s exactly the same as in ram except for “in a, (6)”? What does this do exactly? I’m guessing port 6 contains the current flash page? Does the bcall use register a as input? Also, what is the .db $83 for at the start of the hook code?
Yes, port 6 is the current flash page. You can find further documentation
on WikiTI. The byte $83 doesn't actually get executed, but is there to indicate to the OS that the data there is an actual hook rather than random data.
Oh okay, I see. Does it do the same as ld a,e? I think I saw somewhere that that was the command used at the start of a hook, but I might be wrong. Otherwise, I think I understand everything. However, how could I install the hook in an application from a regular asm program? I guess I would just need to find out the address and flash page, but is there a way I can do that?
Your question makes no sense.
Uhhh, okay. I guess it might not be possible, but I was wondering if I could install the hook from outside of the application. The hook code would be in the application, but it would be a different program that calls the bcall to install it. I'm guessing by your answer, though, that this is not possible.
No, the whole premise doesn't make sense. Why is a program accessing an app like this?!
I never said it wasn't doable.
Okay, I'm not sure how to explain it, and I guess I might not really understand how this all works. The actual code for the hook, what gets executed when the calculator scans for keypresses, is in an application. The way I understand it, the _EnableGetCSCHook bcall is called from somewhere, and it "installs" the hook, so that the code in the application is executed when the os scans for a keypress. The code to install the hook is normally a part of the application which contains the hook code, but I was wondering if there a way to put that part of the code a program instead. I might be completely misunderstanding the way this works, though.
Yes, you can do that; I don't know why the others aren't understanding
In fact, Celtic 3 and Batlib were doing this for a long time (and I'm sure other apps).
The easiest and most reliable way is to start your app code (after the header) with a jumptable like:
Code:
jp start
jp install_hook
...
As long as you don't move the jumptable in your app, then any program or app can:
- Locate the app with _FindApp
- Swap the page with port 6 (for apps, this code must execute from RAM!)
- Call the jump table. For example, if the above jump table starts at $4080, ` call $4083` would run the app's hook installer.
- restore the page in port 6
- Done!
EDIT: For what it is worth, I thought your question was pretty straightforward.
Okay, I think I now have at least a somewhat workable understanding of hooks, and I'm gonna go start experimenting!
Thanks for the help everyone!