Игровая приставка NES (Nintendo Entertainment System) - версия для Америки, известная
также как Famicom (FAMily COMputer) - версия для Японии, в нашей стране, благодаря фирме
Стиплер (Steepler), известна как Dendy. И не смотря на то, что в середине девяностых годов
прошлого века Денди была действительно «народной» приставкой – со стремительным ростом
технического прогресса она сейчас, как игровая система, отошла далеко-далеко на задний
план (уступив место ПК и другим игровым консолям). Но именно в сегодняшние дни Денди
более интересна не геймерам, а радиолюбителям – как простейшая микро-ЭВМ …
Вопросом программирования Денди заинтересовался и я.
В начале изучения и создания материала, который представлен вам ниже, а именно в
2003 году - разнообразной информацией Интернет не изобиловал (хотя кое-что и было) – вся
документация англоязычная (хотя встречались и ее прямые переводы – безо всякого
осмысления переводимого). Тогда же вышла даже книга и мультимедийный диск (разных
издательств, но одинакового содержания – книга даже более полного) – в которых легко
узнавались все теже англоязычные источники (а часть информации взята «с потолка» и
абсолютно некорректна). Поэтому многое пришлось осмыслять на практике (весь текст
исключительно мой, авторский).
Вторая итерация и второе существенное дополнение и переработка данного материала
была в 2007 году … Всего и не вспомнить, некоторые несущественные дополнения и
корректировки были и до и после. Также благодаря отзывам читателей были исправлены
некоторые недочеты, однако не все изменения сразу публиковались на сайте.
И вот в 2016 году текст очередной, что называется «обновленной и дополненной»,
редакции перед вами …
Материал ориентирован на читателя, обладающего базовыми сведениями по организации
ЭВМ.
Общие сведения об архитектуре Денди.
Игровая приставка Денди является микро-ЭВМ для домашнего (игрового) применения
(далее речь пойдет именно о Денди – как наиболее распространенной вариации консоли NES,
а вернее ее японской версии Famicom, в России), ориентированная на использование
телевизора в качестве дисплея. Подключение к телевизору может осуществляться одним из
двух способов – «по низкой частоте» (двумя кабелями – звук и композитный видео) или «по
высокой частоте» (при помощи «антенного» кабеля). Китайские совместимые поделки,
представленные в нашей стране в большом разнообразии – архитектурно совместимы с Денди,
однако зачастую имеют ряд схемотехнических «упрощений», не позволяющих полностью
реализовать функционал оригинальных консолей (и даже стиплеровской «Денди»).
Денди и прочие клоны консолей NES/Famicom (как в общем-то и их оригиналы)
сконструированы на базе микропроцессора (CPU), совместимого с MSC6502 (микросхемы:
RP2A03, RP2A07, UM6527, HA6827 и пр.) и видеопроцессора (PPU) (микросхемы: RP2C02,
RP2C07, UM6538, UM6528, HA6838 и пр.), которые работаютв тесном взаимодействии(такая
вот «двухпроцессорная» система). Пары CPU + PPU подбираются с учетом формата
формируемого кадра – NTSC или PAL. У каждого процессора своё адресное пространство и
своя оперативная память (не путать с адресным пространством). Адресные пространства CPU и
PPU не пересекаются. Микросхема CPU, применяемая в Денди, имеет встроенный звуковой
сопроцессор – pAPU (чего нет у базового процессора 6502), но при этом отсутствует блок
двоично-десятичной арифметики. Помимо CPU и PPU, совместно со статической оперативной
памятью, работу приставки обеспечивают так же прочие «мелкие» компоненты (регистры,
логические элементы), сопрягающие работу всей системы. Архитектура Денди
предусматривает хранение (и исполнение) программ со сменных модулей – «картриджей». Об
архитектуре картриджа см. ниже – здесь лишь скажем, что часть картриджа адресует CPU, а
часть PPU. Изначально плата приставки Денди содержала несколько корпусов микросхем (CPU
и память, PPU и память, регистры логические элементы и прочее …) – как и оригинальные
консоли. Последние ревизии моделей Денди (1996 год) собраны на заказной микросхеме
(UM6561A) – которая совмещает на одном кристалле все «микросхемы» приставки (SoC –
System on Chip). В ревизиях моделей Денди более ранних версий можно встретить «гибридный
вариант» - память (оперативную и видео) установленную в виде двух отдельных микросхем
(UM6516, UM6116 – аналог КР537РУ10), видимо, в центральный «SoC» (xx1818) её нет.
Вне зависимости от элементной базы, структурная схема Денди имеет вид, показанный на
рисунке 1.
Рисунок 1.
Процессор Денди (CPU).
Адрес
Размер
Назначение
$0000-$07FF
2k
RAM
$0800-$1FFF
6k
RAM Mirror (x3)
$2000-$2007
$8 = 8 байт
Registers Video
$2008-$3FFF
$1FF8 = 8184 байта
Registers Video Mirror (x1023)
$4000-$4017
$20 = 32 байта
Registers Audio & DMA & I/O
$4018-$4FFF
$0FE8 = 4072 байта
Not used
$5000-$5FFF
4k
Expansion ROM\RAM (etc. in MMC5)
$6000-$7FFF
8k
SRAM (aka WRAM) (etc. in MMC3)
$8000-$BFFF
16k
PRG-ROM (1)
$C000-$FFFF
16k
PRG-ROM (0)
Как отмечалось ранее, первая (многокорпусная) модель NES/Famicom строилась на базе
процессора Ricoh RP2A03 (архитектура 6502) или его аналога. Все последующие модели сверху
вниз совместимы с ней. Не исключено, что SoC UM6561 более совершенен, имеет расширенную
систему команд, а возможно и другие "фичи" (которые, надо понимать, в дань совместимости,
как правило, не используются). Поэтому, говоря о процессоре Денди, – опираемся на базовую
архитектуру 6502, реализованную в «классическом» RP2A03 (универсальном), или RP2A07 только для варианта PAL.
Подробнее о системе команд 6502 можно прочитать в приложении 1. Примеры
принципиальных схем и их описания - в приложении 5.
Здесь же мы рассмотрим, как этот процессор используется именно в Денди.
Распределение адресного пространства.
Модель 6502 предусматривает единое адресное пространство кода и данных
(принстонская архитектура). Также в процессоре отсутствуют инструкции обращения к портам
ввода/вывода (типа in/out) – порты должны отражаться на адресное пространство памяти. Т.е.
адресное пространство процессора делится между портами и памятью. В архитектуре Денди
это происходит так (кстати, по-моему, не очень рационально):
RAM – Оперативная память (на плате приставки или внутри SoC) объемом 2k – её
распределение следующее:
$0000-$00FF – “Нулевая страница” (Zero Page) – используется для системных целей (для
пользовательских программ предпочтительны адреса $10-$9F, прочие лучше не
трогать). Процессор имеет отдельные инструкции, обеспечивающие быстрый доступ к
нулевой странице. Таким образом, с учетом малого количества регистров в самом
процессоре, нулевая страница может выполнять роль «регистрового банка».
Таблица 1.
$0100-$01FF – Аппаратный стек от старших адресов (размер, понятно, 256 байт).
$0200-$07FF – Пользовательская область оперативной памяти, «не много не мало» а
всего 1.5k.
Начиная с адреса $0800 из-за неполной дешифрации адреса, идут три «зеркала» RAM.
Т.е. обращение к ячейке $0000 эквивалентно обращению к $0800 или к $1000 или к $1800.
(Интересно, что мешало разработчикам установить еще 6 килобайт памяти – лишнего
наверняка бы не было).
Registers Video [8 шт.] – через эти регистры видеопроцессора (и только через эти
регистры) осуществляется связь центрального процессора с видеопроцессором, а через него и
с видеопамятью. Подробнее см. главу «Видеопроцессор Денди (PPU)». Далее с адреса $2008
идут «зеркала» регистров видеопроцессора.
Registers Audio & DMA & I/O [24 шт.] – регистры звукового сопроцессора, контроллера
DMA и портов ввода/вывода. Подробнее см. соответствующие главы. Назначение остальных
($0FE8=4072 шт.) адресов не определено, но может использоваться внешними звуковыми
процессорами, располагающимися на картридже.
Expansion ROM\RAM [4k] – расширение ПЗУ\ОЗУ (или любое другое, располагающееся
на картридже) – используется, например, маппером MMC5 (см. главу «Картридж Денди»)
SRAM (она же WRAM) [8k] – статическое ОЗУ, которое также может находиться на
картридже. Являясь полноценным ОЗУ для процессора, может использоваться для любых
целей, в том числе и для хранения (исполнения) программы. Как правило, в этой области игры
хранят данные состояния текущей игровой локации в процессе игры (маппер MMC3). При
необходимости сохранения игровых ситуаций, эта микросхема питается от батарейки,
расположенной на картридже (сохранение игры на время выключения питания, с
возможностью последующего продолжения).
PRG-ROM [32k] – зачастую представлено 2 окнами по 16k (иногда 4 по 8k или другой
вариант логического разбиения - в зависимости от маппера, для более гибкого варьирования
страничной адресацией памяти картриджа, см. главу «Картридж Денди»). Чтобы подробно
рассмотреть механизмы эффективного использования этого участка памяти – необходимо
иметь представление об архитектуре конкретного картриджа (а вариантов тут много), речь о
них пойдет позже. Самая простая архитектура картриджа маппера не содержит, в картридже
есть лишь две ПЗУ размером 32k и 8k, подключаются они к шинам процессора (CPU) и
видеопроцессора (PPU) соответственно (см. рис.1). Первая (в нашем примере 32k) микросхема
ПЗУ функционально называется PRG-ROM, и содержит в себе программу и возможно данные.
Первые 16k ПЗУ отображаются в окне 1 ($8000-$BFFF), последние 16k в окне 0 ($C000-$FFFF).
Организовано это на схемотехническом уровне. В конце нулевого окна располагаются вектора
прерываний процессора.
Система прерываний.
Архитектура 6502 предусматривает всего 3 прерывания. Рассмотрим подробнее случаи их
возникновения, предварительно указав адреса в таблице векторов прерываний.
$FFFA – NMI (VBlink)
Немаскируемое прерывание. Поступает с видеопроцессора и сигнализирует о том, что PPU
закончил прорисовку очередного кадра и «луч пошел обратно» (в начало экрана). Обработчик
NMI должен производить в этот момент (ограниченное время) необходимые по программе
обновления данных видеопамяти, т.к. во время прорисовки строк кадра видеопамять
недоступна (из нее осуществляет чтение PPU). Существует возможность программного
отключения видеопроцессора – в этом режиме доступна запись в видеопамять
(неограниченное время) прерывание NMI формироваться не будет, но также будет
отсутствовать и картинка на экране (используется при начальной инициализации).
$FFFC – RESET
Происходит по факту включения питания или при нажатии на клавишу «Reset». Стоит
помнить, что в последнем случае изменяется только программный счетчик, все регистры, а тем
более память сохраняют свои значения.
$FFFE - IRQ/BRK
Единственное в системе «пользовательское» прерывание. Возникает по активному
сигналу на соответствующем входе процессора, который выведен на разъём картриджа и порт
расширений (или может вызываться программно – инструкция BRK). Таким образом вызывать
обработчик данного прерывания может как периферия, расположенная на картридже
(например, маппер), так и устройства, подключенные к порту расширений («разъем второго
джойстика»).
Соответственно по указанным адресам (в «таблице векторов прерываний») должны
находиться инструкции перехода к обработчикам соответствующих прерываний. Приоритет
прерываний следующий (от более приоритетного к менее): RESET, NMI, IRQ/BRK.
Видеопроцессор Денди (PPU).
Видеопроцессор (PPU) ориентирован на генерацию картинки на выходе в одном из
стандартов: для американской NES и японской Famicom – это NTSC; для российских Денди (и
китайщины, продаваемой у нас) – это, как правило, PAL (в редких случаях SECAM – что не
меняет формата размера картинки в сравнении с PAL). Далее рассматриваем именно вариант
PAL.
PPU формирует «готовый» низкочастотный видеосигнал, который непосредственно (или, в
зависимости от модели приставки, через каскад(ы) усилителя) подается на видеовыход Денди
и на вход модулятора полного («антенного») сигнала.
Характеристики и возможности PPU:
Шина Адреса – 14 бит (адресное пространство 16k) + 256 байт отдельно адресуемой
памяти спрайтов;
Шина Данных – 8 бит;
Количество цветовых оттенков всего – 64;
Одновременно на экране – до 25 (любые из 64), а именно: до 13-и для фона и до 12-и
для спрайтов;
Количество спрайтов на экране – 64 (не более 8-и на линии);
Разрешение выводимой картинки (PAL/NTSC) – 256x240 / 256x224;
Частота регенерации (PAL/NTSC) – 50Гц/60Гц;
Для программиста (и CPU) –видеопроцессор это 8 регистров, адресуемые CPU по адресам
$2000-$2007 (в архитектуре Денди) –они обеспечивают возможность полного управления
видеопроцессором. Помимо этого, запись в память спрайтов PPU может осуществлять так же и
контроллер DMA (понятно, что без непосредственного участия процессора). Иных способов
общения с PPU нет!
Адресное пространство PPU распределяется следующим образом:
Адрес
Размер
Назначение
$0000-$0FFF
4k
CHR-ROMЗнакогенератор 0(На картридже)
$1000-$1FFF
4k
CHR-ROMЗнакогенератор 1(На картридже)
$2000-$23BF
$3C0 = 960 байт
VRAM Экранная страница 1 –Символы (В приставке)
$23C0-$23FF
$40 = 64 байта
VRAM Экранная страница 1 –Атрибуты (В приставке)
$2400-$26BF
$3C0 = 960 байт
VRAM Экранная страница 2 –Символы (В приставке)
$27C0-$27FF
$40 = 64 байта
VRAM Экранная страница 2 –Атрибуты (В приставке)
$2800-$2BBF
$3C0 = 960 байт
VRAM Экранная страница 3 –Символы (На картридже)
$2BC0-$2BFF
$40 = 64 байта
VRAM Экранная страница 3 –Атрибуты (На картридже)
$2C00-$2FBF
$3C0 = 960 байт
VRAM Экранная страница 4 –Символы (На картридже)
$2FC0-$2FFF
$40 = 64 байта
VRAM Экранная страница 4 –Атрибуты (На картридже)
$3000-$3EFF
$F00 = 3840 байт
VRAM Mirror of $2000-2EFF
$3F00-$3F0F
$10 = 16 байт
Палитра фона(в регистрах PPU)
$3F10-$3F1F
$10 = 16 байт
Палитра спрайтов(в регистрах PPU)
$3F20-$3FFF
$E0 = 224 байт
Не используются
Регистр
(адресация
по CPU)
Биты
Назначение
$2000 w/o
Управление видеопроцессором
7
Формирование запроса прерывания NMI при кадровом синхроимпульсе
(0 - запрещено; 1 - разрешено)
6
Не используется (должен быть 0)
5
Размер спрайтов (0 - 8x8; 1 - 8x16)
4
Выбор знакогенератора фона (0/1)
3
Выбор знакогенератора спрайтов (0/1)
2
Выбор режима инкремента адреса при обращении к видеопамяти
(0 – увеличение на единицу «горизонтальнаязапись»; 1 - увеличение на 32 «вертикальная запись»)
1,0
Адрес активной экранной страницы (00 – $2000; 01 – $2400; 10 – $2800; 11 $2C00)
$2001 w/o
Управление видеопроцессором
7-5
Яркость экрана/интенсивность цвета в RGB (в Денди не используется)
4
0 – Спрайты не отображаются; 1 – Спрайты отображаются
3
0 – Фон не отображается; 1 – Фон отображается
2
0 – Спрайты невидны в крайнем левом столбце; 1- Все спрайты видны
1
0 – Рисунок фона невиден в крайнем левом столбце; 1- Весь фон виден
0
Тип дисплея: Color/Monochrome (в Денди не используется)
$2002 r/o
Состояние видеопроцессора. Чтение сбрасывает некоторые биты!
7
1 – PPU генерирует обратный кадровый импульс; 0 – PPU рисует картинку на
экране. Сбрасывается при чтении.
6
Устанавливается в 1 после вывода спрайта с номером 0. Сбрасывается при
чтении или при кадровом синхроимпульсе.
5
1 – На линии больше 8-и спрайтов; 0 - меньше
4
1 – Запись в видеопамять разрешена; 0 - запрещена
3-0
Не используются
$2003 w/o,
$2004 r/w
Операции с памятью спрайтов. В регистр $2003 записывается адрес в
памяти спрайтов ($00-$FF). После чего с регистром $2004 производится
операция чтения/записи. После каждой операции происходит автоинкремент
адреса на единицу.
$2005
w/o(x2)
Аппаратныйскроллинг фоновой картинки. В регистр последовательно
записываются два байта. Первый – абсолютное значение вертикального
скроллинга; второе – горизонтального (подробнее см. главу «Отражение
экранных страниц».)
$2006
Операции с видеопамятью. Обеспечивают доступ к любой ячейке адресного
пространства видеопроцессора. Регистр $2006 – адрес (2байта), сначала
Регистры видеопроцессора выполняют следующие функции:
w/o(x2),
$2007 r/w
записывается старший. Регистр $2007 – операционный буфер (чтение/запись).
После каждой операции происходит автоинкремент адреса на 1 или на 32 (см.
регистр $2000- бит 2).
Всвязи с тем, что шины адреса и данных у PPU совмещены, в архитектуре
Денди предусмотрен регистр для хранения текущего адреса. Чтение
происходит из ячейки адресуемой этим регистром, а лишь затем он выдает
вновь записанный адрес. Соответственно содержимое новой ячейки будет
доступно при следующей операции чтения. Рассмотрим это на примере:
Пусть в VRAM с адреса $2000 содержится: $AA $BB $CC $DD.
При операциях с VRAM инкремент равен 1.
Результаты исполнения кода приведены в комментариях.
LDA #$20
STA $2006
LDA #$00
STA $2006 ; VRAM address now set at $2000
LDA $2007 ; A=?? VRAM Buffer=$AA
LDA $2007 ; A=$AA VRAM Buffer=$BB
LDA $2007 ; A=$BB VRAM Buffer=$CC
LDA #$20
STA $2006
LDA #$00
STA $2006 ; VRAM address now set at $2000
LDA $2007 ; A=$CC VRAM Buffer=$AA
LDA $2007 ; A=$AA VRAM Buffer=$BB
При работе с палитрами буфер адреса не используется (т.к. они находятся
специальных регистрах видеопроцессора). При записи в память не требуется
лишнего цикла.
Таблицы 2 и 3.
Теперь подробнее:
CHR-ROM (Она же VROM) [8k] – Вспомним нашу модель картриджа (из предыдущей
главы), в которой второе ПЗУ размером 8k подключалось к шинам PPU. Функционально оно
называется CHR-ROM. В нем хранятся два знакогенератора (по 4k каждый). Знакогенератор
содержит «иконки» (они же «тайлы», «спрайты», «значки»), размер каждой иконки 8x8
пикселей. На каждый пиксель выделяется 2 бита. В каждом знакогенераторе 256 таких иконок.
Все что «умеет» видеопроцессор – это отображать содержимое знакогенераторов (и ничего
более!)
VRAM [2k] – Ровно столько в Денди оперативной видеопамяти. Далее под словом
«видеопамять» - понимаем именно VRAM (не путать с адресным пространством PPU, которое
включает, в том числе, и VRAM). В видеопамяти хранятся экранные страницы или иными
словами – фоновая картинка (точнее: информация о том из каких иконок она состоит –
область символов; два старших бита цвета иконки – область атрибутов). Каждая экранная
страница занимает ровно 1k видеопамяти (960 байт – информация о номерах иконок из
знакогенератора + 64 байта – информация о цвете групп иконок). В видеопамяти приставки
(2k) умещается только две экранных страницы – в то время как архитектурно (для PPU)
предусмотрено четыре экранных страницы. Подробнее об экранных страницах см. ниже в
подразделе «Отражение экранных страниц».
Палитры фона и спрайтов [16 + 16 байт] – PPU может отображать 64 цвета (каждому
номеру строго определенный цвет - см. рисунок 2). Соответствие цветов формату RGB см.
приложение 2.
Рисунок 2.
PPU содержит в себе регистры палитр (адресуются через адресное пространство PPU).
Предусмотрено две палитры – палитра фона ($3F00-$3F0F) и палитра спрайтов ($3F10-$3F1F). При помощи палитры происходит выбор любых 16-ти цветов из 64-х возможных для
текущего отображения на экране (в ячейку палитры заносится номер цвета (00h-3Fh) - см.
рисунок 2).
Слои. Общий принцип формирования изображения.
PPU, работающий в системе PAL, формирует картинку с разрешением 256x240. PPU
формирует изображение из четырех слоев путем их последовательного наложения (каждый
следующий слой «заслоняет» предыдущий, если не является прозрачным в данной точке):
Задний план – холст, окрашенный цветом из палитры фона с индексом 0 (цвет любой см. рисунок 2).
Слой спрайтов с битом приоритета = 0 (подробнее см. в разделе «Спрайты. Контроллер
DMA.»)
Фоновый рисунок – картинка, составленная из иконок знакогенератора (как из мозаики
32x30). Фоновый рисунок хранится в экранной странице (VRAM). В области символов - 960 байт
(32x30) должны быть записаны номера иконок знакогенератора фона (см. регистр $2000 - бит
4). На экране отображается содержимое активной экранной страницы (см. регистр $2000 - бит
1,0). Экранная страница содержит только информацию о фоновом рисунке. Знакогенератор
содержит иконки с двумя младшими битами цвета для каждого пикселя иконки. Два старших
бита цвета – общие для всей иконки, берутся из области атрибутов экранной страницы.
Полученное четырехбитное число определяет номер цвета в палитре фона. Таким образом,
каждая иконка (без смены палитры) может иметь до четырех вариантов раскраски. Т.е. при
помощи двух бит из области атрибутов экранной страницы – палитра фактически разбивается
на 4 части (по 4 цвета в каждой), номер части определяется битами области атрибутов, номер
цвета (внутри части) – битами пикселя в знакогенераторе.
Слой спрайтов с битом приоритета = 1 (подробнее см. в разделе «Спрайты. Контроллер
DMA.»)
Далее рассмотрим двоичные форматы перечисленных структур.
Знакогенератор.
В знакогенераторе отводится по 16 байт на каждую иконку (16x256=4096). Первые 8 байт
определяют построчно младший бит цвета иконки. Следующие 8 бит – старший (см. рисунок).
Пиксель иконки, со значением обеих бит равными нулю – считается прозрачным (вне
Последовательно хранятся номера иконок из знакогенератора фона (величина смещения
иконки от начала знакогенератора деленная на 16). Экран заполняется иконками построчно
(32x30=960 иконок на экране).
Область атрибутов экранной страницы.
Для каждой иконки в фоновой картинке, два старшие бита цвета, выбираемого из
палитры фона, определяются соответствующими битами байта атрибута области атрибутов.
Причем старшие биты цвета одинаковы для группы иконок.
Табличка выше иллюстрирует фрагмент VRAM, адреса из области символов Экранной
страницы 1 («левый верхний угол экрана») – изображены ячейки с адресами начала первых
четырех строк экрана. Цветом показаны группы иконок, имеющие одинаковый атрибут (два
старших бита индекса цвета в палитре фона).
Байт области атрибутов (для указанного выше фрагмента: «левый верхний угол» - по
адресу $23C0) содержит атрибуты четырех смежных групп:
Приоритет спрайта. 1 – Спрайт перед фоном; 0 – Спрайт за фоном
4-2
Не используются
1,0
Два старших бита цвета (аналог атрибута цвета для фона)
3 Координата верхнего левого угла спрайта по горизонтали
Весь экран построчно разбивается на группы (8 строк и 8 столбцов) – последняя строка
неполная. Соответственно за каждую группу отвечает один байт атрибутов.
Палитры.
На самом деле не из 16-ти цветов палитры происходит выбор цвета. Происходит это
потому, что и здесь имеет место явление «отражения» (mirroring) – на этот раз применительно
к цветам палитры. Происходит это так. Как отмечалось выше, пиксель иконки знакогенератора,
оба бита которого нулевые, вне зависимости от атрибута, считается прозрачным. Из этого
следует, что в палитре фона есть 3 ячейки, содержимое которых нас не интересует (цвет то и
так прозрачный по условию). Это ячейки с адресами $3F04, $3F08 и $3F0C. В ячейке $3F00 (как
упоминалось выше) хранится номер цвета холста, и именно он виден сквозь «прозрачные»
пиксели. Так вот – архитектура PPU Денди предусматривает отражение «лишних» ячеек
палитры ($3F04, $3F08 и $3F0C) в ячейку цвета холста ($3F00).
С палитрой спрайтов таже история – у спрайтов (подробнее о спрайтах в следующем
разделе) нет «своего» холста, и поэтому ячейки палитры спрайтов, на которые приходятся
прозрачные цвета ($3F10, $3F14, $3F18 и $3F1C), также отражаются на ячейку $3F00.
Спрайты. Контроллер DMA.
Со спрайтами все очень просто. В качестве спрайтов выступают все теже иконки
знакогенератора (определенного, «как знакогенератор спрайтов» - см. регистр $2000 - бит 3).
Внутри PPU есть отдельно адресуемая (от основного адресного пространства PPU – 16k) память
спрайтов, размером 256 байт. Эта память хранит «записи» о 64 спрайтах, размер каждой
записи 4 байта. Располагаются записи последовательно от младших адресов.
Формат записи следующий:
Таблица 4.
Спрайты нумеруются начиная с нуля. После вывода нулевого спрайта (а он может быть в
любом месте экрана) устанавливается бит 6 регистра $2002 PPU. Запись/чтение в/из память/и
спрайтов производится при помощи регистров $2003 (адрес) и $2004 (данные). При каждой
операции адрес автоинкрементируется на 1.
Существует более быстрый способ записи в память спрайтов – запись через контроллер
DMA. Контроллер DMA занимает в адресном пространстве CPU один адрес - $4014. При записи
в этот порт числа $XX, контроллер DMA отправляет в память спрайтов содержимое 256-ти
3
$2800
4
$2C00
1
$2000
2
$2400
ячеек памяти, начиная с адреса = $XX x $100. (Например: при записи в регистр контроллера
DMA $02 – в память спрайтов отправится содержимое ячеек $0200-$02FF). В программах
рекомендуется использовать именно этот способ записи – как наиболее быстрый (около
100мкс.)
Отражение экранных страниц.
Как уже упоминалось выше – в Денди установлено 2k VRAM (сразу еще раз ругнемся на
разработчиков – пожалели еще одну микросхему ОЗУ). Да именно пожалели, если посмотреть
на карту адресного пространства PPU (см. выше) – то можно видеть, что реально
видеопроцессор может работать с четырьмя страницами VRAM. Оно так и бывает, если на
картридже установлены недостающие 2k VRAM – уймись программист или раскошелься
пользователь, если разработчик решил сэкономить!
Но вернемся к архитектуре – какие возможности добавляют нам лишние 2k VRAM?
Рассмотрим все по порядку …
PPU Денди обеспечивает такой эффект, как «скроллинг» (прокрутка) фонового рисунка
(независимо от спрайтов) – причем, абсолютно аппаратно. Скроллинг может быть как
горизонтальным, так и вертикальным или и тем и тем сразу (по диагонали) – таким образом на
в видимую область попадает содержимое нескольких экранных страниц. Экранные страницы
имеют следующую пространственную модель (нумерация с привязкой к адресам в адресном
пространстве PPU):
В регистр $2005 последовательно записываются два значения - абсолютное вертикальное
и горизонтальное смещение (соответственно) относительно текущей активной страницы.
Например, активная страница 1 ($2000) – горизонтальное смещение ноль, а вертикальное $E0
(240) – как результат, на экране видно содержимое страницы 3. Варьируя значение
вертикального смещения, можно получить фон, состоящий из части страниц 1 и 3 (их
стыковку). Если «закрутить» эту операцию в цикл – то можно получить эффект «скроллинга»
фоновой картинки. Аналогично происходит горизонтальный скроллинг (прокрутка).
Программы, не использующие функцию скроллинга, должны записывать в
регистр $2005 два нуля при каждой обработке прерывания VBlank, иначе
изображение будет смещенным!
Но есть один нюанс – в Денди нет памяти подо все четыре страницы. Как и в прочих
случаях, тут тоже имеет место «отражение» - и на этот раз экранных страниц (друг на друга).
Вид отражения определяет архитектура используемого картриджа. Существует 2 вида
отражения – горизонтальное (1=2 и 3=4) и вертикальное (1=3 и 2=4). То есть содержимое
указанных страниц идентично (т.е. зеркалируется).
3 4 1
2
Горизонтальное отражение экранных страниц
3
4
1
2
3 4 1
2
3
$2800
A11
A10 1 0
4
$2C00
A11
A10 1 1
1
$2000
A11
A10 0 0
2
$2400
A11
A10 0 1
Вертикальное отражение экранных страниц
Если в картридже установлены недостающие 2k VRAM – то содержимое всех четырех
страниц может быть различным.
Вне зависимости от способа отражения (или при наличии всех четырех страниц) –
скроллинг возможен в любом направлении (в том числе и по диагонали).
Аппаратная реализация выбора способа отражения экранных страниц следующая.
Старшая линия физической микросхемы VRAM в приставке (A10) выведена исключительно на
разъем картриджа VRAM A10 (см. приложение 4 и Приложение 5), таким образом, управлять
данной линией может либо маппер (например, MMC3) – либо данная линия жестко
«закольцована» в картридже на одну из адресных линий PPU (А10 или А11), тем самым и
определяя вид зеркалирования экранных страниц. Лучше понять суть описанного поможет
следующая (уже знакомая) иллюстрация.
Горизонтальное отражение – источником сигнала VRAM A10 является линия A11
(состояние линии А10 не определяет адрес в микросхеме VRAM);
Вертикальное отражение - источником сигнала VRAM A10 является линия A10 (состояние
линии А11 не определяет адрес в микросхеме VRAM);
(В раскраске бит соответствующих адресных линий видна аналогия с иллюстрациями
видов отражений выше.)
Картридж Денди.
Денди спроектирована так, что вся программа и все данные хранятся исключительно на
картридже. Сама приставка не содержит никакой постоянной памяти. Картридж
устанавливается в разъём, на который выведены как шины CPU, так и PPU (см. приложение 4).
До сих пор мы, для простоты и наглядности, ссылались на модель картриджа, содержащую 32k
PRG-ROM и 8k CHR-ROM без наличия маппера. Такие картриджи подходят для хранения
небольших игр - их память полностью адресуется CPU и PPU. Для большинства же игр такой
объём явно недостаточен – поэтому большинство картриджей имеют значительно больший
объём памяти (до 1024k PRG-ROM и 1024k CHR-ROM). Понятно, что непосредственно процессор
не может адресовать такой объём памяти. В Денди применяется метод «страничной
адресации» памяти картриджа. Картриджи большого объёма содержат, помимо микросхем
памяти, еще и переключатель страниц (маппер). Маппер («mapper») – комбинационная схема
(или контроллер), состояние которого однозначно определяет блоки ПЗУ картриджа,
отображаемые в данный момент в адресное пространство процессора, или знакогенератор
PPU. Размер переключаемых окон адресного пространства CPU зависит от типа маппера, а с
некоторыми мапперами может даже варьироваться, типичные конфигурации - 2*16k,
2*8k+16k, 4*8k (возможны и иные конфигурации - причем, как правило, последнее окно
непереключаемое).
Видов мапперов существует очень много (наиболее распространены около десяти) –
каждый из них имеет свой функционал по управлению аппаратной частью картриджа:
поддержка того или иного вида и объёма используемых в картридже микросхем памяти,
возможность использования дополнительной памяти (ОЗУ), наличие других дополнительных
функций (звукового процессора, таймеров и пр.). Мапперы имеют свои (отличные от других)
«системы команды» управления их состоянием. Большим количеством модификаций
«классических» мапперов мы обязаны «пиратам» - стремящимся либо с сэкономить на железе,
любо запихнуть на один картридж много всего разного, а зачастую - и то и другое сразу ;-)
Несмотря на все разнообразие (см. перечень мапперов), базовый функционал всех без
исключения мапперов по большому счету идентичен – состояние регистров маппера
определяет (управляет) старшими линиями адреса микросхем PRG-ROM и/или CHR-ROM (для
которых не хватает адресных линий в разъеме картриджа).
И так, при наличии маппера, картридж Денди содержит:
PRG-ROM – микросхема ПЗУ, хранящая программу и данные (неотъемлемая часть любого
картриджа). Подключается к шинам процессора. Старшие линии адреса микросхемы ПЗУ, а
также управляющие входы подключаются к мапперу (если маппер предусматривает
переключение страниц PRG-ROM).
CHR-ROM/CHR-RAM – микросхема памяти, подключаемая к шинам PPU - возможен один
из двух вариантов:
ПЗУ (CHR-ROM)
переключаться, если это предусматривает маппер. Подключается к шинам PPU и
мапперу (если маппер предусматривает переключение страниц знакогенератора).
– хранит заранее «прошитые» знакогенераторы PPU, которые могут
ОЗУ (CHR-RAM)
случае «иконки» знакогенераторов должны храниться в PRG-ROM (или генерироваться
алгоритмически) и программно (через регистры управления PPU) загружаться в CHR-RAM. Преимуществом такой организации является то, что есть возможность изменения
одной иконки знакогенератора (или даже ее части), при сохранении всех остальных
иконок неизменными.
– статическая память, размером 8k (два знакогенератора). В этом
В предыдущем случае (CHR-ROM) имелась возможность только
выбирать заранее созданные и прошитые в ПЗУ пресеты знакогенераторов (если их
несколько) – зато путем переключения можно намного быстрее изменить группу иконок,
чем поштучно их подгружать.
Mapper – комбинационная схема (или контроллер), осуществляющиекоммутацию блоков
микросхем ПЗУ в адресные пространства CPU и/или PPU – т.е. фактически управляет старшими
линиями адреса микросхем ПЗУ, для которых «не хватает» адресных линий в слоте картриджа
и/или адресном пространстве процессора. Маппер находится на картридже и подключается к
шинам CPU и/или PPU и соответствующим микросхемам памяти. Некоторые мапперы состоят из
нескольких микросхем. Любая программа (игра) пишется под определенный тип маппера.
Т.е.,
говоря современным языком: драйвер маппера «вшивается» в код программы, более того – он
зачастую «размазан» по всему коду … Возможность адаптировать (модифицировать)
программу (дамп игры) под другой маппер – задача довольно рутинная – нужно найти и
откорректировать все места, где происходит управление маппером.
Также картридж (в редких случаях) может содержать:
SRAM (она же WRAM) - (Адресное пространство CPU $6000-$7FFF) – Статическое ОЗУ,
может питаться от компактной батарейки, располагающейся на картридже. Предназначено для
«сохранения» игр (если есть батарейка), или просто служит дополнительным ОЗУ (хорошее
дополнение). Для него зарезервировано «окно» в адресном пространстве CPU размером 8k (в 4
раза больше встроенного в приставку ОЗУ, а скорость таже и прямая адресация) - существуют
картриджи, несущие на борту до 32k ОЗУ (т.е. 4 страницы, переключаемые маппером в этом
окне).
Expansion ROM\RAM - (Адресное пространство CPU $5000-$5FFF) – Дополнительные
4k памяти (для CPU). В целом аналогично SRAM (используется, как правило, с маппером
MMC5).
VRAM - (Адресное пространство PPU $2800-$2FFF) – «Недостающие» 2k VRAM для двух
экранных страниц PPU (3 и 4). Редкая фишка - используется очень немногими играми.
Звуковой процессор - предназначен для более качественного синтеза звука, нежели
это реализуется встроенным pAPU (например, в мапперах VRC6, VRC7 и других).
Большинство аппаратных возможностей Денди могут быть использованы (дополнены),
например, маппером MMC5 или MMC3 (большинство технологичных игр используют именно
их). Разумеется, ничто не мешает разработать новый маппер самому (в архитектуре приставки
ничего менять не придется! - всю логику управления маппером содержит программа на
картридже), чем китайские разработчики («пираты») увлекаются больше других, а вместе с
этим производят и совместимые аналоги «официальных» микросхем мапперов – наиболее
популярные из которых следующие:
MMC1 – AX5904
MMC3 – AX5202
VRC4 – AX5208
Программирование мапперов.
В адресном пространстве CPU - адреса $8000-$FFFF выделены для отражения на них
памяти картриджа - PRG-ROM. Логически может быть организовано несколько окон,
управляемых маппером. Размер и количество окон определяется архитектурой маппера,
некоторые типы предусматривают переменный размер переключаемого окна (например,
MMC3). Наиболее распространенный вариант 2*16k, 2*8k+16k или 4*8k - в последнее окно
($xxxx-$FFFF) позиционируетсяили«хвост» ПЗУ, илиего начало. Также, зачастую, последнее
окно переключению не подлежит (в нем находятся вектора прерываний).
Каждый маппер имеет определенное количество регистров управления, доступных только
для записи. Адресуются они через области, отведенные для PRG-ROM. То есть – чтение из
памяти по адресам $8000-$FFFF приводит к чтению ПЗУ (PRG-ROM), а запись, по некоторым
адресам из этого диапазона, приводит к записи управляющих слов в соответствующие
регистры маппера.
Подробное описание разных мапперов – не цель данного материала, однако некоторые из
них рассмотрим подробнее.
Маппер UNROM.
Для примера рассмотрим маппер UNROM – один из самых простейших мапперов, но
весьма удобный для знакомства с программированием Денди и написания несложных
программ. Он предусматривает работу с PRG-ROM объёмом 128k (17 линий адреса, 3-мя
старшими линиями управляет маппер), в качестве CHR используется непосредственно ОЗУ
размером 8k (без участия маппера). Маппер строится на базе двух микросхем (74HC161 и
74HC32) и программно представлен как один регистр, который отражается на всё пространство
PRG-ROM ($8000-$FFFF). То есть запись по любому адресу из этого диапазона приведет к
записи в регистр маппера. Записываемый байт (а вернее 3 младших его бита) определяет блок
микросхемы ПЗУ (16k), подключаемый в окно $8000-$BFFF (т.е. при A14=0) - блоки нумеруются
с нуля и с начала адресации микросхемы ПЗУ. В окно $C000-$FFFF (т.е. при A14=1, вне
зависимости от содержимого регистра маппера) всегда подключен последний блок (последние
16k) ПЗУ (A14=A15=A16=1 на адресных входах ПЗУ). Таким образом, возможен вариант (при
«xxxxx111» в регистре маппера) когда последний блок ПЗУ будет последовательно
продублирован в адресном пространстве.
Знакогенератор CHR-RAM - заполняется программно, через регистры PPU ($2006,$2007) –
запись должна производиться в адресное пространство PPU, отведенное под знакогенератор
($0000-$1FFF). Вид отражения экранных страниц определяется распайкой (коммутацией)
перемычки на плате картриджа.
Принципиальная схема маппера UNROM такова:
Loading...
+ 32 hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.