This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's z80 & ez80 Assembly subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Z80 & 68k Assembly => z80 & ez80 Assembly
Author Message
Galandros


Active Member


Joined: 29 Aug 2008
Posts: 565

Posted: 25 Mar 2009 11:25:57 am    Post subject:

As the title says: How to set steady frame rate?
I don't know the right procedure to set that.

And what if calculations (like physics) avoid from reaching the frames per second? Or that is not a problem because it is supposed to not happen any time?

I have other problem but they are hard to write or say... As you explain I will ask other things.

And if you give an general idea and related problems say them.
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 25 Mar 2009 01:41:05 pm    Post subject:

Interrupts. They happen at a steady time, and can be used to update counters/do stuff.
Back to top
Galandros


Active Member


Joined: 29 Aug 2008
Posts: 565

Posted: 25 Mar 2009 04:32:50 pm    Post subject:

WikiGuru wrote:
Interrupts. They happen at a steady time, and can be used to update counters/do stuff.
Thinking about it, I actually see...

Interrupts when triggered changed some counters and the main loop would detect that, "acknowledge" and do things like update the screen.

You could even use interrupts to do more things like update the screen itself if needed? Or that is not optimal? Keeping the above implement is simpler...
Back to top
darkstone knight


Advanced Member


Joined: 07 Sep 2008
Posts: 438

Posted: 25 Mar 2009 04:51:29 pm    Post subject:

well...

suppose you have an interupt that does this:

LD HL,timer
inc (HL)
RET

and in your mainloop, you have this:

someroutine:
LD HL,timer
LD A,HL
CP 3
jr NC,$-2
xor a
LD (HL),A
RET

the loop would pause untill interupts triggered
to avoid the loop slowing down whit alot of items of the screen, consirder doing this:

someroutine:
LD HL,timer
LD A,HL
CP 3
jr NC,$+2+5
call fastcopy
jr $-3-2-3
xor a
LD (HL),A
RET

that way, the screen is only updated (updating the screen takes aprox 50% of the time in games) if the game completed the mainloop in 4/110 seconds or less (highly unlikely)
Back to top
cjgone
Aw3s0m3


Active Member


Joined: 24 May 2006
Posts: 693

Posted: 26 Mar 2009 01:44:02 am    Post subject:

The Way I keep frame rate stable is using interrupts. Have a counter in your interrupt and a check at the end of your program code in main loop. check the value in the counter into it has reached a specific number and just loop forever into the counter is equal to the desired value, and reset the counter. Interrupts run at a constant rate ( 1\60 seconds is normal time).

Obviously the delay will be longer then what the code needs to even out the field. Extremely taxing calculations that happen here and there can be considered anomalies and will probably drop the frame rate at intervals that are really rare and shouldn't be worried about.

To give an idea, my smooth scrolling game thingy i'm working on runs at about 2\60 seconds to complete at a good frame rate. So thats when the counter = 2at 1\60 second intervals. and thats like 30fps drawing and all teh stuff. When there's a lot of crap sometimes it might exceed 2\60 seconds for a code loop and there will be a noticable drop in frame rate, but it shouldn't be a big deal if it doesn't happen to often.. If it does, you just to increase your counter value, at the cost of slowing everything down to that slower speed.

Pretty much play around with the timer crystal to find a good interupt speed that gives your game or w\e the speed you like.



Code:
main:
xor a \ ld (count),a

Call DrawHappyFaces
Call Whateverhell_is_here

_pause:
ld a,(count)
cp 10; some number
jr nc,main; if a >= 10 then continue
jr _pause


interrupt:
;all that crap needed
ld a,(counter)
inc a
ld (counter),a



Darkstone has a similar way of doing it I think. I dunno if he's applying this to specific routines or the whole program. Dunno, both work I presume.
Quote:
LD HL,timer
LD A,(HL)
CP 3
jr NC,$-2
xor a
LD (HL),A
RET


Last edited by Guest on 26 Mar 2009 01:54:24 am; edited 1 time in total
Back to top
calc84maniac


Elite


Joined: 22 Jan 2007
Posts: 770

Posted: 26 Mar 2009 02:05:41 pm    Post subject:


Code:
LD A,(HL)
CP 3
jr NC,$-2
will freeze your calculator in all likelihood. I think
Code:
LD A,(HL)
CP 3
jr NC,$-3
would be more correct.
Back to top
darkstone knight


