ЧАСТЬ 1
Для старых режимов VGA существует фиксированный адрес для записи в (унаследованную) область памяти дисплея. Для текстовых режимов эта область начинается с 0x000B8000. Для графических режимов он начинается с 0x000A0000.
Для режимов видео высокого разрешения (например, настроенных интерфейсом VESA / VBE) это не работает, потому что размер устаревшей области памяти дисплея ограничен 64 КиБ, а большинству режимов видео высокого разрешения требуется намного больше места (например, 1024 * 768 * 32-bpp = 2,25 МиБ). Чтобы обойти это, есть 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 байта определяют каждый символ и его атрибут - например, msgstr "char_address = display_memory_address + (y * Horizontal_resolution + x) * 2". Для других старых режимов VGA (монохромный / 2-цветный, 4-цветный и 16-цветный режимы) память видеокарты расположена совершенно иначе. Он разделен на «плоскости», где каждая плоскость содержит один бит пикселя, и (например, для обновления одного пикселя в 16-цветном режиме вам необходимо записать в 4 отдельные плоскости). По соображениям производительности аппаратное обеспечение VGA поддерживает разные режимы записи и разные режимы чтения, и это может стать сложным (слишком сложным, чтобы адекватно описывать его здесь).
ЧАСТЬ 2
Для портов ввода / вывода (для 80x86, «Совместимые с ПК») есть 3 основные категории. Первый - это «стандартные де-факто» устаревшие устройства, которые используют фиксированные порты ввода / вывода. Сюда входят такие вещи, как микросхемы PIC, контроллер ISA DMA, контроллер PS / 2, микросхема PIT, последовательные / параллельные порты и т. Д. Почти все, что описывает, как программировать каждое из этих устройств, скажет вам, какие порты ввода / вывода использует устройство.
Следующая категория - это устаревшие / ISA-устройства, где используемые порты ввода-вывода определяются перемычками на самой плате, и нет никакого разумного способа определить, какие порты ввода-вывода они используют из программного обеспечения. Чтобы обойти это, конечный пользователь должен сообщить ОС, какие порты ввода / вывода использует каждое устройство. К счастью, все это стало устаревшим (хотя это не обязательно означает, что никто не использует его).
Третья категория - «подключи и работай», где есть какой-то метод запроса устройства, какие порты ввода / вывода оно использует (и в большинстве случаев изменение портов ввода / вывода, которые использует устройство). Примером этого является PCI, где есть «пространство конфигурации PCI», которое сообщает вам много информации о каждом устройстве PCI. Для этих категорий никто не может определить, какие устройства будут использовать какие порты ввода / вывода, не делая этого во время выполнения, и изменение некоторых настроек BIOS может привести к тому, что любое / все эти устройства изменят порты ввода / вывода.
Также обратите внимание, что процессор Intel - это только процессор. Ничто не мешает использовать эти процессоры в чем-то, что радикально отличается от «ПК-совместимого» компьютера. Руководства по процессорам Intel никогда не расскажут вам об оборудовании, которое существует за пределами самого процессора (включая чипсет или устройства).
часть 3
Вероятно, лучшее место для получения дополнительной информации (предназначенной для разработчиков ОС / любителей) - http://osdev.org/ (их вики и их форумы).