tunaでテトリスを吸い出す

 テトリスを吸い出すのにダイオードの向きがわからないけれども、ダイオードは2本だけなので4通り全部試してみればいい。まずは2本とも左向きとして0x30~0x31で試してみるとあっさり吸い出せました。ダイオード実装なしでたまたま吸い出せただけかもしれない。

/* テトリス */
board <- {
	mappernum = 3,
	cpu_rom = {
		size_base = 0x8000, size_max = 0x8000
		banksize = 0x8000
	},
	ppu_rom= {
		size_base = 0x8000, size_max = 0x8000,
		banksize = 0x2000
	},
	ppu_ramfind = false, vram_mirrorfind = true
};
function cpu_dump(d, pagesize, banksize)
{
	cpu_read(d, 0x8000, 0x4000);
	cpu_read(d, 0xc000, 0x4000);
}
function ppu_dump(d, pagesize, banksize)
{
	cpu_write(d, 0x81d6, 0x30);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8e3f, 0x31);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8ed2, 0x32);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x92b5, 0x33);
	ppu_read(d, 0, 0x2000);
}

tunaでスターソルジャーを吸い出す

 スターソルジャーはna6koさんによると2本ともダイオードが右向きなのでバンク切り替えのデータをwriteするとき、D4とD5は両方ともLowでなければならない。D0とD1は切り替えたいバンクとして、他のビットD2、D3、D6、D7は何でも良いことになる。74161でラッチするときにデータが衝突しないようにwriteするのに都合の良いデータをROMから探します。

/* スターソルジャー */
board <- {
	mappernum = 3,
	cpu_rom = {
		size_base = 0x8000, size_max = 0x8000
		banksize = 0x8000
	},
	ppu_rom= {
		size_base = 0x8000, size_max = 0x8000,
		banksize = 0x2000
	},
	ppu_ramfind = false, vram_mirrorfind = true
};
function cpu_dump(d, pagesize, banksize)
{
	cpu_read(d, 0x8000, 0x4000);
	cpu_read(d, 0xc000, 0x4000);
}
function ppu_dump(d, pagesize, banksize)
{
	cpu_write(d, 0x8011, 0x00);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8144, 0x01);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8250, 0x02);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8100, 0x03);
	ppu_read(d, 0, 0x2000);
}

tunaでグラディウスを吸い出す

 バンク切り替えについてEnriさんのところに詳しく書かれています。74161は同期4ビットカウンターですが、プリロードを使って4ビット分D0、D1、D4、D5をラッチしているような感じです。Wでロード設定、ROMSELの立ち上がりでD0->A13、D1->A14としてラッチしますから、バンク切り替えするためにはD0とD1とで切り替えたいバンクを指定してwriteすればいいことになります。Enriさんのところにはグラディウスについて、こう書かれています。

バンク#00を選択するには$8ACEに$30を書き込めばCHR$0000~$1FFFがバンク#00になります
バンク#01を選択するには$8AD0に$31を書き込めばCHR$0000~$1FFFがバンク#01になります
バンク#02を選択するには$8ACFに$32を書き込めばCHR$0000~$1FFFがバンク#02になります
バンク#03を選択するには$8AD1に$33を書き込めばCHR$0000~$1FFFがバンク#03になります

そのとおりにanagoのスクリプトを書きます。D4とD5はダイオードがついているので昨日の図で右向きならLowに、左向きならHighにしておけばアドレスバスで競合しないです。グラディウスは2本のダイオードが左向きについているのでしょう、たぶん。バンク切り替えのデータ書き込みはどのアドレスでも良いというわけではなく、グラディウスの場合、ROMがD4、D5ともHighのデータを格納しているところでwriteしないとデータバスで競合します。

/* グラディウス */
board <- {
	mappernum = 3,
	cpu_rom = {
		size_base = 0x8000, size_max = 0x8000
		banksize = 0x8000
	},
	ppu_rom= {
		size_base = 0x8000, size_max = 0x8000,
		banksize = 0x2000
	},
	ppu_ramfind = false, vram_mirrorfind = true
};
function cpu_dump(d, pagesize, banksize)
{
	cpu_read(d, 0x8000, 0x4000);
	cpu_read(d, 0xc000, 0x4000);
}
function ppu_dump(d, pagesize, banksize)
{
	cpu_write(d, 0x8ace, 0x30);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8ad0, 0x31);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8acf, 0x32);
	ppu_read(d, 0, 0x2000);
	cpu_write(d, 0x8ad1, 0x33);
	ppu_read(d, 0, 0x2000);
}

