<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>'How to make a timer?' Thread RSS Feed</title>
    <link>http://www.programmersheaven.com/</link>
    <description>Contains the latest posts from the thread 'How to make a timer?' posted on the 'x86 Assembly' forum at Programmer's Heaven.</description>
    <language>en</language>
    <copyright>Copyright 2010 Programmers Heaven</copyright>
    <pubDate>Wed, 17 Mar 2010 19:10:00 -0700</pubDate>
    <lastBuildDate>Wed, 17 Mar 2010 19:10:00 -0700</lastBuildDate>
    <generator>Argotic Syndication Framework 2007.3.0.1, http://www.codeplex.com/Argotic</generator>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <ttl>360</ttl>
    <image>
      <url>http://www.programmersheaven.com/images/ph.gif</url>
      <title>Programmers Heaven</title>
      <link>http://www.programmersheaven.com/</link>
      <width>88</width>
      <height>31</height>
    </image>
    <item>
      <title>How to make a timer?</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/213254/how-to-make-a-timer/</link>
      <description>This is what I came up with by my self, but I am sure there are other ways to make a computer "sleep" for a certain time. I was thinking more in the lines of multi-tasking so that a processor could perform other actions (like tracking a mouse or making calculations) while it's sleeping. Any ideas?&lt;br /&gt;
&lt;br /&gt;
MOV     BH,05h  ;set sleeping time for 5 seconds&lt;br /&gt;
MOV     AH,2Ch&lt;br /&gt;
INT       21h   ;call interupt to record the current time&lt;br /&gt;
MOV    [DI],DH  ;record the number of seconds to memory&lt;br /&gt;
&lt;br /&gt;
label1:                     &lt;br /&gt;
INT       21h   ;call interupt again to record the current time&lt;br /&gt;
SUB      DH,[DI] ;subtract first time form second time&lt;br /&gt;
CMP     DH,BH ;compare the time passed to the time needed to pass&lt;br /&gt;
JB         label1 ;jump to the top if 5 seconds didn't pass&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/213254/how-to-make-a-timer/</guid>
      <pubDate>Thu, 18 Sep 2003 19:26:46 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: How to make a timer?</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/213256/re-how-to-make-a-timer/#213256</link>
      <description>&lt;span style="color: Green;"&gt;&lt;br /&gt;
In the BIOS memory segment their is a Dword that counts the&lt;br /&gt;
seconds since midnight.  You can check that for time+wait_time.&lt;br /&gt;
0040:006Ch or&lt;br /&gt;
0000:046Ch it's the same address.&lt;br /&gt;
XOR AX,AX&lt;br /&gt;
MOV ES,AX&lt;br /&gt;
MOV EAX,[ES:046Ch] ; git the Dword (HI nybble is always 0)&lt;br /&gt;
ADD EAX,TIMEtoKILL&lt;br /&gt;
Then have the check time in your mouse check loop,&lt;br /&gt;
or have your check mouse in your time check loop.&lt;br /&gt;
&lt;br /&gt;
0000:046Ch updates it's self about 18 times a second? (I think?)&lt;br /&gt;
You could check into that.&lt;br /&gt;
But their is always problems around midnight.&lt;br /&gt;
Use a JA or JB condition to check cause JE or JZ may not hit the&lt;br /&gt;
exact number and you'll have to loop to get to another try.&lt;br /&gt;
And that's a day on the Dword, but you can just use the LO word of it.&lt;br /&gt;
MOV AX,[ES:046Ch] ; git the LOword&lt;br /&gt;
&lt;br /&gt;
AH=86h&lt;br /&gt;
CX:DX = time to kill in increments of 976&lt;br /&gt;
INT 15h&lt;br /&gt;
since 0-975 is 976 start with DX=975 and add 976 to it for more&lt;br /&gt;
time killing.  My tests revieled that if the CX:DX input is off&lt;br /&gt;
of a 976 multiple -1 the time kilt is off.&lt;br /&gt;
&lt;br /&gt;
Maybe that will help&lt;br /&gt;
Bitdog&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/213256/re-how-to-make-a-timer/#213256</guid>
      <pubDate>Thu, 18 Sep 2003 20:30:56 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: How to make a timer?</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/213265/re-how-to-make-a-timer/#213265</link>
      <description>&lt;em&gt;You can do this by intercepting INT 1C, or INT 08, for example, to decrement a counter.&lt;/em&gt;&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
	mov	timer,number_of_seconds
	mov	ax,351ch
	int	21h
	mov	int1cOff,bx
	mov	int1cSeg,es
	mov	ah,25h
	mov	dx,offset int1cProc
	int	21h
