Терминатор, MOS 6502 и Ion Fury

Тема в разделе "WASM.ARTICLES", создана пользователем aa_dav, 17 ноя 2021.

  1. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    Давненько уже во время просмотра стрима демо–версии ретро–шутера Ion Maiden глаз наткнулся на казалось бы знакомый фрагмент ретро–кода на ассемблере MOS 6502:
    [​IMG]
    MOS 6502 — знатный представитель 8–битных процессоров, трудившийся в таких эпохальных машинах как Apple II, Commodore 64, Atari и Famicom/NES/Денди.

    Типовой ассемблерный код для этого процессора щедро обсыпан инструкциями LDA, LDX, LDY, STA, STX и STY — от LOAD/STORE (сохранения и загрузки) соответствующих трёх регистров общего назначения A, X и Y. Но глаз мой зацепился за знакомое словосочетание "...MOVE DATA FOR VTOC..." в комментариях программы.

    Судя по всему это отсылка к (уже тоже «ретро») фильму «Терминатор», где для пущей убедительности кадры со зрением из глаз самого бездушного киборга–ассасина из будущего были украшены высокотехнологичными на тот момент буквами и цифрами компьютерного происхождения.

    Вот конкретный кадр, который и вызвал этот факт из моей памяти:
    [​IMG]
    Давно уже я читал в разных местах, что это были листинги ассемблерного кода для компьютера Apple II, но в этот раз решил разобраться поосновательнее и докопался до полного разбора полётов в следующем видео (на английском языке):

    Оказалось, что подавляющая часть листингов и таблиц были взяты из компьютерного журнала Nibble — конкретно августовского и сентябрьского выпусков 1984 года. Вышеприведённый фрагмент это кусок кода драйвера RAM–диска с названием Ram.Disk.64 или NEWRAM (то самое сокращение VTOC — это Volume Table Of Contents, а AUXMEM — дополнительная память в которой оно всё и размещается). Кроме того использованы коды программы HIRESEX (Hi–Res–Ex, а не Hire Sex!), выводящей картинки на экран, выводы программ MON.E и Key Perfect 4.0 (последняя использовалась чтобы проверять корректность машинного кода с помощью сверочных кодов и выводила в терминаторе она сверочные коды для файла OVLY.OBJ).

    Использовалась даже таблица параметров орбит нескольких советских и одного западного искусственных спутников Земли!

    Конечно сейчас это воспринимается комично — неужели тот самый терминатор был 8–битным и работал с RAM–диском в десятки килобайт? Или он, попав в прошлое, разграбил где–то по пути компьютерный магазин и фетишировал на своих доисторических предков?

    Так или иначе, если всмотреться в код из игры Ion Maiden, то легко заметить, что он хоть и похож на код из терминатора, но им не является. Это что–то другое.
    Заинтересовавшись я начал его анализировать и сперва пришёл к выводу, что это скорее всего набитая «с потолка» отсебятина, напоминающая код для MOS 6502, но по сути являющаяся бессмыслицей.
    Так, например, первые строки кода в терминаторе:
    Код (Text):
    1.  
    2. LDA #<VTOC
    3. STA A1
    4. LDA #>VTOC
    5. STA A1+1
    6.  
    загружают в аккумулятор и потом сохраняют в параметр A1 верхний и нижний байты адреса пересылаемого блока для процедуры AUXMOVE (# означает, что данное будет зашито в инструкцию, иначе оно бы воспринималось как адрес откуда данное надо взять, а > и < уже означают нижний и верхний байты адреса) — она пересылает куски байт между основной памятью и расширенной (замапленной на последние 8Кб памяти со страничным переключением — AUXMEM собственно).

    Так вот, в коде из Ion Maiden происходит бессмыслица:
    Код (Text):
    1.  
    2. LDA #!PROC
    3. STA $314
    4. LDA #!PROC
    5. STA $315
    6.  
    Во первых — в ассемблере 6502 знак! означает, как я понял, либо признак десятичной системы исчисления перед числом, ибо двоичную операцию XOR и его использование в этом месте является бессмыслицей. Во вторых два идентичных значения #!PROC в те времена, когда экономился каждый байт никакой программист не грузил бы в аккумулятор, это просто расточительно, достаточно было одного, первого LDA. В третьих — PROC это адрес процедуры идущей ниже по коду и в 8–битный аккумулятор оно просто не влезло бы.


    В общем сперва я подумал, что это просто набросанное нечто просто по мотивам реальных исходников.
    Но по прошествии чуть более года вещи внезапно оказались куда интереснее. Т.к. для разработки на денди я зарегистрировался на англоязычных форумах nesdev.com, то решил упомянуть вышерассказанное там (http://forums.nesdev.com/viewtopic.php?f=5&t=20160) и вопрос сдвинулся с мёртвой точки!

    Один из администраторов сайта с ником Memblers написал, что нагуглил, что инструкция JMP $EA31 есть прыжок в процедуру обработки прерывания IRQ в KERNAL (аналог BIOS) у 8–битного компьютера Commodore 64 (очень популярного в Северной Америке), а многочисленные упоминания ячеек памяти вида $D4xx — это явно порты звукового чипа SID этого же ПК.
    Уже хорошо разбираясь в командах процессора MOS 6502 который как понятно использовался и в Commodore 64 я уже легко понял, что этот код выполняет воспроизведение музыкального фрагмента на двух каналах чипа SID и музыка эта зашифрована в байтах лежащих по метке DATA.

    Перенести эту программу на рабочую машину я еще не готов, но зная уже что тут происходит я начал вбивать в поисковик комбинации слов "Ion Fury music Commodore 64" и довольно быстро открыл для себя истину: https://csdb.dk/release/?id=182055
    Действительно еще в 2019 программист с никами Mr.Mouse и Xentax расковырял этот фрагмент кода и перенёс его корректно на ассемблер для этой машины. По ссылке выложен образ, поэтому я загрузил его в эмулятор Commodore 64 и вот результат (это я загрузил его образ в эмулятор C64):


    Тадаааа!!!
    Для большинства ретрогеймеров эта мелодия конечно мёд для ушей — заглавная мелодия Duke Nukem 3D собственной персоной, исполненная на двух каналах звукового чипа SID 8–битного компьютера Commodore 64 ассемблерной программой размещённой картинкой на плакате кинопроектора в комнате совещаний в игре Ion Maiden на уровне Corporate Chaos! И действительно комментарий предваряющий код где написано про "VTOC" это отсылка к виду из глаз из фильма Терминатор. Красота!

    Погуглив еще обнаружил, что адреса $0314–0315 куда процедура SETUP сохраняет адрес PROC это ничто иное как адрес процедуры обслуживания прерывания IRQ в Commodore Basic и поэтому в видео видно, что бейсик спокойно сосуществует с этой подпрограммой как с TSR и то что я там набираю на клавиатуре никак не мешает работать периодическому выводу мелодии.
    Осталось только так и непонятым мною почему в листинге из игры используется некий оператор! и как он должен работать, но в реализации от Mr.Mouse он логично заменён на взятие нижней и верхней половины адреса < и >. Так же там все.dword заменены на.byte.
    Возможно если бы не эти затуманившие мне мозг вещи я бы и сам смог докопаться до истины ранее. Хотя тогда я знал MOS 6502 и ассемблер для него намного хуже.
    Так или иначе — пасхалка супер!
     
    sl0n и Thetrik нравится это.