Welcome to Emulationworld

Forum Index | FAQ | New User | Login | Search

Make a New PostPrevious ThreadView All ThreadsNext Thread*Show in Threaded Mode


SubjectJust a matter of time...Assembly fun cont'd new Reply to this message
Posted bySnowball 2
Posted on11/29/03 02:46 AM



So I've got a happy little program running now with all the fun stuff I wanted to do. My remaining issue? TIMING! I've got an assortment of graphics that I've animated but unfortunately they either animate too fast or too slow depending on who's system I'm running it on. A few threads down I'd gotten some help from Bart T. The waitvsync procedure even works well for me. The only problem is that it doesn't want to do the same thing on different systems. I use it to regulate my framerate on my laptop but so far that I've seen it that can be faster or slower on other machines. I searched around the net and sites make mentions of the 18.2mhz timer that is native to DOS I'm guessing? How can I access this timer? I haven't been able to find the interrupt to do this.

Right now I just need some timer that is regulated the same across Windows platforms or something reasonably close. Can anyone offer up some more help? Thanks to all for contributing. I never thought I'd get this far with it.






SubjectRe: Just a matter of time...Assembly fun cont'd Reply to this message
Posted byRiff
Posted on11/29/03 03:15 AM



If you only need 18.2 ms resolution, you can use the Win32 SetTimer API function. You can set it up to either call a callback function or post a WM_TIMER message to your window procedure.

For animation, I recommend using the multimedia timer interface which is provided by the winmm DLL. The mmtimer related functions will allow similar callbacks as the standard timer interface but the resolution may be, and usually is, as small as one millisecond.

> Right now I just need some timer that is regulated the same across Windows
> platforms or something reasonably close. Can anyone offer up some more help?
> Thanks to all for contributing. I never thought I'd get this far with it.
>
>
>



SubjectSome background new Reply to this message
Posted bySnowball 2
Posted on11/29/03 03:40 AM



This being my first semester with assembly I couldn't honestly say I know how to do either of those things. What I'm writing is in 16 bit real addressing mode written for use with Tasm. I just read about 3 billion things on the 8253 PIT and I can see how it is that I can access it with OUT but I'm at a loss as to how I can set this to speed up/slow down my program. I wish I had a bit more experience with assembly but my knowledge is thus far rudimentary. Can I do what you said with my program?






SubjectRe: Some background new Reply to this message
Posted byRiff
Posted on11/29/03 04:01 AM



Its a different story when running in virtual mode. I'm not sure how consistent the various flavors of Windows are going to be, but you're essentially going to have to program the 8254 to run at 10 Mhz, set the counter to reset/reload mode with an appropriate value to trigger an interrupt every millisecond and then use an interrupt handler to do your animation control. The usage should be fairly obvious if you are doing time-based animation

I don't recall which vectors are used by the 8254 in the PC. All you need to do is store your interrupt handler address into the table when the program begins and restore the old value when the program exits. There is a BIOS handler which will do this.

Rif> This being my first semester with assembly I couldn't honestly say I know how to
> do either of those things. What I'm writing is in 16 bit real addressing mode
> written for use with Tasm. I just read about 3 billion things on the 8253 PIT



SubjectRe: Some background new Reply to this message
Posted byabcdef
Posted on11/29/03 07:27 AM



WM_TIMER has no reasonable accuracy.
GetTickCount has a little higher accuracy, it returns the number of ms since Windows was started.
QueryPerformanceCounter has the best accuracy, but requires hardware that doesn't exist on all machines.

Use some API reference or MSDN for details.


SubjectAlright I gotta have you be a little more descriptive here new Reply to this message
Posted bySnowball 2
Posted on11/29/03 01:39 PM



I know that you're trying to show me how to set up some sort of timer but I'm not too clear on to how exactly that is happening. If you could elaborate?

> Its a different story when running in virtual mode. I'm not sure how consistent
> the various flavors of Windows are going to be, but you're essentially going to
> have to program the 8254 to run at 10 Mhz,

Why? Is that the speed I'm looking for?

set the counter to reset/reload mode
> with an appropriate value to trigger an interrupt every millisecond and then use
> an interrupt handler to do your animation control.

Never made an interrupt handler. How would I substitute it for the old one and what would it do differently? What's an appropriate value to make it trigger?

The usage should be fairly
> obvious if you are doing time-based animation
>
> I don't recall which vectors are used by the 8254 in the PC. All you need to do
> is store your interrupt handler address into the table when the program begins
> and restore the old value when the program exits. There is a BIOS handler which
> will do this.

