DOS EGA Graphics Программирование в режиме 0Dh
Я делаю немного ретро-программирования для удовольствия. То, что я хочу создать, - это игра для DOS, использующая графику EGA, но у меня возникли некоторые проблемы с поиском хорошей ссылки в Интернете. Все, кто говорит о программировании под DOS, предполагают, что программист будет использовать режим 13h, и хотя на некоторых страницах упоминаются другие графические режимы, я еще не нашел ни одного, который бы обсуждал их правильное использование.
Вот что я пытаюсь начать работать прямо сейчас:
//------------------------------------------------------------------------------
// DOS graphics test
//
// Thanks to the following links:
// http://gamebub.com/cpp_graphics.php
//
// Written for Digital Mars C compiler to be compiled as a DOS 16 bit binary.
//------------------------------------------------------------------------------
#include <dos.h>
#include <stdio.h>
#define SCREEN_WIDTH 320;
#define SCREEN_HEIGHT 200;
unsigned char far *vram = (unsigned char far *)0xA0000000L;
//------------------------------------------------------------------------------
void set_video_mode(unsigned char mode)
{
union REGS in, out;
in.h.ah = 0;
in.h.al = mode;
int86(0x10, &in, &out);
}
//------------------------------------------------------------------------------
void plot_pixel(unsigned int x, unsigned int y, unsigned char color)
{
// this is wrong because it's only 4 bpp not 8
vram[y * 320 + x] = color;
//vram[((y<<8)+(y<<6))+x] = color;
}
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// EGA 320 x 200 x 16
set_video_mode(0x0d);
for (unsigned char i = 0; i < 255; i++)
{
vram[i] = i;
}
//plot_pixel(10, 10, 1);
getc(stdin);
return 0;
}
Этот пример кода прекрасно работает, если вы измените set_video_mode() на 0x13 вместо 0x0d, но, как я уже сказал, я пытаюсь получить EGA-изображение здесь, а не VGA.:) Я понимаю, что для того, чтобы сделать четыре бита на пиксель, мне нужно либо предположить, что plot_pixel записывает два пикселя одновременно, либо сделать несколько битов, чтобы убедиться, что я пишу только четыре бита, которые я на самом деле хочу.
Моя проблема в том, что я не вижу того, что ожидаю в качестве выходных данных - в частности, никаких цветов! Все кажется одноцветным, а это совсем не то, чего я хочу. Есть ли какая-то другая процедура для использования цветовой палитры в этом графическом режиме, чем в 13h? Или я как-то вызвал совершенно другой графический режим из того, который я намеревался? Руководство будет очень цениться.
Я не думаю, что мои аргументы компилятора будут актуальны, но на всякий случай:
..\dm\bin\dmc test.c -o test -mm
3 ответа
Режим 0x0d является планарным, а 0x13 - нет (без специальной настройки, как в режиме X). Вы должны проверить больше документов, чтобы увидеть, как работать в плоском режиме.
Хммм.. не знаю, если это достойный ответ, если я помню, вам нужно использовать inport
,inportb
,outport
,outportb
в порты для управления регистрами EGA, это было взято из превосходного FAQSYSW (обширная коллекция материалов, начиная от графической демонстрации, математики, фракталов до сжатий), оригинальный архив был найден здесь и здесь:
3C0h: Контроллер атрибутов: Адресный регистр, бит 0-4 Адрес регистра данных для записи в порт 3C0h. 5 Если заданный вывод на экран включен и палитра не может быть изменена, если вывод на чистый экран отключен и палитра может быть изменена. Порт 3C0h отличается тем, что он является адресом и регистром записи данных. Внутренний триггер запоминает, действует ли он в настоящее время в качестве адреса или регистра данных. Доступ к контроллеру атрибута должен быть разделен как минимум 250 нс. Чтение порта 3dAh вернет триггер в адресный режим. 3C0h индекс 0-Fh (W): атрибут: бит палитры 0 первичный синий 1 первичный зеленый 2 первичный красный 3 вторичный синий 4 вторичный зеленый 5 вторичный красный 3C0h индекс 10h (W): атрибут: регистр управления режимом, бит 0 графический режим, если установлен, Буквенно-цифровой режим остальное. 1 Монохромный режим, если установлен, цветной режим в противном случае. 2 9-битных широких символа, если установлены. 9-й бит символов C0h-DFh будет таким же, как 8-й бит. В противном случае это будет цвет фона. 3 Если установлен Атрибут, бит 7 мигает, иначе высокая интенсивность. 3C0h index 11h (W): Атрибут: Регистр цветовой развертки. бит 0-5 Цвет границы экрана. Цвет определяется как в палитре регистров. Примечание: EGA требует, чтобы цвет Overscan был равен 0 в режимах высокого разрешения. 3C0h index 12h (W): Атрибут: регистр разрешения цветовой плоскости, бит 0 Битовая плоскость 0 включена, если установлена. 1 Битовая плоскость 1 включена, если установлена. 2 Битовая плоскость 2 включена, если установлена. 3 Битовая плоскость 3 включена, если установлена. 4-5 Видео Статус MUX. Диагностика использовать только. Два бита атрибута появляются в битах 4 и 5 регистра состояния входа 1 (3dAh). 0: красный / синий, 1: синий (I)/ зеленый, 2: красный (I)/ зеленый (I) 3C0h index 13h (W): Атрибут: горизонтальный регистр панорамирования PEL, бит 0-3 Указывает количество пикселей для смещения дисплей слева Значение 9-битный текстовый режим 256-цветной режим Другие режимы 0 1 0 0 1 2 н / д 1 2 3 1 2 3 4 н / д 3 4 5 2 4 5 6 н / д 5 6 7 3 6 7 8 н / д 7 8 0 n/a n/a 3C2h (R): Состояние входа #0, бит регистра 4 Состояние переключателя, выбранного регистром разного выхода 3C2h, бит 2-3. Переключите высокий, если установлено. 5 Контакт 19 разъема функций (FEAT0) имеет высокий уровень, если установлен 6 Контакт 17 разъема функций (FEAT1) имеет высокий уровень, если установлен 7 Если установлен IRQ 2, произошел из-за вертикального восстановления. Должен быть очищен с помощью процедуры прерывания IRQ 2 путем очистки порта 3d4h index 11h bit 4. 3C2h (W): Разное Выходной регистр, бит 0 Если установлен Color Emulation. Базовый адрес =3Dxh иначе Моно Эмуляция. Базовый адрес =3Bxh. 1 Включите CPU для доступа к видеопамяти, если установлено 2-3 Выбор часов. 0: 14 МГц, 1: 16 МГц, 2: Внешний 4 Отключите внутренние видеодрайверы, если они установлены. 5 В нечетном / четном режимах. Выберите High 64k bank, если установлено 6 Полярность горизонтальной синхронизации. Отрицательно, если установлено 7 Вертикальная синхронизация полярности. Отрицательно, если установлено. Бит 6-7 указывает количество строк на дисплее: 0: 200 строк, 2: 350 строк. Примечание: Установите все нули при аппаратном сбросе. 3C4h индекс 0 (W): Секвенсор: сбросить бит 0 Асинхронный сброс, если очистить 1 Синхронный сброс, если очистить 3C4h индекс 1 (W): Секвенсор: Бит режима синхронизации 0 Если заданные тактовые импульсы имеют ширину 8 точек, иначе 9. 1 Если установить CRTC использует 2/5 тактов, иначе 4/5. 2 Если установлено, загружает сериализаторы видео каждый тактовый цикл других символов, в противном случае каждый. 3 Если для Dot Clock установлено значение Master Clock/2, то же самое, что и для Master Clock (см. 3C2h, бит 2-3). (Удваивает пиксели). 3C4h index 2 (W): Секвенсор: регистр маски карты, бит 0 Включить запись в плоскость 0, если установлено 1 Включить запись в плоскость 1, если установлено 2 Включить запись в плоскость 2, если установлено 3 Включить запись в плоскость 3, если установлено 3C4h index 3 (W): Sequencer: Символьная карта Выберите регистр, бит 0-1 Выбирает символьную карту EGA (0..3), если бит 3 атрибута символа свободен. 2-3 Выбирает карту символов EGA (0..3), если установлен бит 3 атрибута символа. Примечание. Символьные карты располагаются следующим образом: карта 0 в 0k, карта 1 в 16k, карта 2 в 32k и карта 3 в 48k, индекс 3C4h 4 (W): Секвенсор: регистр режима памяти, бит 0 Устанавливается, если в алфавитно-цифровом режиме снимите флажок в графических режимах. 1 Установите, если на адаптере больше 64 Кбайт. 2 Включает режим нечетной / четной адресации, если установлен. Режим нечетных / четных размещает все нечетные байты в плоскости 1 и 3, а все четные байты в плоскости 0 и 2. 3CAh (W): Графика 2 Положение, бит 0-1 Выберите, какие битовые плоскости должны контролироваться графическим контроллером #2. Всегда установлен на 1. 3CCh (W): Графика 1 Положение, бит 0-1 Выберите, какие битовые плоскости должны контролироваться графическим контроллером #1. Всегда установлен на 0. 3CEh index 0 (W): Графика: Установить / Сбросить регистр, бит 0 Если в режиме записи 0 и бит 0 в 3CEh index 1 установлен, запись в память дисплея установит все биты в плоскости 0 байта на этот бит, если соответствующий бит установлен в регистре маски карты (индекс 3CEh 8). 1 То же самое для плоскости 1 и бита 1 индекса 3CEh 1. 2 То же самое для плоскости 2 и бита 2 индекса 3CEh 1. 3 То же самое для плоскости 3 и бита 3 индекса 3CEh 1. 3CEh index 1 (W): Graphics: Enable Set/ Сбросить регистр, бит 0 Если установлено, разрешить Установить / сброс плоскости 0 в режиме записи 0. 1 То же самое для плоскости 1. 2 То же самое для плоскости 2. 3 То же самое для плоскости 3. 3CEh index 2 (W): Графика: Бит регистра сравнения цветов 0-3 В режиме чтения 1 каждый пиксель по адресу считанного байта сравнивается с этим цветом, и соответствующий бит на выходе устанавливается на 1, если они совпадают, на 0, если нет. Регистр цветных данных (3CEh index 7) может исключать битовые плоскости из сравнения. 3CEh index 3 (W): Graphics: Data Rotate bit 0-2 Число позиций для поворота данных непосредственно перед их записью в память дисплея. Активен только в режиме записи 0. 3-4 В режиме записи 2 это поле управляет отношением между данными, записанными из ЦП, данными, зафиксированными из предыдущего чтения, и данными, записанными в память дисплея: 0: Данные ЦП записываются без изменений 1: Данные ЦП имеют значение И с зафиксированными данными 2: данные ЦП имеют ИД с данными защелки. 3: данные CPU XORed с фиксированными данными. 3CEh index 4 (W): Графика: чтение карты Выберите регистр, бит 0-1 Номер плоскости, с которой будет считываться режим чтения 0. 3CEh index 5 (W): Графика: бит регистра режима 0-1 Режим записи: Управляет преобразованием данных из ЦП перед записью в память дисплея: 0: Режим 0 работает как операция чтения-изменения-записи. Сначала доступ для чтения загружает защелки данных EGA со значением в видеопамяти в указанном месте. Затем доступ для записи предоставит адрес назначения и байт данных процессора. Записанные данные изменяются кодом функции в регистре поворота данных (индекс 3CEh) как функция данных ЦПУ и защелок, затем данные поворачиваются, как указано в том же регистре. 1: режим 1 используется для передачи видео в видео. Доступ для чтения загрузит защелки данных содержимым адресуемого байта видеопамяти. Доступ на запись запишет содержимое защелок в адресуемый байт. Таким образом, одна инструкция MOVSB может копировать все пиксели в байте исходного адреса по адресу назначения. 2: Режим 2 записывает цвет для всех пикселей в адресуемом байте видеопамяти. Бит 0 данных ЦП записывается в плоскость 0 и так далее. Отдельные биты могут быть включены или отключены через регистр битовой маски (3CEh, индекс 8). 2 Принудительно переводит все выходы в состояние высокого импеданса. 3 Режим чтения 0: данные считываются с одной из 4-битных плоскостей в зависимости от регистра выбора карты чтения (индекс 3CEh 4). 1: Возвращенные данные - это сравнение между 8 пикселями, занимающими считанный байт, и цветом в регистре сравнения цветов (индекс 3CEh 2). Бит устанавливается, если цвет соответствующего пикселя соответствует регистру. 4 Включает нечетный / четный режим, если он установлен (см. 3C4h, индекс 4, бит 2). 5 Включает 4 цветных пикселя в стиле CGA, используя четные / нечетные битовые пары, если они установлены. 3CEh index 6 (W): Графика: Разное Регистр, бит 0 Указывает графический режим, если установлен, буквенно-цифровой режим в противном случае. 1 Включает нечетный / четный режим, если установлен. 2-3 Отображение памяти: 0: использовать A000h-BFFFh 1: использовать A000h-AFFFh графические режимы EGA 2: использовать B000h-B7FFh монохромные режимы 3: использовать режимы B800h-BFFFh CGA 3CEh индекс 7 (W): графика: цвет не Регистр ухода, бит 0 Игнорировать битовую плоскость 0 в режиме чтения 1, если сброшен. 1 Игнорировать битовую плоскость 1 в режиме чтения 1, если очистить. 2 Игнорировать битовую плоскость 2 в режиме чтения 1, если она сброшена. 3 Игнорировать битовую плоскость 3 в режиме чтения 1, если она сброшена. 3CEh index 8 (W): Графика: бит 0-7 регистра битовой маски. Каждый установленный бит включает запись в соответствующий бит байта в памяти дисплея. 3d4h индекс 0 (W): CRTC: бит горизонтального общего регистра 0-7 тактовых горизонтальных символов-2 3d4h индекс 1 (W): CRTC: горизонтальный регистр конечного регистра, бит 0-7 отображаемых тактовых импульсов -1 3d4h индекс 2 ((W): CRTC: стартовый регистр горизонтального гашения, бит 0-7 Счет, с которого начинается горизонтальное гашение, индекс 3d4h 3 (W): CRTC: бит 0-4 регистра горизонтального гашения, горизонтальное гашение заканчивается, когда последние 5 битов счетчика символов равны это поле. 5-6 Количество тактовых символов для задержки начала отображения после достижения горизонтального итога. 3d4h index 4 (W): CRTC: Начать горизонтальное восстановление регистра, бит 0-7 Горизонтальное восстановление начинается, когда счетчик символов достигает этого значения. 3d4h index 5 (W): CRTC: Завершить горизонтальный регистр Retrace, бит 0-4 Horizontal Retrace заканчивается, когда последние 5 битов счетчика символов равны этому значению. 5-6 Количество тактовых символов для отсрочки начала отображения после горизонтального возврата. 7 Обеспечивает плавную прокрутку в нечетном / четном режиме. Когда установлено отображение начинается с нечетного байта. 3d4h index 6 (W): CRTC: бит регистра вертикальной суммы 0-7 Младшие 8 бит вертикали полной суммы. Бит 8 находится в индексе 3d4h, 7, бит 0. Индекс в 3d4h (Вт): CRTC: бит регистра переполнения 0 Бит 8 по вертикали (индекс 3d4h) 1 Бит 8 по вертикали (конец 3d4h, индекс 12h) 2 Бит 8 из Начало вертикального восстановления (3d4h индекс 10h) 3 бит 8 начала вертикального гашения (3d4h индекс 15h) 4 бит 8 регистра сравнения строк (3d4h индекс 18h) 3d4h индекс 8 (W): CRTC: регистр сканирования предустановленных битов 0-4 числа из строк мы прокрутили вниз в первой строке символов. Обеспечивает плавную вертикальную прокрутку. 3d4h index 9 (W): CRTC: Максимальный бит регистра строки сканирования 0-4 Число строк сканирования в строке символов -1. В графических режимах это количество раз (-1), когда строка отображается перед переходом на следующую строку (0: нормальная, 1: двойная, 2: тройная...). Это не зависит от бита 7, за исключением режимов CGA, которые, по-видимому, требуют, чтобы это поле было равно 1, а бит 7 был установлен для работы. 3d4h index 0Ah (W): CRTC: регистр запуска курсора, бит 0-4 Первая строка развертки курсора внутри символа. 3d4h index 0Bh (W): CRTC: бит регистра конца курсора 0-4 Последняя строка сканирования курсора в символе 5-6 Задержка данных курсора в символьных часах. 3d4h индекс 0Ch (W): CRTC: бит регистра старшего адреса старшего 0-7 старших 8 битов начального адреса буфера дисплея. 3d4h индекс 0Dh (W): CRTC: бит регистра младшего адреса стартового 0-7 младших 8 битов начальный адрес буфера дисплея 3d4h index 0Eh (W): CRTC: высокий разряд регистра курсора, бит 0-7 старших 8 битов адреса курсора 3d4h index 0Fh (W): CRTC: низкий курс позиционирования курсора, бит 0-7 нижнего регистра 8 бит адреса курсора 3d4h index 10h (R): CRTC: High Pen High Register, бит 0-7 Старшие 8 бит адреса позиции светового пера. 3d4h индекс 10h (W): CRTC: Бит 0-7 регистра запуска вертикального возврата, младшие 8 бит старта запуска вертикального возврата. Вертикальное восстановление начинается, когда счетчик строки достигает этого значения. Бит 8 находится в индексе 3d4h, бит 7 индекса 2. 3d4h, индекс 11h (R): CRTC: регистр нижнего регистра Light Pen, бит 0-7 Младшие 8 бит адреса позиции светового пера. 3d4h index 11h (W): CRTC: Бит 0-3 регистров окончания вертикального восстановления заканчивается, когда вертикальное восстановление заканчивается, когда последние 4 бита счетчика строки равны этому значению. 4 если выбрано, очищает в ожидании вертикальных прерываний. 5 Вертикальные прерывания (IRQ 2) отключены, если установлены. Обычно его можно отключить, но некоторые системы (включая PS/2) требуют его включения. 3d4h индекс 12h (W): CRTC: Бит 0-7 регистра конца конца вертикального дисплея Младшие 8 бит конца конца вертикального дисплея. Дисплей заканчивается, когда счетчик строки достигает этого значения. Бит 8 находится в индексе 3d4h, 7 бит 1. Индекс 3d4h, 13h (Вт): CRTC: бит регистра смещения 0-7 Число байтов в строке развертки / K. Где K - 2 для байтового режима, 4 для режима слова и 8 для Режим двойного слова. 3d4h index 14h (W): CRTC: Бит регистра местоположения подчеркивания 0-4 Положение подчеркивания в символьной ячейке. 3d4h индекс 15h (W): CRTC: стартовый регистр пустого вертикального бита 0-7 Младшие 8 бит вертикального пустого старта. Вертикальное гашение начинается, когда счетчик строки достигает этого значения. Бит 8 находится в 3-м индексе 3-го 4-го бита. 3-й индекс 3-го 4-го полугодия 16-й (Вт): CRTC: Конец вертикального пустого регистра Бит 0-4 Вертикальное гашение прекращается, когда младшие 5 бит счетчика строки равны этому полю. 3d4h индекс 17h (W): CRTC: бит 0 регистра управления режимом. Если очистить, используйте CGA-совместимую систему адресации памяти, заменив бит 0 счетчика сканирования строки символов на адресный бит 13, создав таким образом 2 банка для четных и нечетных строк сканирования. 1 Если очистить, используйте совместимую с Hercules систему адресации памяти, заменив бит 1 счетчика сканирования строки символов на бит адреса 14, создав таким образом 4 банка. 2 Если установлено, увеличивайте счетчик строк сканирования только каждую вторую строку. 3 Если установлено, увеличивайте счетчик адресов памяти только каждые остальные символы. 4 Если установлено, отключите драйверы выхода EGA. 5 В режиме Word бит 15 поворачивается на бит 0, если этот бит установлен, иначе бит 13 поворачивается в бит 0. 6 Если система очистки находится в режиме слова. Адреса поворачиваются на 1 позицию вверх, в результате чего бит 13 или 15 переводится в бит 0. 7 Сброс этого бита будет сбрасывать систему отображения до тех пор, пока бит не будет установлен снова. 3d4h индекс 18h (W): CRTC: бит сравнения строк 0-7 Младшие 8 битов сравнения строк. Когда счетчик строк достигает этого значения, адрес дисплея оборачивается до 0. Предоставляет возможности разделения экрана. Бит 8 находится в 4-м индексе 3d4h. Бит 4. 3dAh (R): входной статус # 1 Бит регистра 0 Активен вертикальный или горизонтальный возврат, если установлен 1 Световое перо сработало, если установлено 2 Переключатель светового пера открыт, если установлено 3 Вертикальное восстановление в ход выполнения, если установлено 4-5 Показывает два из 6 цветовых выходов, в зависимости от индекса 3C0h 12h. Аттр: Бит 4-5: Выходной бит 4 Выходной бит 5 0 Синий Красный 1 I Синий Зеленый 2 I Красный I Зеленый 3dAh (W): Бит 0 регистра управления функциями. Вывод на вывод 21 разъема функции. 1 Вывод на контакт 20 функционального разъема.
Он одноцветный, потому что записывает все четыре цветовых плоскости одновременно. Режим D является плоским, как указывают другие ответы, и регистр контролирует, какой из них записывается в ваш цикл. По умолчанию он выбирает запись во все плоскости одновременно, следовательно, в моно.
Например, чтобы выбрать "красную" плоскость и "интенсивную", вы можете сделать:
mov dx, 3C4h ; address of sequencer address register
mov al, 2h ; index of map mask register
out dx, al
mov dx, 3C5h ; address of sequencer data register
mov al, 00001100b ; turn on the 'red' and 'intense' planes
out dx, al
Последующие записи в VRAM создадут ярко-красный пиксель для каждого записанного бита (1 бит = 1 пиксель). Цвет предполагает, конечно, что палитра не была изменена по умолчанию, что вы также можете сделать.