Подправил в ядре работу с таймером. А точнее - сделал счетчик миллисекунд, прошедших с начала запуска, более независимым от частоты таймера. Частоту таймера можно настраивать при компиляции ядра, в файле const.inc.
Публикую сдесь, ибо как SVN-ами пользоваться не учен, а diff-ы выкладывать - так многие в винде сидят. Лучше так код выложу сюда, что менять, что удалять.
Итак, в const.inc добавляем следующие строки:
Code:
;Don't set hight values on slow machines\emulators!
TIMER_FREQ equ 250 ; From 20 to ...
TIMER_SCALE equ 10000 ; or 1000, etc...
В файле kernel.asm заменяем(строка 564) это:
Code:
; TIMER SET TO 1/100 S
mov al,0x34 ; set to 100Hz
out 0x43,al
mov al,0x9b ; lsb 1193180 / 1193
out 0x40,al
mov al,0x2e ; msb
out 0x40,al
На это:
Code:
; TIMER SET TO 1/TIMER_FREQ S
mov al,0x34
out 0x43,al
mov al, (((1193180 / TIMER_FREQ) and 0x00ff))
out 0x40,al
mov al, (((1193180 / TIMER_FREQ) shr 8) and 0x00ff)
out 0x40,al
А в файле core/sched.inc заменяем это:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
irq0:
pushad
Mov ds, ax, app_data
mov es, ax
inc [timer_ticks]
На это:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
timer_frequency dd TIMER_FREQ ; Need for ``div''
timer_scale dd TIMER_SCALE
timer_accumulator dd 0
align 32
irq0:
pushad
Mov ds, ax, app_data
mov es, ax
mov eax, 100 * TIMER_SCALE
xor edx, edx
div [timer_frequency]
add eax, edx
add eax, [timer_accumulator]
cmp eax, TIMER_SCALE
jb .notick
xor edx, edx
div [timer_scale]
add [timer_ticks], eax
xchg eax, edx
.notick:
mov [timer_accumulator], eax
Дальше все то же.
Вроде часы идут ровно, программы тоже работают(таймер сапера) при любой частоте(тестил от 20 то 1000 Гц(На VBox, на qemu при частоте, большей 350 Гц виснет все)).
Кто разбирается в ядре: там ничего сильно не скосится при смене частоты?