Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: Michael_Lee on September 01, 2010, 11:50:27 pm

Title: How to use interrupts
Post by: Michael_Lee on September 01, 2010, 11:50:27 pm
Hi, can somebody provide a short example on how to use interrupts?
Just a few snippets of code to provide an example for me to work with?
Title: Re: How to use interrupts
Post by: Hot_Dog on September 02, 2010, 12:10:53 am
Do you mean axe or pure asm?
Title: Re: How to use interrupts
Post by: meishe91 on September 02, 2010, 12:12:17 am
I'm fairly sure in Axe since this is in the Axe sub-forum. Plus I think he is planning on trying to use them in his Minesweeper game.
Title: Re: How to use interrupts
Post by: Builderboy on September 02, 2010, 01:30:25 am
So interrupts are not that bad, here is some simple code:

FnInt(INT,6) Run this to turn on inbterupts.  This code turns on interupts with the label INT.  So that every couple of milliseconds, it will Sub(INT).  The second number 6, represents the time it takes between each Sub().  0 is the fastest, and 6 is the slowest.  The only possible values are 0,2,4 and 6.

Do you want some example code?  Interups are surprisingly simple to set up, why dont you give it a try! :D
Title: Re: How to use interrupts
Post by: meishe91 on September 02, 2010, 01:36:51 am
What are interrupts exactly?
Title: Re: How to use interrupts
Post by: Hot_Dog on September 02, 2010, 01:44:33 am
What are interrupts exactly?

Well, suppose you have a routine that you want to run every certain amount of time, no matter where you are in the program.  After the certain amount of time has passed, the program will be "interrupted" and run the routine.  When the routine is finished, the program will continue running normally.

That's why many people use interrupts for things requiring a timer.  For example, in S.A.D., I need a building to construct no matter what the user is doing in a program.  Whether the player is moving a ship, buying buildings, or collecting resources, that building has to keep on constructing.  So I have an interrupt routine to construct the building.  Whenever a certain amount of time has passed, the building's HP will increase by 1 HP.
Title: Re: How to use interrupts
Post by: Quigibo on September 02, 2010, 01:46:07 am
Axe makes interrupts very simple, there really isn't much to them.  You just give it the name of the routine that you want to use for the interrupt and the frequency (how often the interrupt is executed every second).  The fnInt() command also enables the interrupts for you so they start working right away.  Generally though, interrupt code makes the program much larger and slightly slower so I would only use them for applications where you're actually using it for it's timing feature.  For example; a stopwatch or music player.

Once its set up, it will execute the interrupt code at a regular frequency "in the background" except that it has to halt normal code execution while the interrupt code is used which might make your game appear to pause if the interrupt code is too long.  Interrupt code should normally be short like increasing a timer variable.  There are several commands that go with interrupts explained in the commands list.  fnOff will temporarily turn off the interrupts.  fnOn will turn them back on.  Stop will wait until the next interrupt before continuing.  And lastly but most importantly is LnReg which kills the custom interrupt completely and returns back to the normal OS interrupt.  You NEED this before you exit the program or else the calculator will freeze.
Title: Re: How to use interrupts
Post by: meishe91 on September 02, 2010, 02:07:27 am
Oh, ok. That makes sense, I think. So just a quick situation for this. Say your game character has lost health and you want to increase his health by six every few seconds until it is full again. Would you then set the interrupt but then turn it off right away and then when your characters health is lower than full you use FnOn to turn the interrupt on and the when it gets full again run FnOff to stop the interrupts?

