Omnimaga

Calculator Community => TI Calculators => ASM => Topic started by: Jerros on October 08, 2010, 01:08:54 pm

Title: Disabeling the "ON" button during an App?
Post by: Jerros on October 08, 2010, 01:08:54 pm
I'm making a game in which timing is cricial.
You need to press a certain button when a sprite is in a specific area.
However, I have found that spamming the "ON" button significantly slows the programm down, and thus makes things much easier.
I don't exactly know why spamming the "ON" button results in a slowdown (has to do something with interupts?), but I want it to go away.  >:(
How'd I do this? And how would that affect the programm, since from what I've read the "ON" button is pretty special, and I have no idea how this will affect things.
Thanks in advance!
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 08, 2010, 04:31:41 pm
You would be correct thinking that the interrupts are causing your problems. I'm not exactly sure what your calculator is doing in the background to make ON slow it down, but it no doubt changes from program to program.

The obvious way to fix this problem is to just disable interrupts. A simple di somewhere in your loop should take care of this. But now you have to watch out because TI likes to use interrupts. Bcalls that draw to the screen tend to turn the interrupts back on, so just be careful there. Also, bcall(_GetCSC) relies on interrupts to function, so you are going to have to use direct key input with port (01).

The other option that would kind of work is to disable the on interrupt. You would output %00001010 to port (03) instead of %00001011. However, this is just a temporary fix because as soon as the next timer triggered interrupt occurs, it will re-enable the ON interrupts.
Title: Re: Disabeling the "ON" button during an App?
Post by: DJ Omnimaga on October 08, 2010, 04:34:30 pm
yeah the ON key works differently than other keys. When running certain ASM games with Asm(), I noticed the slow down when pressing ON.
Title: Re: Disabeling the "ON" button during an App?
Post by: Deep Toaster on October 08, 2010, 09:12:00 pm
You can actually see it in the TI-OS. Just create a really big string and try to recall it. While it's recalling, pressing ON will make it slow just a little bit.
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 09, 2010, 02:51:40 am
The obvious way to fix this problem is to just disable interrupts. A simple di somewhere in your loop should take care of this. But now you have to watch out because TI likes to use interrupts. Bcalls that draw to the screen tend to turn the interrupts back on, so just be careful there. Also, bcall(_GetCSC) relies on interrupts to function, so you are going to have to use direct key input with port (01).
What's a "di" somewhere in the loop?
And replacing the GetCSC with direct key output.... That'd invlove making a piece of script that would only let it react ONCE when a button is pressed down, right? Else the calc would react as if you were spamming the buttons, but I guess I can do that.
Could you elaborate on that "di" thing please?
Title: Re: Disabeling the "ON" button during an App?
Post by: Runer112 on October 09, 2010, 02:53:19 am
The di instruction disables interrupts.

Perhaps a simpler solution might be to just disable the ON key interrupt, which is controlled by bit 0 of port 3. Outputting 00001010 to port 3 should disable the NEXT ACTIVATION of the ON key interrupt while keeping other interrupts enabled. You'd need to find some way to constantly deactivate it though, I believe.
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 09, 2010, 06:39:00 am
Perhaps a simpler solution might be to just disable the ON key interrupt, which is controlled by bit 0 of port 3. Outputting 00001010 to port 3 should disable the NEXT ACTIVATION of the ON key interrupt while keeping other interrupts enabled. You'd need to find some way to constantly deactivate it though, I believe.
Which would be that di instruction, okay thank you.
Now I've just got to figure out how "di" exactly works and what it does, but that's what the interwebs is for. ^_^
Title: Re: Disabeling the "ON" button during an App?
Post by: Deep Toaster on October 09, 2010, 11:11:02 am
You could send that byte every pass of the loop, I guess.

DI, though, disables all interrupts, including all system interrupts (which includes the ON interrupt), so some functions won't work (including GetKey and GetCSC). If you use it, ALWAYS ALWAYS remember the EI!

More info: http://future_history.freehostia.com/Files/Resources/ASM/ASMin28Days/lesson/day23.html (http://future_history.freehostia.com/Files/Resources/ASM/ASMin28Days/lesson/day23.html)
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 09, 2010, 11:23:40 am
Now I've just got to figure out how "di" exactly works and what it does, but that's what the interwebs is for. ^_^

di is quite possibly the most simple instruction. It is also best friends with ei. Basically, di tells the calculator, stop sending interrupts. The calculator will then stop using interrupts all together and your program flow in never be interrupted by one again. ei turns them back on, when ei is executed, it tells the calculator to start sending interrupts again.

The problem with both of the methods mentioned so far is that if you are using bcalls, both are only very temporary fixes. Using di will make bcall(_GetCSC) stop working, and typically routines like bcall(_clrLCDFull) have an ei at the end of them.