Advanced Member


Joined: 07 Sep 2008
Posts: 438

Posted: 26 Mar 2009 02:09:54 pm    Post subject:

uhm.. yea

by the way, dont use:

LD A,(myvar)
inc a
LD (myvar),A

use:

ld HL,myvar
inc (HL)

saves 3 bytes
Back to top
Galandros


Active Member


Joined: 29 Aug 2008
Posts: 565

Posted: 26 Mar 2009 04:11:59 pm    Post subject:

darkstone knight wrote:
uhm.. yea

by the way, dont use:

LD A,(myvar)
inc a
LD (myvar),A

use:

ld HL,myvar
inc (HL)

saves 3 bytes
But destroys hl. Anyway in a interrupt that is not a problem because of shadow registers.

Now I got the idea. cjgone explained the consequences of long calculations. Modifying the number of the counter needed may take in count more calculations but dropping frame rate.
Or you can do a more complex queue system but in a real time game brings many things down...

Thanks guys!
Back to top
Iambian


Advanced Member


Joined: 13 Mar 2004
Posts: 423

Posted: 26 Mar 2009 08:21:29 pm    Post subject:

Galandros wrote:
...

Now I got the idea. cjgone explained the consequences of long calculations. Modifying the number of the counter needed may take in count more calculations but dropping frame rate.
Or you can do a more complex queue system but in a real time game brings many things down...

Thanks guys!


You could try putting *all* of your game into a series of interrupts, a single interrupt performs a certain number of functions before the next interrupt is waited upon and occurs. The interrupt "counter" in this instance would dictate which task is next to come up. The task table could be written dynamically in some aligned spot of RAM ($8000 would be a good place for this) and then as the game progresses, the scheduled tasks would be performed, all of which would end up with an interrupt that draws to the LCD and would then reconstruct the table given what should occur next. Reading the keys could be done on that cycle.

CaDan uses a static version of this scheme, mostly for grayscale, but to also evenly time out some of the tasks that need to be done. Reconstructing the table in the example above wouldn't require much time if you knew, for instance, how many calculations would be done. In my game, the max number of calculations are already known and will not exceed the timing set forth in the interrupt routine (or if it does, the results won't be that noticeable; it achieves around 19FPS).

Yet just another way to make sure things go according to your timing.
Back to top
TKD_01


Advanced Newbie


Joined: 20 Feb 2009
Posts: 51

Posted: 10 Apr 2009 09:06:26 pm    Post subject:

Galandros wrote:
And what if calculations (like physics) avoid from reaching the frames per second? Or that is not a problem because it is supposed to not happen any time?

Generally, it's ok to have a non-regular spike in calculations every few seconds or so (~2-5 seconds), because any casual user would not notice them. What would be noticable is a constant, regular spike in calculations say every two seconds, because this makes the game/program seem choppy.

For example, let's use your physics idea. If you have a ball falling at a constant rate (just to make things nice), and it encounters a wall, several, if not hundreds, of calculations may be made to determine which direction to spit the ball out at, what speed to spit the ball out at, and for more complex programming, which direction the ball is spinning and how fast it's spinning. After the wall is hit, however, the ball continues in its normal, steady mainloop. This type of spike in code (or something of the like) is perfectly fine, and, once again, will not be noticable by most.
Back to top
Galandros


Active Member


Joined: 29 Aug 2008
Posts: 565

Posted: 13 Apr 2009 06:18:41 am    Post subject:

TKD_01 wrote:
Galandros wrote:
And what if calculations (like physics) avoid from reaching the frames per second? Or that is not a problem because it is supposed to not happen any time?

Generally, it's ok to have a non-regular spike in calculations every few seconds or so (~2-5 seconds), because any casual user would not notice them. What would be noticable is a constant, regular spike in calculations say every two seconds, because this makes the game/program seem choppy.

For example, let's use your physics idea. If you have a ball falling at a constant rate (just to make things nice), and it encounters a wall, several, if not hundreds, of calculations may be made to determine which direction to spit the ball out at, what speed to spit the ball out at, and for more complex programming, which direction the ball is spinning and how fast it's spinning. After the wall is hit, however, the ball continues in its normal, steady mainloop. This type of spike in code (or something of the like) is perfectly fine, and, once again, will not be noticable by most.