&lt;/pre&gt;&lt;br /&gt;
&lt;em&gt;Then, you can test any time if the counter has been reset:&lt;/em&gt;&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
timer_loop:
	mov	ax,3
	int	33h
	cmp	cx,mouse_x
	jz	mouse_pos_changed
	cmp	dx,mouse_y
	jz	mouse_pos_changed
	cmp	bx,mouse_btn
	jz	mouse_btn_changed
	mov	ah,1
	int	16h
	jnz	key_pressed
	.
	.
	.
	cmp	timer,0
	jnz	timer_loop
&lt;/pre&gt;&lt;br /&gt;
&lt;em&gt;INT 1c would do something like this:&lt;/em&gt;&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
int1cProc:
	pushf
	push	ax
	mov	al,0
	out	70h,al		;read number of seconds
	nop
	in	al,71h
	cmp	al,cs:second
	pop	ax
	jnz	timer_not_0
	dec	cs:timer		;if number of seconds changed, then 
					;decrement cs:timer
	jnz	timer_not_0		;if timer=0
	push	ds			;then restore old vector
	push	0
	pop	ds
	cli
	push	cs:int1cOff
	pop	ds:[1ch*4]
	push	cs:int1cSeg
	pop	ds:[1ch*4+2]
	sti
	pop	ds

timer_not_0:
	popf
	jmp	dword ptr cs:int1cOff
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/213265/re-how-to-make-a-timer/#213265</guid>
      <pubDate>Thu, 18 Sep 2003 22:45:16 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: How to make a timer?</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/213446/re-how-to-make-a-timer/#213446</link>
      <description>&lt;span style="color: Blue;"&gt;&lt;br /&gt;
Nice work on the INT 1Ch vector timer.&lt;br /&gt;
I hope my added info is accruate.&lt;br /&gt;
Hook INT 1Ch it's a user available routine that is simply an IRET&lt;br /&gt;
it's called by INT 8 (it's better not to hook INT 8)&lt;br /&gt;
Your INT 1Ch routine could just increment a word/Dword in your program&lt;br /&gt;
that can be zeroed out at any time by your program then loop untill&lt;br /&gt;
you've waited the desired time/increments.&lt;br /&gt;
The INT 1Ch de/increments the word 18.2065 times a second er 18hz, not high resolution, but real usefull. So your check CMOS seconds changing&lt;br /&gt;
gets checked 18 times per change and only gives you a one second resolution that is often off since your start second doesn't start&lt;br /&gt;
exactly on the second change, but might be in the half second,&lt;br /&gt;
so if you want to wait one second, you may only wait 1/100000 of a second or less.&lt;br /&gt;
But at 18hz, a one second delay could be up to 1/18 second off + or -.&lt;br /&gt;
So the simple INT 1Ch increment a Dword, works real well.&lt;br /&gt;
&lt;br /&gt;
Reading CMOS bytes 0-9 should only be done if bit-7 of CMOS byte 10 is clear.  Other wise yer reading the BCD bytes 0-9 during a time update cycle and could be wrong.&lt;br /&gt;
AAM 16&lt;br /&gt;
AAD ; change AL BCD # to unsigned decimal in AL&lt;br /&gt;
&lt;br /&gt;
(I hope that helps somehow.)&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/213446/re-how-to-make-a-timer/#213446</guid>
      <pubDate>Sat, 20 Sep 2003 01:35:27 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: A 1/10000 second delay</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/213525/re-a-110000-second-delay/#213525</link>
      <description>I need a better sample rate than a second, at least 1/1000 of a second. I was using INT 21h with AH set to 2C because it puts 1/100 of second into DL register - but it's still to small. Do the new computers have an interupt that records smaller time increments? I have a realy old book and I couldn't find what INT 1Ch or INT 08h does. I found a website that talks very little about these interupts but that's it:&lt;br /&gt;
