flat assembler
Message board for the users of flat assembler.

flat assembler > DOS > Good alternative for high-resolution timing?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Cas



Joined: 26 Feb 2004
Posts: 82
Location: Argentina
I know that, especially when in protected mode and at a ring other than 0, it may become very messy to deal with the timer and particularly to program it a higher frequencies than 18.2. But sometimes, I need an accurate way to measure time with high resolution, and even in real mode, many times the timer does not do.
One thing I sometimes find OK is to create very short delays, then repeat them and calculate how long they span. But delays have the inconvenience that... well, they are "delays"... and as such, they don't let you do anything while they are going. What is, then, a good alternative to the timer?

One example of how this can be necessary (although an old-fashioned example) is this: how did some old games and applications manage to sample WAV files through the PC speaker? Even some old games (Supaplex, Electro-body) did it while you where jumping and firing or being hit by a zonk! How could you handle such a fast and accurate timing rate if the PC speaker doesn't have something like an interface with a DMA, for instance?

Please somebody clear this doubt... It's a great mistery to me! Shocked

_________________
Ā«Earth is my country; science is my religionĀ» - Christian Huygens
Post 08 Dec 2009, 13:34
View user's profile Send private message Yahoo Messenger MSN Messenger Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA

_________________
----> * <---- My star, won HERE
Post 08 Dec 2009, 15:51
View user's profile Send private message Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
Before the days of windows and rtdsc, many people used the PIT timer described in detail here.

Quote:

read_PIT_count:
pushfd
cli
mov al, 00000000b ; al = channel in bits 6 and 7, remaining bits clear
out 0x43, al ; Send the latch command

in al, 0x40 ; al = low byte of count
mov ah, al ; ah = low byte of count
in al, 0x40 ; al = high byte of count
rol ax, 8 ; al = low byte, ah = high byte (ax = current count)
popfd
ret


It runs at 1.193MHz. This means that it is 65536 times faster than the int 1A clock. I may be wrong but I think the time in Linux and Windows is based on this clock.
Post 09 Dec 2009, 00:51
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
rCX wrote:
Before the days of windows and rtdsc, many people used the PIT timer described in detail here.

Quote:

read_PIT_count:
pushfd
cli
mov al, 00000000b ; al = channel in bits 6 and 7, remaining bits clear
out 0x43, al ; Send the latch command

in al, 0x40 ; al = low byte of count
mov ah, al ; ah = low byte of count
in al, 0x40 ; al = high byte of count
rol ax, 8 ; al = low byte, ah = high byte (ax = current count)
popfd
ret


It runs at 1.193MHz. This means that it is 65536 times faster than the int 1A clock. I may be wrong but I think the time in Linux and Windows is based on this clock.


To use channel 0 for high precision counting, you would need to reprogram it first. By default it has a divisor of 65535 or 65536(depending on the BIOS) and runs at 18.2065 Hz.
But changing channel 0 would mess up the system time, wouldn't it?

_________________
----> * <---- My star, won HERE
Post 09 Dec 2009, 01:04
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
Quote:

the system time, wouldn't it?

It would afect this
Code:
----------M0040006C--------------------------
MEM 0040h:006Ch - TIMER TICKS SINCE MIDNIGHT
Size:   DWORD
Desc:   updated approximately every 55 milliseconds by the BIOS INT 08 handler
SeeAlso: MEM 0040h:0070h,INT 08"IRQ0",INT 1A/AH=00h    


But you can fix it by calling the original interrupt handler at the appropriate intervals.
Post 09 Dec 2009, 01:21
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
LocoDelAssembly wrote:
Quote:

the system time, wouldn't it?

It would afect this
Code:
----------M0040006C--------------------------
MEM 0040h:006Ch - TIMER TICKS SINCE MIDNIGHT
Size:   DWORD
Desc:   updated approximately every 55 milliseconds by the BIOS INT 08 handler
SeeAlso: MEM 0040h:0070h,INT 08"IRQ0",INT 1A/AH=00h    


But you can fix it by calling the original interrupt handler at the appropriate intervals.


Oh ya, I remember now. I read about it here a long time ago, but forgot. That's a very useful article for PIT stuff. The code in it is in pascal, but is very easy to understand.

_________________
----> * <---- My star, won HERE
Post 09 Dec 2009, 01:51
View user's profile Send private message Reply with quote
Cas



Joined: 26 Feb 2004
Posts: 82
Location: Argentina
Thank you, guys! The RDTSC looks like the best to use now. On the other hand, old games must have used the PIT, then. I'm surprised of how they still produce reasonable sound output under emulators. My knowledge on the PIT was not very deep before, I see. I will study both technologies.
Post 09 Dec 2009, 03:13
View user's profile Send private message Yahoo Messenger MSN Messenger Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 688
Location: Adelaide
Do you want to measure time or clocks? The RDTSC reads the number of clock cycles, not time.
You can easily program the PIT for 1000Hz (milliseconds) even on an 8086.
Post 09 Dec 2009, 03:20
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4186
Location: 2018
i think that the timer tick after midnight register is not a critical value.
if not updated, it is not a problem isn't it?
Post 09 Dec 2009, 04:38
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
Quote:

if not updated, it is not a problem isn't it?

Perhaps some TSRs and DOS itself may need it (for file datetimes?). It depends on how much control you have over the environment, but to be sure you won't screw up your neighbors you better keep it running and at the expected rate. I don't remember if TSR were officially allowed to hook the INT 08 but in case they can, not calling the original handler at the expected intervals would make the TSR to stop working properly.
Post 09 Dec 2009, 05:13
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 688
Location: Adelaide
INT 1C is supposed to be the way to hook the timer (called by the BIOS INT 08 handler).

