2024年4月4日の日記を表示中

2024年 4月 4日 (木)

基板

スーパーパンでのSRAM上のデータに対するエンコード方式について、スタックに読み書きしているエンコード済みのデータも含めてツールで絞り込んだところ、以下の通りと判明しました。

  • エンコードは、ただのビットシャッフル
  • ビットシャッフルのアルゴリズム自体はROM上のプログラムと共通
  • シャッフル時のパラメータは命令 (オペコード) とそれ以外で共通
  • ROM上のプログラムでは、アドレスとコンフィギュレーション情報の一部 (MAMEのコード (kabuki.cpp) でいうaddr_key) で決まっていたパラメータ (select) が固定値 (0xffc3) になる
  • ROM上のプログラムではコンフィギュレーション情報の一部 (MAMEのコードでいうxor_key) が使われていたが、ここがゼロ固定になっている

デコード処理は、MAMEのコード (kabuki.cpp) のbytedecode関数を以下のように呼ぶイメージです。

        decode_buf[A] = bytedecode(src[A],swap_key1,swap_key2,0,0xffc3);

エンコード関数はMAMEにないけど、デコードと逆の順番でシャッフルするだけですね。

static int bitswap1x(int src,int key,uint16_t select)
{
        if (select & (1 << ((key >>12) & 7)))
                src = (src & 0x3f) | ((src & 0x40) << 1) | ((src & 0x80) >> 1);
        if (select & (1 << ((key >> 8) & 7)))
                src = (src & 0xcf) | ((src & 0x10) << 1) | ((src & 0x20) >> 1);
        if (select & (1 << ((key >> 4) & 7)))
                src = (src & 0xf3) | ((src & 0x04) << 1) | ((src & 0x08) >> 1);
        if (select & (1 << ((key >> 0) & 7)))
                src = (src & 0xfc) | ((src & 0x01) << 1) | ((src & 0x02) >> 1);

        return src;
}

static int bitswap2x(int src,int key,uint16_t select)
{
        if (select & (1 << ((key >> 0) & 7)))
                src = (src & 0x3f) | ((src & 0x40) << 1) | ((src & 0x80) >> 1);

        if (select & (1 << ((key >> 4) & 7)))
                src = (src & 0xcf) | ((src & 0x10) << 1) | ((src & 0x20) >> 1);

        if (select & (1 << ((key >> 8) & 7)))
                src = (src & 0xf3) | ((src & 0x04) << 1) | ((src & 0x08) >> 1);

        if (select & (1 << ((key >>12) & 7)))
                src = (src & 0xfc) | ((src & 0x01) << 1) | ((src & 0x02) >> 1);

        return src;
}


static int byteencode(int src,int swap_key1,int swap_key2,int xor_key,uint16_t select)
{
        src = bitswap1x(src,swap_key2 >> 16,select >> 8);
        src = ((src & 0xfe) >> 1) | ((src & 0x01) << 7);
        src = bitswap2x(src,swap_key2 & 0xffff,select >> 8);
        src = ((src & 0xfe) >> 1) | ((src & 0x01) << 7);
        src ^= xor_key;
        src = bitswap2x(src,swap_key1 >> 16,select & 0xff);
        src = ((src & 0xfe) >> 1) | ((src & 0x01) << 7);

        src = bitswap1x(src,swap_key1 & 0xffff,select & 0xff);

        return src;
}

...
        encode_buf[A] = byteencode(src[A],swap_key1,swap_key2,0,0xffc3);
...

結局、SRAMアクセス時のエンコードは8bit内のビットシャッフルでしかないので、0x00と0xFFを読み書きするときは必ずエンコード後も同じ値になります。だから最初のRAMチェックの処理では、エンコードが有効になっている状態でも生データと同じ値 (0x00 or 0xFF) が書かれていたんですね。

何か当初の目的を見失いかけていますが、これまでわかったコンフィギュレーション末尾のまとめ。

  • コンフィギュレーションの末尾が 0x70 0x00 のときはSRAM上のデータがエンコードされた状態になるけど、SRAM上に置いたデータを命令列とみなして実行できる
  • コンフィギュレーションの末尾が 0xF0 0x00 のときはSRAM上のデータが生データになるけど、SRAM上に置いた命令をそのまま実行することができない (間違った命令にデコードされちゃうからなのか、そもそもこの設定のときはSRAM上の命令の実行が禁止されているからなのかは不明だけど、おそらく後者だと思う)

こういう理由があって、SRAM上に置かれたコードを実行するタイトルについてはコンフィギュレーション情報の末尾を 0x70 0x00 にする必要があるということなんでしょうね。・・・ということは、もしかしてスーパーパン以外にもそういうやつがあったりするのかな。 (追記: 調べてみたら 麻雀学園2、ポーカーレディース、スーパー○禁版ではSRAM上のコードを実行することが判明しました)

2024年4月4日の日記を表示中

中の人情報

名前:
nosuke (のすけ)
メール:
sasugaanijaのgmail.com
「の」は「@」みたいな
関連リンク:

カレンダー

2024年4月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

<<先月分

翌月分>>

最新の10件のエントリ

最近の10件のコメント

過去ログ