&lt;a href="http://et.nmsu.edu/~etti/winter97/computers/logic/logic.html"&gt;http://et.nmsu.edu/~etti/winter97/computers/logic/logic.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
What book would you suggest or maybe there is a website?&lt;br /&gt;
&lt;br /&gt;
I don't realy understand the codes u guys gave me, but it seems that you all use a loop to check for change in the timer, right? I suppose there couldn't be any other way. Thanx for your replies.&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/213525/re-a-110000-second-delay/#213525</guid>
      <pubDate>Sat, 20 Sep 2003 12:17:40 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: A 1/10000 second delay</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/213529/re-a-110000-second-delay/#213529</link>
      <description>&lt;span style="color: Green;"&gt;&lt;br /&gt;
pctim003.zip&lt;br /&gt;
has details on a variety of timer types,&lt;br /&gt;
I think it's available here in Programmers Heaven also?&lt;br /&gt;
If not, do a www.google.com search for it.&lt;br /&gt;
I think there is a previous post (a month old?)&lt;br /&gt;
that has a link to pctim003.zip ?&lt;br /&gt;
&lt;br /&gt;
If yer doing Sound Blaster direct mode record/play&lt;br /&gt;
you'll want PIT chip info in Ralf Browns INTER61D.ZIP&lt;br /&gt;
PIT = Programmable Interval Timer&lt;br /&gt;
although pctim003.zip has info on it too.&lt;br /&gt;
&lt;br /&gt;
For a smooth kill time, I've made a proc that checks how many times&lt;br /&gt;
the CPU loops in a given time span like 1/18 = one [0000:046Ch] increment&lt;br /&gt;
then use that loop count as a kill time loop count.&lt;br /&gt;
Increment EAX for a fine resolution,&lt;br /&gt;
check the loop time a few times,&lt;br /&gt;
and keep/use the highest value, or an average value of the returns.&lt;br /&gt;
Using this, different CPU mhz speeds kill the same amount of time,&lt;br /&gt;
and the loop count can be inc/dec for a finer resolution.&lt;br /&gt;
I had a little running man graphics that ran smooth that way,&lt;br /&gt;
where other timers didn't work well at all&lt;br /&gt;
since the first time get could be half way through a cycle or more.&lt;br /&gt;
&lt;br /&gt;
TOP: ;recieves CX = kill time count&lt;br /&gt;
IN AL,61h ; safely kill a microsecond&lt;br /&gt;
JMP SHORT $+2 ; won't jump untill I/O port recovery has occured&lt;br /&gt;
LOOP TOP ;this proc is just another try at time killing&lt;br /&gt;
RET&lt;br /&gt;
&lt;br /&gt;
gud luk&lt;br /&gt;
Bitdog&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/213529/re-a-110000-second-delay/#213529</guid>
      <pubDate>Sat, 20 Sep 2003 12:42:28 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: How to make a timer?</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/219408/re-how-to-make-a-timer/#219408</link>
      <description>: &lt;pre class="sourcecode"&gt;