Code: ( Pseudo Code) [Select]
FnInt(HLT,6
FnOff
Some type of loop
If CurrentHealth<MaxHealth
FnOn
End
If CurrentHealth=MaxHealth
FnOff
End
Other code
End
sub(HLT
CurrentHealth+6
Return

Obviously that's not a good example, but ya. Just curious if that's kinda what ya mean.
Title: Re: How to use interrupts
Post by: Builderboy on September 02, 2010, 02:10:29 am
There are only 2 things wrong with that code.  1, its a Label, so you do Label HLT, not Sub(.  The second is to note that interrupts trigger many many times per second, even at the slowest rate, so the health would regenerate very quickly indeed :P
Title: Re: How to use interrupts
Post by: meishe91 on September 02, 2010, 02:17:42 am
Oh ok. I thought it was a sub-routine, misread that :P And for the sake of this we'll pretend the characters health is OVER 9000! :P
Title: Re: How to use interrupts
Post by: Builderboy on September 02, 2010, 02:19:31 am
Well it is a subroutine, which are defined with labels :) Sub() is the command to call a subroutine, not define it
Title: Re: How to use interrupts
Post by: meishe91 on September 02, 2010, 02:23:01 am
OH! That's right. My bad. Show's how much I use Axe :P
Title: Re: How to use interrupts
Post by: Hot_Dog on September 02, 2010, 10:44:50 am
By the way, you should take into account that at least in normal speed (6Mhz), the Ti-83+ has more interrupts per second than a Ti-83+ silver edition does.  It's roughly 110 interrupts per second for the Ti-83+ SE, and 120 interrupts per second for the Ti-83+. 

This was only tested on Wabbitemu, so please feel free to correct me.
Title: Re: How to use interrupts
Post by: calc84maniac on September 02, 2010, 10:48:40 am
Wikiti agrees with you: http://wikiti.brandonw.net/index.php?title=83Plus:Ports:04#Write_Values (http://wikiti.brandonw.net/index.php?title=83Plus:Ports:04#Write_Values)
Title: Re: How to use interrupts
Post by: Quigibo on September 02, 2010, 11:49:31 am
Also, you are increasing health by 6 each time but checking that it's equal to the max health.  If the current health is 999 and you add 6, that's 1005 which is not equal to 1000 and the health would continue to increase.
Title: Re: How to use interrupts
Post by: DJ Omnimaga on September 02, 2010, 01:44:59 pm
By the way, you should take into account that at least in normal speed (6Mhz), the Ti-83+ has more interrupts per second than a Ti-83+ silver edition does.  It's roughly 110 interrupts per second for the Ti-83+ SE, and 120 interrupts per second for the Ti-83+. 

This was only tested on Wabbitemu, so please feel free to correct me.
Could this be why on the 83+SE, most ASM games run slightly slower than on the regular 83+?
Title: Re: How to use interrupts
Post by: Michael_Lee on September 02, 2010, 01:58:23 pm
So if I set interrupts at a frequency of 6, how many times would it run in a second?  What unit does it mean by '6'?
Title: Re: How to use interrupts
Post by: Hot_Dog on September 02, 2010, 02:35:47 pm
So if I set interrupts at a frequency of 6, how many times would it run in a second?  What unit does it mean by '6'?

Unfortunately, it's not as simple as "units."

6 is the binary number 00000110.  Axe uses the 6th and 7th digits of this binary number to set an interrupt speed, because that's just the way the calculator works.  The calculator interrupt speed is set by a two-digit binary number, and Axe takes that number from the 6th and 7th binary digits of the number you specify. 

On a Ti-83+, if you specify a speed in axe of 0, the calculator reads the 6th/7th digits of the binary number 00000000 = 00, and it knows your interrupt routine should be run 560 times a second.  That's just the way the calculator works, it's a predefined interrupt speed.

If you specify a speed in Axe of 2, the calculator reads the 6th/7th digits of the binary number 00000010 = 01, and it knows your routine should be run 248 times a second.

If you specify a speed in Axe of 4, the calculator reads the 6th/7th digits of the binary number 00000100 = 10, and it knows your routine should be run 170 times a second.

If you specify a speed in Axe of 6, the calculator reads the 6th/7th digits of the binary number 00000110 = 11, and it knows your routine should be run 118 times a second.



Title: Re: How to use interrupts
Post by: Deep Toaster on September 02, 2010, 02:37:39 pm
OH is that how the Mirage speed settings work?
Title: Re: How to use interrupts
Post by: Hot_Dog on September 02, 2010, 02:47:07 pm
OH is that how the Mirage speed settings work?

Yes indeed, which is why it doesn't work for all programs.
Title: Re: How to use interrupts
Post by: Michael_Lee on September 02, 2010, 06:24:12 pm
Okay, so would the following work?

Code: [Select]
.TEST
DiagnosticOff
[FFFFFFFFFFFFFFFF]->Pic1
ClrDraw
0->A->B->C->D
fnInt(SEC,6)
While 1
If C>=118
FnOff
0->C
1+D->D
Text(60,60,D>Dec)
DispGraph
FnOn
(Code to move sprite around and exit)
End

Lbl SEC
C+1->C
Return

Lbl END
LnReg
DiagnosticOn
Return

I think it should post the second while allowing me to move my sprite around.
Title: Re: How to use interrupts
Post by: meishe91 on September 02, 2010, 06:34:19 pm
Also, you are increasing health by 6 each time but checking that it's equal to the max health.  If the current health is 999 and you add 6, that's 1005 which is not equal to 1000 and the health would continue to increase.

Oh, ya, I know. It was just a quick example. Not perfect or anything like that. Just to see if my thought was correct :)
Title: Re: How to use interrupts
Post by: Deep Toaster on September 02, 2010, 06:48:34 pm
@Michael_Lee: It should, don't know for sure, though...
Except for the fact that there should be another End.
Title: Re: How to use interrupts - getKey confusion
Post by: Michael_Lee on September 06, 2010, 08:07:50 pm
The following works:

Code: [Select]
.TEST
ClrDraw
0->A->B->C
fnINT(TIM,6)
While 1
    If getKey(4)
        1+C->C
        Text(0,0,C->DEC)
    End
    If getKey(15)
        Goto END
    End
    If A>=118
        0->A
        1+B->B
        Text(0,10,B->DEC)
    End
End

Lbl TIM
    1+A->A
Return

Lbl END
    FnOff
    LnReg
    ClrDraw

It acts as a timer while allowing me to increment the variable C at whim,
but if I try doing this:

Code: [Select]
.TEST
ClrDraw
0->A->B->C
fnINT(TIM,6)
While 1
    getKey->D
    If D=4
        1+C->C
        Text(0,0,C->DEC)
    End
    If D=15
        Goto END
    End

...etc.

the getkey doesn't appear to work, or store anything to the variable D.

Meh?  What gives?

(I added indents for clarity)
Title: Re: How to use interrupts
Post by: FinaleTI on September 06, 2010, 08:55:48 pm
I think that's because storing getkey to a pointer uses the OS interrupts and using a custom interrupt overrides the OS interrupt during program execution. Direct input doesn't rely on the OS interrupts, so that's why it works.
Title: Re: How to use interrupts
Post by: Quigibo on September 06, 2010, 10:04:39 pm
Yeah, the OS interrupt needs to be on in order to use the BASIC getkey because it has to detect when keys are pressed in the background.  You could tack on your own getkey routine for a few keys to the end of your interrupt if you really need a feature like that.
Title: Re: How to use interrupts
Post by: Michael_Lee on September 06, 2010, 11:29:03 pm
Ahh, that would be why. 
Well, thankfully, this isn't much of a problem.

btw, can you have more then one custom interrupt running at a time?
Title: Re: How to use interrupts
Post by: Quigibo on September 07, 2010, 12:20:36 am
You can't have more than one interrupt running at once independently meaning an interrupt that interrupts the main code and the other interrupt.  But you can have multiple interrupt routines at once for different frequencies. Lets say you want one interrupt at 110Hz and one at 22Hz.  What you can do is setup a single interrupt at 110Hz (number 6) that increments a timer and when the counter gets to 5, then you call the 22Hz routine which also resets the timer.
Title: Re: How to use interrupts
Post by: LordConiupiter on September 07, 2010, 01:48:40 am
And which frequency is the getKey command using? is it true that when I am going to add BGM, I can't use the getKey routine anymore?
Title: Re: How to use interrupts
Post by: Deep Toaster on September 07, 2010, 07:21:59 pm
Ahh, that would be why. 
Well, thankfully, this isn't much of a problem.

btw, can you have more then one custom interrupt running at a time?

You could add code to the end of one interrupt routine that basically jumps to the beginning of the second, so that you could run just the second routine or both.