Programmable Interval Timer: Difference between revisions

m
Simplified the PIT Channel 0 Example Code
[unchecked revision][unchecked revision]
m (Doh - another little bug in PIT Channel 0 Example Code)
m (Simplified the PIT Channel 0 Example Code)
Line 332:
; Calculate the reload value
mov eax,3579545 * 256
mov edx,0 ;edx:eax = 3579545 * 256
div ebx ;eax = 3579545 * 256 / frequency, edx = remainder
cmp edx,3579545 * 256 / 2 ;Is the remainder more than half?
jb .l1 ; no, round down
inc eax ; yes, round up
.l1:
mov ebx,3 * 256
mov edx,0 ;edx:eax = 3579545 * 256 / frequency
div ebx ;eax = (3579545 * 256 / 3 * 256) / frequency
cmp edx,3 * 256 / 2 ;Is the remainder more than half?
jb .l2 ; no, round down
inc eax ; yes, round up
.l2:
; Store the reload value and calculate the actual frequency
.gotReloadValue:
push eax ;Store "3579545 * 256 / reload_value" for later
mov [PIT_reload_value],ax ;Store the reload value for later
mov ebx,eax ;ebx = reload value
mov eax,3579545 * 256
mov edx,0 ;edx:eax = 3579545 * 256
div ebx ;eax = 3579545 * 256 / reload_value, edx = remainder
cmp edx,3579545 * 256 / 2 ;Is the remainder more than half?
jb .l3 ; no, round down
inc eax ; yes, round up
.l3:
mov ebx,3 * 256
push eax ;Store "3579545 * 256 / reload_value" for later
mov edx,0 ;edx:eax = 3579545 * 256 / reload_value
div ebx ;eax = (3579545 * 256 / 3 * 256) / frequency
mov ebx,3 * 256
movcmp edx,0 3 / 2 ;edx:eaxIs =the 3579545remainder *more 256 /than reload_valuehalf?
div ebx ;eax = (3579545 * 256 / 3 * 256) / frequency
cmp edx,3 * 256 / 2 ;Is the remainder more than half?
jb .l4 ; no, round down
inc eax ; yes, round up
.l4:
mov [IRQ0_frequency],eax ;Store the actual frequency for displaying later
; Calculate the amount of time between IRQs in 32.32 fixed point
;
; Note: The basic formula is:
; time in ms = reload_value / (3579545 / 3) * 1000
; This can be rearranged in the follow way:
; time in ms = reload_value * 3000 / 3579545
; time in ms = reload_value * 3000 / 3579545 * (2^42)/(2^42)
; time in ms = reload_value * 3000 * (2^42) / 3579545 / (2^42)
; time in ms * 2^32 = reload_value * 3000 * (2^42) / 3579545 / (2^42) * (2^32)
; time in ms * 2^32 = reload_value * 3000 * (2^42) / 3579545 / (2^10)
pop eaxebx ;eaxebx = 3579545 * 256 / reload_value
mov eax,0xDBB3A062 ;eax = 3000 * (2^42) / 3579545
mul ebx ;edx:eax = (3579545reload_value * 2563000 * 0x01000000 / 3(2^42) / reload_value3579545
shrd eax,edx,10
shr edx,10 ;edx:eax = reload_value * 3000 * (2^42) / 3579545 / (2^10)
mov ebx,0x01000000 / 3
mov edx,0 ;edx:eax = 3579545 * 256 / reload_value
mul ebx ;edx:eax = (3579545 * 256 * 0x01000000 / 3) / reload_value
; = (1193182.66 * 2^32) / reload_value
mov [IRQ0_mS],edx ;Set whole mS between IRQs
mov [IRQ0_fractions],eax ;Set fractions of 1 mS between IRQs
; Program the PIT channel
250

edits