Ответ 1
ЧАСТЬ 1
В старых режимах VGA существует фиксированный адрес для записи в (память) области памяти дисплея. Для текстовых режимов эта область начинается с 0x000B8000. Для графических режимов он начинается с 0x000A0000.
Для видеорежимов с высоким разрешением (например, установленных с помощью интерфейса VESA/VBE) это не работает, потому что размер унаследованной области памяти дисплея ограничен до 64 KiB, и для большинства видеорежимов с высоким разрешением требуется намного больше места (например, 1024 * 768 * 32-bpp = 2,25 MiB). Чтобы обойти это, существуют 2 разных метода, поддерживаемых VBE.
Первый метод называется "банковское переключение", где только часть памяти отображения видеокарты отображается в унаследованной области в любое время (и вы можете изменить, какая часть отображается). Это может быть довольно запутанным - например, чтобы нарисовать один пиксель, вам может понадобиться вычислить, в каком банке находится пиксель, затем переключитесь на этот банк, а затем вычислите, какое смещение в банке. Чтобы сделать это хуже, для некоторых видеорежимов (например, видеорежимов с 24 байтами в секунду, где есть 3 байта на пиксель), только первая часть данных пикселя может находиться в одном банке, а вторая часть тех же данных пикселя находится в другом банке, Основное преимущество этого заключается в том, что он работает с адресацией реального режима, поскольку унаследованная область памяти дисплея ниже 0x00100000.
Второй метод называется "Linear Framebuffer" (или просто "LFB" ), где доступна общая область памяти видеокарты без какого-либо беспорядочного переключения банков. Вы должны спросить интерфейс VESA/VBE, где находится эта область (и обычно она находится в "отверстии PCI" где-то между 0xC0000000 и 0xFFF00000). Это означает, что вы не можете получить доступ к нему в реальном режиме и должны использовать защищенный режим или длинный режим или "нереальный режим".
Чтобы найти адрес пикселя, когда вы используете режим LFB, вы бы сделали что-то вроде "pixel_address = display_memory_address + y * bytes_per_line + x * bytes_per_pixel". "Bytes_per_line" поступает из интерфейса VESA/VBE (и может быть не таким же, как "horizontal_resolution * bytes_per_line", потому что между горизонтальными линиями может быть прокладка).
Для режимов "с банковским переключением" VBE/VESA это становится чем-то более похожим:
pixel_offset = y * bytes_per_line + x * bytes_per_pixel;
bank_number = pixel_offset / bank_size;
pixel_starting_address_within_bank = pixel_offset % bank_size;
Для некоторых старых режимов VGA (например, 256-цветного режима "0x13" ) он очень похож на LFB, за исключением того, что между линиями нет прокладки, и вы можете делать "pixel_address = display_memory_address + (y * horizontal_resolution + x) * bytes_per_pixel". Для текстовых режимов это в основном одно и то же, за исключением того, что 2 байта определяют каждый символ и его атрибут - например. "char_address = display_memory_address + (y * horizontal_resolution + x) * 2". Для других старых режимов VGA (монохромный/2-цветный, 4-цветный и 16-цветный режимы) память видеокарты устроена совершенно по-разному. Он разбивается на "плоскости", где каждая плоскость содержит один бит пикселя и (например,) для обновления одного пикселя в 16-цветном режиме, который вам нужно записать в 4 отдельные плоскости. По соображениям производительности аппаратное обеспечение VGA поддерживает разные режимы записи и различные режимы считывания, и может стать сложным (слишком сложным для адекватного описания здесь).
ЧАСТЬ 2
Для портов ввода/вывода (на 80х86, "Совместимость с ПК" ) есть 3 общие категории. Первый - это "де-факто стандартные" устаревшие устройства, которые используют фиксированные порты ввода-вывода. Это включает в себя такие вещи, как чипы PIC, контроллер ISA DMA, контроллер PS/2, чип PIT, последовательные/параллельные порты и т.д. Почти все, что описывает, как программировать каждое из этих устройств, сообщит вам, какие порты ввода/вывода используются устройством.
Следующая категория - устаревшие/ISA-устройства, где порты ввода-вывода, используемые устройствами, определяются перемычками на самой карте, и нет разумного способа определить, какие порты ввода-вывода они используют из программного обеспечения. Чтобы обойти это, конечный пользователь должен указать ОС, какие порты ввода/вывода используют каждое устройство. К счастью, этот хрустящий материал стал устаревшим (хотя это не обязательно означает, что его никто не использует).
Третья категория - "подключи и работай", где есть какой-то способ спросить устройство о том, какие порты ввода-вывода он использует (и в большинстве случаев, меняя порты ввода-вывода, которые использует устройство). Примером этого является PCI, где есть "пространство конфигурации PCI", которое сообщает вам много информации о каждом устройстве PCI. Для этих категорий никто не может определить, какие устройства будут использовать порты ввода-вывода, не выполняя его во время выполнения, а изменение некоторых настроек BIOS может привести к тому, что все/все эти устройства изменят порты ввода-вывода.
Также обратите внимание, что процессор Intel - это только процессор. Ничто не мешает использовать эти процессоры в чем-то, что сильно отличается от компьютера, совместимого с ПК. Руководства для процессоров Intel никогда не расскажут вам ничего о аппаратном обеспечении, которое существует вне самого процессора (включая чипсет или устройства).
Часть 3
Вероятно, лучшее место для получения дополнительной информации (предназначенной для разработчиков ОС/любителей) - http://osdev.org/ (их вики и их форумы).