Programmable Interval Timer: Difference between revisions

m
covnert some code to C to reflect the purpouse of the article better
[unchecked revision][unchecked revision]
(convert exotic assembler syntax to NASM)
m (covnert some code to C to reflect the purpouse of the article better)
Line 231:
For the "lobyte/hibyte" access mode you need to send the latch command (described above) to avoid getting wrong results. If any other code could try set the PIT channel's reload value or read its current count after you've sent the latch command but before you've read the highest 8 bits, then you have to prevent it. Disabling interrupts works for single CPU computers. For example, to read the count of PIT channel 0 you could use something like:
 
<source lang="asmc">
unsigned read_pit_count(void) {
read_PIT_count:
unsigned count = 0;
pushfd
cli
// Disable interrupts
mov al, 00000000b ; al = channel in bits 6 and 7, remaining bits clear
cli();
out 0x43, al ; Send the latch command
mov al, 00000000b ;// al = channel in bits 6 and 7, remaining bits clear
in al, 0x40 ; al = low byte of count
outb(0x43,0b0000000);
mov ah, al ; ah = low byte of count
in al, 0x40 ; al = high byte of count
count = inb(0x40); // Low byte
rol ax, 8 ; al = low byte, ah = high byte (ax = current count)
count |= inb(0x40)<<8; // High byte
popfd
ret
return count;
}
</source>
 
Line 251 ⟶ 253:
For the "lobyte/hibyte" access mode you need to send the low 8 bits followed by the high 8 bits. You must prevent other code from setting the PIT channel's reload value or reading its current count once you've sent the lowest 8 bits. Disabling interrupts works for single CPU computers. For example:
 
<source lang="asmc">
void set_pit_count(unsigned count) {
set_PIT_count:
// Disable interrupts
pushfd
cli();
out 0x40, al ; Set low byte of reload value
rol// ax, 8 ; al = high byte, ah =Set low byte
out outb(0x40, al count&0xFF); // Set highLow byte of reload value
outb(0x40,(count&0xFF00)>>8); // High byte
rol ax, 8 ; al = low byte, ah = high byte (ax = original reload value)
return;
popfd
}
ret
</source>
 
170

edits