• avatar aa-dav
  • 0
«откуда инфа? что именно с бета-диском так происходит?»

Я из таких лоскутов это собирал что уже не вспомню, иногда просто форумы какие то. Если это точно неправда, то надо исправить и тут. Прошу проверить даже такой момент — есть ли точки входа где байты в оригинальном пзу ненулевые.
переключение банков ПЗУ отстаёт на один запрос

откуда инфа? что именно с бета-диском так происходит?

я вот сдуру сделал так в своём эмуляторе, и после этого стал неправильно работать TESTall:
vtrd.in/system/TEST_ALL.zip
который переходит на #3D30 явно предполагая, что выбираться с него будет уже опкод ret из ПЗУ тырдоса

а в других эмулях — unreal, spin, xpeccy — оно работает!
  • avatar Shiru
  • 1
Да, забыл упомянуть, что нужно сделать .import объявленным символам (ну или .autoimport + ). Битовые операции и прочее работают нормально.
  • avatar aa-dav
  • 0
Попробовал так сделать — ассемблер ругается что символ неопределён. Логично, ведь ini-файл есть параметр в линкер, но не в ассемблер. А если сообщаешь через .global что есть символ который потом пытаешься положить в .byte, то ругается что range error. Опять таки логично, ведь символы это адреса как правило и обойти можно сделав <NAME, т.е. взять младший байт и видимо в простой ситуации как PRG_BANKS уже сработало бы, но я попытался воткнуть это в вычисление по битовым маскам
byte MIRRORING | (HAS_SRAM << 1) | ((MAPPER & $0F) << 4) | NAME
и тут линкер выдал ошибку «Attribute expected» которая даже не гуглится особо да и я не понимаю как линкер может такое вообще отрабатывать нормально. Если только весь байт сразу там и определить разве что, но есть ли там битовые операции?
Отличная реакция на данный анонс!!!

Сидим пердим с дедом
  • avatar Shiru
  • 1
Чтобы не разбрасываться параметрами конфигурации образа iNES по разным файлам, можно в конфиг-файле линкера задать символы типа:

SYMBOLS {
	NES_MAPPER	  = 0;
	NES_PRG_BANKS = 2;
	NES_CHR_BANKS = 1;
	NES_MIRRORING = 0;
}

И в теле объявления заголовка использовать эти определения, типа .byte NES_PRG_BANKS.
  • avatar aa-dav
  • 0
Нда, сам не заметил как скатился к полному разжёвыванию каждого нового встреченного ключевого слова и объяснения как байты лежат в памяти, так что заявление из первой статьи о том, что я не буду учить как программировать в ассемблере и архитектуре 6502 вообще пошло ломанными трещинами и начало рассыпаться в пух и прах.
Уже даже не пойму какая аудитория выйдет идеальной для этого всего, уже даже закрадывается что как тот PHP-шник который стал делать выступления на конференциях как он стал писать на NES за месяц. :D
  • avatar aa-dav
  • 0
P.S.
А ведь если задуматься, то такой подход (как у SjAsm) ничем не мешает и созданию кросс-платформенных форматов — генерацию каких то заголовков и служебных вещей тоже легко положить на какие то макросы из SAVEBIN OUTPUT_FILE которые обязательно надо выполнить в оговоренном порядке. В общем то дело техники. И у меня возникает подозрение, что FASM так и работает, поэтому конкретные форматы конкретных PE и COFF там дело библиотечного уровня.
  • avatar aa-dav
  • 0
В SjAsmPlus код в банках размещается как раз ORG'ами в одни и те же адреса и сохраняется в бинарники по мере трансляции, т.е. в те моменты, когда в нужных адресах виртуальной памяти сгенерирован нужный код, а дальше по ходу трансляции он может быть перезаписан.
О, кстати, вчитался и да — это то что мне было непонятно, вчера уже сонный был, так что цитата выше немного не по делу и касается только первой части. Получается что путало само наличие директивы PAGE X, и это воспринималось как раз как то наподобие сегментации, но непонятно как работающее в рамках многостраничных моделей. А это просто как бы переключение виртуальной памяти по схеме реальных 128Кб для возможных упрощений в каких то моментах, но сбрасывать на диск всё-равно надо постранично в момент активации нужных страниц.
Теперь и с SjAsmPlus всё понятно, спасибо.
  • avatar aa-dav
  • 0
