Привет! В предыдущей части этой серии статей мы рассмотрели процессор и память DMG. Следующим логическим шагом является эмуляция того, как DMG выводит изображение.
Написание эмулятора Gameboy, часть 1 Написание эмулятора Gameboy, часть 2 Написание эмулятора Gameboy, часть 3
Оглавление
Отображать Таймеры Контроль Собираем все это вместе Тестирование ЗаключениеОтображать
На этом этапе нам нужно эмулировать, как DMG отображает изображение на экране.Все будет в классе Cookieboy::GPU ( связь к исходному коду Cookieboy).
Задачу можно разделить на две большие части — эмуляция специфики того, как DMG рисует картинку; эмуляция логики, управляющей экраном.
ЖК-контроллер.
Теория Начнем с логики, поскольку именно она будет определять, когда и что мы будем рисовать.
Как всегда, перед реализацией нам нужно понять, как работает компонент. DMG отображает изображение на экране построчно и эмулирует состояния, характерные для экранов ЭLT. Каждое состояние длится строго определенное количество циклов.
Это необходимо для обеспечения доступа к памяти.
Для рендеринга графики необходим доступ к видеопамяти и ОАМ сразу в двух местах — контроллере ЖК-дисплея, который отображает все на экране; игра (ЦП), которая модифицирует память для вывода нужного ей кадра.
Для решения этой проблемы вся задача вывода графики была разбита на интервалы (каждый соответствует определенному состоянию), определяющие время, в течение которого логика экрана или игра могут обращаться к памяти.
Всего состояний четыре (числа не случайные, а строго определенные для DMG):
- 0. H-пробел.
Для экранов ЭLT это означает, что в этот момент сканирующий луч перемещается в начало следующей строки.
Никаких лучей у ДМГ, естественно, нет. Это состояние означает две вещи.
Сначала была напечатана одна строка.
Во-вторых, видеопамять и OAM не используются контроллером ЖК-дисплея и доступны ЦП.
- 1. V-заготовка.
Еще одно состояние из мира ЭLT, означающее момент, когда луч достиг конца последней строки и переходит в начало первой строки.
Для нас это означает две вещи.
Сначала были напечатаны все 144 видимые строки.
Во-вторых, видеопамять и OAM не используются контроллером ЖК-дисплея и доступны ЦП.
- 2. ОАМ.
Это состояние означает, что контроллер ЖК-дисплея использует память OAM. Она недоступна для ЦП, но видеопамять все еще доступна.
- 3. ОАМРАМ.
Это состояние означает, что контроллер ЖК-дисплея использует OAM и видеопамять.
Они недоступны процессору.
На рисование одной линии уходит ровно 456 тактов.
Это время представляет собой сумму длительности состояний 2, 3, 0 и всегда равно 456 циклам, однако длительность самих состояний может варьироваться.
Поскольку на экране 144 строки, их вывод занимает 65664 такта.
Состояние 1 длится ровно 4560 тактов.
На рисунке видно, что это время равно 10 строкам.
Это действительно так – в состоянии 1 как будто рисуется еще 10 линий.
Счетчик строк (регистр LY) не останавливается на 143, а идет до 153. В результате полное обновление экрана занимает 70224 такта или 154 строки по 456 тактов.
Переход между состояниями сопровождается запросами прерываний, если они разрешены.
Переход в каждое из четырех состояний, кроме третьего, сопровождается запросом прерывания LCDC. Кроме того, это прерывание запрашивается, если LY и LYC равны.
Запрос выполняется только в том случае, если в регистре STAT разрешено прерывание LCDC для этого состояния.
Его структура выглядит следующим образом:
Биты | Цель |
6 | Включить прерывание LCDC, если регистры LY и LYC равны.
|
5 | Включить прерывание LCDC при переходе в состояние 2 |
4 | Включить прерывание LCDC при переходе в состояние 1 |
3 | Включить прерывание LCDC при переходе в состояние 0 |
2 | Бит устанавливается, если LY и LYC равны.
Сбросить в противном случае |
0-1 | Текущее состояние |
Многое из этого можно было бы почерпнуть из Руководства ЦП, но есть одно обстоятельство — это далеко не все, что нужно знать о работе контроллера ЖК-дисплея для его эмуляции.
Я не стал вдаваться во все детали (фактически я их и не нашел), а просто сосредоточился на том, что позволяет мне корректно отображать графику в тестируемых мной играх и при этом проходить тест ЖК-контроллера.
Чтобы хотя бы грубо эмулировать контроллер, нам придется ввести еще один набор состояний — внутренний, доступный только нашему эмулятору.
Всего их 8:
Теги: #эмулятор #gameboy #DMG #C++ #Разработка сайтов #программированиеenum InternalLCDModes {
-
Xml, А Также Перспективы Технического Письма
19 Oct, 24 -
Что Лучше Dsl Или Кабельное?
19 Oct, 24 -
Как Работает Яндекс.автопоэт
19 Oct, 24 -
Планировка Без Макетов
19 Oct, 24 -
Kubernetes Ingress Глазами Новичка
19 Oct, 24