カートリッジの不可侵領域

不可侵領域アドレス PICO-8
不可侵領域アドレス

ご無沙汰になっている、PICO-8スネークゲーム「ピコニョロ」ですが、カートリッジを2つにしようと考えています。

というのも、1つのカートリッジに書けるコードの量がギリギリで(最大8192トークン)、別のカートリッジを読み込んで容量を稼ぐ方法の存在を知っていたからです。

と言っても、実際にどうしたら良いのかわからないのと、ハイスコアなどを扱う場合には、カーリッジを読み込むと消えてしまうのでは?という不安もありました。

まずは出来るのか出来ないのかを確認するために、人が書いたコードや、サイト解説ページなどを読んでみて、あることを知りました。

「カートリッジを読み込んでも、変更されないメモリ領域が存在する」

という仕様です。

ここで、不可侵領域のアドレス 0x4300 番地の内容が 0 なのを確認し、そこに1を書き込んだ後、カートリッジを読み込んでも、変更されていない確認動画を御覧ください(反対に 0 を書き込んだ後、カートリッジを読み込んでも 0 のままでした)。

カートリッジを読み込んでも、メモリ内容は変更されない
カートリッジを読み込んでも、メモリ内容は変更されない

また、関連することを調べたら、カートリッジ自体に記録することも出来ることを知りました(CARTDATA関数で、記憶できる容量は256バイト分)。

ゲームだったら、何回プレイしたかの回数、ハイスコア、ゲーム途中の状態 などを保存することが出来ます(よくあるセーブデータですね)。

また、任意のアドレスの読み書きの命令、PEEK POKE もあり、どのように実装するのかが見えてきました。

以下のフローチャートになりました。

ピコニョロ フローチャート図
ピコニョロ フローチャート図

_init() 内で、cartdata() を実行し、引数にユニークIDを指定し特定のカートリッジを指定しておく。

dget() 関数を実行し、カートリッジからデータを読み込み、そのデータを不可侵領域に poke() 関数で書き込む。

ゲーム中は保存するデータが更新されたら、不可侵領域のデータも更新する。

ゲームオーバー時に不可侵領域のデータを peek() 関数で読み込み、dset() 関数でカートリッジへ書き込む。

という流れです。

これで、「タイトル&デモ カートリッジ」と「ゲーム カートリッジ」を行き来しても、データは消えず、プログラムを終了しても、カートリッジにデータが保存されるようになり、次回起動した時に読み込むようになります。

コメント

タイトルとURLをコピーしました