ダブルプロファイターBIOS改造


このページに記載されている内容は私が独自に解析した結果です。
メーカー等へのお問い合わせはご遠慮ください。なお、質問は受け付けておりません。

目次

はじめに

「ダブルプロファイター」は1台でスーパーファミコンやメガドライブの2機種に対応できる、ユニークなコンセプトを持ったバックアップマシン(ディスクド ライブ)です。特に日本では「MGH」「スーパーマジックドライブ」「ASIC POWER」などがあまり出まわらなかったため、メガドラ用のバックアップマシンではもっとも多い機種と思われます。

ただ、この「ダブルプロファイター(以下ダブルプロ)」には、メガドラ側で使用した場合、いくつか不具合があります。今回はそれを多少とも解消するため、制御プログラムを解析してバグを取ってみました。

この解析および改造は、私の所有するダブルプロファイターXで行ったものです。ロットによってはROMバージョンが異なる可能性があります。

なおこの改造により、メーカ及び輸入元の保証が受けられなくなりますので改造は自分の責任において行ってください。

実際の改造手順

1.ダブルプロの底面、手前側に付いているネジ2本をはずします。

2.電源横の封印シール下のネジをはずします。

3.これで上面のフタが外れます。プログラムROMは「U2」とシルク印刷された部分の512Kbit EP-ROMです。これをソケットから取り外します。

4.ROMリーダで読みだし、後述のパッチを当てます。

5.新しいEP-ROMにパッチ後のプログラムを焼きこみます。

6.焼きこみ後のROMをソケットに差し込み、逆の手順で組み立てて完成です。

マッピング

以下にダブルプロファイターで使われているROM(27C512,64KByte)のマップを示します。
開始アドレス内容サイズ
0000メガドライブ側制御プログラムA16KByte
4000メガドライブ側制御プログラムB16KByte
8000スーパーファミコン側制御プログラム32KByte
上の表で、メガドラ側プログラムA、Bは同じものです。これは実行時のメガドラ側メモリマップに理由があります。

ダブルプロ動作時、メガドライブのメインCPUである68000はHALTされ、サブCPUのZ80で全ての処理を行っています。以下にダブルプロ動作時のZ80側メモリマップを示します。
開始アドレス内容サイズ
0000メガドライブ側制御プログラムA16KByte
4000メガドライブ側制御プログラムB18KByte
4000ROMウインドウ1(↑とバンク切り替え)8KByte
4000SRAMウインドウ(↑とバンク切り替え)8KByte
6000メガドライブ側制御プログラムB28KByte
6000ROMウインドウ2(↑とバンク切り替え)8KByte
8000RAMウインドウ1(256バンク切り替え)8KByte
A000RAMウインドウ2(256バンク切り替え)8KByte
C000ワークRAM8KByte
E000未使用エリア8KByte
さらにこの上に、次のI/Oがメモリマップドでマップされます。
開始アドレス内容サイズ
2000ダブルプロファイター制御システムレジスタ13Byte
2800ROM/RAMバンクセレクト256Byte
3000FDC(μPD765A)&FDD制御用I/O8Byte
このような複雑なメモリマップ構成となっているため、プログラムROMを2重に持ち他と重ならない部分のみ使用しています。したがって以下の書き換えにおいても、両方のイメージを書き換えなければなりません。

コントローラ取得処理

まず最初に、コントローラセンスのバグ修正を行ないます。ダブルプロの読み取りルーチンでは純正3ボタンパッドは読み取れるのですが、6ボタンやジョイス ティックタイプなどのコントローラが正常に読み出せないという問題があります。読み出せない場合はたとえば一定方向しか利かなかったり、リピートがかかっ たりします。

