2008/4/10 木曜日

F1レースでファミコンロッキー

Filed under: ファミコン — playoffline @ 23:39:52

ファミコンロッキーの愛蔵本がゴミ置き場に捨ててありました。

コラコラコラコラーッ!

というわけで、別に拾ってきたりしてはいませんが(本当です)、ふとF1レースで50連打するとマッハを超えるという話があったことを思い出しました。もちろんマンガ内での話であって本当には出来ません。さすがに当時の僕でもこれを真に受けることはありませんでしたが、今思えば秒間60フレームのゲームだと最大でも30回しかONとOFFを認識することはできないわけで・・・などと屁理屈を言ってみたりして。

50連打は置いておくとしても、改造すればマッハを超えるようにできるのではないだろうか?

そうだ、検索してみよう!

こういうものは世の中でもう誰かがやっているに違いないのです。検索の結果それらしきスクリーンショットを見つけることはできたのですが、どうしても動画が見てみたくなったので、自力で改造してみることにしました。

改造方法も載っていなかったため、とりあえず足がかりとして逆アセンブルしたソースから416Km/hを超えるとターボになるという裏技の処理を探してみることにしました。ここが分かればスピードのワークが分かり、そこから芋づる式にいろいろ解析できるのではないかという目論見です。

6502はバイトでしか検索できないので、496=$01A0となるから、きっとソース内を#$A0で検索すればヒットするはず。

・・・発見しました。スピードが496Km/hの時にワークを1にしているようです。あとはこのワークを使っているところを色々と調べていったところ、スピードのデータテーブルと思われる部分があったので、そこを適当に書き換えてみました。


うーん・・・、速すぎてまともに走れませんね。

画面も壊れてしまいましたが、スピードが上がりすぎてVBLANK中に書き換えられなかったか、描画に使用しているデータテーブルのインデックスの範囲を超えてゴミを拾ってしまったのでしょう。深く気にしないことにします。

とにもかくにも、これでファミコンロッキーに一歩近づいたことは間違いありません。

2008/3/9 日曜日

ファミコンの特殊ネジをボールペンで開ける方法

Filed under: ファミコン — playoffline @ 12:41:46

スーファミの特殊ネジ用ドライバーはその昔持っていたのですが行方不明になってしまい、この前中古屋で購入したMMC5のカセットが開けられない状態になっていました。

そんな中、先日ネットでこんな書き込みを発見しました。

http://pub.ne.jp/kirifuri/?entry_id=830375

おお!これは目から鱗ですね。というわけでさっそくボールペンの芯をライターであぶり、ネジ穴に押し付けてみました。

すると確かに芯が溶けてネジ穴の形状になりましたが、この細い芯を回すのが一苦労です。ペンチでもあればもっと力が入るんでしょうけど・・・。

今回は結局諦めてしまいましたが、ペンチを入手次第またチャレンジしてみたいと思います。

2008/2/16 土曜日

カセットずらし(nesterJ編)

Filed under: ファミコン — playoffline @ 0:55:17

前回のカセットずらし(おさらい編)で予告しました通り、カセットずらしのシミュレーションをnesterJ上でテストしてみます。

今回nesterJを選んだ理由は、同じくソースが公開されているVirtualNESと比べてみたところ、今回変更したい部分がnesterJのほうが1箇所にまとまっていたからというだけで、他のエミュレータでもほぼ難易度は変わらないと思います。

さて、カセットずらしはPPUへのアクセスが正常に行えなくなるのが原因ですので、ソースから該当部分を探してみます。

#define VRAM(addr) \
  PPU_VRAM_banks[(addr) >> 10][(addr) & 0×3FF]

ありました。

nesterJでは画面描画の処理とPPUポートの処理の両方ともこのマクロで処理されているため、ここを置き換えるだけでうまくいきそうです。

