Подтвердить что ты не робот

Как нарисовать пиксель на экране в защищенном режиме в сборке x86?

Я создаю небольшое ядро ​​bootloader +, и до сих пор мне удалось прочитать диск, загрузить второй сектор, загрузить GDT, открыть A20 и включить pmode.

Я перешел на 32-битную функцию, которая показывает мне символ на экране, используя видеопамять для текстового контента (0x000B0000 - 0x000B7777)

pusha
mov edi, 0xB8000
mov bl, '.'
mov dl, bl
mov dh, 63
mov word [edi], dx
popa

Теперь я хотел бы пойти немного дальше и нарисовать один пиксель на экране. Когда я читаю на каком-то веб-сайте, если я хочу использовать графический режим VGA, я должен написать свой пиксель в месте 0x000A0000. Правильно ли это?

Теперь, каков формат одного пикселя? Для одного символа вам нужен код и атрибут ASCII, но что вам нужно для определения пикселя (если он работает так же, как текстовый режим)?

4b9b3361

Ответ 1

К сожалению, это немного больше, чем немного дальше.

Правила записи в видеопамять зависят от графического режима. Среди традиционных видеорежимов режим VGA 320x200 (8bpp) является единственным, где видеопамять ведет себя как обычный вид памяти: вы пишете байт, соответствующий пикселю, который вы хотите использовать для видеобумага, начиная с 0xA000: 0000 (или 0xA0000 linear), и что все.

Для других режимов VGA (pre-SVGA) правила сложнее: когда вы пишете байт в видеопамять, вы обращаетесь к группе пикселей, а некоторые регистры VGA, которые я давно забыл, указывают, какие плоскости этих пиксели обновляются и как используется старое их значение. Это не просто память.

Существуют режимы SVGA (начиная с 800x600x8bpp); вы можете переключиться на них аппаратно-независимым способом, используя VESA Video Bios Extensions. В этих режимах видеопамять ведет себя как память снова, с 1,2,3 или 4 байта на пиксель и без VGA-подобных 8-пиксельных групп, которые вы касаетесь одним байтовым доступом. Проблема в том, что видеобуфер реального режима уже недостаточно велик для адресации всего экрана.

VESA VBE 1.2 рассмотрел эту проблему, предоставив функции для изменения базы окон памяти: в любой конкретный момент сегмент с линейным 0xA0000 обращается к области видеопамяти на 64 Кб, но вы можете контролировать, какие 64 Кбайт всего фреймбуфера доступны на этот адрес (минимальная единица настройки базового адреса, а также гранулярность окна зависит от аппаратного обеспечения, но вы можете полагаться на возможность сопоставить смещение N * 64 Кбит на 0xA0000). Недостатком является то, что он требует вызова VBE BIOS каждый раз, когда вы начинаете работать с другим блоком 64Kb.

VESA VBE 2.0 добавлен плоский фреймбуфер, доступный на некотором высоком адресе в защищенном режиме (также в нереальный режим). Таким образом, вызов VBE BIOS требуется для входа в режим видео, но не для рисования пикселей.

VESA VBE 3.0, который может быть недостаточно переносимым, обеспечивает способ вызова функций VBE в защищенном режиме. (У меня не было возможности попробовать, его там не было во время моего "OS в сборке" ).

В любом случае вам нужно сначала переключиться в графический режим. Это несколько вариантов:

  • Самое простое - это использовать вызов BIOS перед входом в защищенный режим. С VBE 2.0 вам не понадобятся вызовы настройки окна видеопамяти.
  • Другим способом является создание среды V8086, которая достаточно хороша для BIOS. Самая сложная часть - пересылка прерываний в обработчики прерываний реального режима. Это непросто, но когда это будет сделано, вы сможете переключать видеорежимы в PM и использовать некоторые другие функции BIOS (например, для ввода/вывода на диске).
  • Еще один способ - использовать интерфейс VESA VBE 3.0 с защищенным режимом. Не знаю, насколько это легко или сложно.
  • И настоящий способ джедаев выкапывает информацию о вашей конкретной видеокарте, переключает режимы, устанавливая свои регистры. Был там, сделал это для некоторых карт Cirrus в прошлом - получение большого фреймбуфера в PM не было слишком сложным. Он неспособен, но, возможно, это просто то, что вам нужно, если целью является понимание внутренних компонентов вашей машины.

Ответ 2

Это зависит от используемого графического режима, и есть много различий. Режим видео VGA видео 13h (320x200 на 8 бит/пиксель), вероятно, проще всего начать с (и это единственный режим видео VGA с 256 цветами, однако вы можете создавать свои собственные режимы, записывая непосредственно в порты видеокарты): в режиме видео BIOS в течение 13 часов видеопамять, отображаемая на экран, начинается с 0x0A0000, и она работает непрерывно 1 байт для каждого пикселя и только 1 битовая плоскость, поэтому каждый адрес координатной памяти 0x0A000 + 320*y + x:

Чтобы перейти в режим видео в BIOS 13h (320 x 200 при 8 бит/пиксель), в реальном режиме:

mov ax,0x13
int 0x10

Чтобы нарисовать пиксель в верхнем левом углу (в режиме видео 13h), находясь в защищенном режиме:

mov edi,0x0A0000
mov al,0x0F      ; the color of the pixel
mov [edi],al

Ответ 3

org 100h бит 16 cpu 386

section.text: НАЧАЛО: mov ax, 12h int 10h mov al, 02h mov ah, 0ch

pixel.asm c: > nasm pixel.asm -f bin -o pixel.com int 10h