: timer_loop:
: 	mov	ax,3
: 	int	33h
: 	cmp	cx,mouse_x
: 	jz	mouse_pos_changed
: 	cmp	dx,mouse_y
: 	jz	mouse_pos_changed
: 	cmp	bx,mouse_btn
: 	jz	mouse_btn_changed
: 	mov	ah,1
: 	int	16h
: 	jnz	key_pressed
: 	.
: 	.
: 	.
: 	cmp	timer,0
: 	jnz	timer_loop
: &lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The INT 33h interface allows you to "install" event handlers for clicks, cursor moves, etc. so polling isn't really required IIRC.&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/219408/re-how-to-make-a-timer/#219408</guid>
      <pubDate>Tue, 21 Oct 2003 17:39:09 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: I need a millisecond delay..</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/219606/re-i-need-a-millisecond-delay/#219606</link>
      <description>Can any one show me a code that makes a millisecond delay?&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/219606/re-i-need-a-millisecond-delay/#219606</guid>
      <pubDate>Wed, 22 Oct 2003 14:59:18 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: I need a millisecond delay..</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/219612/re-i-need-a-millisecond-delay/#219612</link>
      <description>&lt;strong&gt;&lt;span style="color: Red;"&gt;This message was edited by Moderator at 2003-10-22 15:31:36&lt;/span&gt;&lt;/strong&gt;&lt;hr /&gt;&lt;br /&gt;
I think this should work.&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
;NASM code:

Count equ 1193 ;1193182 / 1000 and round.
PIT_Setup equ 10110110b
ModeControlReg equ 43h
TimerCountReg equ 42h

in al,61h ;This turns off the internal speaker b/c we're changing the freq.
and al,~((1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;0)) ;Clear bits 1 and 0.
out 61h,al

mov al,PIT_Setup ;Get the last PIT counter set up for the count down.
out ModeControlReg,al
mov al,Count &amp;amp; ((1&amp;lt;&amp;lt;8) - 1) ;Get the LSB
out TimerCountReg,al
mov al,Count &amp;gt;&amp;gt; 8 ;Get the MSB
out TimerCountReg,al

Wait:
in al,TimerCountReg
mov bl,al
in al,TimerCountReg
or al,bl
test al,al ;If AL == 0 (both AL and BL were zero), then ZF gets set.
jnz Wait

;...
&lt;/pre&gt;&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/219612/re-i-need-a-millisecond-delay/#219612</guid>
      <pubDate>Wed, 22 Oct 2003 15:31:17 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>ahhhh Programming is tough</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/223401/ahhhh-programming-is-tough/#223401</link>
      <description>Sorry I don't understand your code. Can you refine it more. Here is a timer I made before all these posts and I need something that could replace those timer blocks with something that can time below a millisecond.&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
ADD      SP,0100h         ;Setting the stack pointer to 256 bits,
MOV     CX,0005h

label2:
PUSH    CX
MOV     AX,0034h
MOV     DX,0378h
OUT      DX,AX
MOV     AX,0001h         ;This block sends 34h to parallel port
MOV     DX,037Ah
OUT      DX,AX
MOV     AX,000Ch
OUT      DX,AX


MOV     BH,01h
MOV     AH,2Ch
INT       21h
MOV    [DI],DH
label1:                  ;This block is timer #1
INT       21h
SUB      DH,[DI]
CMP     DH,BH
JB       label1


MOV     AX,0048h
MOV     DX,0378h
OUT      DX,AX
MOV     AX,0001h
MOV     DX,037Ah         ;This block sends 48h to parallel port
OUT      DX,AX
MOV     AX,000Ch
OUT      DX,AX


MOV     BH,01h	   ;Set delay to 1 second
MOV     AH,2Ch	   ;Interupt 21 function 2C
INT       21h
MOV    [DI],DH	   ;Copy current time in seconds to memory
label3:                  ;This block is timer #2
INT       21h	   ;Get new time
SUB      DH,[DI}   ;Get time elapsed
CMP     DH,BH	   ;Compare the elapsed time to BH
JB       label3    ;Jump to label3 if DH is smaller than BH


POP      CX
LOOP   label2       ;Loop to the biggining and repeat 5 times