このマクロをインライン関数に置き換えます。(本来は単純にインラインに置き換えるとエラーが出ますので、get/setの2種類のインラインを用意する必要がありますが、詳細は省略します。)

unsigned char NES_PPU::VRAM(unsigned short addr)
{
 addr = addrSlide(addr);
 return dataSlide(PPU_VRAM_banks[(addr) >> 10][(addr) & 0×3FF]);
}

この際、普通に置き換えるだけではなく、addrSlde/dataSlideという関数で引数のaddrと戻り値を書き換えるようにします。

#define ADDR_OR  0×0555
#define DATA_OR  0×05

inline static unsigned short addrSlide(unsigned short addr)
{
 addr |= ADDR_OR;
 addr &= 0×3fff;
 return addr;
}

inline static unsigned char dataSlide(unsigned char data)
{
 data |= DATA_OR;
 return data;
}

 これでバスの一部が切れてしまい、常時1が返ってしまうようになります。ADDR_ORやDATA_ORを好きな値に変更すれば、カセットのずらし具合と同等のことをシミュレーションできます。上記のソースのままでは毎回コンパイルが必要になってしまいますが、少し処理を追加すれば、実行中にショートカットキーで値を自由に変更できるようにすることも出来ますね。

さて、作ってはみたものの、何か違和感があるんです。・・・そう。実機ではもっとこう画面がギラギラしてるんです。そこでもうひとひねり。

#define DATA_OR  ((rand() & 0×01) ? 0×05 : 0×0a)

おお!実機っぽくなりました。

slide1

カセットをずらすと、端のほうのピンから順につながっていない状態になっていきますが、ちょうど境界にあるピンは不安定な状態になるはずです。上記の処理は、乱数を使ってアクセスするたびにマスクするビットを変えて、その状態をシミュレートしています。

slide2

この画面はマリオブラザーズのゲーム中のものですが、ちゃんとキャラクタが奈落に落ちていきました。

本当は動画にしたかったのですが、nesterJはムービーをAVIにすることが出来ないようで断念しました。(もし方法があったら教えてください)

ちなみにファミコンは音声もいったんカセットの内部を経由するので、カセットをずらすとバリバリという音がするんですね。でもこれのおかげで様々な外部拡張音源が実現しているわけです。キャラクタROMもカセットにあるからこそ後にバンク切り替えという技が使えるようになるわけで、そう考えるとファミコンって素晴らしい設計だったのですね。

2008/2/10 日曜日

カセットずらし再び(おさらい編)

Filed under: ファミコン — playoffline @ 13:38:46

近所のゲーム屋で中古のファミコンカセットを買ってきたのですが、そのうちの1本が起動しても画面がゴミっていしまい、微妙に差し加減を調整しながら何度もトライ。

・・・なんだかとっても懐かしい行為ですね。

というわけで、久々にカセットずらしネタをやりたくなってしまいました。まずはちょうど10年前に当ホームページに掲載していた記事をご覧ください。

その昔、禁断の秘技とされていた”カセットずらし”。電源が入ったままのファミコン本体からカセットを少しだけ引き抜く事により、表示がおかしくなるばかりではなく、マリオブラザーズでマリオを地中奥深くに落としたり、クルクルランドで見えていないはずの金塊の場所がわかったり、ドラクエではまだ行ったことのない場所に移動できたり・・・、と、いろんなことが出来ました。

しかし、ファミコンが壊れるからという理由で、雑誌の裏技コーナーでは禁じ手となり、話題になることもありませんでした。当時まだ小学生だったボクは、どうしてカセットをずらすことによって、こんな現象が発生するのかなど、知る由もありません。ただ、その時は経験から、なぜかカセットの片方を引き抜くとうまくいくんだけど、反対の方を引き抜くとハングアップしてしまう、ということだけは分かっていました。今考えると、FCはそれ以降のゲーム機とは違い、プログラムROMとキャラクタROMが別になっていたんですよね。そしてそれぞれのROMの信号線がカセットの左側と右側から出ていたんです。だから片方をずらすと絵が読み出せなくなり、反対側をずらすとプログラムが正常に実行できなくなりハングアップしたというわけです。