Процитирую себя же из начала статьи:
В целом такой же «сегментированный» модульный и высокоуровневый подход не редкость и в ассемблерах и активно использовался и в программировании на Intel 8086, так что наверняка для многих из вас открытием он не будет. Но тем кто привык под «модулями» понимать просто включаемые в основной файл директивой INCLUDE тексты цельной программы компилируемые в один проход — тем надо немного переучится.
Не оно разве?
  • avatar Shiru
  • 0
Есть ассемблеры без линкеров, есть с линкерами. Для того, чтобы были упоминания сегментов, нужно, чтобы исходник был под ассемблер с линкером. SjAsmPlus — ассемблер без линкера. В среде любителей-энтузиастов это более типичная архитектура ассемблера, т.к. её проще сделать (любители же сами эти ассемблеры и писали) и проще пользоваться в рамках одной целевой платформы. Из любительских кросс-ассемблеров с линкером сходу вспоминаю разве что WLA DX.

В SjAsmPlus код в банках размещается как раз ORG'ами в одни и те же адреса и сохраняется в бинарники по мере трансляции, т.е. в те моменты, когда в нужных адресах виртуальной памяти сгенерирован нужный код, а дальше по ходу трансляции он может быть перезаписан.
  • avatar aa-dav
  • 0
CA65/CC65 — пакет не для конкретно NES, а для любых систем на 6502
Нигде я не говорил что CC65 это только для NES, более того в начале этой части статьи написано про любой MOS 6502, но как то абстрактно и действительно стоит обозначить что cc65 имеет широкий охват. Это стоит сделать еще в предыдущей части. Действительно.

Также бывают ситуации, когда часть памяти кода переключаемая (разная память в одних и тех же адресах, т.е. банки)
Ни видел упоминаний сегментов в нескольких серьёзных исходниках, например Mighty Final Fight (под SjAsmPlus), но я тут реально слабо понимаю в том как именно в таком коде метки привязываются к переключению страниц.
У меня сложилось ощущение что просто через пару еще других ключевых слов и, вероятно, привязанных к виртуальным образам самого спектрума. Вообще не уверен.
Но разбираясь с секциями MEMORY и SEGMENTS ini-файла линкера cc65 очень быстро и легко понял как оно должно ложится на мапперы и любую структуру памяти любой машины. Это действительно сложно на первый взгляд, но понять нетрудно как и все выгоды — на самом деле даже очень просто.
Т.е. как переключать банки памяти на CA65 я понял даже быстрее чем на SjAsmPlus несмотря на то что со вторым столкнулся намного раньше.
Забавно, ведь во втором это сделано явно проще и для конкретной платформы, но глядя в документацию я не смог понять как.
А в CC65 просто поглядел пару минут в файл .ini с описаниями кусков памяти и сегментов и понял всё очень быстро.
Дальше только уточнения насчёт align и т.п. из официальной документации. И сразу понял кристально как сюда встраивать переключения банков.
Действительно вроде и сложнее, но по факту много проще.
  • avatar Shiru
  • 0
CA65/CC65 — пакет не для конкретно NES, а для любых систем на 6502 (и частично 65816) в принципе, изначально для восьмибитных Atari (1989 год, между прочим). Соответственно сегментная модель в линкере позволяет задать любую карту памяти для любого компьютера с этим процессором. Также бывают ситуации, когда часть памяти кода переключаемая (разная память в одних и тех же адресах, т.е. банки), часть обязательно должна быть фиксированной, есть разные виды памяти, и всё это дело сохраняется в какой-то образ определённого формата — всё это легко позволяют задать сегменты (для NES: хидер iNES, расположение ОЗУ, банки PRG и CHR).
  • avatar aa-dav
  • 0
У меня есть такая проблема — я вырос в детстве на ZX Spectrum 48 (конкретно отечественном клоне Кворум-64), но именно в детстве не стал в это деле опытным и начитанным ассемблерщиком и сейчас возвращаясь к этому и восторгаясь тем или иным вещам просто вынужден описывать как можно более подробно, вплоть для самого себя, с чем сталкиваюсь, причём опять и снова, но уже наученный про всё.
Вероятно действительно выходит ну очень подробно и с остановкой на каждом шаге. Надеюсь так и есть.
  • avatar sq
  • 1
