VOGONS


First post, by Bondi

User metadata
Rank Oldbie
Rank
Oldbie

I'm writing a little programm in assembly language and need some help. I'm trying to get 1 ms delay.
Now this code below counts clock ticks, but to my understanding it's min delay is arounf 50 ms. if delay variable is set to 1. 18 is around one second.

delay:
pusha
pushf

mov ah, 0
int 1ah
mov di, 18 ;delay variable
mov ah, 0
int 1ah
mov bx, dx

wait:
mov ah, 0
int 1ah
sub dx, bx
cmp di, dx
ja wait
popf
popa
ret

There is also this simple loop. But not sure what loop count value to set on a P200 Mhz to have 1 millisecond delay?

mov cx, 10000 ;loop count
.delay:
nop
loop .delay

Last edited by Bondi on 2022-09-25, 19:07. Edited 1 time in total.

PCMCIA Sound Cards chart
archive.org: PCMCIA software, manuals, drivers

Reply 1 of 9, by Azarien

User metadata
Rank Oldbie
Rank
Oldbie

It's hard to get precise delays as short as 1 ms on a PC.
Why do you think you need 1 ms delay?

Reply 3 of 9, by Namrok

User metadata
Rank Oldbie
Rank
Oldbie

Funny, I'm in a similar boat to you, in that I'm learning assembly, and was wondering how measure time relatively accurately. I found this article pretty helpful.

https://www.xtof.info/Timing-on-PC-familly-un … and-programming

My understanding is that the best approach might be to reprogram the CTC chip to have the IRQ0 timer go off at the desired interval. But also keep count and make sure you chain the interrupt to the standard DOS version roughly 18.2 times a second/every 55 ms, so DOS keeps proper time and continues doing all the things it expects to do 18 times a second.

This article was also helpful

https://wiki.osdev.org/Programmable_Interval_Timer

Win95/DOS 7.1 - P233 MMX (@2.5 x 100 FSB), Diamond Viper V330 AGP, SB16 CT2800
Win98 - K6-2+ 500, GF2 MX, SB AWE 64 CT4500, SBLive CT4780
Win98 - Pentium III 1000, GF2 GTS, SBLive CT4760
WinXP - Athlon 64 3200+, GF 7800 GS, Audigy 2 ZS

Reply 4 of 9, by Bondi

User metadata
Rank Oldbie
Rank
Oldbie

Thank you for your respond and for the links, Namrok. Yes, reprograming the timer is one of the options. One thing I did not like about it is that it messes up the time. So need to see further how to keep it updated correctly, guess this is what you meant by chaining the interrupt to keep proper time. On the other hand the programm runs just for seconds, I could just program the timer back to normal in the end and ignore the discrepancy.
Another thing I wnat to do for now is just to measure the simple loop timings and find the right value. Very straight forward and inflexible, yet easy 😀

Namrok wrote on 2022-09-26, 00:23:
Funny, I'm in a similar boat to you, in that I'm learning assembly, and was wondering how measure time relatively accurately. I […]
Show full quote

Funny, I'm in a similar boat to you, in that I'm learning assembly, and was wondering how measure time relatively accurately. I found this article pretty helpful.

https://www.xtof.info/Timing-on-PC-familly-un … and-programming

My understanding is that the best approach might be to reprogram the CTC chip to have the IRQ0 timer go off at the desired interval. But also keep count and make sure you chain the interrupt to the standard DOS version roughly 18.2 times a second/every 55 ms, so DOS keeps proper time and continues doing all the things it expects to do 18 times a second.

This article was also helpful

https://wiki.osdev.org/Programmable_Interval_Timer

PCMCIA Sound Cards chart
archive.org: PCMCIA software, manuals, drivers

Reply 5 of 9, by bakemono

User metadata
Rank Oldbie
Rank
Oldbie

You don't necessarily need to reprogram the PIT to use it for finer resolution, the first channel is normally running at ~1.2MHz already and you can read the current count from IO port 40h any time you want. The problem is that the channel mode is not configured the same on every PC so you'll probably want to detect the actual counter speed first (otherwise you can be off by a factor of 2 sometimes). That, and just being sure to deal with overflow properly and not to get the high and low bytes mixed up.

If your program doesn't need to run on anything less than a Pentium you can always use RDTSC.

GBAJAM 2024 submission on itch: https://90soft90.itch.io/wreckage

Reply 6 of 9, by Bondi

User metadata
Rank Oldbie
Rank
Oldbie

Thanks for the info, bakemono. RDTSC is not an option, unfortunately, as I intend to use the program on a 486 eventually.
I'll look at how I can use the 40h port anyways. Should not be difficult to detrmine the count speed.

PCMCIA Sound Cards chart
archive.org: PCMCIA software, manuals, drivers

Reply 7 of 9, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

pit countdown timer is buggy in a lot of systems. if RDTSC is not an option your chances are low 🤣 (rdtsc is also unreliable if its a laptop and speeds up or down etc)... . normal irq0 is 18.2 ticks a second, or 1 IRQ firing every 52ms give or take.

so you can hook IRQ0, and read timer, while read timer() == what I read before..

or simpler, hook IRQ0, the moment it triggers, set a value. because you only need 1 irq trigger.

the PC timers are all crappy so your in the weeds, especially with such small fine grained timing.

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 8 of 9, by mkarcher

User metadata
Rank l33t
Rank
l33t
bakemono wrote on 2022-09-26, 11:14:

The problem is that the channel mode is not configured the same on every PC so you'll probably want to detect the actual counter speed first (otherwise you can be off by a factor of 2 sometimes). That, and just being sure to deal with overflow properly and not to get the high and low bytes mixed up.

To do the stuff right, use the readback mode of the 8254 (so you need an AT at least), and capture status, low count and high count in that command. If the PIT is in square wave mode (mode 3), it will count in steps of two and toggle the output bit every time it expires. The status byte tells you the mode (so you know whether you need square wave "adjustment"), and it will also tell you whether the output is currently high or low. Armed with this knowledge, you should be able to read the PIC "good enough" for most general purpose applications without any need of reprogramming.