sold1

そこでこのカセットずらしを、以前ネットやろうぜ用に作った”FCエミュレータ for PlayStation”上で再現してみることにしました。おそらく世界初!?

(中略)

タイトル画面が出たら、R2ボタンを押してみてください。押すたびにだんだん画面がバグっていくと思います。
プログラム的には、以下のカセットコネクタ表(略)のうち、R2ボタンを押すたびに、一番下の30/60pinから順番に、強制的に信号を1にしてしまいます。

(中略)

sold2

予想通り、実機と同じような画面になりました。

ところで、実機上ではカセットをずらすことによって、たとえばマリオブラザーズであれば床の当たり判定がなくなり、マリオ達が奈落の底へ落ちていく現象が発生しますよね。これはなぜなのでしょうか。

実はマリオブラザーズでは、当たり判定のデータは、VRAM上のBG配置のデータをそのまま読み込んで使用しているのです。カセット上にはキャラクタの絵のデータしかなく、VRAMは実際にはファミコン本体にあるのですが、なぜかカセットをずらすことによって、この部分のデータも正常に読めなくなるようです。おそらく、先にカセットを通過してから本体に行くような流れになっているのでしょうか。ともかく、カセットをたくさんずらしてアドレスバスまで到達すると、本来はVRAMの0×0000を読みたかったのに、PA13が接続されていないために0×2000を読んでしまい、当たり判定がおかしくなるのではないかと仮定して、そのようにプログラムしてみました。

sold3

これも正解だったようです。ちゃんとエミュレートできました。

確かに当時は、どうして少しずらすと絵がバグりはじめ、たくさんずらすと動作がおかしくなりはじめるのか、と不思議に思っていたものです。

そういえば、確かタイトル画面でカセットを大幅にずらしておいてゲームをはじめると、タイトル画面のままでゲームが始まったような記憶が・・・。

さっそくやってみましょう。

sold3

これはさっきとは逆に、アドレスバスが切れてしまったことにより、VRAMを書き換えられなくなってしまったためだと思われます。

15年来の謎がようやく解けました。

当時はよく意味もわからずにやっていたことにも、きちんと理由付けができ、ちょっと感動しています。

さて、次回はこの”カセットずらし”を、ソース付きで公開されているnesterJに組み込んで、windows上での再現を試みます。お楽しみに!

2008/2/3 日曜日

ファミコンで最初のΔPCMはテニス!?

Filed under: ファミコン — playoffline @ 13:29:05

ネットを検索していたところ、ファミコンでΔPCMを最初に使用したタイトルは、スパルタンXであるという記述がありました。

 スパルタンXといえば、ステージ間デモでボスが「ワッハッハッハ」と笑っている時にポーズをかけるといつまでも笑い声が聞けるという、ちょっとした技(バグ?)が有名ですね。

当時はそんなことは知る由もなかったけど、今思えばあれはPCMだったんだよなあ・・・、ファミコンって何気にすごいよなあ・・・、などと考えていたところ、別のページで、スパルタンXよりワイルドガンマンのほうが先であるという記述を発見。

ワイルドガンマンのどこにPCMが使われていたっけなあ・・・、あ!そういえば「ファイア」って喋ってたっけ。

と、ここで、ふと思い出したことが・・・。

あれ・・・?確かテニスでデュースになった時に、マリオみたいな審判が「デュース」って喋っていたような気がするぞ!?もしそうだったら、テニスがΔPCMを使った最初のソフトになるはず。

というわけで、さっそくテニスを確認してみました。


 やっぱり喋ってる!

ところが、一応逆アセンブルしてΔPCM関連の処理があることまで押さえようと思って調べてみたところ、そのような処理はどこにも見当たりませんでした。