The problem with disabling only the ON interrupts through port (3) is that the ON key is only disabled for .01 second. This is because as soon as the next Ti interrupt fires, it will turn them right back on.
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 09, 2010, 01:43:57 pm
You could send that byte every pass of the loop, I guess.
The problem with disabling only the ON interrupts through port (3) is that the ON key is only disabled for .01 second. This is because as soon as the next Ti interrupt fires, it will turn them right back on.
Is this info contradictive, or don't I understand it?
If it will only turn ON off for .01 sec, then just sending that once per loop won't be enough, right?

As for the DI instriction, that seems like a good way, though all I have to do is replace GetCSC with a directly-into-port routine?
Or would it be nesaccery to do DI after every B_Call, since:
typically routines like bcall(_clrLCDFull) have an ei at the end of them.
Or perhaps do this? :
Code: [Select]
   EI
   B_Call(_GetCSC)
   cp  SKwhatever
   JP   Z, Randomness
   DI
But thanks, I'll mess around a bit tomorrow and see what works and what not. (though I've gotten a very scary error message on my calc last week - never seen that one before... Maybe the trail-and-error way of working might have it's downsides after all. ^_^).
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 09, 2010, 01:58:32 pm
That code you posted should work. When the calculator is in DI mode and something tries to do an interrupt, the calculator remembers that. So then as soon as the EI comes around, it instantly interrupts. You probably don't even need that EI before the GetCSC because the screen routines have their own EI, plus, there's an EI in bcall(_GetCSC). So I would imagine if you just put a DI after each bcall, your problem would go away and GetCSC should still work.
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 10, 2010, 02:36:05 am
if you just put a DI after each bcall, your problem would go away and GetCSC should still work.
Thanks, I'll try that. :P
It isn't sacret though that GetCSC must work, it's always possible to use the direct-output thing (I got a script for that already somewhere, I believe :P).

EDIT:
Nope, this didn't work.
Spamming on will still result in a slowdown.
I'll be trying some of the other suggestions.

EDITEDIT:
Nothing I've tried with DI worked so far, spamming on will still slow the lot down.
It's a BIG loop, with loads of calls, jumps, sprites checking and drawing and moving and other stuff (but just 1 b_call iirc).
Putting the DI as the first line of the loop does nothing, and I've put it before and after the B_call and at some random places just to be sure, but ON will still blow the lot.
Also, you're all saying that GetCSC will stop working, but even this still works:
Code: [Select]
DI
    b_call _GetCSC
DI
    CP     skButton
    JP     Z, Label
Which proves that I have no idea what I'm talking about...
Title: Re: Disabeling the "ON" button during an App?
Post by: DJ Omnimaga on October 10, 2010, 01:04:15 pm
I unfortunately cannot help due to lack of ASM knowledge but one thing to be careful with when using direct input is to make sure to either add a delay between key detections or get rid of key repeat by checking if the user has released the key you pressed before continuing further in the program. Also make sure there's a small delay before checking if people released the key, so it gets detected at all. Not sure how long the delay would be in ASM, though. Otherwise, what happens is that in your game menus, options will be chosen way too fast and it will be impossible to accurately navigate through menus due to key detection being too sensitive. In-game it can also pose problem if your game has everything moving tile-by-tile. An example of this problem would be the first version of Splut, which was submitted to the contest.
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 10, 2010, 01:27:29 pm
I unfortunately cannot help due to lack of ASM knowledge but one thing to be careful with when using direct input is to make sure to either add a delay between key detections or get rid of key repeat by checking if the user has released the key you pressed before continuing further in the program. Also make sure there's a small delay before checking if people released the key, so it gets detected at all. Not sure how long the delay would be in ASM, though. Otherwise, what happens is that in your game menus, options will be chosen way too fast and it will be impossible to accurately navigate through menus due to key detection being too sensitive. In-game it can also pose problem if your game has everything moving tile-by-tile. An example of this problem would be the first version of Splut, which was submitted to the contest.
I had that problem before already, but luckely Quigibo had a perfect solution for that:
http://ourl.ca/6459/105146

So direct input would defenitely be an option.
Although I'm still unsure of how to completely disable the ON button.
Like other here have said - completely disabeling it would force the use of direct input, which I'm fine with.
So, how to disable it?
I'm not good enough (yet) to understand what the kind people post here. ;P
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 10, 2010, 01:28:04 pm
Thats strange. If interrupts are disabled, the on button should do nothing. Are you sure nothing in your loop turns interrupts back on? Also, how fast would you say your program is running? 20fps, 40fps, 150fps? If your program is getting in GetCSC's faster than the interrupts fire, pressing on would slow it down.

