ピロ彦の何か置き場

ドラゴンクエスト3 ファミリーベーシック任意コード新チャートについて

アーカイブはこちらから

www.twitch.tv

youtu.be

ファミコンは電源を入れたままカセットを抜くと、
通常はROMが読み込めなくなってプログラムが動作しなくなる。
しかし、『メモリ上の』プログラムを無限ループで実行している間は
ファミコンのカセットを抜いてもCPUは動作し続けているので
別のカセットに差し替えてもコードが実行され続けることになる。

ファミリーベーシックにはファミコンバイナリーコード(ネイティブコード)を
実行できる『CALL命令』があるため、ファミべ上で任意コード実行することは容易である。
$0300-$03FFには1行分のプログラムバッファが格納されるので
CALL773'~というコードを入れてReturnキーかF8を押すと、メモリアドレス$0305(773)
つまり「'」以降の文字がバイナリコードとして実行される。

しかし、メモリ上に無限ループを作って実行しても
1/60秒毎の垂直同期タイミングであるVBlank時にNMI割り込みが発生して
描画・音声を更新するためのROM上のプログラムなどを実行しようとしてしまうので、
NMI割り込みを止める命令をループ前に書く必要がある。
※I/Oレジスタ$2000(のミラーアドレス$2020)のBit7に0をセットすることでNMI割込がオフになる。

無限ループ中には冒険中のゾーマ討伐フラグ($60C5)、復帰場所フラグ($60C3)、
NMI割り込みオフ($2020)、カートリッジRAMオフ($AEAE)の4箇所に書き込むコードを書いている。
カートリッジRAMオフには$A000-$BFFFのどこかに5回書き込む必要があるので
無限ループ中のどのタイミングで挿しても問題ないが
斜め差しをするとROMSEL(A15)が中央寄りなのでアドレスバスが小さくズレたままカートリッジRAMがオフになり、
目当てのアドレスへの書き込みがされず失敗することがあるので
左側から挿すか、まっすぐ勢いよく挿す必要がある。
https://wiki.nesdev.org/w/index.php?title=Cartridge_connector

 

冒険の書を作成した後、朝になるタイミングで冒険中フラグである$6A58がONになるので
そこでカセットを入れ替え、ファミリーベーシックでコードを実行して再度差し替え
DQ3のカートリッジRAMがオフになると電源バグの準備状態になるので、
リセットを押すか電源ON/OFFをしてAボタン等を押すと
王様セーブまでの過程を省略しバグアイテムを使うこともなく
エンディングを建てた状態でラダトームで全滅復帰することが可能になった。


        A:02 X:03 Y:00 S:FC P:nvUbdizc  レジスタの初期値、Cフラグはクリア
$0300   CALL773                         $0305(773)をバイナリコードとして実行。
$0304   '                               引用符、これがないと一部の文字列が無視される。
$0305   コザ    69 9C     ADC #$9C      Aレジスタに0x9Cを足す、A:02だったので0x9Eになる。
$0307   ゾエ    A0 63     LDY #$63      Yレジスタに0x63を入れる。
$0309   グウア  99 62 60  STA $6062,Y   $6062+Y = $60C5のゾーマ討伐フラグにA:9Eを書き込む、0x80ビットでゾーマ討伐状態。
$030C   グアア  99 60 60  STA $6060,Y   $6060+Y = $60C3の城復帰場所フラグにA:9Eを書き込む、06または0Eでラダトーム。8箇所ループ。
$030F   ァ    8E 20 20  STX $2020     $2000のミラーアドレスである$2020にX:03を書き込み、MNI割込をオフにする。
$0312   ァペペ  8E AE AE  STX $AEAE     $A000-$BFFFの間に5回書き込みがあるとカートリッジRAMへのアクセスがオフになる。
$0315   ゥ┛    90 F2     BCC $0309     キャリーフラグがクリアなら分岐、$0309へループ。
※"┛"は、[GPRH]+ラ
CALL  773   ’ コ ザ ゾ エ グ ウ ア グ ア ア ァ     ァ ペ ペ ゥ ┛(ラ+[GRPH])
AD 12 05 03 27 69 9C A0 63 99 62 60 99 60 60 8E 20 20 8E AE AE 90 F2
↑$0300    ↑$0305   ↑$0309

ファミリーベーシックの$0700~$07FFは文字出力バッファのため、
そのままでは00で埋め尽くされていて0勇者が出て大ロスしてしまうので
電源ON/OFFバグを併用してキャラ生成する必要がある。


※要約
ファミリーベーシックでCALL773'+文字列と打ち込んで
RETURNキーか改行を含んだファンクションキーを押すと、
引用符以降の文字列がファミコンの命令として直接実行される。
文字列で書かれた任意コードはファミコン本体メモリ上でループするように書かれ、
その状態だとカセットを引っこ抜いてもファミコンのCPUは動き続けているので、
ファミリーベーシック任意コードがドラクエ3に差し替えた後もそのまま実行され続ける。
今まではファミリーベーシックではDQ3のカートリッジ上のフラグ類は直接いじることが
出来ないと思われていたがこれによって可能となった。


ファミリーベーシックのキー配列はWikipedia画像を参照

ja.wikipedia.org