もしや・・・、と思いVirtualNesで1つ1つサウンドチャンネルのボリュームを変更しながらプレイしてみたら、「デュース」の声が三角波のボリュームに反応するではありませんか!

結論としては、「デュース」の声は三角波でそれっぽく演奏しているだけでした。

これを作った人はスゴイですね。

2008/1/27 日曜日

消火栓

Filed under: ゲーム — playoffline @ 0:30:44

消火栓

写真は旅行先での1コマ。

これを見て、押せば動くんじゃないかと思ってしまう世代を計算してみたところ、1960年~1975年生まれという結果になりました。

このブログをお読みの皆さん、当たってましたでしょうか。

パックランドは1984年の作品で、翌年にはファミコンにも移植されていますが、これらの時期に小学校高学年から大学生だったとすれば、そのくらいの生まれになるはずです。

 この消火栓を見て、ふと長年僕の中で謎のままになっている事があったのを思い出しました。パックランドの復路にはスペシャルパックマンという1UPフィーチャー(いわゆる隠れキャラ)が登場するのですが、確実に出す方法が分からずじまいでした。

当時のベーマガなどのゲーム雑誌にもハッキリとしたことは確か書かれておらず、とにかくサボテン付近を適当にジャンプしていると出ることがある、ということ以上は分かりませんでした。

しかし時代は変わり、今はインターネットという素晴らしい情報検索ツールがあります。さっそく調べてみました。

・・・うーむ、やっぱり分からない。

おそらくは、現在のスコアの特定の桁が絡んでいるとか、ステージ内のチェックポイントのような場所を何箇所か通過していないといけないとか、そういった類のものだと予想はしているのですが、僕が(適当に)調べた限りでは答えは見つかりませんでした。

どなたかご存知の方おられましたらご一報ください。

2008/1/19 土曜日

パチモノファミコンをエミュレート

Filed under: ファミコン — playoffline @ 3:41:14

以前の記事の際に、手持ちのファミコン本体がなかったため(実家にはたくさんあるのですが)、近所のゲームショップでパチモノのファミコンを購入したのですが、これが大失敗でした。結局もう一度純正のAVファミコンを買う羽目になりました。

何がダメかといいますとサウンドです。スタソルをプレイしてみてすぐに違和感を感じ、ネットで検索してみたところ、

http://www.gradius2.com/index.php?UID=1104407895

Duty比とやらが逆転しているということらしいです。うーん、ちゃんと調べてから買えば良かった・・・。

というわけで、せっかくなのでVirtualNesでこのDuty比の逆転をエミュレートしてみようと思いつきました。

さっそくソース一式をダウンロードしてきて、サウンドのエミュレーション部分を探してみると、いかにもな部分を発見しました。

INT APU_INTERNAL::duty_lut[4] = {
  2,  4,  8, 12
};

 逆転してるってことはテーブルを反転させてみれば良いわけでして、

INT APU_INTERNAL::duty_lut[4] = {
  12, 8, 4, 2
};

こんな感じにして再ビルド。


うーん完璧ですね。完璧にパチモノそっくりのサウンドになりました。

2008/1/16 水曜日

バブルへGO!・ビフォーアフター

Filed under: テレビ — playoffline @ 1:09:35

15.3% 21:00-23:20 CX* バブルへGO!

誰もがさほど期待せずに観たのではないでしょうか。しかし想像以上にバカバカしい展開の連続で、最後まで目が離せませんでした。同じタイムトラベルものとしてバック・トゥ・ザ・フューチャーを挙げるのはものすごく失礼ですが(もちろんバック・トゥに対して)、何度も見返してあちこちに散りばめられた小ネタを発見したくなる作品であるという点は共通しているかもしれません。

バブルって本当にこんな感じだったんでしょうか。こんな時代に社会人でいたかったものです。 

10.1% 18:56-20:54 EX__ 大改造!!劇的ビフォーアフタースペシャル