まずオリジナルのセンスルーチンを紹介します。
        ;
        ; キースキャン
        ;
        0B35    C5              PUSH    BC
        0B36    3A 03 30        LD      A,(3003)
        0B39    CB 7F           BIT     7,A
        0B3B    28 03           JR      Z,0B40
        0B3D    CD 48 1D        CALL    1D48
        0B40    3E 55           LD      A,55
        0B42    D3 3F           OUT     (3F),A          ; パッド情報1選択
        0B44    00              NOP*16
        0B54    DB DC           IN      A,(DC)          ; パッド情報1読取り
        0B56    07              RLCA
        0B57    07              RLCA
        0B58    E6 C0           AND     C0
        0B5A    47              LD      B,A
        0B5B    3E FF           LD      A,FF
        0B5D    D3 3F           OUT     (3F),A          ; パッド情報2選択
        0B5F    00              NOP*16
        0B6F    DB DC           IN      A,(DC)          ; パッド情報2読み取り
        0B71    E6 3F           AND     3F
        0B73    B0              OR      B               ; 合成
        0B74    EE FF           XOR     FF
        0B76    32 95 DF        LD      (DF95),A        ; 格納
        0B79    C1              POP     BC
        0B7A    C9              RET
このルーチンでは時間を置いて2度読み、合成しているのですが、その間隔の取り方が甘いため3ボタン以外では動作しないのです。私は正確な(=セガ推奨の)読み取り間隔がわからなかったため、データが安定した時点で読み取るように変更しました。

テストの結果、好結果が得られたルーチンは以下の通りです。
        ;
        ; キースキャン
        ;
        0B35    C5              PUSH    BC
        0B36    3A 03 30        LD      A,(3003)
        0B39    CB 7F           BIT     7,A
        0B3B    28 03           JR      Z,0B40
        0B3D    00              NOP                     ; よく解らないですが
        0B3E    00              NOP                     ; カットしても動作に
        0B3F    00              NOP                     ; 支障ないようです。
        0B40    3E 55           LD      A,55
        0B42    D3 3F           OUT     (3F),A
        0B44    06 40           LD      B,40
        0B46    DB DC           IN      A,(DC)          ; パッド情報1読んでみる
        0B48    E6 30           AND     A,30
        0B4A    4F              LD      C,A
        0B4B    DB DC           IN      A,(DC)          ; 64回連続して同じ値が
        0B4D    E6 30           AND     A,30
        0B4F    B9              CP      C
        0B50    20 F2           JR      NZ,0B44         ; 読みだせなければやり直す
        0B52    10 F7           DJNZ    0B4B
        0B54    07              RLCA
        0B55    07              RLCA
        0B56    47              LD      B,A
        0B57    C5              PUSH    BC
        0B58    3E FF           LD      A,FF
        0B5A    D3 3F           OUT     (3F),A
        0B5C    06 40           LD      B,40
        0B5E    DB DC           IN      A,(DC)          ; パッド情報2読んでみる
        0B60    E6 3F           AND     3F
        0B62    4F              LD      C,A
        0B63    DB DC           IN      A,(DC)          ; 64回連続して同じ値が
        0B65    E6 3F           AND     3F
        0B67    B9              CP      C
        0B68    20 F2           JR      NZ,0B5C         ; 読みだせなければやり直す
        0B6A    10 F7           DJNZ    0B63
        0B6C    C1              POP     BC
        0B6D    B0              OR      B               ; 合成
        0B6E    EE FF           XOR     FF
        0B70    32 95 DF        LD      (DF95),A        ; 格納
        0B73    C1              POP     BC
        0B74    C9              RET
基本的には上の変更で正常にセンスできますが、もう1箇所ポートから読み出しているルーチンがあります。
        ;
        ; 離されるまで待つ
        ;
        0B7B    DB DC           IN      A,(DC)
        0B7D    E6 3F           AND     3F
        0B7F    FE 3F           CP      3F
        0B81    20 F8           JR      NZ,0B7B
        0B83    C9              RET
(DF95)を壊しても支障はないので、ルーチンコールに変更します。
        ;
        ; 離されるまで待つ
        ;
        0B7B    CD 35 0B        CALL    0B35
        0B7E    B7              OR      A
        0B7F    20 FA           JR      NZ,0B7B
        0B80    C9              RET

SRAM処理(その1)

ダブルプロファイターには256KビットのSRAMが搭載されており、セーブデータの保持が行なえる様になっています。ただしここでも問題があり、20Mビット以上のソフトではSRAMが使えません。

ここで書いた通り、メガドライブでは20Mビット以上のソフトでSRAMのマッピングが違います。ダブルプロファイターではハード的には両方のマッピングに対応しているのですが、振り分けているプログラムに問題があり実質使えないのです。