AFAIK DOS uses the ticks and midnight flag if there is no RTC.
The BIOS handles that flag, that's why you chain to the original INT 08
Post 09 Dec 2009, 05:35
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
> Oh ya, I remember now. I read about it http://www.qzx.com/pc-gpe/pit.txt

Good link, check also: http://www.sat.dundee.ac.uk/~psc/pctim003.txt

And the FAQ : http://board.flatassembler.net/topic.php?t=9473 "15. How to use timers / cause a delay ?"

> I know that, especially when in protected mode and at a ring
> other than 0, it may become very messy to deal with the timer

NO. The timer is accessible from any Ring (still not from NTVDM Laughing )

> need an accurate way to measure time with high resolution, and
> even in real mode, many times the timer does not do.

Why ??? Rise the PIT frequency Wink

> how did some old games and applications manage to sample WAV files through the PC speaker?

4 ways:

- delay loop
- delay using the PIT
- high frequency interrupt fired by the PIT Smile
- RDTSC (and WRTSC) (not 80486 and below)

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 11 Dec 2009, 01:49
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 754
Location: Massachusetts, USA
Ooh, a delay loop Smile
Code:
repeat 8
jmp $ + 2
end repeat
    

_________________
Coding a 3D game engine with fasm is like trying to eat an elephant,
you just have to keep focused and take it one 'byte' at a time.
Post 12 Dec 2009, 05:46
View user's profile Send private message Reply with quote
Asmix



Joined: 07 Sep 2004
Posts: 5
Location: Ukraine
CMOS REAL-TIME CLOCK

Int 70h is called when the real-time clock chip generates an alarm or periodic interrupt. The periodic interrupt by default occurs 1024 times per second.

May be masked by setting bit 0 on I/O port A1h

details here http://www.compuphase.com/int70.txt

_________________
2 beer or not 2 beer?
Post 13 Dec 2009, 12:40
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4186
Location: 2018
Quote:
RDTSC (and WRTSC) (not 80486 and below)


WRTSC is not fasm compilable.
i wonder if it exists in IA architecture.
Post 13 Dec 2009, 19:00
View user's profile Send private message Visit poster's website Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 294
Maybe as a macro for
Code:
mov ecx,10h
wrmsr    
Post 13 Dec 2009, 20:22
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
Post 15 Dec 2009, 02:51
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
Yep, pretty bad documentation, AMD's nor Intel's manuals mention such instruction.

Intel - Vol 3B wrote:
The RDMSR and WRMSR instructions read and write the time-stamp counter, treating
the time-stamp counter as an ordinary MSR (address 10H). In the Pentium 4, Intel
Xeon, and P6 family processors, all 64-bits of the time-stamp counter are read using
RDMSR (just as with RDTSC). When WRMSR is used to write the time-stamp counter
on processors before family [0FH], models [03H, 04H]: only the low-order 32-bits of
the time-stamp counter can be written (the high-order 32 bits are cleared to 0). For
family [0FH], models [03H, 04H, 06H]; for family [06H]], model [0EH, 0FH]; for
family [06H]], display_model [17H, 1AH, 1CH, 1DH]: all 64 bits are writable.
Post 15 Dec 2009, 04:31
View user's profile Send private message Reply with quote
Cas



Joined: 26 Feb 2004
Posts: 82
Location: Argentina
Wow! All those alternatives sound very useful!
For those who asked or mentioned... these are some points I wanted to state:
- DOS386... yes, you can use it on any ring, but I guess you can't change the frequency from a ring other than 0, because you have to access ports. Am I right?
- One concern about using high frequency PIT is that, if not in pure DOS, there is a chance that the code behind the INT08 is HUGE! If that is the case, a high frequency may cause the interrupt to be requested more often than it is possible, because it takes so long to return from it. Of course, the programmer of that HUGE code could have been good enough to make a good dispatcher and STI as soon as possible, but... you never know... This would make the system unstable and the time measure inaccurate
- I'm interested in measuring time, not clocks, but I know that, with one loop, I can calculate the proportion and then use the TSC to measure time as well. Unless I'm using an incredibly high resolution, this should not create considerable errors, would it? Still, when it regards to old games sampling through the PC speaker, I understand they couldn't possibly have used this method
- One example of when I would need this high resolution is this: suppose I want a routine to run at the start of every vertical retrace, but my board, as many others, does not support interrupt triggering. I have no option but to poll, but then, if I'm busy doing other things, when my polling tells me there's a VR going on, it may be just about to end... so I have to "sit and wait" for it! What if I'm busy doing other things?
- Another example... suppose I'm recording audio in CD resolution to a buffer and I want my application to react immediately if a sound of a certain type (i.e.: a square wave of a given frequency) enters the buffer. I would need to be checking the buffer freq/2 times, that is, at 22KHz. Of course, if the "reaction" is only meant to be directed to the human user, I understand that 25Hz would be enough, as the conscious part of the brain understands as "immediate" anything that happens within about 1/25th of a second, but that does not have to be the case.

QUESTION:
Can I have different frequencies for the different PIT channels and.... while not using the PC speaker (having the output off all time)... use its channel for other purposes? This would be a good background counter, compatible with very old hardware, and not calling interrupts all the time, so it would be stable as well Smile
Post 17 Dec 2009, 02:59
View user's profile Send private message Yahoo Messenger MSN Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16586
Location: Earth 2.0 beta
Cas wrote:
yes, you can use it on any ring, but I guess you can't change the frequency from a ring other than 0, because you have to access ports. Am I right?
There is a mechanism in the x86 CPUs that allows selected port access from any ring. The selected ports can be any combination from none to all ports allowed. You just have to update a bitmap array to enable particular ports for access.
Post 17 Dec 2009, 03:15
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.