That was I wanted to know. But I thought of that while playing a recent game in a relatively slow computer... The game had moments of speed even with vsync on.


Appeared more questions:
When you disable interrupts, the timer for interrupts continue or stops?

Is possible to disable the TI-OS interrupt without disabling your custom interrupt? And odds of it disabled during a program and TI-OS normal execution xD


Last edited by Guest on 13 Apr 2009 06:26:37 am; edited 1 time in total
Back to top
cjgone
Aw3s0m3


Active Member


Joined: 24 May 2006
Posts: 693

Posted: 13 Apr 2009 05:03:19 pm    Post subject:

When you disable interrupts your timer will stop incrementing and your program will freeze up in an infinite loop when it reaches a timer check.

I'm pretty sure that the TI-OS uses im 1 and not im 2 so the Ti-OS is disabled when you run your custom interrupt in mode 2. That's why you must change it back to mode 1 before you end your program, or the calculator will crash.


And yea, Iambian's way is definitely the best, but harder to implement. An overall counter for the whole program is pretty simple--his idea is slightly harder. Both work tho.



P.s you could also calculate other stuff instead of wasting loops, ehh. ;o


Last edited by Guest on 13 Apr 2009 05:12:52 pm; edited 1 time in total
Back to top
darkstone knight


Advanced Member


Joined: 07 Sep 2008
Posts: 438

Posted: 13 Apr 2009 05:33:39 pm    Post subject:

well, iambians routine wont work for my game, the psychics (run once in 8 frames) take a RIDICULOUS amount of time te complete

when i add 4 halts (on non-psysic frames, duh), the game runs fairly consistant :biggrin: (about 1/30 sec......)

ima post the code soon, its only 10 lines... (a 58*22 arrays) Neutral
Back to top
Galandros


Active Member


Joined: 29 Aug 2008
Posts: 565

Posted: 14 Apr 2009 04:31:51 pm    Post subject:

cjgone wrote:
When you disable interrupts your timer will stop incrementing and your program will freeze up in an infinite loop when it reaches a timer check.

The timer I was referring is the timer that causes interrupts... Not the one you create.
For example, you had installed a interrupt. Somewhere you disable interrupts by di. When you enable with ei, is possible to happen a interrupt right after ei or the timer is kind of reset with di/ei?

cjgone wrote:
I'm pretty sure that the TI-OS uses im 1 and not im 2 so the Ti-OS is disabled when you run your custom interrupt in mode 2. That's why you must change it back to mode 1 before you end your program, or the calculator will crash.

Oh I finally understand why having to go back to im 1 and the concept of making a stay resident custom interrupt if you jump to the TI-OS routine (near $0038 if my memory is good)
Back to top
FloppusMaximus


Advanced Member


Joined: 22 Aug 2008
Posts: 472

Posted: 15 Apr 2009 01:04:25 pm    Post subject:

As long as the calculator is turned on, the interrupt timer runs continuously, firing three times every 1/118th of a second. An interrupt will be generated if the appropriate bit of port 3 is set at the time the timer fires. At that time, the hardware sets the Z80's /INT line low, and it will remain low until the CPU resets that bit of port 3.

Now as to how the CPU reacts: It will only acknowledge an interrupt after it has completed a full instruction, and only if IFF1 (the primary interrupt flip-flop) is set. So if you execute a DI and then do some work, and the timer fires during that time, the /INT line remains low until you execute an EI, and only then will the CPU jump to 0038 or the IM 2 handler or whatever. (In fact, the CPU also won't acknowledge an interrupt immediately after an EI - it waits until the next instruction finishes. That's why it's safe to end an ISR with "ei \ reti" or "ei \ ret".)

It's worth noting that timer interrupts don't get queued up. If you have interrupts disabled for more than 1/118th of a second (for example, if you're copying a full screen image to the LCD) then the timer will fire more than once, but you'll only ever see one interrupt. So if you want to use interrupts for precise timing, be sure that you actually enable interrupts periodically. For the same reason, you want to keep your ISR itself as short as possible. (Hint: if you're going to do a non-trivial amount of work in the ISR, then reset and set bit 1 of port 3 before you do that work. If a second interrupt occurs, it will be acknowledged immediately after your ISR finishes, taking advantage of the behavior of EI noted above.)
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    »
» View previous topic :: View next topic  
Page 1 of 1 » All times are UTC - 5 Hours

 

Advertisement