Omnimaga

Calculator Community => TI Calculators => ASM => Topic started by: Sue Doenim on February 16, 2019, 05:07:27 pm

Title: Miscellaneous ASM Questions
Post by: Sue Doenim on February 16, 2019, 05:07:27 pm
I have a few small questions that I'm not sure about, but I don't want to make a separate thread for each of them, so I'm combining them all in here.
1) What RAM pages can I use within programs without having any bad consequences?
2) When an appvar is less than 16kb and is archived, will it all be on the same ROM page?
3) Can you interface with headphones beyond simply sending them signals with the ring and the tip? If so, how?
If anyone can answer these questions, or refer me to a source that as answers, I would greatly appreciate it.
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on February 16, 2019, 06:44:13 pm
1) What RAM pages can I use within programs without having any bad consequences?
Even numbered pages are execution protected by default, so executing code here will crash your calc. That said, you can definitely store data. On the calcs with USBs, page 83h has some data that should be preserved or restored in the first 128 bytes. Just remember that any OS routines that interact with memory or variables expect the right pages to be there.

Ram Pages (http://wikiti.brandonw.net/index.php?title=83Plus:OS:Ram_Pages) (WikiTI)

2) When an appvar is less than 16kb and is archived, will it all be on the same ROM page?
No, you can't expect this. Variables won't cross sector boundaries (groups of four RAM pages), but they may cross pages.

3) Can you interface with headphones beyond simply sending them signals with the ring and the tip? If so, how?
I don't know what you mean by this, sorry :| If you want to use headphones, you have to interact directly with port 0.
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on February 16, 2019, 09:31:54 pm
Thanks for the answers! I have just a couple more follow ups.
1) What RAM pages can I use within programs without having any bad consequences?
Even numbered pages are execution protected by default, so executing code here will crash your calc. That said, you can definitely store data. On the calcs with USBs, page 83h has some data that should be preserved or restored in the first 128 bytes. Just remember that any OS routines that interact with memory or variables expect the right pages to be there.

Ram Pages (http://wikiti.brandonw.net/index.php?title=83Plus:OS:Ram_Pages) (WikiTI)
If you overwrite the data at the start of page $83, will bcall(_fillAppBaseTable) fix that?
3) Can you interface with headphones beyond simply sending them signals with the ring and the tip? If so, how?
I don't know what you mean by this, sorry :| If you want to use headphones, you have to interact directly with port 0.
I looked for a while, and the most info I could find/understand on output to headphones was that you have to use bits 0 and 1 of port 0 (the tip and the ring), and switch them between set and reset at a desired note's frequency (e.g. 440Hz for A4). I thought that for more high quality sound than simply beeps, you send a full byte at a time to the headphones, but after looking at the source code for TruSound, I realize that that was wrong.
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on February 16, 2019, 09:33:05 pm
Yes, bcall(_fillAppBaseTable) should be sufficient.
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on April 04, 2019, 09:09:31 pm
Where is the edit buffer for the homescreen stored? What general guidelines should I follow when editing it?
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 04, 2019, 09:26:42 pm
What do you mean by the edit buffer? Edit buffers can be fairly complicated to work with.

The home screen does have a 128 byte buffer reserved as a copy for each char on it (16*8) called textShadow. There is another, similar buffer called cmdShadow that is intended for programs to use to back up that data.

For those two 128-byte buffers, you can do whatever you want with them. Worst case is that the home screen displays garbage. You can just fill it with spaces manually or preferably through one of the bcalls (I believe bcall 0x4546 is the bcall, but I forgot the name and I'm on mobile so it's a pain to search).
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on April 04, 2019, 10:35:47 pm
What do you mean by the edit buffer? Edit buffers can be fairly complicated to work with.
I don't mean the text shadow, but the place the tokens that you type in are stored.  I want to work with hooks to change things.  My current plan is to make an app that supports double-clicking of certain keys to access the [2nd] function of that key (e.g. double clicking [^] puts the pi token).
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 04, 2019, 10:57:31 pm
Oh, you probably don't want to work with an edit buffer for a task like that!

