Мне нужнна прорисовывать полностью экран - Сначала я повесил это дело на прерывание таймера - с задержкой до обратного хода но таймер и без того перегружен кодом поэтому я решил отрисовывать экран по прерыванию обратного хода луча - только возникла проблема как его включить? Взял для справки то что написано у Зубкова: Регистры контроллера CRT (03D4h – 03D5H) Контроллер CRT управляет разверткой и формированием кадров на дисплее. Как и для графического контроллера, для обращения к регистрам контроллера CRT следует записать индекс нужного регистра в порт 03D4h, после чего можно будет читать и писать данные для выбранного регистра в порт 03D5h. Если требуется только запись в регистры, можно просто поместить индекс в AL, посылаемый байт — в АН и выполнить команду вывода слова в порт 03D4h. ... 11h: Конец вертикального обратного хода луча без старшего бита бит 7: защита от записи в регистры 00 – 07 (кроме бита 4 в 07h) бит 6: 1/0 — 5/3 цикла регенерации за время обратного хода луча бит 5: 1/0 — выключить/включить прерывание по обратному ходу луча бит 4: запись нуля сюда заканчивает обработку прерывания биты 3 – 0: конец вертикального обратного хода луча ... Код (Text): Следовательно TR_ENABLE = 11011111b BASE_ADDR = 03D4h MOV DX,BASE_ADDR ;DX = 03D4h MOV AL,11h ;AL = 11h (Index) OUT DX,AL ;OUT 3D4h,11h INC DX ;DX = 03D5h IN AL,DX ;AL = ????????b MOV AH,AL ; AND AH,TR_ENABLE ;AH = ??[b]0[/b]?????b MOV AL,11h ;AL = 11h (Index) DEC DX ;DX = 03D4h OUT DX,AX ;OUT 3D4h,11h : OUT 3D5h,??[b]0[/b]?????b 1.Что я делаю не так? мож кто обьяснит бедному чукотскому мальчонке? 2.Кто нибудь знает как наиболее быстро организовать послойную отрисовку экрана? допустим есть некоторое количество слоёв - их все последоватьно надо отрисовать на экран. как сделать это наиболее быстро?
1. Отрыл где-то код, может поможет. почему порты другие не знаю Код (Text): (*-----------------------------------------*) procedure VBLANK; assembler; asm cmp TimerInstalled,TRUE je @timerinstalled mov dx,3DAh @vent1: in al,dx test al,8 jz @vent1 cli @vent2: in al,dx test al,8 jnz @vent2 sti jmp NEAR PTR @done @timerinstalled: mov ax,total_retraces @vent3: cmp ax,total_retraces je @vent3 @done: end; procedure VBLANK_QUICK; assembler; asm cmp TimerInstalled,TRUE je @timerinstalled cli mov dx,3DAh @vent1: in al,dx test al,8 jz @vent1 sti jmp NEAR PTR @done @timerinstalled: mov ax,total_retraces @vent2: cmp ax,total_retraces je @vent2 @done: end; 2. Что под слоями понимать?
>1. Отрыл где-то код, может поможет. >почему порты другие не знаю Регистр состояния ввода 1 (ISR1) — доступен для чтения из порта 03DAH бит 3: происходит вертикальный обратный ход луча бит 0: происходит любой обратный ход луча Это код задерки до начала обратного хода луча. Так он выглядит у зубкова Код (Text): wait_retrace proc near push ax push dx mov dx,03DAh ; порт регистра ISR1 wait_retrace_end: in al,dx test al,1000b ; проверить бит 3 если не ноль jnz wait_retrace_end ; подождать конца ; текущего обратного хода wait_retrace_start: in al,dx test al,1000b ; а теперь подождать начала следующего jz wait_retrace_start pop dx pop ax ret wait_retrace endp Могу твой код прокоментировать подробно. 2.Допустип есть 7 рисунков их все один поверх другово надо вывести на экран - только есть проблемы - у каждого рисунка могут поменятся координаты. Сейчас я делаю так: A.Отрисовываю в буфер слои - по порядку с новыми координатами. B.Вывывожу буфер на экран. Это не совсем эфективно так как на экране рисунок меняет координаты с легким запозданием и это смотрится не красиво.
Same по прерыванию обратного хода луча - только возникла проблема как его включить? В аттаче отрывок из 12 главы Richard Wilton. Programmer'S Guide to PC(R) And PS/2(TM) Video Systems. Отрисовываю в буфер слои ... Вывывожу буфер на экран Afaik наиболее быстрый метод. с легким запозданием Может быть алгоритм заполнения буфера не оптимальный? _1628849966__V12.RAR
Same Теперь понял!!! это я протупил Ты ждать VSync не хочешь, а хочешь прерывание включить по нему. Как я знаю, это не все видеокарты поддерживают (раньше вообще была перемычка такая), может у тебя как раз такой случай. Про "слои" - теоретически, можно запараллелить рисование рисунков, например по 2 или 3. Эмулировать тайловую архитектуру - разбить экран на квадраты и смотреть какая часть какого слоя куда попадает.. IMHO гемора много и реального выигрыша может не дать, т.к сейчас у компов архитектура не фон-неймановская. "7 рисунков" слишком расплывчатое понятие, многое зависит от того, каков их размер, как они перекрываются, способ наложения и т.п. Возможно получится как-то сэкономить не рисуя перекрывающиеся участки или обновлять только dirty rectangles... > Что значит лёгкое запаздавание? не успевает каждый кадр перерисовывать? Проверь с простой анимацией, может быть проблема в синхроницации.
2 q_q В аттаче отрывок из 12 главы Richard Wilton. Programmer'S Guide to PC(R) And PS/2(TM) Video Systems. Спасибо большое - счас прочитать не успею, но вечером займусь. Afaik наиболее быстрый метод. Может быть алгоритм заполнения буфера не оптимальный? Что посоветуеш почитать на тему? 2 S_T_A_S_ "7 рисунков" слишком расплывчатое понятие, многое зависит от того, каков их размер, как они перекрываются, способ наложения и т.п. Возможно получится как-то сэкономить не рисуя перекрывающиеся участки или обновлять только dirty rectangles... Что значит лёгкое запаздавание? не успевает каждый кадр перерисовывать? Проверь с простой анимацией, может быть проблема в синхроницации. Что бы люди не смеялись я умолчал что пробую делать жалкое подобие GUI.В этой области я совсем зеленый и не знаю что почитать на эту тему в нете алгоритмов нет, есть готовые реализации типа Z-Buffer на Си. Пока интерфейс простой - фон пять окон курсор. Раньше я например при отрисовке курсора сохранял облась под ним после смещения востанавливал и отрисовывал снова.сейчас я пошел другим путём. Код (Text): ==========[Курсор ]============ Слой 0Fh =============================== ... ==========[Фон]================ 00h В промежуточных слоях отрисовываются окна по таблице есесно они могут менять координаты и размер. Так вот при быстром быстром движении мышкой или перемещении окна оно несколько отстаёт от мышки а при медленном всё нормально.
2 q_q Пример не помог. На счет заполнения буфера возможно ты прав - вот пример рисования квадрата. Код (Text): ;------------------------------- ;DBLCOORD:dd ? ;00h;x1 ; dd ? ;04h;y1 ; dd ? ;08h;x2 ; dd ? ;0Ch;y2 ;------------------------------- ; FSTYLE:dd ? ;04h;FColor ; dd ? ;0Ch;RESERVED ; dd ? ;10h;RESERVED ;=============================== ;EBP = ip DBLCOORDS Struct ;ESI = ip FSTYLE Struct ;EAX = Layer DrawRect8:PUSHA MOV EBX,DS:[EBP+00h] ;X1 MOV EAX,DS:[EBP+04h] ;Y1 MOV ECX,DS:[EBP+0Ch] ;Y2 SUB ECX,EAX ;Y2 - Y1 = Height MUL WORD PTR[FS:SYS_SCREEN_WIDTH];EAX = Y1 SHL EDX,10h MOV DX,AX MOV EDI,EDX ;EDI = Line MOV EDX,DS:[EBP+08h] ;X2 SUB EDX,EBX ;X2 - X1 = EDX = WIdth MOV EAX,DS:[ESI+00h] ;FColor RectHloop8:PUSH ECX PUSH EBX MOV ECX,EDX RectVloop8:CMP EBX,[FS:SYS_SCREEN_WIDTH] JGE RectNxtPx8 CMP AL,CLR_NO JZ RectNxtPx8 MOV GS:[EDI+EBX],AL RectNxtPx8:INC EBX loop RectVloop8 ADD EDI,[FS:SYS_SCREEN_WIDTH] POP EBX POP ECX loop RectHloop8 POPA RETN CLR_NO = 0FFh Я работаю с буфером как с двухмерной матрицей X,Y Обрати внимание на Код (Text): MOV GS:[EDI+EBX],AL ;EDI = Y*ScreenWidth = Current_Line ;EBX = Pixel offset from Line_Start Это позволяет мне котролировать избражение чтобы оно не отрисовывалось за пределы экрана.Последний допустимый пиксель это ScrenWidth - 1 По адресу [FS:SYS_SCREEN_WIDTH] находится текущий размер одной линии экрана в Байтах Код (Text): CMP EBX,[FS:SYS_SCREEN_WIDTH] ;If current Pixel offset >= ScrenWidth JGE RectNxtPx8 ;Then Don't Draw it 2 S_T_A_S_ Как я знаю, это не все видеокарты поддерживают (раньше вообще была перемычка такая), может у тебя как раз такой случай. Странно карточка вроде новая или это вышло из моды?(GeForce 4 mx 440 64mb) Про торможениее графики скорее всего прав q_q На прерывание таймера я повесил такую процедуру Код (Text): ;================================;|| DrawScreen:PUSHA ;|| PUSH DS ;|| PUSH ES ;|| ;--------------------------------;|| PUSH VIDEO_BUFFER_Sel ;|| POP DS ;|| PUSH EXT_VIDEO_MEM_Sel;|| POP ES ;|| XOR EDI,EDI ;|| XOR ESI,ESI ;|| Call WaitSync ;-> ;|| ;--------------------------------;|| MOV ECX,[FS:SYS_SCREEN_WIDTH] ;|| DrawScrnH8:PUSH ECX ;|| MOV ECX,[FS:SYS_SCREEN_HEIGHT];|| SHR ECX,02h ;|| DrawScrnV8:MOVSD ;|| LOOP DrawScrnV8 ;|| POP ECX ;|| LOOP DrawScrnH8 ;|| ;--------------------------------;|| POP ES ;|| POP DS ;|| POPA ;|| RETN ;|| ;=================================|| А в заполнении буфера оставил только: Код (Text): ;===============================|| FillVBuffer:PUSHA ;|| ;==============================;|| MOV EAX,03h ;Color ;|| call FillScreen ;|| ;===========[ Mouse ]==========;|| call DrawCursor ;|| ;==============================;|| POPA ;|| RETN ;|| ;===============================|| Все равно торможение чуть есть - правда эта процедура висит на IRQ12...
Same > Ну теперь понятно, значит почти всё что я говорил мимо IMHO ждать синхру в этом случае не нужно, врядли кто так делает, это ж не игрушки. > afaik так и делают, правда в виндосе курсор обычно аппаратный. перерисовывать окна целиком в этом случае не выгодно, т.к. в GUI ОС никто никогда не ставит задачей добится нормального функционирования самого GUI, приоритет отдаётся "задачам". Посмотри ещё сорцы SolarOS, автор хвалился, что у него gui быстрое. > Делай корректировку размеров ДО рисования, тогда проверка будет лишней. Вообще, в виндосе подобными квадратами можно раз 5 заполнять целиком экран 640*48*32 _каждый_ кадр
2 S_T_A_S_ afaik так и делают, правда в виндосе курсор обычно аппаратный. перерисовывать окна целиком в этом случае не выгодно, т.к. в GUI ОС никто никогда не ставит задачей добится нормального функционирования самого GUI, приоритет отдаётся "задачам". Посмотри ещё сорцы SolarOS, автор хвалился, что у него gui быстрое. Я хочу сделать сам а не копировать чужие идеи аки абизьяна У него в ОС кроме GUI не чего и нет Делай корректировку размеров ДО рисования, тогда проверка будет лишней. А ты представь окно не выходит за пределы экрана на половину обрезаясь - а просто уменьшается в размерах?) Вообще, в виндосе подобными квадратами можно раз 5 заполнять целиком экран 640*48*32 _каждый_ кадр 640*480*32? у меня при 640*480*8/16 тоже скорость офигенная Короче я решил эту проблему так: У меня был таймер настроен на 256 Тиков в секунду а поскольку Отрисовка висела на нём то торможение возникло в связи с нагрузом на код таймера. Я добавил счетчик синхронизуя ~30fps - торможение исчезло
Same > IMHO это невозможно! если ты не знаком с чужими идеями, то можешь случайно их повторить, сам того не осознавая > Нет, размеры не нужно уменьшать. Например, если backgroung окна имеет прямоугольную форму и однотонный, то прямоугольник меньшего по ширине размера - это тоже самое, что и часть предыдущего. Т.е. он просто отрисовывается, никаких проверок не нужно. Потом по краям рисуются части рамки. понятное дело, что правую рамку не нужно будет рисовать, если она выходит за пределы экрана. Проверять координаты для каждого пикселя - это расточительство . > Зачем сейчас эти анахронизмы? делай 32 bpp и не парься со всякими палитрами и масками цветовых компонент. А "лишний" байт можно как-нибудь хитро задействовать, например для элементов управления > Нет смысла перерисовывать чаще, чем частота кадров. А для "не-GUI" ориентированной ОС можно перерисовывать только в случае каких-то действий пользователя и/или пользовательских программ. Т.е. даже меньше, чем 30fps
S_T_A_S_ 32bpp это расточительство. Я пока тольком не разобрался с видео картой чтобы переключать режимы и задавать частоту развертки через порты ввода вывода - а делать это через VESA я не хочу. При проверки пикселя экран не тормазит пока оставлю так потом сделаю по другому как говориш ты Если X+Width > Screen Width то лишнее обрезаем У меня вопросы есть но пока осмысленно задать их не могу -кое чего у меня с собой нет - задам завтра.
1.Как опредилить базовый адрес видео памяти не средствами Vesa? 2.Можно ли использовать второй кадр 48мб под буффер? Чтобы понять вопрос желательно бегло пробежатся по аттачу В свое время хотел статью написать да лень переборолла 1709669452__Arch001.zip