Perhaps you could post the source, that way we could see what is really happening.
Title: Re: Disabeling the "ON" button during an App?
Post by: DJ Omnimaga on October 10, 2010, 02:47:28 pm
I unfortunately cannot help due to lack of ASM knowledge but one thing to be careful with when using direct input is to make sure to either add a delay between key detections or get rid of key repeat by checking if the user has released the key you pressed before continuing further in the program. Also make sure there's a small delay before checking if people released the key, so it gets detected at all. Not sure how long the delay would be in ASM, though. Otherwise, what happens is that in your game menus, options will be chosen way too fast and it will be impossible to accurately navigate through menus due to key detection being too sensitive. In-game it can also pose problem if your game has everything moving tile-by-tile. An example of this problem would be the first version of Splut, which was submitted to the contest.
I had that problem before already, but luckely Quigibo had a perfect solution for that:
http://ourl.ca/6459/105146

So direct input would defenitely be an option.
Ah good to hear. Good luck with your other stuff. :D
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 11, 2010, 07:03:50 am
Perhaps you could post the source, that way we could see what is really happening.
The loop is over 600 lines, and that's without the calls and jumps outside of the loop, so I don't think I can bother anyone with that. :O
If you REALLY wan't  me to post it, I will, but it would take way to long for someone to look through it, only to find that I'm making some nooby mistake that could've easely been fixed without all that efford...

So basically, as long as I don't know that turns interrupts back on, I'd have to put di's everywhere at random? (hehe...)
Rather than doing that, is there a concrete list with command that turn interrupts back on?
That way I can go over things myself without bothering anyone.

Thanks for the replies all!
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 11, 2010, 10:10:24 am
I'll look through it. Basically what I would do is run it in wabbitemu and place a breakpoint at $0038. $0038 is where the calculator goes when an interrupt happens, so if you follow the interrupt through, it will point you back to the location of the hidden EI.

Actually, even just posting the app I could probably find the problem.
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 11, 2010, 01:34:13 pm
I'll look through it. Basically what I would do is run it in wabbitemu and place a breakpoint at $0038. $0038 is where the calculator goes when an interrupt happens, so if you follow the interrupt through, it will point you back to the location of the hidden EI.
I'll send you a PM tomorrow then, if it's not too much trouble for you.
Thank you.
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 12, 2010, 05:18:12 pm
Jerros already knows, but for every one else... The OS actually delays when it sees an ON interrupt. It runs a 100 t-state loop 4000 times waiting for the state of the ON button to change. That's just stupid, this is horrible for any type of program that needs to run at a decent pace.

Anyways, the fix was to put a di \ ld a, %00001010 \ out (03), a after the GetCSC. Oh, and be prepared for a great game from Jerros ;).
Title: Re: Disabeling the "ON" button during an App?
Post by: DJ Omnimaga on October 12, 2010, 10:31:45 pm
Is that why code in Axe interrupts run slower than if you don't use them?

Also I can't wait to see his game :D
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 13, 2010, 04:55:54 am
Like ThePenguis already said, it's fixed now.
This what I did with his solution:
Code: [Select]
   (...)
    b_call _GetCSC
    CP     skKey
    JP     Z, Label
AfterLabel:
di
ld a, %00001010
out (03), a
         (...)

Label:
   (...)
   JR   AfterLabel
If you put this in the loop, ON won't cause much trouble anymore.
(Though EXESSIVELY spamming the button will still result in a very occasional small slowdown, though the origional point was to prevent cheating, which is effectively impossible now;P)
Works good enough for me. :P
Thank you ThePenguin!
Title: Re: Disabeling the "ON" button during an App?
Post by: DJ Omnimaga on October 13, 2010, 05:02:55 am
Nice :D
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 14, 2010, 02:56:57 am
Is it a mindf**k of me, or does it seem to be slightly less responsive to the keypresses when using the code above?
Any theory that can back that up, or am I making up things here?
Title: Re: Disabeling the "ON" button during an App?
Post by: thepenguin77 on October 14, 2010, 05:02:51 pm
If you are still using getCSC then yes, it will be less responsive because the interrupts aren't turned on for most of the time. Which would make the getCSC only check for keypresses once per loop. If you are using direct key presses, then it wouldn't have any affect, unless you didn't make the checking routine very well. ;)
Title: Re: Disabeling the "ON" button during an App?
Post by: Jerros on October 15, 2010, 06:09:52 am
If you are still using getCSC then yes, it will be less responsive because the interrupts aren't turned on for most of the time. Which would make the getCSC only check for keypresses once per loop. If you are using direct key presses, then it wouldn't have any affect, unless you didn't make the checking routine very well. ;)
Using GetCSC...
So I guess I replace it with a direct routine.
Though I'd have to fix the fact that holding down buttons will result in ALOT of keypresses, but I believe I already have a script for that somewhere.
Thanks.

EDIT: Haha, found a way to bypass the whole problem; just make sure people don't press the ON button at all:
Code: [Select]
in a,($04)
bit 3,a
jp z,Quit