The data is stored in the program named !. (That's an exclamation point). Just locate the variable, get its size and locate the end if the program.

Just remember that if you replace a 1-byte token with a 2-byte token, you'll need to increase the size of the var (use InsertMem and manually update the var's size bytes) and vice versa.
Title: Re: Miscellaneous ASM Questions
Post by: Runer112 on April 04, 2019, 11:03:16 pm
... except you have to work with an edit buffer for that, because home screen input works by having that program open in an edit buffer.
Title: Re: Miscellaneous ASM Questions
Post by: E37 on April 18, 2019, 12:49:39 pm
I know that I'm 2 weeks late to the party (and several months if you count it from the original post) but I actually did something pretty similar to what you are trying to do a while ago. If you want to mess around with the homescreen input, you should use a homescreen hook. (http://wikiti.brandonw.net/index.php?title=83Plus:Hooks:9B8C) Since you mentioned hooks already, I assume that you already know how to use them. If you use the mode when A=2, then you don't have to worry about edit buffers and you can just open prgm! and edit it like anything else without worrying about edit buffers and such. If you want to change what a key sends on a double press by using the mode where A=1, you are in for something much trickier. It is simple to change B to the keypress that produces the token that you want. If I recall correctly, you should change keyExtend to the second byte if it is a two byte keypress.
The problem is with removing the previous token. There is an edit buffer command to shift the cursor one token to the left (BufLeft) so that might work, and then you could call BufReplace to replace that token that was previously typed in with the one you want to change it to and then return nz to ignore the keypress since you handled it manually. I don't know how this would work when the user is in insert mode.
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on April 19, 2019, 11:53:00 am
I don't think I'll keep trying to make that program. I like the idea, but there are just some logistical issues. Things like "sin(arcsin(" would get messed up a bunch, and I don't see a nice way to fix that problem. I decided to work on another similar but probably simpler thing. My friend is a tau enthusiast, and he would like the pi keypress to be replaced with a functional tau keypress. (In case you don't know, τ=2π.) I was thinking I would set a raw key hook, and whenever pi is pressed, I would add tau to prgm!. Then I'd install a homescreen hook to allow the tau token to signify its value. What I'm not sure about is what prgm# is. Wikiti says "To retreive the expression to be evaluated use prgm#," but does that mean I edit prgm# to change the answer? Does prgm# hold a copy of prgm!, or what? My plan was to insert "(6.28[etc.])" Where ever a tau was.
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 19, 2019, 12:04:45 pm
Oh, you might actually be able to do that relatively easily. If there is a getKey code for the tau token (you'd have to look it up, there might not be), then you could use a getKey hook to override a [PI] keypress.

Then you also have a parser hook that replaces all of the tau tokens with 2pi before passing it back to the OS parser. The nice thing is that 2pi takes 2 bytes and tau is a 2-byte token, so you don't even need to resize. I don't think the parser hook has a mode for when a program ends, so you won't be able to re-replace the 2pis as taus that way, but you could probably make your getKey hook do it!

EDIT: there is in fact a ktau in the ti83plus.inc ! You'll want to use the RawKeyHook (http://wikiti.brandonw.net/index.php?title=83Plus:Hooks:9B84) and the Parser hook (http://wikiti.brandonw.net/index.php?title=83Plus:Hooks:9BAC).
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on April 20, 2019, 11:23:59 pm
I got the Raw Key Hook to work, so now pi keypresses put a tau token. I'm not sure about the Parser hook. I think I understand it pretty well. Replacing all of the tau tokens with 2pi wouldn't always work, though, would it? If you have 3tau, wouldn't that become 32pi?
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 21, 2019, 03:35:41 pm
Oh, you are right about that. That would be a little more difficult as you would have to resize variables.
When the parser hook triggers mode 0, the name of the program being parsed is in basic_prog. You could first scan for all tau tokens that can be directly replaced (and replace them), while counting all of the ones that need extra work. Then verify there is enough memory to insert an additional two bytes for each remaining entry. Use InsertMem at the end of the program, but remember to adjust the variable's size bytes as well as basic_end. Finally, replace the remaining tau tokens with "(2pi)".

It is a complicated process, so good luck!
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on April 22, 2019, 09:31:44 pm
You wouldn't be able to modify the function of the tau token using the other modes of the parser hook, would you? That seems like it would be a cleaner, if more difficult solution.
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 22, 2019, 09:34:37 pm
I'm fairly sure that the parser hook doesn't let you intercept non-function tokens. I could be wrong about that, but I don't think so.
Title: Re: Miscellaneous ASM Questions
Post by: E37 on April 23, 2019, 01:43:18 pm
If you are ok with cheating a bit, there is a somewhat easier way to accomplish it. At a glance, the statistics variables all have their own dedicated ram area. A wild guess, but they are probably in statVars. If you can find the ram area for one of these stat vars, every time your hook runs, you can set the value of that stat var to the value of tau and instead of replacing the pi with a tau, replace it with that stat var. You could install a token hook to change whatever that stat var was to the tau character. It would look just like the tau token and work like it in all cases too. The only problem is that it would mess with the value stored in that variable unless you can find a way to save and restore it.
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 23, 2019, 02:10:19 pm
Holy heck that is clever! So all you'd need a token hook, RawKeyHook, and parser hook.
Title: Re: Miscellaneous ASM Questions
Post by: E37 on April 25, 2019, 01:12:16 pm
Holy heck that is clever! So all you'd need a token hook, RawKeyHook, and parser hook.
I can't tell if you are being sarcastic. Given how much trouble I always have when trying to use more than one hook at a time, I suspect you are laughing at me.

Why a parser hook? Isn't that for modifying functions? I don't see why you would need one unless you are trying to disable all functions that would modify the hacked stat var's value. Since Sue Doenim has found a way using some hook or other to insert the token, it should be simple to change the stat var to tau's value then to be sure it is the correct value when it runs.
Title: Re: Miscellaneous ASM Questions
Post by: Xeda112358 on April 25, 2019, 06:34:33 pm
Oh, good point, I was still stuck on translating the tau tokens at parse time.

I wasn't intending to come off as sarcastic, I just went from point A to C without sharing point B, so to speak. I was thinking context hooks and whatnot, but the hooks I listed are easier to work with. "Only" those hooks seemed like a way easier task to me :P

Your idea(s) are legitimately really clever and I just got really excited when I read it (how I feel whenever I see a really clever implementation or optimization).
Title: Re: Miscellaneous ASM Questions
Post by: Sue Doenim on April 28, 2019, 01:46:20 pm
I was planning on using a finance variable to hold the value, since unlike statistic variables, they are borderline useless. The problem I was running into was that the TIOS doesn't seem to allow writing to variables from a hook. Whenever I copy a float into the RAM area from a hook, the OS sets the variable to 0, and when I use OS routines (stoSysTok), all kinds of junk happens. I can write to the variables from a normal program, but not from the hook. Is there any way to bypass this?
Title: Re: Miscellaneous ASM Questions
Post by: E37 on April 30, 2019, 09:12:53 am
I threw together a quick Axe program and I didn't have any issue with it. I can set finance vars just fine inside a hook. Here is my code:

:.TestApp
:LHook    //Loads the address of the hook into HL
:Asm(DB06)      //In a,(6) - This gets the page we are currently on and loads it into A
:Asm(EFAB4F)    //B_CALL EnableHomescreenHook
:Return
:
:Lbl Hook
:Asm(83)    //Make it a valid hook
:Asm(3d3d)    //dec a, dec a - Decrements A twice so that A is zero if we are in mode 2
:Asm(6F67)    //ld l,a , ld h,a - Load A into H and L
:!If        //If A is zero then HL will be zero and the stuff inside the if statement will run
:Asm(F5C5D5E5)    //Push AF, BC, DE, HL
:37->float{E9055}    //Convert my favorite number into a float and set 0x9055 to its value
:Disp "Test"    //Display some text to verify that the hook actually ran
:Asm(E1D1C1F1)    //Pop HL, DE, BC, AF
:End
:Asm(AF)    //xor a - Set the Z flag before I return
:Return

It worked perfectly well. To run it, you just have to compile it as an app, and run the app once. After that, every time you hit enter on the homescreen the weird 'N' finance var (the one that is kind of bolded) is set to 37. In fact, you can set 'N' to whatever you want, type it in on the homescreen, and it will tell you that 'N' is 37 so it does set the value before the program evaluates the finance var.

I actually wrote a whole response thinking that finance vars worked like the basic letter vars and that they weren't created until used. Since they use a fixed memory area and aren't created dynamically, that answer won't help you but Ill include it here in case some future person finds it useful.
Spoiler For Answer for a different problem:
Let me take a guess: The hook that you are trying to edit it in is the homescreen hook or some other hook that is run while the user is still typing things in. Your problem is that when the user is typing things on the homescreen, the OS opens an edit buffer. That edit buffer takes all of the free ram left so you can't create any new variable since there is no ram to create them in. I had this problem at one point as well. To check if I'm correct, you can use B_CALL MemChk from wherever you are having your problem. It returns the amount of free ram available. If it returns 0, then that's your issue.
Spoiler For (Optional) How edit buffers work:
This is what I've figured out from of trial and error and careful reading of the documentation. I'm pretty sure it is correct but I can't promise it is.
The OS uses edit buffers for a lot of different things. From what I can tell, they are used pretty much any time you type something into a field that has no size limits. So this includes everything you type on the homescreen, when you edit programs, and more. If you aren't familiar with how exactly edit buffers work, from what I understand, they basically expand to take all the free memory so that it doesn't need to resize and create delays while it is running. The memory moves around based on where your cursor is. Its structured so that the at the beginning of the edit buffer is all the data from the start of the edit buffer up to wherever your cursor is. It then has a giant blank gap where there is no data. At the bottom of the buffer is all of the data after the cursor. When you insert things into the buffer, it just inserts that data into the blank space after the cursor and moves it forward, no shifting data around. That also means when you move the cursor, it is moving data to and from the 'behind the cursor' area and the 'after the cursor' area to keep them accurate.
(I created my own program editor a while back and this isn't really a good excuse. Inserting at the top of a giant program and having to shift down all of the data each time a character is added isn't noticeably slower than inserting at the bottom  <_< )
How to fix it (assuming that I guessed your problem correctly)
You can't create any new variables while the homescreen edit buffer is open. I don't think there is any way around that without doing some serious hacks that would be far too much work. What you want to do instead, is just insert your finance variable using whatever trick you are doing normally. Then on your homescreen hook, use mode 2. That is the mode that is called right before it evaluates what is typed in on the homescreen. At that point the edit buffer will be closed. You don't need to take advantage of any of the features of this mode, just create your finance variable, set it to your value and return Z.