長く苦しい戦いだった - エンディングを呼び出す

エンディング呼び出しと言えば任意コード実行の花形みたいなところがありますが、初代ポケモンではドアの行先書き換えで部屋に飛ぶ方が早いのでめったに使うことはありません。

原理

でんどういりからスタッフロールにかけてのプログラムはバンク 1C の頭から入っています。
というわけで、2000 と FFB8 に 1C を書いて、jp 4000 すれば終わり!
と思うじゃないですか。

コーディング

ざんねんながら

00,40 は入力不能文字なので即値ジャンプ命令つかえません!
唯一ジャンプ先をレジスタ指定できる E9 もつかえません!

ということで、回避のためのトリックでサイズが倍に膨れ上がった完成したコードがこちらになります。

; 1匹目 ョぺぽひゃ
AF; xor a
47; ld b,a
48; ld c,b c=00
CB E0; set 4,b b=10
50;

; 2匹目 ひヂぼボパ
CB 10; rl b; b=20
3E 1C; ld a, 1c
40; nop
50; ld d,b

; 3匹目 ゃくデひヂ
E0 B8; ld (FFB8), a
12; ld (de),a
CB 10; rl b; b=40
50; ld d,b

; 4匹目 なの
C5; push bc
C9; ret
50;

コード解説

AF; xor a
47; ld b,a
48; ld c,b c=00
bc か de あたりに 2000, 4000 を作る方針でいきます。
とりあえず 00 は AF (xor a) でつくればいいでしょう。
これを ld b,a と ld c,b に送り込むことで a,b,c はすべて 00 に初期化。
CB E0; set 4,b
50; 終端文字 特に意味はない
CB 10; rl b
bc=0000 になったので、次は b レジスタに 20 を作ることを考えます。
もちろん a にadd を駆使して作ってもいいのですが、CB 命令を使えば4バイトで直接 b に作れます。
set 5,b できれば手っ取り早いのですが入力できないので、set 4,b で 10 にしてから rl(左ローテート) すれば、20 の出来上がり。
3E 1C; ld a, 1c
40; nop
50; ld d,b
E0 B8; ld (FFB8), a
12; ld (de),a
a レジスタに切り替える先のバンク 1C を入れておきます。
ここでどさくさにまぎれて終端の 50 で ld d,b されます。
忘れがちですが、バンク切り替えは 2000 から 3FFF までのどこかに書き込めばよいので、d レジスタが 20 なら e レジスタの値は何が入っててもいいことになります。
CB 10; rl b
50; ld d,b
C5; push bc
C9; ret
b レジスタをさらに左ローテートして 40 に。
バンクの切り替えが終わったので jp しますが、 jp hl は使えないので push bc からの ret で代用します。

ちなみに

めんどくさいですが、飛び先を 4000 から 4003 にするとでんどういり画面を飛ばしてスタッフロールに直接飛びます。
ただし、画面の初期化処理が一部飛ばされてしまうので、表示が乱れます。


戻る
connecting: riko.2rnd.msmrrneda.net