これで吸い出せました。

kazzo互換tunaでcnrom(mapper 3)を吸い出せない

 BAKUTENDOさんの情報を参考にkazzo互換のtunaを作りました。老眼に手半田はきついです。組み立て後に全然動かない(0xffのデータだけ返ってくる)ので回路を一本一本調べたらやっぱりブリッジがありました。それを治すとmapper0はちゃんと吸い出せる。

 でもmapper3が吸い出せない。手元にあるのはグラディウス、スターソルジャー、テトリス。使っていたcnrom.adは下記の通り。

board <- {
	mappernum = 3,
	cpu_rom = {
		size_base = 0x8000, size_max = 0x8000
		banksize = 0x8000
	},
	ppu_rom= {
		size_base = 0x8000, size_max = 0x8000,
		banksize = 0x2000
	},
	ppu_ramfind = false, vram_mirrorfind = true
};
function cpu_dump(d, pagesize, banksize)
{
	cpu_read(d, 0x8000, 0x4000);
	cpu_read(d, 0xc000, 0x4000);
}
function ppu_dump(d, pagesize, banksize)
{
	for(local i = 0; i < pagesize; i++){
		cpu_write(d, 0x8000, i);
		ppu_read(d, 0, banksize);
	}
}

 webの検索では、cnrom.adで吸い出せたというものしか見つけることができない。でも自分の環境ではプログラムROMは吸い出せている(CRCがwebの情報と一致)けどキャラクターROMはダメ。エミュレータで起動してみると、ゲームは動いているけれどもちゃんと(w)キャラクターが化ける。
 mapper3のバンク切り替えの仕組みをきちんと理解していなかったということもあるし、anagoのスクリプトの仕様もよくわからない。キャラクターROMのバンク切り替えを自動でしてくれるくらいに思っていたので、ソフトウェアの問題なのかハードウェアの問題なのか切り分けができず悩みました。まだどこかにブリッジやハンダ不良があるかもしれないとか。
 吸い出したバイナリを見てみると0x8000~と同じデータが0xc000~に出てきている。これはバンク切り替えができていないですね。mapper3のバンク切り替え周りの回路は下記のような感じとのこと。ここらへんの信号を見ることにする。

 anagoにはtuna_canという簡易デバッガがついているのでビルドして実行。writeやdumpが個別にできるんですね。これは良い。単発でwriteができる。オシロをつないで書き込み時のD4やD5を見るとROMSELが来たあとにデータが変化しているんです。本来Highのデータwriteなのにレベル的にHighとLowの中間(自分の環境では)Low寄りが見える。カートリッジを外してみるとちゃんとHighで安定。あーこれはプルアップが足らないの?と最初は思ったけど、ROMSELが来てからレベルが落ちるのでコンフリクトですね。

 A11、A12に正しいアドレスがいくためにはD4とD5に正しいデータが出てくるアドレスにwriteしないと書き込みのデータとROMから出てくるデータとが衝突しちゃうと。cnrom.adが何か自動でやってくれるわけではないとそういうことですね。

ファイナルファンタジーI-VI ピクセルリマスター Iだけプレイ

 Iをプレイしました。経験値とギル4倍モードでストーリーを追う感じで。ギルは途中でカンストしちゃうのでそこからは1倍にしました。セーブとエンカウントのON/OFFがどこでもできるのはいいですね。ゲームについては、オリジナルの内容を忘れていて普通に迷ったし、楽しめました。
 クリア後のスタフッフロールは日本語(漢字かな混じり)ではなく英語(ローマ字)表記でした。

ニンテンドースイッチ修理

スイッチが起動しなくなりました。メンテナンスモードでも立ち上がらず。

11月30日(土)コンビニから宅配便(ヤマト運輸)で送付。箱が大きかったのか、80サイズで送料1160円。12月1日(日)ヤマトで保管扱い。2日(月)に任天堂へ到着。

4日(水)任天堂から修理品受付完了メールが来る。

5日(木)11時頃、任天堂から点検の都合上、NNIDとの「いつもあそぶ本体」設定を解除したとのメール。

5日(木)20時頃、任天堂から修理品出荷とのメール。12540円。

6日(金)修理品到着。まっさらでセーブデータ全滅。データ消えるのは当たり前なんだけども、ひどいもんですな。