JR-300エミュレータの開発その6

JR-300エミュレータの開発話、第6弾!(^-^)

 

かなり動いてきた感はあるけれども、今の動きがどのくらい正しいのか私には分かってない。分からないどころか、誰もJR-300を知らないので答えがない(^^;;

 

実は妄想のマシンを作り上げてるだけなのかもしれないな……

そんな不安を感じつつも、JR-300と書かれたカセットテープを信じて作っていくよ!(^^;

 

2022/11/26(土)

テキストに描画するフォントを、ノーマルフォントを使うのかPCGフォントを使うのかの切り替えは、どうやらアトリビュートのbit6(0x40)らしい事が判明。

bit6が1の場合はノーマルフォントを、0の場合はPCGフォントを使うらしい。


8ビット情報のうち、これで7ビットの役割が判明。(xP_BBB_FFF)

残りのMSB(x)は何に使われているのか…汗

 

PCGを表示出来るようにプログラムを変更してみたところ、画面上から変なゴミみたいな表示は消えた。でも…画面には文字しか表示されていない。

まさかこういうデモ??(@_@;
いや違うだろうな…うーん…

 

動作時のログを追ってみると、大量のLINE描画が発行されている。
LINE命令のPSETするかPRESETするか判定がBASICの時と違っているようで、なぜかLINEが描画しない。
あれれおかしいな…BASICでさんざんテストしていたのに(T-T)

VRAMにはデータがでてるんだろうか?

うん、VRAMを無理やり描画(というよりもアスキーアート的な感じで出力)してみると、確かにデータは出力されてるっぽい。

 

仕方ないので、オールセット(理論上は真っ白な線が表示される)でテストしてみたところ…

うお!絵が出た!!

出たけど…出たけど……なんか変?!

 

画面の解像度が640x200ドットになっていそう…

あとグラフィックよりもテキストが奥に表示されてる。

 

これはBASICインタプリタの初期化に合わせたつもりだったけど、解釈が逆だったか。

デモンストレーションの結果を見て修正する必要がありそう。

あと…なぜか色が出てる。

ドットが真っ白になる事を覚悟して変更をしたつもりだったのに…。

うーん、1つ1つの動作が謎いぞ。

 

横のドットを修正して表示されたJR-300ロゴ!
気になるところが多いなー。
まず…背景が青一色であってるんだろうか??
それに画面下の無限マークのテキスト。これも意図と違う気がする。
カーソルが表示されちゃってるのは、これはまだ未解析のサブCPU側のコマンドがあるからだろう。

 

デモを1周回す
おかしな画面は置いとくとして、まずは先にデモを1周回しちゃおうと思い、未定義なグラフィックコントローラな部分などをすっとばしていったところ、なんとか回ることに。

 

デモは全部で5種類入っていた。

・タイトル(JR-300表示)
ワープロ(漢字表示は??)
・絵(ペイントで塗りつぶされちゃう:最後に飛行機?が飛ぶ)
スプレッドシート
・棒グラフ?(白で塗りつぶされちゃう)

 

絵が表示されるデモを見たとき、PAINTがハデにあふれて画面が1色になってしまう現象が出ていた。LINEの終端が届いてないのかと思ったけれど、デバッグログに不穏なものが…。

…なにかの……補間機能っぽいものを使おうとしているデータがでていた。

しかもタイプ違いの8種類。

コレは嫌な予感がする…(-_-;

 

これ…もしかしたら円を描こうとしてるんじゃんないだろうか??

BASICではドットを計算してPSETしていたCIRCLEだけど、デモでは違う?

私自身、グラフィックコントローラで円を描かせた経験がないので、パラメータが想像できぬ。

うぬぬ…これは困ったぞ(T-T)

気になる問題はあるけれど、後回しにできるものは後で解決する!

 

まずはこれらのデモを個別に1つずつ見られるようにする手法を確立しとかないと、この先のデバッグがとても大変になりそうだ!

プログラムで個別ジャンプ、またはジャンプテーブルが見つからないかな…。

…と思っていたら、あっさり見つかった!

 

0x010Dから並んでいるCALL nnnnがデモ呼び出しだった!

これを修正すれば、選んだデモだけをテストする事ができそうだ!(^-^)

そして目視で確認した時には5つのデモだと思っていたが、どうやら見えてないデモがあるらしく全部で6種類存在するっぽい。

 

・タイトル(JR-300表示)
ワープロ(漢字表示は??)
・絵(ペイントで塗りつぶされちゃう:最後に飛行機?が飛ぶ)

・未知のなにか

スプレッドシート
・棒グラフ(白で塗りつぶされちゃう)

 

2022/11/27(日)

謎の8回出ていた補間機能っぽいものが気になる。

もしも円の描画だとすると、なんとなくPC-9801で使用されていたGDCに似た機能を持ってるコントローラなんだな…。当時、そんな何種類もグラフィックコントローラって出てたんだっけ??
そう思いつつGDCの資料を見直したところ、同じものではないけれども、構造的には良く似てるとわかった。


コマンドそのものに共通点はないものの、コマンド系体的に良く似てるというか。
参考になるところがたくさんあることがわかった。

 

あああ……GDCの資料を見て思い出したことが!

  LINE(0,0)-(319,199),7,,&HABCD ← 最後がラインスタイル

GDCと同じような機能があるのなら、ラインスタイル指定ができそうなんだけどなぁ…と思って調べていたら、しっかりデータが出てました…。


N88-BASICやF-BASIC4.0以降にあるラインスタイルと同じ指定方法だった。
うーん、一度試してみてErrorになった気がしてたんだけどな…。

 

対応するべき事がどんどん増えていく…。

・LINEのラインスタイル対応
・謎の8回補完機能解析
・グラフィックコントローラの実行サイクル試案

 

2022/11/28(月)
LINE命令のラインスタイルに対応させるため、一度初心に戻って詳しく調べる事にした。

 

そういえば、今までアドレスデータがビット反転されていたのをいちいち手で元に戻してチェックしていたが、デバッグログに出力するときにひっくり返したら簡単じゃん…と今更ながら思った。

 

それで一度、アドレスデータだけじゃなくて、すべてのデータをひっくり返して出力した。

出力されたデータを見たとき……ある衝撃が…。

つい先日、GDCの本を見た時のコードが思い出される…。

μPD7220でLINEを描画するのは

  [78] TEXTW
  [33] WRITE
  [49] CSRW
  [4C] VECTW
  [6C] VECTE

の順番でコマンドを発行するらしい。

 

そんな目線でBASICのLINE命令で発行されているコマンドを追いかけてみると……

01 1E [78] - [TEXTW] 
00 AB [D5]
00 CD [B3]

01 CC [33] - [WRITE] 

01 92 [49] - [CSRW] 
00 84 [21] 
00 C0 [03]
00 04 [20]

01 52 [4A] - [MASK]
00 20 [04]
00 20 [04]

01 32 [4C] - [VECTW]
00 90 [09]
00 28 [14]
00 00 [00]
00 28 [14]
00 00 [00]
00 00 [00]
00 00 [00]
00 14 [28]
00 00 [00]
01 36 [6C] - [VECTE]

……え?

……ええ?

………えええ!!??

マジで?(@_@;

 

ちょっと待って!!

GDCと同じデータが出力されている!

 

今まで、アドレスデータはプログラムでビット反転されていたので「このデータは反転している」と認識できたけれど、コマンドデータはそのまま出力されていたので意識していなかった。

けど、よくよく考えれば同じデータポートに出力されているんだから、同じようにビットが反転したデータが送られていると考えるべきだったのか!

 

μPD7220は3画面同時書き込みが出来ないので、3回同じデータが出るのもうなづける。

あとPC-9801のようにメインメモリにはVRAMがマッピングされていないと思えば、沢山のコマンドが発行されるのも理解出来る。

 

なんてこった……ずっと不明だったグラフィックコントローラは、μPD7220だったのか!

これはもう確定事項にしてしまって良いと思う!(^-^)

ずーっと手元にGDCの資料を置きながら作業してたのに気づかなかったなんて…orz

 

うーん…ソースを書き直したくなるよ…どうしよ…(^^;;

 

ではまた次回!(^-^)ノ

JR-300エミュレータの開発その5

JR-300エミュレータの開発話、第5弾!(^-^)

いくつまで続くんだろ…多分7くらいで終わる気がする(^^;;

 

JR-300エミュレータを公開してからというもの、すごい量のDMが届く!

日本語英語のみならず「これは何語??」って思うメッセージまで(^^;;

JR-300ってそんな有名なマシンなんだっけ?(@_@;

 

「解析のコツみたいなものはあるのか?」という質問が多いのでお答えします!

コツというよりは「過去に自分でBASICインタプリタを作ったことがある」というのが大きい気がする。

BASICインタプリタが内部でどのように動いてるのかを理解しているので「これは何をしてるんだろう?」というよりも「多分こういうことをする処理があるはず」という狙った解析ができているんだと思う。

LINEやPAINTのアルゴリズムも、実際に作ったことがあるから迷うところが少ない。

コツというよりも、過去の経験と知識が役立ってるんじゃないかなー(^^)

 

 

2022/11/21(月)
BASICの命令や関数を実行しまくって、不具合が出るもの片っ端から直していく。
各命令を見ていくとJRシリーズっぽいもの(FIND命令とか)もあるけれど、SYMBOLなどのF-BASICっぽいものも存在する。
各メーカーの良いとこ取りをしたマシンっぽかったのかな…。

MON命令(マシン語モニタ)で ? を入力すると停止する。
何かヘルプを表示させようとしているとか??
調べてみると制御文字の0x07を出力していた……BEEPか!
音は最後の最後にしたいので、今は何もしないのが一番の対処!(^^;;

 

CONSOLE命令はスクロール開始行、スクロール行数の指定となっていた。
これもWIDTH命令で初期値に設定されたまま放置していたが、ちゃんと設定することで簡単に対応終了。
CONSOLE命令の省略形としてC. が使えるようだ。

 CONSOLE 0,25 → C.0,25

各命令の省略形を調べるのは、全コマンドを打ち込みまくるしかないか…。

これは別の機会に頑張ろう、おう!

 

PEEK、POKE、CALLのテストもサクッと終了。
この辺りの…サブCPUもグラフィックコントローラも触らないものは、今の状態でもほとんどが動くんだろうな…と思いつつも念のためテスト。

テストしてると楽しくて1日の作業時間があっという間に終わっていくw

    
2022/11/22(火)

今日はカラーパレット関連を見ていく。

 

PALET命令は2つの引数を持つ。

それぞれが数値で0〜7の範囲という、いかにもカラー番号を表している。

しかし…PALET命令を実行しても、グラフィックコントローラ側に情報が出ない。

ありゃ…と思っていると、意外にもサブCPUコマンドが(今まで出現した事のない)別のカタチで呼ばれている事に気がついた!

 

今までテキスト関連を制御する時には、[0xFC01]←0x06が入るタイプで、コマンドコード自体は[0xFC47]に入っていた。

 

そういえばこのサブCPUアクセスのサブルーチン群は、さらに上のレベルで分離していたんだった…。別のレベルでもサブCPUアクセスがあるとは!

 

コマンド 引数   パラメータアドレス
00      02    [FC27]
01      01    [FC34]
02      01    [FC2A]
03      01    [FC2F]
04      02    [FC34]
05      06    [FC3F]
06      23    [FC47] ← これがサブCPUアクセスの関数群
07      0B    [FC88]
08      0A    [FC90]
09      0C    [FC99]
0A      07    [FCAF]
0B      01    [FCB6]
0C      05    [FCBB] ← これも出てきてる
0D      03    [FCC6]
0E      01    [FCC9]
0F      03    [FCCE]
10      01    [FCED]

 

今までは0x06の呼び出ししか対応出来てなかったけれど、この機会に全て受け取れるように修正する。

かなり大きなコード修正になるので、2~3日はかかりそうな予感。

 

2022/11/23(水)
サブCPU処理のリファクタリング
元の構造を残さずキレイに書き直す判断をしたため大幅な変更。
今まで書き散らかしたコードの多いことよ…orz

 

2022/11/24(木)
サブCPU処理のリファクタリング作業が落ち着いてきた。

キレイに整理してみて分かったが、サブCPUのコマンド番号はまだまだ空きがあって、正体不明な部分だらけだった!

こんな少しの実装だけでもBASICって動くんだな…(^^;;

 

ようやくPALET命令の作業に戻ってこられた!

PALET 1,7
この指定で、カラー番号1の色(青)をカラー番号7の色(白)にチェンジする。

数値をカッコでくくるとSyntax Errorなので注意。

 

サブCPUコマンドの0x0C系列0x02がパレット変更機能と判明。

 

パレットの変更は、なぜかサブCPU側に情報が出ている。

パレットってグラフィック画面への命令だと思いこんでいるが、もしかしてテキスト画面にも影響するって事??

それとも最終的な表示は合成も含めてサブCPUが処理してるから?


…常識的に考えたらグラフィックのパレット変更だと思うので、今のところはそのように実装してみる。

実機で見てるわけではないので、これが正しいかどうかは分からない。

デモンストレーションのプログラムでパレットチェンジが出てくるかなぁ…。

 

BASICのシステムコール

BASIC内部で呼び出されるシステムコール、コマンド番号の後ろに2バイト空けるのがルールらしい。
この構造はF-BASICを解析してた時に見た覚えがある。

コマンド番号、戻り値、Reserve…みたいな感じなんだろうな、きっと。

 

表示プライオリティ
PRTY命令、おそらく画面のプライオリティなんだろうと想像。
どこかの資料に表示プライオリティを変えられると書いてあったので、この命令がそれなのかも?

 

PRTY命令の書き方は「PRTY 式」となっている。
数字は0〜255の範囲を取るみたいだけど、さすがにこれだけあると想像が付かない…。
スーパーインポーズ、テキスト、グラフィックの3つだと思うけれども、他にもあるのかな…。

 

BASIC起動時に1で初期化されているので、これがデフォルトっぽい。
この設定で、テキスト画面を手前、グラフィック画面を奥に設定しておく。
「PRTY 0」とすれば、テキストとグラフィックの表示優先順位を変えるようにしてみた。

この辺りも実機がないと確認は出来ない。

実機で見てみないと案件が増えてきた(^^;

 

 

2022/11/25(金)
謎のマシンJR-300、今までの解析でおぼろげに見えてきたのは…

 

Z80
メインのプログラムシーケンス

サブCPU
おそらく6802なんじゃないかと想像してるけどクロック数含めて詳細不明。
テキスト画面、サウンド、画面制御(パレットや表示優先順位など)を担当

グラフィックコントローラ
グラフィック全般を担当。
直線補間はあるっぽいけれど、それ以外は特筆する機能を見つけられていない。

 

メインCPUからビデオメモリを分離してる事で、表示に必要なDMAがZ80側に割り込まずに済むはず。その分、Z80はノーウェイトで動いていた可能性が高い。

ただ、サブCPUやグラフィックコントローラとのやりとりは複雑怪奇で、全体的なバランスは悪く感じる。

カタログスペック上は最高性能に見えたかも知れない!(^^;

 

さあ!

BASICインタプリタの各種命令もだいぶ動いてきたし…

そろそろデモンストレーションを動かしてみたいと思うようになってきた!(^^)

出来る限りBASICの命令でハードウェアの詳細を調査し、万全の体制でデモンストレーションへ移行したい気持ちが強かったけれど、まだまだ完全ではない。
PCG機能とか音楽演奏とかは放置したままになっている。

音楽はどうしようかな…とかなり悩み中。

 

不安は残るものの前に進むしか無いのでデモンストレーションの動作確認に入る!

デモンストレーションプログラムはBASIC言語で書かれているわけではない。オールマシン語プログラムとして独立している。

そのため、今まで解析してきたBASICのワークエリアなどは役に立たず、あくまでもサブCPUとグラフィックコントローラの仕様のみが生きる感じだ。

今までプログラムを書いてきたJR-300エミュレータの素性が試される!(T-T)

 

PCG

デモンストレーションプログラム先頭で、PCG定義みたいなエントリを見つけた。
サブCPUコマンドの0x06系統0x0Dでキャラクタを定義しているみたいだ。

データフォーマットはキャラクタ番号、実際のデータという感じの単純なものだったため、特に悩むこともなくサクッと対応。

フォントの0x00~0x3Eまでが書き換わってるのがわかるだろう。

ちなみにこのフォントビュワーも即席で作った!(^^;

こういうしょーもないツールが増えていくのも仕方ないだろう…w

 

フォントデータはBASICプログラムに埋まってるわけではない。私自身がJR-200を所有しているので、そこからデータを拝借してきた。このJR-300のフォントセットはコレで正しい…というわけではないのでご注意!

 

定義するキャラクタのデータは8バイト固定となっている。この事から察するにPCGはX1のような8色ではなく単色であることが分かる。

これは…ちょっぴり惜しさを感じちゃうな…(^^;

 

サウンド

次にサウンド関連の処理らしきものが出てきた。
どうやらサウンドはサブCPU側で動かしているらしい。

 

サブCPUとの共有メモリである0xFC0Eに0x00、0xFC02に0x80を書き込んだのち、0xFD00からサウンドデータ(微妙にバイナリ化されたMML)を書き込んでいく。

このMMLをテキスト化したデータは以下の通り。

 

T90V15O5L20C+L4DD+EL8AEDC+O4L24BO5L8DL24F+L8DO4L20BL4A+BO5L4CL7C+R1L8EDC+O4BAG+AL16O5C+L8O4BEO5L20C+L4DD+EL8AEDC+O4L24BO5L8DL24F+L8ED+DC+O4BAG+O5C+O4L7BR1L32BL16A
T90V15O5L8R8AR16O5R8ER16O4R8F+R16O5R8DR16O4R8G+R16O5R8ER16O4R8AR16R8AR16R8AR16O5R8ER16O4R8F+R16O5R8C+R16R8DR16O4R8G+R16R16L16G+R16
T90V15L8O3AR8O4ER8O3C+R8O4AR8O3DR8O4DR8O3BR8O4BR8O3G+R8O3G+R8O3AR8O4AR8O3G+R8O4DR8O3ER8O4G+R8O3AR8O4ER8O3C+R8O4AR8O3DR8O4DR8O3A+R8O4F+R8O3BR8O4F+R8O3ER8O4ER8O3L16AR16O4E

 

友人がMSXで演奏させてくれたけれども、微妙に…ちょっと…とても変!(^^;

私がテキストに変換する際にMMLの解釈を間違えているのか、それとも何かクセのあるサウンドドライバだったのか…(^^;;

これはエミュレータではないところで悩みそうw

 

プログラムを見る限り、サブCPUへ渡すMMLの長さは256バイトを超えても大丈夫のようだけど、限界値は不明。サブCPU側のバッファに依存しそう。

実機がないとわからんなぁ…。

とりあえずエミュレータ側がPSG対応するまでは仮対応で先に進む。

 

デモンストレーション画面
デモンストレーションの最初の画面を描画する辺りで、今まで制御文字だけだと思っていたエントリが、実は通常文字も扱える事を知った今!

こういう使い方の幅については、実例が出てこないと気が付けないよね…汗

 

でも表示された画面を見ると……

うん、見事に化けてるね(T-T)

 

多分だけど…標準フォントとPCGフォントを切り替える必要がありそう。
あるとしたらアトリビュートかな…。
JR-200ではアトリビュート情報の中にノーマルフォントとPCGフォントの切り替えビットがあったので、JR-300でも同じ機能があるのかも?

 

今回はここまで!

あと数回続きます~!

 

ではまた次回!(^-^)ノ

JR-300エミュレータの開発その4

JR-300エミュレータの開発話、第4弾!(^-^)

 

開発時に書いていた記録から引っ張ってきているので、どうしても中身が日記っぽくなってしまっている!読んでて気持ち悪くないかな…心配(^^;;

生暖かく見てくださると助かります~!

 

なんでも良いけど……

いろんな人から「セミリタイアいいですね!」とかDM来るんですけど…汗

ちゃんと仕事してるよ!(ToT)
空いた時間でエミュレータ作ってるよ!(^^;;

信じて~~!(泣)

 

2022/11/18(金)
次はLINE命令に取り掛かる。
簡単なテストをしてみたところ、グラフィックコントローラに渡るパラメータは想像よりも少ない。
この結果から、な~んとなくだけど直線補間ハードが載っているらしいと思ってる!

律儀に1ドットずつ描いてたCIRCLEとは違うぜ!(^-^)

 

I/OアクセスはLINE命令1つにつき60回出てくる。

そのうち先頭の6回はコマンドモードの初期化っぽいアクセスで、残りの54回でLINEを引いてるっぽい。

54回の内訳はRGBで各18回ずつとなっていて、それぞれよく似たパラメータが出ている。
つまり18個のパラメータを解析する事が出来れば、画面にLINEが引かれる…という事だ!(^o^)

 

先にPSETをテストしていたおかげで、なんとなくデータの並びが理解できる。

LINE(50,0)-(0,75),3 とすると、以下のようなデータがI/Oアクセスする。

 

1E  FF FF
CC
92  60 00 04
52  20 20
32  F0 D2 00 98 00 73 FF 26 00
36
CC
92  60 02 04
52  20 20
32  F0 D2 00 98 00 73 FF 26 00
36
4C
92  60 01 04
52  20 20
32  F0 D2 00 98 00 73 FF 26 00
36

 

最初の1バイトがコマンドコード、続くのがオプションという感じ。
この並びはPSETと共通なところもあり、先に解析しておいた情報が役立つ。
例えばコマンド0x92はVRAMアドレスを指している。

60 00 04というデータの先頭2バイトがVRAMアドレス。

0x0060は1バイトごとにビットを反転させて0x0006。

…みたいな感じで、1つずつ意味を解読していく必要がある。

 

コマンド0x32が長くて、これは何だ???となった。
何度もLINE命令のパラメータを変更してはチェックしてみたところ、どうやら最初の0xF0というのはサブコマンドコードらしい。


LINEの角度によって8種類のコードがある事がわかった。
角度によって変わるとなれば、これはもうDDA補間(ブレゼンハムの線分発生アルゴリズム等)で描画するためのパラメータだろうとピンと来る。
ただ…確か計算に必要な数値は3つだった気がするけど、4つ(4word)あるね…。

 

その後、0xF0の次にある2バイトは、ループ回数だと判明する。
0x00D2のビットを反転させると0x004B、10進数で75、なるほど(^^)

こうやって1つ1つのパラメータを丁寧に解析していく。

 

残りの3つがDDA補間に必要なパラメータ(e,dx,dy)だろうと予想して数値を見ていくけど……なんか違う。
それっぽい数字なんだけど、誤差が多くて長いLINEを引くとドットが目的の位置に到達しない。
うーん…これは???

 

手を変え品を変え、いろんな直線補間アルゴリズムにアテてみるけど、どれも計算結果と合わない。
困ったぞ、LINEがちゃんと機能しなければPAINT漏れとかあるし、そもそもデモンストレーションが動かないかも。
これは是が非でも合わせるぞと頑張ってみる!!

 

……頑張ってみたが、結局どれも計算式が合わない!
グラフィックコントローラの中で行っている直線補間アルゴリズムが分からない以上、どうにかして辻褄を合わせるしか無い。

 

仕方ないので、3つ出ているパラメータのうち、2つが誤差多くて使えないため、1つの情報を元に、他の2つのパラメータを計算する事にした!
つまり2つのパラメータは使わない判断をした(^^;;
これでいいんだっけ?(@_@;;

ま、いっかw ← さっき丁寧に…って書いた人と同一人物

 

ここまでやったところで、ようやく画面に正しそうなLINEが描画出来た!
ひー!LINEはかなり大変だった!!(T_T)

 

2022/11/19(土)
次はPAINT命令に取り組む!
最終的にデモンストレーションを動かすためには、おそらく避けては通れないと見ているため、頑張って動かしたい。

 

PAINTは最初っから大変であろう事が、なんとなくだけど見えている。
PAINTという処理は、境界線の情報をVRAMから拾ってくる必要がある。
つまりグラフィックコントローラから何かしらの情報を返さねばならない。

今まではグラフィックコントローラに出力するばかりだったので、データを返す方法も含めて経験値がゼロだ!

 

PAINTのアルゴリズムとして想像出来るのは、指定されたポイントから左右にRayを伸ばしていき、境界色に突き当たったらその範囲を塗る…というのを繰り返すモノだろう。塗るという動作はLINE命令としてI/Oに出てくるんだと思う。


問題は、どんな情報が与えられて、どんな情報を返したら良いのかがさっぱり分からない事だ。
これはもう逆アセンブラリストを追いかけるしかないが、PAINT命令のような複雑なものを逆アセンブラで追いかけるのは(出来れば)避けたい(-_-;;

 

PAINT命令を動かしてみると、RGBごとに3回x2のI/Oリクエストが来ているので、おそらく左右のサーチをプレーンごとにしていそう。
各プレーンごとなので、ドットがあるところまでの距離…とかじゃないだろうか??

 

……と思ってみていたけれども、PAINTする座標によってグラフィックコントローラから返すデータが1バイトの時と2バイトの時があるようだ。
しかもコマンドが0x40と0x60の時がある…これはなんだ???(@_@;

 

PAINTの起点座標をアドレス変換したデータをコントローラに出力しつつ、何かの返事を期待している。
PAINT処理だと考えれば、右をみるか左をみるという処理が必ず入るはず…それが0x40と0x60??
うーん、全く仮説が立たない。これは厳しいぞ(T-T)

 

別の業務作業をしている時、ハタと気がついた。
そうか、PAINTを開始する座標を見て、すでにその場所が境界色になってるかどうかを判定しているのではないかと…。
グラフィックコントローラから返すデータを適当にしていたが、これを境界色ではない色を返すように変えてみた。

 

そしたら!!!
2度めのアクセスがあって40回 x 3のデータロードが発生した!!!
ををををを??(@_@;;
ちょっと待て。
そうなの?そういう事?

 

……つまりこういう事だ。
PAINTしようとする起点のデータを得て、Z80側でPAINTの必要があるかを判定し、必要があるとなったらその1ライン(320 or 640ドット x 3プレーン)すべてをZ80側に転送して、PAINT範囲をチェックした後、LINE命令で線を引くという流れ。

 

いや…いやいやいや……汗

グラフィックコントローラってそういうモノなの??(T-T)
せめて左右のビットが立ってるところまでの距離を返すとか、そういう機能なのかと思ってた(^^;

せっかくLINE描画が速くても、これでは相殺どころかマイナスになるのでは…orz

 

メインCPU側の動作を見て大雑把なプログラム方針が決まったので、さっそく実装してみる。
いろいろと試行錯誤はあったけれど、無事にPAINTが動くようになった!
これは嬉しいなー!(^^)
もっと時間がかかると思っていたので、ワリとあっさり動いたのは感動です♪

 

よし、せっかくなのでCLS 2の方も対応させてみよう。
これで今までの解析実績があったので、割と簡単に対応完了。

 

ただ…気になったことがあって、マシンの初期化時にグラフィックコントローラの0xA000から16KBをクリアするコードが出てる。
VRAM領域自体は0x0000~0xBFFFまでの48KBあるのでメモリオーバーにはなっていないのだけど、なぜ0xA000をクリア???
こういう些細な事が気になってくる(^^;;

 

2022/11/20(日)
画面解像度(320 or 640)を変更する方法を探す。

 

PRINT SCREEN(1,1) とすると、テキスト画面の座標(1,1)のアスキーコードを返す。
そういえばFMシリーズを使ってる時、カッコを付けると関数として動くけど、つけなければコマンドとして動く命令があることを思い出し、
なにげに SCREEN 0 とかしてみた!
するとエラーにならずテキスト画面がクリアされた!

 

詳しく調べてみたところ、以下のような状況だった。

SCREEN 0,0 ... 不明(テキストのみクリア)
SCREEN 0,1 ... 不明(テキストのみクリア)
SCREEN 1,0 ... 320x200
SCREEN 1,1 ... 320x200
SCREEN 2,0 ... 640x200
SCREEN 2,1 ... 640x200

第2オプションは全くの不明。

アセンブルしてみないと分からないかも。

 

カタログスペックには640x400ドットのモノクロモードがあるように読み取れるのだけど、プログラムコードを読む限り縦方向は200にハードコーディングされている。
プログラム自体がRAMに置かれているので自己書き換えの可能性は否定しないが、今のところは無いのではないか…と思いたい。

ちなみにMicrosoftのGW-BASICでは自己書き換えあったぞ…(ぼそっ

 

次にグラフィックに関係しそうな命令は…と思ってみてみると、SYMBOL命令があった。
過去にFM-11を使っていた時の記憶では、グラフィック画面に拡大された文字を表示する機能だった。

 

同じかどうかは分からないが、試しに実行してみたところ、サブCPU側へコマンドが発行された。
あれ???サブCPUなの??
サブCPU = テキスト画面側だと思うんだけど、そっちに発行する??
んー……しばしSYMBOL命令の構造を考えてみる……
あ、違う、多分コレはフォントデータをサブCPU側に問い合わせしてるんだ!

 

試しに&H3021とかやると”亜”の漢字データへのアクセスが発生しないかと思いやってみたが、Type mismatchになってしまう。

残念ながら漢字はサポートしてないみたいだ(^^;

 

うーむ、SYMBOL命令が全く解析できない。
FM-7のBASIC資料を見ると、以下のような文法なんだけど…
SYMBOL(X座標,Y座標),"文字列",横倍率、縦倍率、カラー

JR-300ではどうやら、
SYMBOL(X座標,Y座標),"文字列",不明、カラー、不明
となっているみたいなのだ。

 

しかもサブCPUにフォントデータを取得しに行くのは理解できるのだけど、その結果としてグラフィックコントローラに出力されるデータが少なすぎる。
高性能ではないであろうコントローラにこんな短いコマンド??
これが全く理解できない(T-T)
SYMBOL命令の解析実装は一旦中止だ(TT)

 

グラフィック周りはまだまだ続くよー!(^-^;;

 

ではまた次回!(^-^)ノ

JR-300エミュレータの開発その3

JR-300エミュレータのお話、第3弾!(^o^)

 

なんとなく3日分ずつ書いていたけれど、意図したわけではないぞ!

長すぎず短すぎず…という感じで調整したら、たまたま3日分になってるだけw

濃ゆい内容になったら2日分とかになったりするからね!

 

(この開発ブログの中では)JR-300を解析し始めて丸6日経つわけですが、すでに解析しつつエミュレータの開発をしつつという感じの流れとなっている。

本当は解析が目的だったはずだけど、なんとなくエミュレータも目的となっている。

まぁいいか…(^^;;

 

今の状態は、テキスト画面がスクロールしない限りはBASICコマンドの実行が出来る。

スクロールしようとするとサブCPU側のコマンドがないという理由で停止する状態。

 

2022/11/15(火)

テキスト画面がスクロールしようとするとおかしくなる現象を調べる前に、まずは画面クリア(BASICのCLS命令)の実装について調べてみる事にした。

 

BASICのCLS命令は3つのオプション(0,1,2)を持つ。

CLS 0と2でテキスト画面をクリアするサブコマンドが発行される。
CLS 1の時には、そもそもサブコマンドが発行されない。

 

テキスト画面のクリアにはサブCPUコマンド0x02が呼び出される。

パラメータは7つ!7つは多いなー(T-T)

頑張って調査してたところ、クリア開始のXY座標、クリアするバイト数があるのは分かった(のちに画面の横幅(WIDTH)を切り替える機能のある事が判明する)。

 

CLS 1がグラフィック画面のクリアだとすれば、(まだ未知の)サブCPUコマンドが発行されそうな気がするけれど…それが発行されないという事は、もしかしたらグラフィックを使用する宣言コマンドなどがあるのかも知れない。


この問題の解決は簡単ではなさそうなので後に残すしか無いけれど、後々になって大きな問題が発生しそうで怖い…(T-T)

 

無事に画面クリアが出来るようになったので、次はBS(BackSpace)の処理を入れる。
BASIC上で文字を打ち間違えると指が勝手にBSを押してしまうのだけど、そのたびにエミュレータが止まってしまうので効率が悪すぎる(^^;

 

BSを押すと、サブコマンド0x15が発行される。
パラメータの数が5つあるけれど、それぞれの意味が……わからん。
パラメータ3と4に座標が入っているようなので、その場所をクリアするコードを追加。
見た感じはそれっぽく動作するようになったが、このコマンドの応用例が出てこないとなんとも言えん…(-_-;

 

さて……今回の本丸である、スクロールの処理を見ていく。
現状ではサブコマンドが発行されているのは確認しているけれど、そこでプログラムを停止させていたので詳細は不明。
試しにスクロールさせてデバッグログを見ると、かなりの数のサブコマンドが発行されている…なんなのこれ(T-T)

 

詳しく見ていくと、サブコマンド0x15が大量に発行されている。
[15: 00 01 00 00 28]
[15: 00 02 00 01 28]
[15: 00 03 00 02 28]
[15: 00 04 00 03 28]
  :

あ、なんとなく分かった!
サブコマンド0x15は、テキスト画面のコピーコマンドだ!
転送元X,Y座標、転送先X,Y座標、転送バイト数 みたいだ!(^-^)

 

え、こんなん一気に80x24の領域を1行上にコピーしたらいいやん…と思ったが、最後の転送バイト数が1バイトしかない。
これだと最適化が面倒なので24回もコマンド発行しちゃうのもわからないでもない。
先輩が作ったサブコマンドシステムに「サイズを2バイトにしましょう」と意見できず、そのまま無理に実装した感じが見え隠れ(妄想)

 

24回サブコマンドを発行してメモリコピーをした後、最下行をサブコマンド0x02でクリアする。
[02: 01 00 00 00 18 28 00]

 

おそらく、01は(今は)無視、不明、不明、X座標(0x00)、Y座標(0x18)、そして0x0028がクリアするバイト数。
あれ?こっちはサイズ指定が2バイトだ。
きっと先輩自身がCLSコマンドを作り、1バイトでは困ったので2バイトへ拡張し(略

 

これでスクロールが出来……ん??……中途半端に出来た!?
あれ??なんで??
リターンキーを無駄押しして強制的にするスクロールは問題ないけれど、コマンド実行の結果によるスクロール(LISTとかRUNした結果)が変になる!
そもそもメインCPUからスクロールの要請が来てない…orz

 

え?それって……文字を表示した結果、スクロールが必要になったらサブCPU側が勝手にスクロールさせるって事??
メインCPUにも知らせずにスクロールって、そんな忖度ある??(T-T)

 

仕方がないのでサブCPU側の処理で改行の必要性が出た時スクロールさせてみた。
そしたらLIST、RUNの結果が正しく表示された!

えー…メインCPU側が全部管理するとかじゃないんだ…これは難しい(^^;

 

あと、作業の過程で気がついたけれど、カーソルのY座標の扱いが混沌としてる。
メインCPU側からアクセスされる時は0〜24の値を取るけれど、表示に関する部分では1〜25の値を取るようだ。
ものすごく分かりづらい!!
これはこの先も問題を引き起こしそうなので、頭に叩き込んでおかねば…。


WIDTH80と40に切り替わらない問題を見る。
WIDTH 80と打ち込んでみると、サブコマンド0x16が呼び出されていた。
BASICインタプリタの起動時にも呼び出されてた事から、サブコマンド0x16はスクリーン関連の初期化か、またはサブCPU全体の初期化と見ている。

 

WIDTH 40、WIDTH 80と何度か打ち込んでいると、1つめのパラメータに変化がある事が分かった。
このパラメータを見て横幅を変えてみたところ、表示が切り替わった!
でもスクリーンは初期化しないといけないのね、なるほど。

なぜかカーソルの位置はメインCPU側で戻してくれてるようで、サブCPU側への初期化命令は出ていない。
なんか中途半端感のある不思議な仕様だ…(^^;

 

BASICのコマンドを1つずつ調べていってるけれど、特殊なもの(BOOTとかTIME$などのクロック系)は後回しにしている。

処理自体がZ80側で完結するタイプの命令(文字列操作など)は問題なく動いてる。

テキスト画面への出力についても、ある程度動いてきたと思って大丈夫そうだ!

マンデルブロ集合のBASICプログラムも無事に動いた!

ここにきてようやく「BASICの主要命令は動いてそうだ」と思えるようになってきたので、明日はついにグラフィックにチャレンジするぞ!

 

2022/11/16(水)

今日からおそらく鬼門になるであろう、グラフィックス周りを解析&実装していく。

予想としては、サブCPU側のコマンドが増えるんだろうな…と想像。

 

まずは基本中の基本、画面へドット打ちをしてみる!

……しーん…
あれ?サブCPU側に何も反応が来ない…。
あれ?あれれ??これは一体??(@_@;;

 

てっきりサブCPU側にコマンドが発行されると思っていたのだが…。

予想されるのは、グラフィックモードがONになっていない、またはグラフィックはZ80側で処理してる…とかかなぁ…。

しかたないので、BASICコマンドが実行される部分を追いかけてみる。

 

中間言語に変換されたBASICプログラムは、メモリの0x0D00から格納されている事が分かったので、ここのデータが参照される流れを捕まえる。
その結果、中間コード0x81(NEW)〜0xD9(AUX)までの実行アドレスが分かった。

 

そしてPSET本体は0xD49Bからプログラムが始まる。
このアドレスを元に逆アセンブラリストを追いかけるのスタート!(T^T)

 

未知なるマシンJR-300のBASICとは言え、中身は普通のインタプリタのはずだ。

プログラムの流れはある程度承知しているはずなんだけど、ジャンプテーブルを多用するコードであっちへ飛びこっちへ飛び、とにかく解析しづらい…


まだシステムコール(0xC595からのファンクション群)の使い方をちゃんと把握していないおかげもあって、同じプログラムを何度も何度も見る羽目に。

 

でも……そのおかげもあり、グラフィック画面の横幅640ドットと320ドットを識別するワークエリアを見つける事が出来た。

問題は、そのワークエリアを書き込みしているコードが見つからず、いまだモードを切り替えるBASICコマンドが分からない事だ…orz

 

PSETが実行されると、指定された座標とカラーの範囲をチェックした後、パラメータをセットしつつシステムコール0x20を呼び出す。


分かってきたのは、VRAMのアドレスは[B:0000h]、[R:4000h]、[G:8000h]と3プレーンあること(これは想像に難しくない)、

ドットのデータがMSB...LSBの並び(PC-9801PC-8801FM-7など)ではなく、LSB...MSB(MZ-80Bなど)になっている事(のちにコレは間違ってると気づく)、
そして恐ろしい事が……アドレス指定がビットの並びが反転している!


例えば、VRAMのアドレス0x1234(0001_0010:0011_0100b)は、0x482C(0100_1000:0010_1100)に変換されて使用される。
これは……今までに見たことがないタイプの変態さんだ!!(@_@;;

 

テキストVRAMがサブCPUっぽいモノの先にあったので、てっきりグラフィックもサブCPU側にあると思っていたけれど…解析してみると、どうやらコントローラの先にありそうな雰囲気。

テキストVRAM系にアクセスする際には共有メモリを使ってパラメータを受け渡していたが、グラフィックはI/Oポート経由でアクセスをする。

 

しかも点(ドット)を1つ打つだけで39回もアクセスが入る。これはドットを描画するための最低限のアクセスの回数であり、実際にはコントローラのBUSY信号を見たりするのでもっと増える。

 

ちょっと試した感じではBASICのCIRCLE命令を実行すると、おびただしい数のPSETが発行されている感じ、LINEはアクセス少なめ、PAINTも数は多いけれどそこまでじゃない。

ということは、直線補間ハードが入っている可能性もある?!
うむむ、これは楽しみだ!(^-^)

 

2022/11/17(木)
引き続きグラフィックコマンドを調べている。

 

1つのドットを打つために、似たようなI/Oアクセスが3セット分されている事から、3プレーン同時書き込み機能はないらしい。

 

1つの点を描画するだけで39回のI/Oアクセスがある。
え?なぜそんなに???
グラフィック画面のCLS命令とか、LINE命令とかどうなっちゃうの??と思い、軽く調査してみたところ、CLSでは90回、LINEでは60回で済んでいた。

やっぱり描画支援ハードが存在するって事かな…事だよね??(^-^)

8bit機ではFM-77AVに直線補間が載ってた気がする(日立S1も?)けれど、ここに来てJR-300も載っていた可能性が出てきた!これは萌える!(^o^)/

 

PSET処理のI/Oアクセスを見てみると、大きく分けて同じようなアクセスがRGB分3回ある。それぞれのプレーンに11回ずつ。

もう少し細かく見ていくと、コマンドと思われるアクセスが1プレーンで5つ、パラメータらしきものが6つあった。

 

PSETのパラメータを変えて何度も何度もテストをして、どのようにI/Oアクセスが変わっていくのかを見ていく。

すると、ドットのON/OFF、VRAMのアドレスとビットパターンが見えてきた。
しかもアドレスは昨日解析したビットパターンを反転してのご指定だ!

 

このアドレスの反転指定は何か事情があるんだと思うけど、解析をしていてこの数値を見てもピンとくるものがない。


例えば0x3E80とくれば「VRAMのサイズかな?」とか、0xC8と来れば「10進数の200だから縦のドット数?」とか、何かしらピンとくるものがあるんだけど、0x7C01の数値をみても脳内で0x3E80に変換出来たりはしない。いちいち値を変換しないといけないので、どうしても解析に時間がかかっちゃう(T-T)

 

解析にものすごく手間取ったものの、なんとか点が打てるようになった!
むしろスクリーンに描画させるのに手間取ってしまった!(単なるバグw

 

そういえば、昨日書いていたドットのMSBが逆転している件は、私の解析ミスだった!
PC-8801とかと同様、MSBが左に来ている仕様でした!!

 

PSET命令が動くようになったら、同時にCIRCLE命令も動くようになった。

ということは、CIRCLE命令はBASIC内部でドットに分解して描画してるって事なんだね。さすがにハードウェアでの円弧描画機能などは載ってないか(^^;

 

初代M1 Macのフルスピードで動かしているというのに、円を描画しているところが見えるほどの速度だ!
これ…実機だとどのくらいの速度だったんだろうか…(-_-;;

 

ちなみにPSETを200回、CIRCLEを30回描いた時のI/Oアクセスの総数は50万回以上!
……とても効率が良いとは言えないだろう(T-T)

 

このアドレスのビットを上下逆転しなければならない仕様は、逆アセンブラリストを見ていた時に気がつくことができた。
なぜ反転させているのか、その時は意味がわからなかったけど、その反転されたデータがI/Oに出てきた時、さっき見たデータだ!と気がつけたw

これに気がつけなければグラフィックの解析は難しかっただろう。


これって…本体の基板を設計した時に、間違えてバスを逆転させて繋げちゃったとか、そういう理由???
またはI/Oの先はシリアルで繋がってて、その順番の関係とか???
どっちにしても現状ではプログラムで律儀に反転させてるのがもったいない…

256バイトの反転テーブルを持っても良かったと思うぞ…(^^;;

きっと先輩から省メモリをきつく言われてて、気の弱い後輩は(以下略

 

絵が出てくるとテンション上がるね!(^-^)

 

ではまた次回!(^-^)ノ

JR-300エミュレータの開発その2

JR-300エミュレータのお話、第2弾!(^-^)

その1でも書いた通り、開発中の記録が手元にあるのでブログ書くのも早いよ!

 

前回のブログでもうBASICが起動してて、あれ?その後ってやることあるの?とか思うことなかれ。まだまだ解決しないといけない事柄がたーくさんあるのですよ…(-_-;;

 

前回、あっさりとZ80エミュレータを起動している事に驚かれた方も多いかと思うけれど、自前で開発したZ80モジュールがあるのだ。

これとZ80のプログラムコードを合体させれば、ワリと簡単な作業でZ80エミュレーション環境が出来てしまう(^^)

 

2022/11/12(土)

先日までの作業で、内部的な話であるけれどBASICインタプリタが起動できた。

単に起動画面が出ただけだと思うなかれ!(^-^)

BASICが起動してキー入力待ちになるという事は、それまでに必要な初期化などがすべて終了したって事なのだ。

 

全く動かないものを修正していくよりも、仮であっても動いてるものを修正していく方が気持ち的にも良い…というのは分かってもらえるだろう(^-^)

 

でもJR-300のハードウェアは何も理解出来ていないけれど…(^^;;

サブCPUを制御するためのハンドリングについては先日の解析で実装した。正解かどうかは分からないけれども、動いてる!←動けば正解の精神w

 

次はキー入力系を調べ始める。

 キー入力はサブCPU側の仕事かもしれない
 キーが押されるとメインCPU(Z80)に割り込みが発生する

 キー情報はメインメモリのバッファに格納されていく

という感じの想像をしているけれど、実際にはどうなのか…。

 

キー入力割り込みの処理を捉えることが出来れば、プログラムでキー入力を発生させてテストを繰り返す事が出来る。

この流れが出来れば、ホスト(エミュレータを実行している)マシンからのキー情報をエミュレータへ流し込む事も簡単だ!(^-^)

 

割り込み(RST)?は3種類のエントリがあるっぽい。

 

 RST20      0xD883
 RST30/38   0xD7C7
 RST28      0xD7D1

 

想像出来るのはキー入力、タイマー、シリアルなどだろうか。

これらの割り込みがどのようなタイミングで入ってくるのかは不明。

割り込みエントリを1つずつ解析していって、バッファにデータを貯めるようなコードを探せば…それがキー入力でした~……とか簡単に見つからないだろうか…(^^;

 

何でも良いけど誕生日になにやってんだ私は…orz

 

2022/11/13(日)
RST20を解析していったところ、おそらくキー入力と思われるコードが見つかった。
やはりキー入力は別のCPU側が管理していたか…。

サブCPU側の機能面から見ても、コントローラでなくてCPUがいると仮定した方が良さそうだ。

 

以下の手順で、Z80側にキー入力割り込みを発生させられる。

・キー情報を0xFC2Eに書き込む(アスキーコード or 制御コード)
・0xFC02のbit1(0x02)を立てる(これが割り込み要因となる)
Z80に割り込みを掛ける

 

キー入力バッファは0xDD12からの32バイトとなっている。
32バイトを越えたキー情報は捨てられてしまうので、エミュレータのプログラムでキー情報を発生させる場合にはバッファ溢れの配慮が必要。

 

returnキーのコードは0x0Aまたは0x0Dのどちらでも良いらしい。
もしかしたらフルキーのreturnと、テンキーのreturnでコードが違うとか??

 

外部割り込みでRST20が入る事から、Z80の割り込みはモード0が使われている。

 

問題発生!!

キー情報が入れられるようになったことで気を良くしていたら、なんとBASICのコマンドが実行出来ない。
RUN[return]としても、なーんにも起こらない…。
10 REM[return] としても入力された感じがしない。

 

こういう……それっぽく動いちゃうバグが、エミュレータを作ってて最も面倒くさい。
原因を探って行こうにも取っ掛かりがないのだ(T-T)

 

根気よくコードを追ってみると、メモリ0x0300にある「00で埋まっている場所」と「何か」を比較しているようなコードがあった。
この00が埋まってるところが怪しい…。

この領域を初期化しているプログラムコードが見つからないのだ。

ということは、サブCPU側から送られてくる何か

 

…なんて事を考えていたら、そうか、今から実行しようとしているコマンドの文字列が、Z80側には情報が無いのか…と気がついた。

 

キー入力があると1文字ずつ表示はしているけれど、あくまでも表示をしてるだけ。

JR-300はメインCPU(Z80)側にテキストバッファを持っていない。


カーソル位置の左側に何の文字があるのかは、サブCPU側にあるテキストバッファを知る必要があり、そのためにはサブCPUへお伺いを立てる必要があるのだ。


そのためのサブCPUコマンドがあるはずなんだけど……。

こうなってくるとコードを追いかけるというよりは「おそらくこういう構造になっているはず。そのためのプログラムを探す」という感じになってくる(^^;;

そんな感じに探していたら、こんなコマンドが引っかかってきた。

 

SUBCPU  DE:A4AF (06 0E 05  [ 0B 00 09 00 03 ])

 

サブCPUコマンド0x0E、パラメータは5つ。
このパラメータ自体はサブCPUが解釈するものなので詳細は分からない。

わからないけど予想するしかない!

 

実験の結果、おそらくこうだろうというのが予想出来た。

1バイト スクリーン情報からコピーするバイト数
1バイト コピー開始するスクリーンX座標
1バイト コピー開始するスクリーンY座標
2バイト コピー先アドレス(サブCPU側のオフセットアドレスっぽい)

 

ここで実行時にちょっと変な動作があった。
コピー先アドレスが、なぜか0300hから0100hに変わってサブCPUに渡ってしまう。
ん?これは??バグ??バグなのか???
ここでもサブCPU側の動作を予想する。

 

おそらく…これまでの流れで見ると、サブCPU側は(Z80側の)0xFC00からアクセス出来るっぽい。
その0xFC00からのオフセット0x0100で、0xFD00からデータを書き込め…という指定ではないかと考えた。


そして0xFD00に書かれたデータを、Z80側の0x0300へコピーするコードがどこかに有るはずだ。
実験的に0xFD00へテストデータを置いて試してみると、0x0300からテストデータがコマンドが入る事が分かった!

 

この実験結果に基づいて、サブCPU側の処理を追加してみた。

これでZ80側に実行するべきコマンドの文字列が渡り、実行できる…はず!

おおお、無事にプログラムが実行できた!!!(^o^)/

 

試してはいないが、1行の長さはコマンドパラメータならびにバッファサイズの関係から256バイトに制限されている気がする。

 

FOR I=20の値を200とかにすると、プログラム終了時に表示されるReadyの位置がずれてしまう。
おそらくまだ正しく解釈出来ていないサブCPUコマンドのせいだろうな…。

 

この先はBASICの命令を解析しつつ、サブCPU側の実装を進めていく流れとなる。
同時にBASICもマニュアルも書けるといいなぁ…。

 

2022/11/14(月)
JR-300にはあまり見覚えのないBASIC命令がいくつか存在している。

BASICインタプリタ内にあるコマンドを可視化してみた。

 

AUTO AUX ABS AND ASC ATN
BEEP BOOT 
CONSOLE CONT COS COM COLOR CIRCLE CHR$ CHR CSRLIN CLOSE CLEAR CALL CDBL CINT CLR CLS CSNG
DELETE DIM DEF DATA DATE$ DAY$
END ELSE ERASE ERROR EOF EQV ERL ERR EXP 
FIND FOR FIX FRE FN
GOTO GOSUB GCURSOR GCOLOR GET
HEX$ HCOPY 
INPUT INTERVAL INKEY$ INITP INSTR INP INT IMP IF
KEY
LIST LLIST LAYER LOCATE LPRINT LOAD LINE LEFT$ LFIND LPOS LEN LOG LOC LTRON LET
MON MERGE MLOAD MSAVE MAT MID$ MOD
NEXT NOT NEW
ON OFF OPEN OUT OR
PRINT PAINT PALET POKE PRESET PUT PSET PRTY PEEK PLAY PLOT POINT POS
RETURN RENUM RESTORE RESUME READ RANDOMIZE RIGHT$ RUN REM RND
SCREEN SAVE STOP STEP SOUND SYMBOL STRING$ STICK STR$ SPC( SQR SIN SGN SET
THEN TERM TAB( TAN TIME$ TROFF TRON TVMD TVCH TVPW TVOL TO
USING USR
VIEW VERIFY VARPTR VAL
WIDTH WINDOW WAIT
XOR

 

BOOT、INITP、OFF辺りはタイマーによる電源制御系かな…。
TVxxはテレビコントロールな気配がする。
PRTYは表示のプライオリティ??
LAYER……レイヤーとは?
PALETはパレット機能??あるんだっけ?
PSETとPLOTは別命令?
COMとAUXの関係は??
MATとは?
…ぱっと見ただけでもそれなりに不思議な命令が揃ってる。

でもMON(マシン語モニタ)があるのは素直に嬉しいw


今後の方針を簡単に決めてみた。

・ここまでのプログラムをいちど整理したいw
・BASICコマンドの解析
 ・テキスト周り
 ・グラフィック周り(ここで表示をWindow対応する)
サウンド解析
・デモンストレーション解析

こんな感じ?

まだまだ先が長いぞコレは…orz

 

キー入力が完成した事によりBASICのコマンドを実験できる環境が整ったので、せっかくなのでテキスト文字に色をつけてみたい!
ということで、COLOR命令を試してみる。
試した結果、COLOR命令はJR-200と同じオプションらしい。

 

  COLOR 文字色[,背景色[,オプション]]

 

文字色と背景色だけを指定すると、サブCPUコマンド0x04が呼び出される。
何故か色フォーマットは上位下位の4ビットずつではなく、00bbbfffと律儀な3ビット形式。

 

そして3つめの引数であるオプション指定が様々な問題を引き起こす…。
オプションは0〜3の値を取り、それぞれに以下の意味らしい(JR-200)。

 

0 ... ユーザー定義モードの解除
1 ... ユーザー定義図形の表示
2 ... 文字色と背景色を反転
3 ... 背景色を式2の指定色に一括変更

 

0と1はPCGの事で、これがJR-300に存在する命令なのかどうか現時点では不明。


2を指定した場合は、サブCPUコマンドの色情報が上下ひっくり返って渡される。

 

そして3を指定すると…サブCPUコマンド0x12,0x13,0x1Fの3つが呼び出され、それぞれの意味は解析出来ていない。

そもそも一括変換ってどんな動作するの??


うーん、未解析なサブCPUコマンドがどんどん増えていく恐怖よ…orz

 

ちなみにCOLOR命令単体(引数なし)で実行するとSyntax errorとなる。
Illegal function callじゃないのか…汗


WIDTH(横の文字数)の実験してて気がついた。
どうやらリセット後の横文字数はWIDTH 40が標準らしい。

 

どーにも我慢しきれなくて、先にウィンドウ表示させてしまった!(TT)

エミュレータを開発してる時は、可能な限り画面表示は後回しにして、テキストベースでデバッグするのが好みなんだけど、色とか使い始めたら見てみたいワケで(^^)

 

SDL2というライブラリを使用して表示するようにしておけば、WindowsでもMacでもLinuxでもソース共通で動く。

 

SDL2に対応した記念?に、適当にも適当なるキー入力を実装してみた。

実行しているエミュレータ上でキー入力することが出来るようになった!

これで好きなコマンドを入れることが出来るようになったよ!(^-^)

特にデバッグの役に立つわけではないけれども、すごーく出来てきた気分になれるw

 

ではまた次回!(^-^)ノ

JR-300エミュレータの開発その1

今回からは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が動いてる」というよりは「処理が進んでる」程度だけど!

 

ではまた次回!(^-^)ノ

National JR-300について!

National JR-300というレトロパソコンをご存知だろうか??

そもそもNationalって何?って言う人もいるのかも?!(^^;

 

JR-300、1983年頃に広告が出て、おそらくちゃんと販売されたのだろうけれども、ほとんどの人は見たことが無いという不思議な…まさに幻のマシン!

もちろん私自身も見たことがないし、触ったという人に会ったことも無い。

ただ以前から都市伝説のように「JR-300という機種があるらしい」という事は知っていた。

ネットで検索するとJR-300のパンフレットも存在していたらしい。

 

このたび、ワケあってJR-300エミュレータを開発した(まだ途中)。

本日以降、ブログで開発日記的なものを書いていこうと思うけど、単純にJR-300のスペックだけを知りたいという方も多いだろう。

 

…というわけで、スペック情報を書いていくよ!

あくまでも解析した結果であり、確定情報ではないのでご注意ください!

苦労話を読んでくれる方は、次回以降のブログもお願いしますw

 

メインCPU:Z80

サブCPU:存在している

GDC:μPD7220A

メインメモリ:64KB

テキスト:80x25、40x25(VRAM 4KB) PCG機能

グラフィックス:320x200、640x200(VRAM 48KB)

その他:

カラーパレット機能あり、PSGあり

 

メインCPU

どの情報を見てもメインのCPUがZ80という事だけは共通だった(^^;

実際、BASICとデモンストレーションプログラムを見たら、確かにZ80のコードで書かれていた。

 

クリーンコンピュータ構成となっていて、本体の起動にはプログラムの入ったテープが必要。

本体には16KBほどのIPL ROMが載っているらしいけど詳細は不明。

 

メインCPUから利用できるメモリは64KB。

メインCPUからテキストおよびグラフィックのVRAMはアクセスできない。

 

サブCPU

存在している事は間違いないが、CPUの型番含めて詳細不明。

JR-300には「JR-200との互換機能」があるらしいので、そのCPU(6802)と思われる。

BASICおよびデモプログラムからはサブCPUの型番を知る情報がない。

 

サブCPUはテキスト表示(PCG含む)、パレットチェンジ、サウンド、カセットテープ関連など、いろんな事を担当。

メインCPUとは共有メモリを介してハンドシェイクしている。

 

GDC(Graphic Display Controller)

グラフィックスの描画を担当するGDCが存在していて、型番はμPD7220A。

初期のPC-9801に載っていたμPD7220Aのグラフィック側と同等。

最初の頃のGDCなので3プレーン同時書き込み等が出来ない。

グラフィック用のRAM(VRAM)はGDC側に接続されていて、メインCPUからは直接読み書きができない。

 

GDCのコマンドを介して、高速に描画する事が可能。

……なのだが、JR-300特有の理由があり速度は速くなさそうだ。

 

テキスト表示

80x25または40x25の表示が可能。

テキスト用のRAM(TVRAM)はサブCPU側に接続されていて、メインCPUからは直接読み書きができない。

 

文字色と背景色が設定出来るらしい。

PCG機能を有していて、おそらくX1のようなハードウェアPCG。色は単色。

定義できる文字数は不明だが、構造上は256文字。

 

グラフィック画面と重ね合わせ表示されて、グラフィックとテキストは分離しているっぽい(テキストがスクロールしてもグラフィック画面に影響なし)。

 

グラフィック画面とテキスト画面の表示優先順位を変更できる(BASICからも変更可)。

 

サウンド機能

まだ実装前だけど存在しているらしいことは確認清み。

サウンド自体はサブCPUがMMLの解釈実行まで行う(らしい)。

おそらくPSG3重和音が可能。

カセットからデータを読み込むバッファと、MMLを格納しておくバッファが同じアドレスとなっていて、音楽演奏とカセットからの読み込みは同時使用が出来ない。

 

その他

キー情報は別のサブCPUまたはコントローラがつながっていて、キーが入るとメインCPU側に割り込みが掛かる。

 

他にも追加項目があったら随時更新していきます。

このページを見ればJR-300の最新情報が得られるようにします。

 

 

次回以降、いかにして解析をしつつエミュレータを開発していったのかを書いていくよ!乞うご期待(^^)

 

ではまた次回!(^-^)ノ