Я читал Робуса, и не понял ни слова (это проблема, разумеется, моя, а не Робуса :)
А тут прям всё хорошо и понятно! Даже обидно, что никто не комментирует.
Я бы и сам рад, но нечего добавить :)
  • avatar aa-dav
  • 1
А ведь я искал по сайту на слова «многопоточность» и «многозадачность», но т.к. эта статья не содержит таких слов, то успешно не нашёл. :)
По существу всё правильно, но для полноты картины хочу напомнить ссылку на предыдущий пост на ту же тему: hype.retroscene.org/blog/dev/271.html
  • avatar Shiru
  • 2
Лет десять назад я сделал три вещи, которые оказались весьма востребованными в тот момент, и с помощью которых с тех пор была создана добрая половина homebrew для NES:

— Конвертер-редактор графики и экранов, а впоследствии также и составных спрайтов — NES Screen Tool, с довольно корявым, но вполне человеческим лицом. До этого были только редакторы тайлов типа Tile Layer Pro и YY-CHR, а также дикие утилиты под DOS, что очень затрудняло подготовку графики для игр. Альтернативы ему не появилось до сих пор (а надо).

— Библиотеку FamiTone, которая позволила легко и просто добавлять музыку и (решающий фактор) звуковые эффекты в игры, делая их в человеческом FamiTracker. В этом также большая заслуга jsr, Gradualore и rainwarrior, которые добавили и развили поддержку кастомных экспортёров из FamiTracker. До этого не было готового плеера, который можно было просто взять и вставить — все либо изобретали велосипед, обязательно включающий написание музыки в hex-кодах, либо приватно делились кодом. К тому же, в тот момент предпочтения в комьюнити касательно кросс-ассемблеров делились на три равные части, NESASM/asm6/CA65, код между которыми переносить довольно затруднительно, а я поддержал все три сразу. С тех пор появилось несколько альтернатив (в том числе форков моего кода), FamiTone ещё в лидерах, но его начинает теснить решение от Gradualore, которое встроили в NES Maker.

— Библиотеку neslib, которая позволила легко и просто писать на C. Ранее на сцене ходили настроения, что ничего путного сделать на C невозможно, не стоит даже и пытаться — никто и не пытался. А я видел, что делают Mojon Twins с компилятором C на ZX (как известно, ныне чурерра заполонила), и показал, что так можно было. Также я привлёк самих Mojon'ов, чтобы они показали класс (Sir Ababol и другие игры). Это в свою очередь сподвигло nesdoug'а не только самому начать писать на C, но и сделать серию туториалов, которые потом перевели на русский.

Соответственно, теперь куда не клюнь — ваш пострел везде поспел.
  • avatar aa-dav
  • 0
Shiru, ты везде!
Когда я искал аналогичные материалы, то наткнулся на статью на хабре про Си в рамках cc65 тут habr.com/ru/post/348022/
А это перевод англоязычных статей от Nesdoug: nesdoug.com/ где если в архив заглянуть, то в первоварианте от 2018 года написано: nesdoug.files.wordpress.com/2018/07/introduction-e28093-nesdoug.pdf
«As far asI know, there are no other tutorials for cc65 (not counting the example games over at Shiru’s site.)»
Воу, круто.
Тут еще на выходных пообщался с Кристофером который делает IDE Nesicide — он сейчас оказывается учавствует в джеме (сделать игру на NES за 48 часов) где вот: globalgamejam.org/2020/games/super-city-mayor-3
Credits:
Music by Shiru from the Famitone library.
xD И снова Shiru!
Ну прям респект как говорится.
  • avatar aa-dav
  • 0
Хехехе, первая тестовая программа с обильными комментариями на русском готова и крутится в эмуляторе:


Так что скоро наверное будет вторая часть. Правда таки разрываюсь на тему того не сделать ли сперва одну часть краткого введения в ассемблер и архитектуру MOS 6502 чтобы статья в целом лучше заходила тем кто в этом ни бум-бум изначально, а так, из Си пришёл. Хм…