INT      20h
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/223401/ahhhh-programming-is-tough/#223401</guid>
      <pubDate>Sun, 09 Nov 2003 20:02:26 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: ahhhh Programming is tough</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/223403/re-ahhhh-programming-is-tough/#223403</link>
      <description>Have you tried a simple time delaying loop?&lt;br /&gt;
TTIME EQU 0xFFFF ;at top of code&lt;br /&gt;
&lt;br /&gt;
 MOV CX,TTIME&lt;br /&gt;
KILLT:&lt;br /&gt;
 NOP ;add more NOP instructions, delays more time&lt;br /&gt;
 LOOP KILLT&lt;br /&gt;
&lt;br /&gt;
Test &amp;amp; deincrement the TTIME amount untill it works fine.&lt;br /&gt;
&lt;br /&gt;
pctim003.zip for sound blaster type PIT &amp;amp; PIC programming.&lt;br /&gt;
See Ralf Browns interrupt list for interrupt information.&lt;br /&gt;
Both are downloadable on the net, google search.&lt;br /&gt;
&lt;br /&gt;
The code you included used AH=2Ch get current time, DH=seconds&lt;br /&gt;
check if second changed is real bad for delay code.&lt;br /&gt;
If your program calls just before the seconds change, there isn't much of a delay. Or there could be a full second delay and that's too much time wasted to get anything done in your program.&lt;br /&gt;
DL returned is 1/100 of a second.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/223403/re-ahhhh-programming-is-tough/#223403</guid>
      <pubDate>Sun, 09 Nov 2003 20:58:51 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: PCTim</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/223414/re-pctim/#223414</link>
      <description>Yes, I was reading pctim003.txt 7th chapter and what I know so far is that there are 3 channels. I suppose we can only use the third channel (CTC CHANNEL 2) because it allows to change frequency and it won't change DRAM timings right? But I am not getting how to read the elapsed time from the mode/command register 43h, or where ever it is read from.&lt;br /&gt;
It's funny, Bitdog, how u made up a delay with NOP cause we made the same kind of thing but it looks like this:&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
timer:
MOV   	CX,0EA60h

a10:
MOV   	AX,0EA60h

a20:
DEC    	AX
JNZ     a20

LOOP	a10
RET
&lt;/pre&gt;&lt;br /&gt;
It takes about 7 seconds to go through this loop on my machine, AMD 1.4Ghz, about 500 million operations a second, wow. :)&lt;br /&gt;
Thanks for all your help, I think sooner or later we will figure out the pctim file, together.&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/223414/re-pctim/#223414</guid>
      <pubDate>Mon, 10 Nov 2003 00:31:33 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
    <item>
      <title>Re: PCTim</title>
      <link>http://www.programmersheaven.com/mb/x86_asm/213254/223586/re-pctim/#223586</link>
      <description>It's been a while since I worked on pctim003.zip and I'm in a project&lt;br /&gt;
so I can't go back and write a sound card type IRQ interrupt routine&lt;br /&gt;
timer using channel 0 for you.  You're kinda on your own, sorry.&lt;br /&gt;
If I run into one I'll send it.&lt;br /&gt;
For delays longer than a few milli seconds AH=86 INT 15h works well.&lt;br /&gt;
Also the 18.2065hz tick timer at 0000:046C is accurate when working&lt;br /&gt;
with seconds. (it will only be an eight of a second off max)&lt;br /&gt;
Your loop below is not CPU independant for it doesn't check the&lt;br /&gt;
loops a CPU can do in a given time, then use that loop count to delay&lt;br /&gt;
in your program.  There is a recient post on CPU independant delays some where?  I use an AMD 1.6gh Duron &amp;amp; 1.4gh Tbird also..&lt;br /&gt;
&lt;br /&gt;
Bitdog&lt;br /&gt;
&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/mb/x86_asm/213254/223586/re-pctim/#223586</guid>
      <pubDate>Mon, 10 Nov 2003 14:31:53 -0700</pubDate>
      <category>x86 Assembly</category>
    </item>
  </channel>
</rss>