В продолжение темы, нарыл я тут интересную и старую как мир мульку относительно двойной буферизации (далее описаны исключительно мои личные фантазии, которые могут не совпадать с реальностью).
А именно, вовсе не обязательно отлавливать прерывание видюхи, тем более что его можно и вовсе не дождаться, а как же тогда быть?
Да очень просто, в ядре по любому есть обработчик таймера на IRQ0, пусть, для примера, это будет 1000 раз в секунду, все одно видюха больше 60 раз в секунду не сможет обновить экран, так что с запасом.
Так вот при срабатывании таймера можно проверить состояние видюхи (т.н. Input Status Register One) на предмет обратного хода луча по кадру фреймбуфера и как только луч пойдет обратно подсунуть ему второй буфер.
А сделать это не составляет никакого труда, например (тиснуто у Кулакова, так что это уже не мои фантазии):
Код:
;=======================================================================
; Ожидание обратного хода луча по кадру
;=======================================================================
WaitVSync:
push rax
push rdx
mov edx, 0x03DA ; читаем регистр статуса VGA
@WaitNotVSyncLoop:
in al, dx
and al, 0x08 ; выделяем бит вертикальной синхронизации
jnz @WaitNotVSyncLoop
@WaitVSyncLoop: ; не пойму только, зачем здесь два раза
in al, dx
and al, 0x08 ; выделяем бит вертикальной синхронизации
jz @WaitVSyncLoop
pop rdx
pop rax
ret
;=======================================================================
А вот мой вариант, в отличии от оригинала нет никаких бесконечных циклов ожидания выстрела, срабатывает только по таймеру и исполняется только один раз за сеанс:
Код:
WaitVSync:
push rax
push rdx
mov edx, 0x03DA ; читаем регистр статуса VGA
in al, dx
bt eax, 3 ; проверяем бит вертикальной синхронизации
jc @VSYNC_EVENT
... ; нет? ну так может в другой раз, я подожду
@VSYNC_EVENT:
... ; здесь перещелкиваемся на backgroung буфер
pop rdx
pop rax
ret
Если кто в теме покритикуйте мой вариант, в сравнении с оригиналом, камень не нагружаем, а событие ловим.
На практике пока не проверял, кто-нибудь уже пользовал такой метод, поделитесь