毎回あり得ない設定で楽しませてくれる番組ですが、今回のリフォーム物件は、知人にしばらく家を貸したところ、家中のドアというドアを全て取り外され、お風呂の浴槽も位置をずらされて蛇口が届かなくなり湯はりが出来なくなってしまった状態。壁か柱あたりも一部取り外された模様で、倒壊寸前。

とにかく気になるのが、その知人が何者で、いったいなぜそんな嫌がらせのようなことをしたのかだが、番組では特にそれに関しては多くを語らず。

なんということでしょう。

2008/1/14 月曜日

映画と同じROMを作る

Filed under: ファミコン — playoffline @ 12:38:02

“GAME KING 高橋名人VS毛利名人 激突!大決戦”

1986年公開のこの映画。名人ブームの頃に小中学生だった僕は当然のように、友達と公開初日に観に行きました。その後しばらくは、テレビとファミコンを2台並べてのスタソル対決ごっこが流行ったのは言うまでもないことで・・・。

ところで映画館では全然気づかなかったのですが、数年後にビデオを購入したところ、何と無敵ROMでの対決だったことが分かりました。


思いっきり当たってる!

ただ、実際に対決ごっこをしてみれば分かるのですが、真面目にプレイしていると被弾して2方向ビームになってしまったり敵にぶつかって爆破されてしまうことも多々あり、はっきり言って全然盛り上がれないんですよね・・・。

きっとこの映画のスタッフも(スタッフロールを見ると、あの渡辺浩弐さんも参加してるんですね)同じ結論に達して、無敵ROMでの対決にするという英断をしたのではないでしょうか。

その甲斐あってか、映画は白熱した戦いとなり、結果としては大成功を収めました。もしこれが無敵ROMでなかったら、かなりお寒い対決になっていたと思います。

でも、何で被弾している部分を編集でカットしなかったんでしょうね。名人の顔のアップを挿入するなどで、いくらでもごまかせた気がするのですが・・・。

当時からこの無敵ROMが欲しいなあ、と思っていたのですが、スターソルジャーにはスターフォースのように無敵にする裏技もなかったので、子供だった僕にはどうすることもできませんでした。

でも今なら何とでも出来る!

というわけで、さっそくカセットを分解です。

カセットを分解

分解というか破壊してしまった感がありますが・・・。これまで何度かカセットを分解したことがあるのですが、必ずといっていいほどカセットのツメが割れてしまうんですよね。うまく分解する方法があったらぜひ知りたいところです。

でも基板のほうが無事でしたので、マスクROMを取り出し、ROMライタでプログラムを吸い出して、さっそく解析です。

ちなみに、 ネットを検索するとスターソルジャーの無敵コードが見つかりますが、こちらは無敵時間(自機が点滅している時間)を無限にしているようで、これだと無敵ということがバレバレなうえに、ワークRAMへのパッチですので、カセットを作る際には使用できません。

ただ、このワークに無敵時間が格納されているという情報は有難く使わせて頂くことにして、逆アセンブルしたプログラムコードから、これで比較して分岐していそうなところを検索します。きっと当たり判定の部分が、

if (当たった)
{
 if (!無敵時間)
 {
  当たった処理
 }
}

になってるに違いないという予想からです。(実際はC言語ではなく6502ですが・・・)

この予想は見事的中。判定部分(被弾と本体の2箇所)を適当に書き換えてみて、(いきなりEPROMに焼くのは面倒なので)エミュレータでテストプレイ。

バッチリ!

というわけで、先ほどマスクROMを取り外した基板にソケットを取り付け、その上に焼きたてのEPROMをセット。

ソケット+EPROMに

完成!

・・・ただソケットのせいでカセットに収まらなくなってしまいました。


20年越しの夢がひとつ叶った瞬間です。

HTML convert time: 0.445 sec. Powered by WordPress ME