IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

> Совсем прямое обращение к видеопамяти., навеяло работой с режимом VGA 640x480
TarasBer
сообщение 4.03.2009 23:18
Сообщение #1


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


В режиме 640 на 480 видеопамять состоит из 4 цветовых слоёв. Которые в оперативной памяти расположены... по одному и тому же адресу! Для доступа к тому или иному слою надо записать какое-то значение в порты. Но тогда получается, что физическое расположение видеопамяти - это вовсе не $A000: $0000, ведь иначе один слой затирал бы информацию о другом. Можно ли обратиться к видеопамяти ещё более непосредственно, минуя механизм обращения по известному адрему? Или это на уровне железа так сделано, и по другому никак? Ведь помню, когда с портами баловался - экран покрывался цветными пятнами, причём разрешение экрана было довольно высокое.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
Гость
сообщение 13.03.2009 10:53
Сообщение #2


Гость






На EGA/VGA можно переключать слой. Чтобы делать продвинутые операции типа вывода спрайта, слои последовательно переключаются с 1 на 4, и в каждый выводится изображение. Спрайт при этом по соображениям эффективности тоже хранится по слоям, а не по пикселам.

Далее, если надо рисовать одним цветом, есть режим записи 2, при котором при записи пикселы, в которые записался ноль, не меняются, а в которые записалась 1, меняются на заданный цвет.

Далее, есть режим копирования 1. При считывании байта он сохраняется в регистр–защёлку, а при записи все восемь пикселов копируются на новое место. Это можно использовать для отрисовки тайлов: Сначала рисуем тайлы в видеопамяти, в невидимой области, а потом копируем куда надо. Тут, правда, проблема, если надо делать гладкую прокрутку по горизонтали, но она решаема: был какой–то регистр, позволяющий прокрутить графическое поле на несколько пикселей. Графическое поле нужно подкручивать так, чтобы тайлы приходились в аккурат по границам байтов.

Для прикидки: видеопамять вмещает в себя примерно поле 640x818. В 640x480 на две страницы пямяти не хватает, зато в 640x350 образуется избыток 640x118.

Учитывая необходимость подкрутки по горизонтали, имеем:
Графическая область (648x350x2) / 8 = 56700 байтов.
65536 - 56700 = 8836

8836 байт -- это 1262 тайла 8x7 или 315 тайлов 16x14 или 78 тайлов 32x28. Формат тайла 8x7 -- это, чтобы скомпенсировать растянутость режима 640x350.

Если честно, очень рад, что больше не надо выкраивать по байту, как бы уместиться на крохотном кусочке видеопамяти. Как и большинство программистов, в детстве мечтал забацать гаму, а в результате потратил кучу времени на изучение видеоконтроллёра, выучил ассемблер, чтобы рисовать спрайты и обрабатывать прерывание клавиатуры, потому что DOS несколько клавиш одновременно не понимает как надо.

И всё это устарело в считанные года, когда современные PC стали доступными и в России тоже. Ни гамы, ни детства smile.gif

В SVGA обращение к видеопамяти очень даже прямое. Но нужно учитывать, что вплоть до VGA, адаптеры были совместимыми и взаимозаменяемыми, а, начиная с SVGA, нужно уже работать по прерываниям, потому что схемы записи/чтения в порты отличаются от модели к модели.

Если использовать работу SVGA, то прямое обращение возможно. Можно адресовать окно $A000, а можно, читал в одной книжке, использовать 32битный хак: спроецировать видеопамять на один цельный кусок в расширенной (выше мегабайта) памяти, затем ненадолго переключиться в защищённый режим, установив GS или FS на начало графического сегмента. В книжке, которую я читал, FS устанавливается на начало памяти, а GS -- на видеопамять.

Фишка в том, что у каждого регистра сегмента (DS, ES, CS, SS, FS, GS) есть теневой регистр, который содержит информацию о настройке сегмента (начало, длина). Поведение сегментного регистра при адресации определяется не режимом (реальный/защищённый), а как раз вот этими теневыми регистрами. Содержимое теневого регистра обновляется только при перезаписи, так что, если в защищённом режиме запрограммировать GS, вернуться в реальный, а потом не трогать GS, он так и останется указывать на видеопамять. При этом можно использовать 32битную адресацию. Встроенный ассемблер TP не сможет, а вот TASM понимает. Если в 16битном коде используются 32битные значения и адреса, TASM генерит префиксы $66 и $67, и это работает.
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 18.07.2025 23:48
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"