先日のHello Worldから1日、ようやくグラフィックスが表示出来るようになった!
想像以上の複雑さに音を上げそうになった(^^;;
しれっと何も無かったことにして次のマシンに行っちゃうのもありだったけど、もう少し6301を楽しみたかったので年甲斐もなく奮起してみた!
グラフィック描画のヒントがない!
先日からOh!HCを片っ端から調べて、ROM内ルーチンの情報や解析情報などを読みまくった。解析情報の多さはさすが専門誌と言ったところか!
ほぼ全ての情報が網羅されていると言っても過言ではなかった!
これだけ情報あったら困る事ないじゃーん!
……そう思ってました(T-T)
そしたら…グラフィックスに関係する資料を見た事がないと気がついた!
Oh!HC誌上では「SGS-sys6」という、BASICを拡張してグラフィックス描画が出来るシステムで盛り上がっていて、大半のソフトがそれを使って絵を表示していたのだ。
そのSGS-sys6のソースリストがあれば良かったんだけど、どうも見つけられない。私の探し方がダメなのか、所有していない号に載っているのかはっきりしないけど!
それ以外にグラフィックスについて細かく書かれた資料を見つけらなく、どうやって画面に絵を出したら良いのか、方法がさっぱり分からない…。
そういえば昔、I/OにHC-20用の「BUG FIRE」というゲームが掲載されていた気がする!しかもマシン語使ってたぞ!ソースは載っていなかったと思うけれども、もしかしたらプログラムの説明などで解説が載ってるかも知れない!そう思ってI/Oを探しまくった!(ToT)
ようやく探し当てた1983年8月号!
読んでみたけど「画面のスクロールはシフトではなく仮想画面からの…」という説明のみで、アクセス方法については書かれていなかった…orz
ぐぬぬ、残念…
ちょっとだけヒントあった!
Oh!HCをよーく読み込んでいくと、LCDについての記述があるのを見つけた。
どうやら「コマンド」と「データ」の設定があるらしい…けど、肝心のコマンドリストは??
そしてなんとなく使うべきROM内ルーチンは想像出来るんだけど、使い方(エントリ時のレジスタ設定など)が書かれていない。うーん、情報が足りない(T-T)
解析していくしかないんだよなぁ…。
HC-20のLCD関連
結局、HC-20のROMを解析するのが一番!という結論に至った!
表示周りを中心に解析したので、分かってきた事をきちんとまとめてみようと思う。
かなり複雑な作りになっているので、頭がこんがらがらないようにしたい。
この先、HC-20でプログラミングしようって人が現れるかも知れない(!?)ので、その時の資料となるべく情報を残していこう!
HC-20にはμPD7227GというLCDコントローラが6つ搭載されている。
それぞれ#0〜#5となっているが、実際にレジスタに値を載せる時は1〜6になる。
1つのLCDCには「40ラインx8ドット=40バイトを1つのバンク」として「2つ分のメモリ」を持っている。つまり横40ラインx縦16ドットの領域だ。
そして両方のバンクへの同時アクセスは出来ない。
このLCDCが横に3つ、縦に2つ繋がっていて、表示領域の120x32ドットを形成している。
プログラムからどのLCDCにアクセスをするのかを決めるのが、HC-20のポート26に出ている設定。このポートでは「どのLCDCにアクセスをするのか」と「コマンドを書き込むのか、データを書き込むのか」を選択する。
ここのポートは他にも割り込み系や拡張カートリッジ系の機能が入ってるようなので、直接アクセスするのは危険。ROM内ルーチンWRTP26($FED4)があるので、これを利用する。
μPD7227のコマンドリストは以下のようになっている。
英語で書かれていたμPD7227のデータシートを、単純に和訳したものだ。
ちょっと面白いのは、ハードウェア的にANDしてORしてという重ね合わせに有利な処理が入ってる点だ。しかし逆にちょっと残念なのは「ANDしてOR」を一発のコマンドで出来ないため、実際にやってみようとすると相当面倒な事がわかった。
じゃあ妥協してXORで書こう…という逃げ道もない。うーん…(^^;
さて、要素は書き出せたので、これをプログラムするために組み立てる。
どの資料を見ても分かりづらいと感じてしまったのは「これはHC-20の機能」「これはLCDCの機能」と切り分けて書いてくれていない点だ。おそらく筆者は理解して書いているのだろうけれども、残念ながら文章から読み取る事は容易では無かった…(T-T)
そして当然だがソースの中では区別なくごちゃまぜでアクセスがされている。コード解析能力が試されるところだ(T-T)
LCDアクセス手順
今回はハードウェアべたべたなプログラムではなく、HC-20とHX-20の互換性を保ったままプログラムしたかったので、可能な限りROM内ルーチンを活用した。
1、WRTP26($FED4)を呼び出して、アクセスするLCDCを決める
ldaa #0000_1111b
ldab #1 + $08
jsr WRTP26
パラメータの与え方がちょっと特殊だ。Aレジスタに変更するビット、Bレジスタに代入したい値を入れる。ようするにI/O26ポートの値に対してANDしてORして書き込むのだ。
これはHC-20側の設定で、6つあるうちのLCDC(μPD7227)の、どれに対してコマンドやデータを発行するのかを決めるもの。2つ上の私がテキストエディタで書いたポート情報が対象。
Aレジスタで「1番のLCDCが対象で、書き込むのはコマンド」と指定している。
2、対象となったLCDCへコマンドを発行
発行するコマンドは2つ。
ldaa #0110_0100b ; データの書き込み指定だが下位2bitは詳細不明
jsr LCDMOO ; $FF55
ldaa #$0 + $80 ; ドットを書き込みするXライン
jsr LCDMOO
ここでいう「コマンド」とは、μPD7227へ与えるコマンドで上のExcelで書かれたコマンドリストの事。
HC-20のROM内ルーチンを利用して、μPD7227へコマンドを書き込んでいる。6つあるLCDCのうち、1で選択したLCDCが書き込み対象となっている。
なお、μPD7227内部にあるバンクの切り替えは、Xラインの6bit目が担っている。0ならばバンク0、1にするとバンク1にアクセスする。
3、データ書き込みモードへ移行
ldaa #0000_1000b
ldab #0
jsr WRTP26
1でコマンド書き込みモードを指定していたが、これをデータ書き込みモードへ切り替える。ここでAレジスタに入れている値は、HC-20のROM内ルーチンで使うパラメータだ。
4、ビットマップデータを書き込み
ldaa #ビットマップデータ
jsr LCDMOD
↑これを40回繰り返すとバンク内のデータ全てにビットマップデータを書き込める
これはLCDCへの書き込みとなる。
この1〜4の手順を1回すると、1つのLCDCの片方のバンクにデータを書き込む。
↑の図で言うところの「#0 BANK 0」にデータを埋められると思ったら良い。
つまり画面全体を更新するためには、同じことを12回繰り返さないといけないのだ!
とっても面倒だったので、テーブルを作ってこれを参照しながら書き込むことにした!
6301にはインデックスレジスタがあってオフセット指定ができるので、こういう構造体的なデータ構造はとても作りやすい!(^-^)
ついでだったので、スクロールさせてみるテストもしてみた。
EPSON HC-20(HX-20)のグラフィックス表示で無駄にスクロールさせてみた。
— PocketGriffon (@GriffonPocket) 2021年8月9日
コレでフルスピード。
もっと速く出来るだろうけど、倍にはならない気がする(^_^;) pic.twitter.com/S3ZbC1CBwT
これはウェイトも何も入れていない、最高速で動かした状態だ。スクロールは単純なメモリコピーであり、工夫も何もしてないので、慣れた人が書いたら倍速間違いなしw
今回作った全画面表示プログラムは、おそらくHC-20でもHX-20でも動くはずだ。
この先もどちらでも動くことを意識しながらプログラムせねば…と思った!
とりあえずひと仕事終えた感じw
未定義命令実行で停止した!
ちょっと番外編的な話だけど、この画面を見て欲しい。
アセンブラのバグを踏んづけてしまって、未定義命令が出力されてしまったのだが、見事にその命令を実行する時にTrapで停止した!
Pにプログラムカウンタの場所が表示されてるので、デバッグがとても楽ちんだった!これは便利機能!(^-^)
これは6301CPUに備わっている機能。未定義命令を実行しようとすると、このようにトラップが掛かるのだ。デバッグ時に使えていいかもなぁ…と思っていたけど、このタイミングで発動するとは(^^; ちょっとおもしろかったのでご紹介してみた。
通信環境その後
その後の通信環境だけど、転送速度を300bpsから4800bpsへ上げて使えている。
1バイト送るたびに入れていたウェイトは10ms→4msに減少。
この辺りが限界かも。3msにするとIO エラーが出てしまった!
そろそろバイナリ転送プログラムが欲しくなってきますねぇ……(遠い目
さて、今回はもう少しだけ頑張ってみる気になってるよ!
久しぶりの6301は楽しいです!(^-^)
ではまた次回!(^-^)ノ