99/05/30 確証はありませんが、20MBit以上の場合はバンク切り替えにより16MBit目にSRAMを出現させている感じです。

では早速、サイズによって振り分けている部分を見てみます。
        ;
        ; RAMから起動
        ;
        1BC1    32 08 20        LD      (2008),A
        1BC4    32 00 20        LD      (2000),A
        1BC7    3A 00 DC        LD      A,(DC00)        ; 最終ファイルのサイズ
        1BCA    B7              OR      A               ; (512byteヘッダの+0)
        1BCB    C8              RET     Z
        1BCC    CD 2D 09        CALL    092D
        1BCF    32 0C 20        LD      (200C),A        ; SRAM禁止
        ; ヘッダ +1 によって分岐
        1BD2    3A 01 DC        LD      A,(DC01)        ; ヘッダ +1
        1BD5    CB 7F           BIT     7,A
        1BD7    28 03           JR      Z,1BDC
        1BD9    32 02 20        LD      (2002),A
        1BDC    E6 7F           AND     7F
        ; $01 の場合 (20M以上タイプ SRAMマッピング)
        1BDE    FE 01           CP      01
        1BE0    20 08           JR      NZ,1BEA
        1BE2    32 09 20        LD      (2009),A
        1BE5    32 0D 20        LD      (200D),A        ; SRAM有効
        1BE8    18 22           JR      1C0C
        ; $05 の場合 (16M以下タイプ SRAMマッピング)
        1BEA    FE 05           CP      05
        1BEC    20 08           JR      NZ,1BF6
        1BEE    32 0D 20        LD      (200D),A        ; SRAM有効
        1BF1    32 01 28        LD      (2801),A
        1BF4    18 16           JR      1C0C
        ; $03 の場合 (ロードサイズによってSRAMタイプ振り分け)
        1BF6    FE 02           CP      02
        1BF8    28 18           JR      Z,1C12
        1BFA    FE 04           CP      04
        1BFC    28 08           JR      Z,1C06
        1BFE    3A AA DE        LD      A,(DEAA)        ; ロード済みサイズ
        1C01    3D              DEC     A               ; (16KB単位)
        1C02    FE 80           CP      80              ; 16Mを越えた場合
        1C04    30 06           JR      NC,1C0C         ; 有効にならない(バグ)
        1C06    32 0D 20        LD      (200D),A        ; SRAM有効
        1C09    32 01 28        LD      (2801),A
        1C0C    32 07 20        LD      (2007),A        ; ダブルプロモードOFF
        1C0F    C3 00 00        JP      0000            ; リセット
このプログラムでは、ファイルヘッダ(512バイトヘッダ)の+1によって振り分けています。01hなら20M以上タイプ、05hなら16M以下タイプ、03hなら自動です。通常は03hになっています。

したがって、このバグについてはヘッダを05hに書き換えることでROMを焼き直すことなく対応可能ですが、やはり自動判定できたほうが良いことには違いありません。

修正については流れを見てわかるとおり、1C04での分岐先を1BE2にすれば良いわけです。
        1C04    30 DC           JR      NC,1BE2

付録・警告画面

プロファイターシリーズでは起動時に必ず警告画面が表示されますが、何度も見てもしょうがないので、ダブルプロファイターでの画面カットの方法を紹介します。
        ;
        ; 警告文表示
        ;
        0BC5    3E 2A           LD      A,2A            ; メッセージ番号
        0BC7    CD 89 09        CALL    0989            ; メッセージ表示
        0BCA    21 00 00        LD      HL,0000
        0BCD    CD 35 0B        CALL    0B35            ; キースキャン
        0BD0    3A 95 DF        LD      A,(DF95)        ; キーコード
        0BD3    B7              OR      A
        0BD4    20 05           JR      NZ,0BDB
        0BD6    2B              DEC     HL
        0BD7    7C              LD      A,H
        0BD8    B5              OR      L
        0BD9    20 F2           JR      NZ,0BCD
メッセージ表示した後で、一定時間過ぎるかキーが押されたら次へ進むようプログラムされている事がわかりますか?

このブロック自体をスキップすればカットできます。
        0BC5    18 14           JR      0BDB


$4E75
ytanaka@ipc-tokai.or.jp