I had this problem both on the Nutoak and on my new Quartz Operating System, the fact that the PIT without the "realtime" Bochs setting is too quick, with it it's ticking too slow (~5 times slower than it was set to be), and with "slowdown" even further in the deep abyss of slowness.
Related code:
pit.asm (MASM)
Code: Select all
PUBLIC __usleep
PUBLIC __tckc
_intend PROTO
.data
__tckc DWORD 0
.code
_pit_irqHandler:
inc [__tckc]
push eax
push ebx ;These two registers are used in _intend.
push 0
call _intend
pop ebx
pop eax
iretd
__usleep:
push ebp
mov ebp, esp
push ebx
push ecx
push edx
mov edx, [__tckc]
mov ecx, [ebp+8]
add ecx, edx
_loop:
cmp ecx, edx
jle outfc
hlt
mov edx, [__tckc]
jmp _loop
outfc:
pop edx
pop ecx
pop ebx
xor eax, eax
mov esi, [ebp+4]
pop ebp
add esp, 4
jmp esi
END
Code: Select all
#define PIT_FREQ 1193180
unsigned pit_initCounter(unsigned freq, unsigned counter, unsigned char mode_bin)
{
unsigned char counter_bin;
unsigned char rcounter_bin;
switch (counter)
{
case 0:
counter_bin = x86_PIT_OCW_COUNTER_0;
rcounter_bin = x86_PIT_RCOUNTER0;
case 1:
counter_bin = x86_PIT_OCW_COUNTER_1;
rcounter_bin = x86_PIT_RCOUNTER1;
break;
case 2:
counter_bin = x86_PIT_OCW_COUNTER_2;
rcounter_bin = x86_PIT_RCOUNTER2;
break;
}
unsigned short tpf = PIT_FREQ / freq;
outb(x86_PIT_COMMAND, counter_bin | x86_PIT_OCW_RL_DATA | mode_bin);
outb(rcounter_bin, tpf);
outb(rcounter_bin, tpf >> 8);
_tckc = 0;
return counter;
}
...
pit_initCounter(100, 0, x86_PIT_OCW_MODE_SQUAREWAVEGEN);
The code I use for testing:
Code: Select all
for (int i = 0; i < 10; i++)
{
_usleep(100); //Sleep one second
if(i%2) v_term_write('t');
else v_term_write('T');
}
v_term_write('e');
Did anybody had such problem or know a proper solution to this?
I'll appreciate any of your help.