I think I saw something like that but where would I store my new interrupt handler? What is it doing to slow down timing and animations?











SubjectRe: Alright I gotta have you be a little more descriptive here new Reply to this message
Posted byBart T.
Posted on11/29/03 03:05 PM



> > Its a different story when running in virtual mode. I'm not sure how
> consistent
> > the various flavors of Windows are going to be, but you're essentially going
> to
> > have to program the 8254 to run at 10 Mhz,
>
> Why? Is that the speed I'm looking for?

I'm not sure why Riff suggested 10MHz... AFAIK, it can't even clock that high.

What you want to do is lock your game to a fixed frame rate. I'm not completely sure how games like Quake III work -- they seem to render as fast as your hardware allows and sychronize game logic to some other frequency, or they interpolate movement for each frame based on how fast the graphics are being rendered, I can't say for sure.

What rate you need is up to you. VGA refreshes at 70Hz. It should be the same on ALL platforms. If you run it windowed on different platforms, you will see speed differences because VSync doesn't work in a window (I'm assuming Windows just doesn't handle it unless it's in full screen mode.)

You can try 30Hz, 50Hz, 60Hz, or 70Hz. What you'll want to do is program the timer to generate interrupts at these frequencies. Each time an interrupt is generated, your interrupt handler catches it and sets a memory flag.

Then, your main loop waits for this memory lap to become 1. When it does, you clear it, perform your game logic, draw the screen, and loop. When drawing, you may still want to wait for VSync before blitting.

> Never made an interrupt handler. How would I substitute it for the old one and
> what would it do differently? What's an appropriate value to make it trigger?

There should be plenty of documentation out there for the 8254 PIT. Intercepting interrupts is easy: You just overwrite the interrupt vector to point at your interrupt handler.

When you're done, restore the old pointer.

DOS uses that same interrupt handler to keep track of time. It assumes the timer is running at 18.2Hz. I think replacing the handler can cause system time on Win9X and DOS systems to drift, but I'm not sure (it certainly will on a DOS system.)

The solution is to jump to DOS's handler at 18.2Hz (you have to calculate on which ticks to do this in the interrupt handler by using some fixed-point math.) You probably don't need to worry about that now, just getting it to work will be your main concern.


----
Bart


SubjectRe: Alright I gotta have you be a little more descriptive here new Reply to this message
Posted byfinaldave
Posted on12/02/03 06:36 AM



> > > Its a different story when running in virtual mode. I'm not sure how
> > consistent
> > > the various flavors of Windows are going to be, but you're essentially going
> > to
> > > have to program the 8254 to run at 10 Mhz,
> >
> > Why? Is that the speed I'm looking for?
>
> I'm not sure why Riff suggested 10MHz... AFAIK, it can't even clock that high.

Is it really necessary to reprogram timers and use interrupts?
That was scary enough in Protected mode, never mind Real mode

Did DOS really never have any kind of out of the box pollable timer which did 1/70 second accuracy?



SubjectRe: Alright I gotta have you be a little more descriptive here new Reply to this message
Posted byBart T.
Posted on12/02/03 11:34 AM




> Did DOS really never have any kind of out of the box pollable timer which did
> 1/70 second accuracy?

The VGA VSync occured at 70Hz for 320x200. For 320x240 Mode X, it was 60Hz.

The PIT can be programmed and it certainly can handle these sorts of resolutions.


----
Bart


SubjectRe: Alright I gotta have you be a little more descriptive here new Reply to this message
Posted byfinaldave
Posted on12/03/03 08:04 AM



>
> > Did DOS really never have any kind of out of the box pollable timer which did
> > 1/70 second accuracy?
>
> The VGA VSync occured at 70Hz for 320x200. For 320x240 Mode X, it was 60Hz.

Can you poll for a vblank flag or a scanline or something then?

>
> The PIT can be programmed and it certainly can handle these sorts of
> resolutions.
>
>
> ----
> Bart
>


You learn something old everyday...



SubjectRe: Alright I gotta have you be a little more descriptive here new Reply to this message
Posted byBart T.
Posted on12/03/03 11:14 AM



> Can you poll for a vblank flag or a scanline or something then?

You can poll for VBlank. There is a VGA flag that is set for the duration of this period. I posted code for it in this thread.


----
Bart


SubjectRe: Alright I gotta have you be a little more descriptive here new Reply to this message
Posted bysmf
Posted on12/04/03 06:02 AM



the geforce 2 go in my old laptop never went into vblank, which was a bit annoying.

smf





Previous ThreadView All ThreadsNext Thread*Show in Threaded Mode