今回からはJR-300エミュレータを開発していく流れを書いていきます!
詳細を覚えてるの??と言われそうだけど…
私は大きめな何かに取り組む時には日記というか記録をつけるクセがある。
毎日何を考えて何をやったのかを記録しておく事で、できる限り無駄な作業を避けようという事だ。自分の記憶だってアテにならないw
その記録を眺めつつ、良い感じにブログにまとめるという簡単なお仕事だw
今記録を見直してみたら、解析始めて3日後にはBASICを立ち上げてた!
我ながら呆れる……汗
ではいってみよう!
2022/11/09(水)
友人から「JR-300のカセットからバイナリに変換したデータがあるんだけど、解析に興味あります?」という話が来る。
BASICインタプリタ本体であろうファイル
デモンストレーションプログラムのファイル
あるのはテープのデータのみであり、本体に載っているであろうROMは無い。
「本体のROMが無いと解析は無理かもしれない」と返しつつ、BASICプログラムがテープで供給されている事からMZやX1のようなクリーンコンピュータなのかもな…と想像。
デモンストレーションはBASIC言語で書かれてるんだろうか?
だとすると、どちらにしてもBASICが起動しないと手に負えないよな…と思うものの、資料がゼロの状態で取り組むのはリスクが高すぎる…。
でも……やらずに文句言うよりも、やってから文句言うのが筋だろうw
以前から使っている自作逆アセンブラ(configファイルを編集する事でコメントやラベルを付加してくれるので見やすくなる)を使用して、BASICプログラムの解析を始める。
テープのデータということで、先頭にプログラムが置かれるアドレスや実行開始アドレスなどが含まれていると思っていたのだけど、どうもそうではないらしい。
どこのアドレスに配置されるプログラムなのかも分からないので、適当に0000番地に配置して逆アセンブル。
そしたらどうも0000番地であってるっぽい。
しかし解析を続けると、途中からおかしなアドレスに飛んでしまうなど、やっぱり全体的におかしい!
プログラムを頭(0000番地)から見ていくが、0xFD00以降にあるデータを繰り返しコピーする不可解なコードに遭遇する。
これは???
メモリウィンドウとかの機能だろうか?
アクセスしているI/Oポートなどを調べるが、どうもそうではないらしい。
うーん、ハードの仕様がゼロってのはホントに厳しいな…
I/Oポートの各ビットの意味がわからないので適当に進むしか無い。
明らかに割り込みで値が変わるワークエリアを参照しているモノも多い。
ということは、何かのハードが裏で動いてるって事か。
……この辺りでようやくピンときた。
おそらくIPL-ROMはテープから先頭の256バイトをメモリの0x0000へ読み込んで、そこへ制御を移すという機能をもっているのではないかと。
つまりプログラムの先頭256バイトがbootstrapなのか!
じゃあ0xFD00はカセットから読み込んだデータのバッファなんだろう。
プログラムを見る限り、一度に読めるバッファサイズはMAXで256バイト。
そのデータを順次別のアドレスにコピーするのがbootstrapの役目だ。
BASICは0x5E00から読み込まれ、スタートアドレスは0x6280。
デモは0x0100から読み込まれ、スタートアドレスも0x0100。
これらの値はプログラム中にハードコーディングされている。
うーむ、これは単に逆アセンブルしていくよりも、Z80エミュレータを起動させた方が早く解析できるかもしれないぞ…
2022/11/10(木)
解析2日め。
本来のお仕事もある(あるよ?!)ので集中できる時間が短い。
Z80命令でのI/Oアクセスは少なく、むしろメモリマップドI/Oのハード構成に見える(のちにサブCPUとの共有メモリなのだと気が付く)。
両者が混じったマシンは滅多に見ないけれど、ここまであからさまに出てくるのも珍しい。
書かれてるZ80のコードが妙に素人っぽい感じを受けるところと、PUSHしてRETとか商用プログラムでやる??とか思うコードが混ざってる。
複数人でコードを書いていたか、または書いてる途中で上達したのか。
コードから読み取れるストーリーを勝手に想像していくだけでも楽しいw
こういうのはコードを読んでいく楽しみのひとつでもある(^^)
Cコンパイラなどで出力されたコードではこうはいかないw
まずはBASICの起動画面が表示されるまでを頑張りたい。
おそらくだけど、メインメモリのどこかの場所にコンソールバッファがあり、そこにBASICが起動した時のテキストが配置されるのではないかと想像。
正体不明なハードを相手に悩みたくないので、どんなI/Oアクセスがあったとしても、今はそれっぽい値を返すコード(適当すぎる疑似ハード)を追加。
処理速度なんて気にならないだろうから、無駄コードいっぱい入れるよ!(^^)
0x7BCE 文字列表示処理
0xA561 1文字表示処理
文字の表示処理がとにかく複雑。
どうしてこんなに??と思うほど複雑。
テーブルジャンプを多用するコードが多いため、逆アセンブルでの追いにくさも拍車を掛ける。
簡単に追えない(T-T)
これは泣きが入る…。
記憶容量の少ないおっさんをイジメるんじゃないよ!(ToT)
そしてどうやら表示系はサブCPU(またはコントローラ?)が担当していそうな動作を発見する。
サブCPUアクセスと思われるサブルーチンを呼び出すと、1文字出力っぽい動作をするらしい。
サブCPUとの共有メモリであろう0xFC4Aに'M'を出力している動作を確認した。
サブCPU側の仕様がまーったく分からないので、これは大変過ぎる…。
せめてサブCPU側のROMだけでも手元に欲しい…。
2022/11/11(金)
予想されるオープニングメッセージは以下の通り。
MATSUSHITA JR-300
JR-ZBASIC 1.0
Copyright (C) 1984 by Matsushita
Free Bytes
これはBASICインタプリタに埋め込まれているアスキー文字をひろっただけ。
どうやら表示はサブCPU、またはコントローラが担当していそうなので、そういうつもりで解析していく。
0x0001にある2バイトを先頭とするジャンプテーブルが有る。
おそらくシステムコールの類と思われるが詳細は全て不明。
この中のオフセット0x0066([0x0001]+0x66)にある0xDA26からのサブルーチンが、サブCPU(表示系?)関連の関数となっているっぽい。
DEにパラメータへのポインタアドレスを入れて、0xA673をコールすることで、サブCPUへのコマンドが発行される仕組み。
DEで指定されるパラメータのフォーマットは以下の通り。
・コマンドID(メインCPU側でのコマンド番号[00h-11h]
・サブコマンドID(サブCPUへ渡すコマンド番号)
・パラメータのバイト数(0=無し)
・パラメータ、...
サブCPUのコマンドID=06(DC07)がテキスト文字に関する制御っぽい。
サブコマンドについてはまた別途まとめないと手に負えん!
サブコマンドID
03 カーソル位置指定(LOCATE x,y)
08 制御文字[00h~1Fh]の解釈
09 1文字文字表示
以上の3つが解析できた時点で、テキストが表示出来るようになり、BASICの起動画面が出た。
BASICのフリーエリアが20477バイトと少ないが、BASICインタプリタ自体が0x5E00からを先頭にして読み込まれている事を考えれば、こんなもんだろう。
それにしても…1文字を表示するだけでZ80側で5957サイクルも掛かる。
しかもコレはサブCPUの処理終了待つ時間を0とした場合…だ。
ということは、1秒間に671キャラクタの表示が出来て、80x25キャラクタの1画面を埋め尽くすには2.98秒掛かる。
…あれ?それって……思ったよりも遅いんじゃない???
今回はここまで!
3日間の作業で、システムの初期化からBASICの起動までが出来た状態!
まだテキストベースでデバッグしているだけで「BASICが動いてる」というよりは「処理が進んでる」程度だけど!
ではまた次回!(^-^)ノ