本題部分が片付いてしまいだんだんダレてきてますが、今回はグラフィックデータ修正作業です。
Tinyみずいろのプログラム構成
前回も書いたように、当時は変換ツール bas2txt の存在を知らなかったため、プログラムリストの解析に当たっては「エミュレータ上の BASIC上でひたすら LIST コマンドを叩いた結果を斜め読みしながら概要を把握する」というなんとも場当たり的な方法を採りました。
よくわからないところは後回しにしつつざっと眺めると以下のような感じでした。
- 初期化とメッセージ・画面表示制御の ADVゲームエンジン(?)本体部は BASIC
- グラフィックデータのテープからのロードとグラフィック画面表示のみ機械語ルーチン
- ADVゲームエンジンは DATA 中にメッセージと制御文が埋め込まれているオーソドックスな形式
BASIC部分
BASIC で書かれたアドベンチャー形式のゲームのリストというのはあまり見たことがないのですが、データ形式としては以下のような仕様のようでした。
- "*" +数字 が書かれていたら制御構文
- 0: 黒背景塗りつぶし
- 1: 白背景塗りつぶし
- 2: 最後のタイトル・発売日表示
- 3: 使われているけれども未実装?
- 4: 最初に戻る
- 5〜9: 対応する番号のグラフィックを表示
- "+" が書かれていたらメッセージウインドウクリア
- それ以外の文字列はそのままメッセージ表示
機械語部分
機械語部分は BASICリスト中に DATA 文で埋め込まれていて、先のプログラムリストの先頭のほうにあるように POKE 文でアドレス &H9F00〜 にロード(?)されます。
とりあえず呼び出し側の BASIC リストを見ると、 &H9F00 の先頭の 2バイト×5 に 5枚のグラフィックデータの先頭アドレスが入っているようでした。次に機械語部分を前から適当にハンド逆アセンブルすると、グラフィックデータ先頭から &HE200 の VRAM 領域に何かしらコピーしているようでした。
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
メモ
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
DATA*5: A00A
DATA*6: AC29
DATA*7: B822
DATA*8: C4CC
DATA*9: CEDA
エミュレータもクロスアセンブラも存在するのにいまどき手動はないよな、と逆アセンブラ的ツールが無いか探したのですが、なんのことはなく PC6001V のエミュレータのモニタ機能に逆アセンブラが付属してました。マニュアルを読めと怒られるパターン
Z80のハンド逆アセンブルなどしなくても PC-6001V のモニタに disasm コマンドがあった
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
さっそくグラフィック展開ルーチンを逆アセンブルすると以下のような感じでした。
なるほどといった感じです pic.twitter.com/BNPLi60tuU
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
データ中で ”FF" のみが特別扱いで、それ以外のデータであればそのまま VRAM へコピー。 "FF" の場合はその次のデータの数字の分だけ "FF" が連続するものとしてランレングス展開。 1ビット/ピクセルのモノクロ表示でディザ主体かつベタの黒塗りがない絵の場合、同一データが連続で現れるのはほぼ白背景部分だけなので、ランレングス圧縮として合理的な仕様といえます。
また、 "FF 00" のデータがあった場合はそこで VRAM データ展開を終了します。データ圧縮をした場合、展開時には圧縮後のデータ長を知る必要がありますが、データの中に終了マークを持たせればデータ長をカウントする必要がなりますので、レジスタの少ない Z80 には優しいうまく考えられた仕様といえます。
というわけで、前回の画像
のように表示がズレるというのは
- ランレングスマークの "FF" 自体が化けている
- ランレングスマークの "FF" の後の数字データが化けている
- 本来ランレングスマークではない "FF" 以外のデータが "FF" に化けている
のいずれかということになります。ランレングスマーク以外の化けについては (化けた結果がランレングスマークの "FF" でない限りは) そのまま表示が化けるだけ、つまり wma→wav 変換で補正しきれなかった 1,2ビットの化けなら 1,2ドット表示が化けるだけなので、とりあえず考えないことにします。
データ修正作業
とりあえずズレている部分のデータをズレる前の部分のデータと重ねてみて、データ化けが発生している位置を特定してみます。
モノクロ雪希さん(データ化け箇所探索中) pic.twitter.com/QTcFiGJrSB
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
適当にツールでズレた領域を切り取って移動してみると、以下の赤丸部分が化けているっぽいことがわかります。
で、画面上でデータ化けしている座標 (VRAMアドレス) がわかったとして、ランレングス圧縮されたデータにおいて対応する位置を探すのは実データのランレングス圧縮状態を見ないとわからないのでめんどくさいと思ったのですが……
画像上で化けてる場所がわかってもそれをアドレス換算するのは模擬プログラムでも作らないとムリ という気もするな……
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
よくよく考えると、模擬プログラムもなにも、そもそも実プログラムがエミュレータ上で実行されているのだから、グラフィック展開ルーチンを実行している部分をエミュレータ上でステップ実行させればいいだけでした。
鬼トレース実行
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
エミュのマニュアルを見つつ適当にブレークを張って画面を見ながらなんとなく場所を特定:
鬼トレースによる特定は可能かどうか pic.twitter.com/VavrG8P9vo
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
が、最初の修正箇所であったこの部分が実は一番難易度の高い修正でした。
化けていそうな場所は特定できたけれども 化ける前が何だったのかがさっぱり検討つかんな
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
この画像の次に配置されている画像
をよく見ると、先頭の左上が 8ドット黒になっていて (=前の画像の終了マークの "00" が表示されている?) 全体も 8ドット (=1バイト) 右にズレています。また、元データと対応する画面パターンおよびデータズレの量からすると、ここでは実はランレングスマークは関係なく「完全に1バイト余分なデータが挿入されている」と判断し、周囲のドットデータから見て不要と思われる1バイトを削除しました。
とりあえず1か所修正。残りあと2か所だけど寝ます(ヽ´ω`) pic.twitter.com/2beHVJbKdz
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
wav → wma 圧縮および wav 波形データ補正では再生時間は変わらないはずで、何をどうすると「1バイト (8ビット) ものデータが余計にデコードされる」ということが起きるのだろうかとは思いましたが、さすがにこのデータ化け箇所に対する wav データの位置を特定することは (手動では) 無理で、現状どのような波形および補正がこのデータ化けを引き起こしたのかは確認できていません。
同じ画像の 2か所目のズレ、およびもう一枚のズレている画像についても、同様にトレースで場所を特定して画像データを見ながら修正を試みます。
鬼トレースふたたび pic.twitter.com/qsUzyjcUdh
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
これも何がどう化けるとこうなるのかがよくわからん(´・ω・`)
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
心眼で修正データを入れたら行けたっぽい。 pic.twitter.com/nXKWLaYQDf
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
次のデータ化けはこれ。また鬼トレースでなんとかなるかどうか…… pic.twitter.com/oprprhdayg
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
このへん pic.twitter.com/O7PfaJVl1J
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
これは1ビットコケてるだけだろうか
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
FD → FF の修正でOK。 pic.twitter.com/crjYMtDsml
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
ほとんど Togetterまとめ状態ですが、ここまでの作業でグラフィック表示ズレは一通り修正できて、デモとして見た目の問題なく一通り実行することが可能になりました!
デモが一通りちゃんと動いたので寝ます(データずれ以外のビット化けは画像データが1ドット単位で変わるだけなのでもはや検証しようがない)
— Izumi Tsutsui (@tsutsuii) 2016年6月11日
実機動作確認
エミュレータ上ではデモが一通り動いたので、次は PC-6001 初代実機上でデモを試してみました。が、元の P6バイナリでは一点問題がありました。
配布されていた wma の音声ファイルは1つだけでしたが、実際のデータとしては先に書いたように BASICプログラム部分と、後からロードされるグラフィックデータ部分に分かれています。エミュレータの場合は 1つの P6バイナリで複数回のロードが可能なようですが、実機の場合はボーレートの判定があるためかテープの読み始めにヘッダマーク (最初の約3秒のピー音) が必須のようでした。
ダウンロード配布されている wma だと BASICプログラムとその後ロードされる画像データ部が P6形式のまま連続でエンコード(?)されてますが、実機ロード時は後半画像データ部の前にヘッダマークを入れてやらないとロードできないっぽい(いまさら誰にも必要とされない情報という説)
— Izumi Tsutsui (@tsutsuii) 2016年6月12日
TINY野郎さん作の P6データ→wav変換ツール なんでもピーガー では P6バイナリの任意の位置で wav ファイルを分割してヘッダを付加してくれる「カスタム分割」選択肢があるので、最初はそれを使おうとしたのですが、これはうまく行きませんでした。
Tinyみずいろのグラフィックデータの末尾の方を見ると、読み込み長を固定にするためか最後の画像データの後ろもしばらく "00" で埋められていました。一方、「なんでもピーガー」は「BASICファイル・データファイル」の形式を選択した場合に「00Hが 9バイト連続した場合 (BASIC プログラムの終了と判定して) wav ファイルを分割する」という仕様なのですが、どうもこの自動分割判定動作が「カスタム分割」のときにも効いてしまっているようで、そのまま分割すると 3つの wav ファイルができてしまい、ローダー部分が想定しているデータ長と合わないデータが生成されてしまうようでした。
後半画像データ部の最後の方には(おそらく23KBのフリーエリア上限確認用のパディングで) 1KB弱の 00h データが入っていてそのサイズ分読み込もうとするのだけれど、なんでもピーガーで wav変換すると連続の 00h が区切り記号と解釈されて捨てられてしまうので手動分割が必要
— Izumi Tsutsui (@tsutsuii) 2016年6月12日
&H9F28 からのローダー部分を逆アセンブルしてみるとわりと簡単な構成で、以下のような仕様のルーチンでした。
- BIOS のテープロード OPEN ルーチン(?)を呼ぶ
- BIOS の 1バイト READ ルーチンを使い、ヘッダマーク(?)の C3h が読まれるまで読み飛ばす
- ヘッダマークの C3h が読まれたら、今度は C3h 以外が現れるまで読み飛ばす
- C3h 以外が来たら、その次のデータから指定バイト数のロードを開始
- すべてのデータを読んだら BIOS の CLOSE ルーチンを呼んで終了
上記の仕様から、 バイナリエディタで P6バイナリから C3h のヘッダ部分を探し、その部分で P6バイナリを前後に分割して、それぞれを個別に wav 変換することで対処しました。
これで P6実機でもテープロードからのデモ動作が可能になりました。
ちなみに、液晶でもコンポジット入力で SCREEN4 のにじみカラー が出るディスプレーと出ないディスプレーとがあるようです
追加修正
こうしてデモとしては動くようになったのですが、上記の P6実機雪希さん画像をよーく見ると、 1か所どうも不自然な箇所があります。
Tinyみずいろの雪希さんのこの絵の赤丸をつけた部分、元からこういうドットなのか wma からデータ起こしたときのデータ化けなのかが気になってしょうがないというどうでもいい問題 pic.twitter.com/c5LezHbxpr
— Izumi Tsutsui (@tsutsuii) 2016年6月12日
せっかくなので、これも場所を特定して適当に修正してみました。
左:修正前 FF 01 FB 8E
— Izumi Tsutsui (@tsutsuii) 2016年6月12日
右:修正案 FF 01 7F FE
が、この化け方は無いんじゃないのという気はするな……
(なお FF はランレングス処理が入る) pic.twitter.com/x69U9odJNH
上記の修正を入れた時は「正しい」データがどうなのかわからなかったのですが、今回一連のブログエントリの 2回目 を書いた際に wav 変換と補正をいろいろ試したところ、やはりこの部分はゴミドットが無いのが正しいデータのようでした。
ただし、その際の補正後のデータは FF 01 3F FC であり、上記ツイートでの修正内容 FF 01 7F FE と比べると微妙に 1ドット単位の差がありました。これ以外にも 1ドット単位での差異が 3, 4箇所あったので、「真に正しい(?)グラフィックデータ」を得ようと思ったらオリジナルのデータを入手して比較するしか無さそうです。
デモ動画撮影に向けて
というわけで、 wma 変換と wav 補正から始まって、 BASIC プログラムデータ修正、グラフィックデータ修正、という長い長い過程を経て、実機で Tinyみずいろが動くようになったわけです。無駄に長いブログエントリにここまでお付き合いいただきどうもありがとうございました。
で、せっかくなので P6月間活動の成果として「実機で動くようになった Tinyみずいろデモ」を動画に撮って上げようと思ったのですが、ここで1つ問題がありました。
オリジナルの「みずいろ」には当然ながら CD-DA の BGMがあり、 「Tinyみずいろ」のページ にも
●音楽アレンジ
シンセサイザーLSI AY-3-8910相当による8オクタープ3重和音フルアレンジ
などとアオリが書かれていたりします。ネタはネタだとしても、テープロードのピーガー音が4分程度流れた後、それに続く本体部分のデモ本体がずっと無音の動画というのは実際かなりさびしいものがありました。
というわけで、実際の動画撮影にあたっては BGMを付けるという追加作業をしたわけですが、
この BGM作業についてはまたまた次回以降のエントリで書こうと思います。