EPSON PX-8に増設メモリユニット その1

今回はEPSON PX-8のお話。

f:id:PocketGriffon:20210820171523j:plain

 

ひょんな流れから、PX-8拡張ユニットのRAM DISK UNITを入手できたのだ!

f:id:PocketGriffon:20210820172128j:plain

これは海外で販売されていたPX-8用の拡張ハードで、接続して起動するだけでOSが自動的に認識して、すぐ120KBのRAM DISKが増設される。

 

メモリはバッテリーでバックアップされているので、電源を切っても中身のファイルが消えない。かつ、本体のメモリマップとは物理的に離れた場所にあるので、プログラム開発中にハングアップしてもファイルが消える事が無い。これはめちゃくちゃ使いやすい(^^)

 

全体的な形はこんな感じ↓

f:id:PocketGriffon:20210820172153j:plain

これはPX-8の下側に取り付けるユニットで、本体と接続するとこんな感じになる。

f:id:PocketGriffon:20210820172503j:plain

下側にくっついてるのがRAM DISK UNITだ。

上がPX-8本体。

 

本体に取り付ける前に、まずはRAM DISK UNITを確認してみる。

f:id:PocketGriffon:20210820182123j:plain

フタを開けてみると、基板が向こう側を向いて入っていた(^^; しまった、これじゃあ部品が見られないw 付属のバッテリーを確認してみると、なんとビックリ!新品に交換されていた!これは嬉しい!(^o^)

 

f:id:PocketGriffon:20210820182321j:plain

ひっくり返してみたところがコレ。

メモリがたくさん載っていて、なんとなく安心感(^-^)

RAMは128KB載っている……んだと思う(^^;;

 

この↓メモリユニットに興味があるところがコレ!!

f:id:PocketGriffon:20210820191311j:plain

ユニットにZ80が載っているのだ!そう、これはインテリジェントタイプのRAMドライブ。

PC-8801シリーズのFDDみたいな感じで、ドライブ側にCPUがついている。

なんか楽しい使い方はできないだろうか…とニヤニヤしてしまう(^^)

 

f:id:PocketGriffon:20210820191554j:plain

クロックは…9.8304を2分周しても4.9152MHz…?速すぎるね…

4分周して2.4576MHzなのかも??

使い方含めて全く分からないので、今後の解析に期待したい。

 

さあ、PX-8本体に繋げてRAM DISKの確認をしてみよう!(^-^)/

……

………あれ?

PX-8が起動しない!!(TOT)
うそ!!ついこの前まで動いてたのに(T-T)

……orz

レトロやってると良くあるよね…(T^T)

 

f:id:PocketGriffon:20210820204039j:plain

コンデンサ交換をしようと分解してみたけれども、調べてみると手持ちでは足りない事が判明。16v330μFの在庫なんて持ち合わせてない(T-T)

f:id:PocketGriffon:20210820204122j:plain

交換するコンデンサを別に保管しつつ、足りない分を発注した。

手元に届き次第、またブログに書いていきたい!

…まさか動かないと思わなかったので、ブログ書き始めちゃったもんなぁ…(イイワケ

 

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

PC-G850Vでプログラム その2

f:id:PocketGriffon:20210818170012j:plain

引き続きSHARP PC-G850Vの事を調べている。

 

前回のブログでは、PC-G850のプログラムを思い出す意味合いもあり、過去の開発環境を利用して、そのままプログラムをしてみた。

BASIC+マシン語の構成だったので、プログラムはBASICとして送り込むのが都合良い。いつもの感じでDATA文でマシン語コードを含めて送り込んだ。

 

今回は開発環境を「いま」の状態にしつつ、画面に何かを表示する仕組みを作ってみる。

全体的にC言語で書けるよう環境を整えるが、速度を有する部分だけはアセンブラで書く。テスト処理を書くにも高級言語を使えるメリットは計り知れない(^-^)

 

PC-G850Vはマシン語データをインテルHEX形式で読み込む事が出来る。昔、CP/Mを使っていた時代にさんざん使ってきたインテルHEX形式ファイル…この時代でも使うなんて!(^^;

当時はHEX2COM / HEX2BINなどのツールの存在を知らず、どうやってバイナリに変換するんだよ…と思いつつ、コンバータをBASICで書いたりしてたw

 

LSIC-80は都合よくインテルHEX形式を出力する事が出来る。それをモニタ(MON)のRコマンドでロード出来る。他のマシンのように特殊な形式に変換しなくても済む分、取り扱いも楽ちんだ(^-^) 

なぜロードなのに「R」なんだろ?と思ったが、説明書を見ると「リード」らしい(^^;

 

PC-G850の動作クロック

そういえば…先日、PC-G850を分解した際にこんな写真を撮っていた。

f:id:PocketGriffon:20210819002708j:plain

LZ8514というのがCPUを含むチップなんだと思うけど(データシートが見つからない…汗)、この横に「8.00」と書かれた部品がついてる。これって水晶発振器なんだろうか??

 

8MHzがそのまま使われてるのか、2分周して使われてるのか分からないけれども、ポケコンに8MHzが使われているとしたら胸アツだ!(^-^) PC-8801FHなどが発売されてから10年あとに発売されてるので十分にありうる!

いつかクロックについても調べてみたい。

 

ちなみにネットにあった資料を見ていたら、I/Oポート67hにCPUクロックの設定というのがあった。たまたまブート周りのプログラムを見ていたら、そこで「高速動作」の初期化をしていた。試しにBASICから「OUT &H67,1」としてプログラムを実行すると、実行速度がきっちり半分になる。動的に変えられるのも便利だ(^-^)

 

LCDに直接書き込み

2年半前にPC-G850でのテストをしていた時、LCDに直接データを書き込むプログラムを作っていた。これがそのまま動くのかわからないけれど、理解が追いついていない現状でそのまま使うのは危険だ(ブラックボックスになっちゃう!)。

一度、当時のプログラムを分解して理解を深めてみる。

 

基本的な考え方は、

・仮想的なビットマップバッファを確保

・そのメモリへ画像データを(なんらかの方法で)書き込む

・ビットマップバッファをLCDへ書き込み

という流れ。

当面は画面全体を書き換える方向でプログラムを組み立ててみる。

 

画面全体を書き換えるとなると、大体以下な感じでよさげ。

・データを書き込むアドレスの初期化

・データ書きまくり

 

これを行数分(PC-G850では6行)繰り返せば画面に表示される事になる。

 

ひとつハマりやすいのは、PC-G850には「表示座標」というのが存在する。BASICでスクロールする際に、実際のデータを書き換えるのではなく、レジスタを1つ書き換えて表示する座標をずらすという機能があるのだ。

 

このレジスタの初期化を忘れると、画面の変な場所に表示されて大いに悩む事になる(^^;

f:id:PocketGriffon:20210819082321j:plain

↑とりあえず動くように作りました…って感じのコード丸出しだw

この先、機能を追加していき、一段落した後に高速化してみたい(^^)

 

ところで…このブログを書きながら気がついたけれども、どこにもLCDCのBusy信号を参照している箇所がない。他のレトロマシン(PC-8201など)ではLCDCがBusyの場合が多く、常に意識しないとちゃんと動かす事ができなかったが、PC-G850のLCDは優秀(高速)なのか、今のままでも動いてしまってる(^^; これ…いーんだろーか??

 

今回実験するにあたり、いくつかの疑問があった。

・LCDC内部のVRAMは何行分あるのか

・表示座標をずらしていった時、表示はどうなるのか

この先、ライブラリを充実させていくためには、どうしてもこの2つを解決…というか理解しておく必要がある。

 

LCDC内部のVRAMについては、書き込みする際に指定する座標が0〜15まで指定出来る。しかしテストした結果、0〜7までが有効っぽい。8以降を指定しても表示には特に影響がないようだ。

 ・LCDC内部のVRAMは何行分あるのか

  →8行分あるらしい

 

行数が8ある事は理解した。ではスクロールさせていった時、8行を超えた部分については「どう見える」のか?

1、何も表示されない

2、ゴミが表示される

3、1行目が表示される

果たしてどれだろう??

 

 実際に実験をしてみたところ、どうやら3が正解っぽい。いわゆる円筒スクロールが出来るみたい。ということは、それを前提にした画面書き換えをする事ができそうだ!(^-^)

 ・表示座標をずらしていった時、表示はどうなるのか

  →上の行から表示が繰り返される

 

動画にも出ているけど、スクロールさせるとインジケータの大暴れする。これについては調査していくが、何か触ってはいけないレジスタを触ってるんだろうなぁ…としか思えない(T-T)

 

とりあえず今回はここまで!(^^)

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

 

PC-G850Vでプログラム その1

f:id:PocketGriffon:20210816091323j:plain

今回のPC-G850Vプログラムでは、解析にあまり重きをおいていない。

過去に結構調べた経緯があった事と、せっかくなのでもう少しプログラミングを楽しんでみたいという思いからだ。

 

で、プログラムの基本から…と思いつつも、なぜか最初に調べたのが割り込み系(^^;

過去のプログラムを見て、とても不自然に感じたことがあったので再調査したかったのだ。

 

過去の私は、1/30秒での割り込みをテストしていたようだ。

でも……これ、ホントに動いてたの?(^^;;

そもそもPC-G850シリーズにそういう事出来るんだろうか??

もうね、めいっぱい自分を疑って掛かるww

まずは当時の自分と同じ知識レベルまで追いついてみる!

 

PC-G850シリーズの割り込み

f:id:PocketGriffon:20210816153935j:plain

PC-G850シリーズは…というよりは、Z80では…と言った方が良い気がする(^^;

Z80ではNMI(Non Maskable Interrupt)が入ると0066hが呼び出されると決まっている。

まずはここから見ていこう。

 

0066: ED 45  RETN

 

……うん、何もしてなかった!(^^;;

 

別の割り込みも調べてみる。

Z80には割り込みモードが3つあり、PC-G850がどのモードを利用しているのか分からない。

試しにブートシーケンスを途中までハンド逆アセンブルしてみたけど、割り込みモードを設定するところが見つからなかった(事情ありそう)。

 

じゃあということで、割り込みモードは1と勝手に仮定して(そうしないと探すのが面倒)、0038hからを解析してみる。

f:id:PocketGriffon:20210816121517j:plain

お、それっぽいプログラムが入っている!

そして追いかけてみると、最後はRETIで終わっていた。

どうやらこれであってるっぽい!

 

f:id:PocketGriffon:20210816123325j:plain

f:id:PocketGriffon:20210816123349j:plain

この本↑にI/Oポートの情報が書かれていて、そこに「1S」というタイマーがあるらしい。

1Sって??1秒の事?1秒に1度割り込み入るの???

実際にどのくらいの頻度で割り込みが入っているのかを調べてみたい。

 

そう思って、まずは割り込み処理を横取り出来ないかと思いHookを探してみた。割り込みプログラムを(おそらく)全部見てみたけれども、どうもHookらしいものは存在しないようだ。

コレは…ユーザーから割り込みは利用できない仕様??

 

うーん、だって0038h付近はROMのはずなので(BOOTする関係上)、0038hのフックなんて書き換え出来ないし…。

そんな事を思いながら、BASICで書き換えのテストをしてみた。

f:id:PocketGriffon:20210816124538j:plain

あれ?!書き換えが出来た!!

え?どゆこと???このマシンはどうやってBOOTしてるの?(^^;;

 

もしかしたら起動時にのみ見えるROMがあって、起動が終わったら切り離されるとか?そこで割り込みモードの設定とかしてるから、BOOT後のリセットベクタを追いかけてもモード切替が見つからなかったのかも…と思った(完全なる想像)。

 

解析の結果は疑問だけが残ったけれども、0038hにある割り込みフックがRAMという事が分かったので、任意に書き換えが出来る。

ここを書き換えて自分のプログラムに処理を飛ばし、飛んできた回数をカウントする。

大雑把ではあるけれども、だいたいの数がわかるはずだ。

 

動画がなくて恐縮だが、5秒くらいの処理をしてみたところ、プログラムに飛んできた回数は6と出た。つまり、1S割り込みの名前の通り、どうやら1秒に1回呼び出される割り込みのようだ。ホントに???

…これだけ(1秒という)タイマー割り込みの間隔が広いと、何かに使うのは厳しいかも?

 

通常、この手の割り込みの間隔はソフトウェアで設定が可能な場合が多い。しかしそれを何の資料もなく調査するのは不可能に近い(T-T) ここはネットの力を活用しよう!

 

そしたら…とても有用な情報を調査公開してくださっているページがあった!

■とある言語の開発記録II / PC-G850の回路図とLCDの低レベル制御

この資料を見ると、どうやら"とある"LCDのコマンドを設定してやれば、1S割り込みの間隔が短くなるらしい。これは……なんだろう?本来ならばカーソル点滅速度とかで使われるモノ?

 

試しにI/Oポート 40hに 31hを入れてみたところ、割り込み間隔が短くなった!正確な間隔はわからないが、実験してみた感じでは1/30秒くらいの間隔のようだ。

システム的にどのような影響があるのか分からないので、プログラム終了後にはもとに戻すようにした。

 

割り込みの応用

せっかくなので、この割り込みカウンターを利用して速度チェックをしてみた。

一度、PC-G850シリーズの速度チェックをしてみたかったのだ(^-^)

方法としては……

・割り込み初期化

・BASICで適当な処理

・割り込み終了

・結果を表示

という、超簡単なモノ。

ベンチマーク的な処理をBASICで書けるので、時間稼ぎ処理?が手軽だ(^^;;

3D的なグラフィックの絵(↓こんな感じ)を表示させてみたかったのだが……

f:id:PocketGriffon:20210816152225j:plain

算数するのが面倒だったので、安直にPC-G850Vのマニュアルにあるプログラムを利用した(をぃ)。

 

結果はTwitterにも載せたけど、こちらにも。

f:id:PocketGriffon:20210816152912j:plain

f:id:PocketGriffon:20210816152935j:plain

f:id:PocketGriffon:20210816153005j:plain

画面上部に表示されている数字が、ベンチマーク実行中に呼び出された割り込み回数。数字が大きい方が時間がかかっている。そしてなぜかPC-G850Sだけ表示位置が違う…。

 

結果を見ると、PC-G850VとVSは誤差の範囲かなーと思うけれども、Sだけが2割近く遅い。

これは……割り込み間隔の変更プログラムの問題なのか、BASICインタプリタの実装上の違いなのか、それとも…なんなのかは分からない(-_-;;

ベンチマークプログラムも自分で作ったものを利用しないと状況が絞れない(^^;;

これはこの先、別のものを作っていこうかなーと思う。

 

あれ??今、先頭から読み返してみたら「解析に重きをおかない」って書いていたけど…汗

 

この先は、少し開発環境を今風に整えてみたい(^^)

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

 

過去にPC-G850Vでテストしてた事

f:id:PocketGriffon:20210814105014j:plain

前回のブログにも書いたが、2019年1月頃にPC-G850のプログラムテストをしていた。

どんな事にチャレンジしていたのかを書いてみたい。

 

通信環境を準備

この頃に「ちょっとずつレトロパソコンに取り組んでいこう」って感じの気持ちになって、初めてホストマシンと通信してみたのがPC-G850Vだった。

 

当時は拡張端子のピンを調べて自分で作ってみるとか到底無理だったので、ネットを検索して参考にして同じものを作った。

その時に参考にしたのがこのサイト!

ポケコン用USB通信ケーブルを作ろう!

 

このサイトを参考にして、通信アダプタを作ろうって気になった。

そしてうまれて初めて行った秋葉原秋月電子!(^^;;

これまで秋月電子の名前は聞いたことがあっても、どこにあるのか知らなかった!

f:id:PocketGriffon:20210814112028j:plainf:id:PocketGriffon:20210814112045j:plain

そして作った通信アダプタ。

はんだづけの下手くそさ加減は気にしないで欲しい(T-T)

はんだごてを握って4ヶ月後の作業だ(^^;;

最初は抵抗を付けずに通信していたけれども、参考にした記事に書いてあったのと同じように通信が安定しなかったので、後日抵抗を買ってきて取り付けた。

この時に購入した抵抗が、まだ80本くらい手元に残っているw

 

当時のビルド&テスト環境

当時、開発をしていた環境を見返してみると、どうやら「asz80」「aslink」というツールを使っていたようだ。

ASxxxx Cross Assemblers

 

そして、通信アダプタを作ったことから、おそらく実機でのテストもしていたはず。

いくつかの簡単なプログラムを作っていた。

f:id:PocketGriffon:20210814120811j:plain

当時のやっつけで作ったHello Worldプログラム(^^;

そしてなんと!

どうやら当時は動作確認にエミュレータも活用していたようだ。

律儀にもスクリーンショットを残してあった!

f:id:PocketGriffon:20210814121201p:plain

表示されてるテキストは違うけれど、実験段階で何度か表示させていたのだろう(^^;

 

この頃にテストしていたフォルダを見ると…

  color

  hello

  intr

  vram

……うーん…何の実験をしていたのか(^^;;

このフォルダ名と中にあったソースから見るに、どうやらこんな感じらしい。

 

まずはLCDCに直接アクセスをする実験をしていた。

f:id:PocketGriffon:20210814142432p:plain

ソースの更新履歴を見ると、どうも速度の限界にも挑戦していた模様。

こんなテキストが残されていた。

f:id:PocketGriffon:20210814141813j:plain

うーん…これを見る限り、ループ展開でLCDCへの書き込みを行えば、秒間578回くらいの書き換えが出来るという結果を得てるらしい。もちろん理論値であり、実際には2か3で割ったら良いかも(^^)

でもココに書いてある8MHzってなんだったか…PC-G850Vの動作速度??

そういえばPC-G850シリーズでも動作速度が違う…と思った覚えがあるけど、記憶違いも十分ありうるので確証は無い。今回テスト出来ると良いけれども(^^)

 

そしてcolorというのがグレイスケール表示を実験していたようだ。

f:id:PocketGriffon:20210814142618p:plain

そうだ、それでエミュレータで実験をしようとしたけれども、一部の割り込みが実装されていなくて、エミュレータそのものを改造した覚えがある!

 

グレイスケールをキレイに安定して表示するために、タイマー割り込みでの切り替えは必須と考え、エミュレータで未実装だった割り込みを追加しているようだ(ソースに本名が書かれていたのでお見せできないけどw)。

 

うーん……ここまでソースを見ても詳細を思い出せない(^-^;;

これは…やっぱりまたしても1からのチャレンジに近いのではないかとw

 

今回は開発にCコンパイラを使おうと思っている。

実行時間が気になるところは今まで通りアセンブラで書き、シーケンスに近い部分はC言語で書くようにすれば、プログラムもちゃかちゃか組めるはずだ!

 

よし、次回から実際にプログラミングしてみよう!

楽しみだ!(^-^)

 

PC-G850をメンテナンス

f:id:PocketGriffon:20210813110225j:plain

少し事情があって、SHARP PC-G850シリーズを使ってみる。

実は過去に一度、PC-G850シリーズのプログラミングにはチャレンジしている。

作っていたファイルの日付を見てみると2019年1月頃に取り組んでた。

 

もう2年半前の話でもあるし、当時の記憶も曖昧だ!

当時はブログなどを書いていなかったので、記録として何も残っていない。もう一度最初からチャレンジしたら、ちょうど良い感じにブログ書けるからな…&事情にも対応できるのでいいかな…と思った。いわゆる自己都合ってヤツだ!!(えっへん

 

f:id:PocketGriffon:20210813105845j:plainf:id:PocketGriffon:20210813105907j:plain

PC-G850シリーズは4つの機種が出ていた……と思われる。

 PC-G850

 PC-G850S

 PC-G850V

 PC-G850VS

発売のタイミングもこの順番??

 

PC-Gシリーズとしてはもっともっとたくさんあるけれども、機能として最終的に落ち着いた機種を対象にした方が、作る側としては対応が楽ちんだw

機能に大した差がないのならば、PC-G850シリーズの長男であるPC-G850を使ってプログラミングをしてみよう!

 

PC-G850

ただ……残念ながら、ウチにあるPC-G850は動かない。何を手に入れた時におまけについてきた記憶がある。全く修理もしていなかったので、試しに修理をしてみる。

乾電池を入れてONボタンを押す。

f:id:PocketGriffon:20210813112145j:plain

しーん…。

やっぱりというか期待もしていなかったけど電源入らない(T-T)

 

さっき電池を入れる時にすでに気がついていたけれども…

f:id:PocketGriffon:20210813112320j:plain

f:id:PocketGriffon:20210813112341j:plain

この電池液漏れは……内部にも達しちゃってるんじゃないですかね…?(T-T)

自分の経験上、中にまで液漏れが行っちゃってる場合は直せた事がない。

とりあえず電池ボックスをキレイにしてみよう。

 

f:id:PocketGriffon:20210813112629j:plain

本体からスプリングを外してキレイにする!このスプリングはプラスチックの溝にカチっとハマっているだけなので、マイナスドライバーなどで引っ張り上げてやれば簡単に取れる。その際に溝を割ってしまわないように気をつけよう。

 

f:id:PocketGriffon:20210813112945j:plain

頑張ってキレイにしてみたけれども、どうだろうか?(^-^)

スプリングとくるくる巻きの部分をピンセットのようなものでガリガリと削り、ピカール(金属みがき)で磨いてみた。さらに接点部分を軽くやすりで削っておいた。あんまり削ると錆びてしまう気がするので、撫でる程度にしてる(^^;;

さてこれでどうだろう?

f:id:PocketGriffon:20210813113522j:plain

お、電源入った!

入ったけど……一切のキーを受け付けない…。しかもリセットを押してもメモリクリアの画面が出ない。これは……全体的に変だ(T-T)

あと、OとDの間にライン抜けがあった…。

 

うーん……仕方ないので分解してみる。

あまり分解の気がすすまないのは、PC-G850シリーズはケースを開けるのが大変なのだw

分解(というか液晶のライン抜け修理)については過去のブログで書いてるので、ぜひ参照して欲しい。

 

 

f:id:PocketGriffon:20210813114000j:plain

分解してみたのがこの状態。なんか……コンデンサがでかくね???

こういうもん??

 

f:id:PocketGriffon:20210813114111j:plain

うむむ…やっぱり内部にも液漏れが達してる感じだ。

f:id:PocketGriffon:20210813114409j:plain

キーボード周りはとてもキレイ。

ここに強く液漏れの影響が出ていると、私のような素人が直すのは厄介…というか無理だ(T-T)

 

f:id:PocketGriffon:20210813115749j:plain

とりあえずコンデンサを交換してみよう。ただこのコンデンサ、すごい違和感…。

こんなでっかいものがついてる??

よくよく見てみると、どうもこのコンデンサは交換された後っぽい。コンデンサを固定しているゴム?が削られていた(写真撮るの忘れた)。

そして交換したコンデンサも写真撮るの忘れてた…orz

 

同時にライン抜けも修理してみた。

ライン抜けの修理方法についても、上に書いたブログへのリンクを参照してみてほしい。

 

さて、この状態で電源を入れてみると……

f:id:PocketGriffon:20210813120431j:plain

おおお!メモリクリアを聞いてくる画面が出た!

 

f:id:PocketGriffon:20210813120615j:plain

f:id:PocketGriffon:20210813120534j:plain

メモリをクリア後、コントラストの調整をしてみたけど、ライン抜けはキレイに直ってるようだ!直ったかな!?

 

……と思ったが、どうやら入力出来ないキーがあった。

T、N、Hとか、テンキーの369とイコール(=)、そして…もっと困った事にスペースバーが入らない。これは…なんとなくだけどキーマトリクスのどっかのラインが入ってない気がする。

断線の可能性が高くなってきた。

うーん……もう一度基板を確認してみる。

f:id:PocketGriffon:20210813121313j:plain

あ、さっき気が付かなかったけど、液漏れが基板についてた。

これはキレイにしておきたいね。

 

f:id:PocketGriffon:20210813121712j:plain

こんな感じ!!

キレイにしてみたけど……これって入らないキーと影響あるのかな??

汚れていたから電気通らなかった…みたいのだったら直るかも知れないけど。

テスターで断線箇所を調べてみたけれども、この黒いシール?が邪魔で途中までしか追えない。うーん…これはちょっと困ったぞ。

 

それからもうひとつ。

f:id:PocketGriffon:20210813121815j:plain

この左側にある、いかにも増設してくださいといわんばかりのパターンは??

同じチップが手に入ったらできるのかな??

まぁ出来たとしてもメモリマップ的にどうなるのかわかんないけど…。

 

この状態で組み立ててみたけれども、やはりキーは直らず。

起動までしているので、動作確認には使えそうだけど開発では厳しいかな???

 

 

……というわけで!!!

開発はPC-G850Vですすめるようにする!汗

ほら、PC-G850よりもVの方が手に入りやすいし!!(イイワケ

f:id:PocketGriffon:20210813124828j:plain

 

次回以降、少しの間だとは思うけどPC-G850シリーズでのプログラム開発を試してみようと思う。

 

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

HC-20を使う その6

f:id:PocketGriffon:20210811090724j:plain

せっかくなので何かHC-20(HX-20)で作ってみたい!

そう思ってゲームを作り始めたのだが……やっぱり途中で飽きてしまった(^^;;

 

私は趣味で開発したゲームというのが数える程度しかない。最後までちゃんと作り終えたのは2本のみ。あとは全部中途半端かも知れないw 移植もタイトルが出てゲームが始まればそこで終了、最後まで通して遊んでみるとかしない。

興味の対象がゲーム開発にない事は明らかだ!(^-^)

 

上の発言とは矛盾するが(察して!)、今までゲームはたくさん作ってきているので、もはや技術的に難しいと感じる事がないから…なのかも知れない。先が見えてしまった行程ほど気合が入らない事はない(T-T)

 

というわけで、今回は総集編という感じでHC-20(HX-20)でプログラムする上でのあれこれを書いてみたいと思う。

 

 

全体的な構成

全体としては「仮想画面を更新」「画面全体を書き直す」というのを繰り返しているだけだ。

画面は部分的に書き換えるなどの最適化もしてなく、全く更新されていないスコアなども毎回律儀に全部更新されている。ようするに最適化する前の段階で終わってるって事だ。

 

垂直同期信号での速度調整…なんてしていないので、倍速で動くHC-20ならば倍速で動いちゃう。ゲームとしての基本構成が完全に破綻している(^^;;

 

仮想ビットマップ情報(仮想VRAM)

内部で大きめな仮想ビットマップ情報(以下仮想VRAM)を保持している。画面サイズは120x32ドットだが、仮想VRAM内部では128x32の構成となっている(全部で512バイト)。

これは横方向を2のn乗にしておく事で計算をラクする狙いがあったが、乗算命令(Mul)を持つ6301では効果が感じられなかった。

 

仮想VRAMは横方向に128x8ドット分が連続している。HC-20(HX-20)のVRAM構成と異なっているが、これは専用の転送ルーチン(前回のブログで説明したもの)が差を吸収している。そのため、仮想VRAM中のアドレス計算および描画そのものが高速化出来ている。

 

縦のドット単位スクロール

多分、これがこのプログラムで一番の技術的なところかも知れない。

 

仮想VRAMは縦方向に8ドットが1バイトとなっていて、アドレスを+1すると右の8ドットへ移動していく。この仮想VRAMの構成では(どちらかと言えば)横スクロールの方が得意だ。

 

縦方向にドット単位にスクロールするということは、縦方向の連なる32ドット(つまり4バイト分の情報)を上方向にシフトする必要がある。

f:id:PocketGriffon:20210811095023j:plain

いきなりプログラムコードを載せてしまうが、これで32ドットを上方向にスクロールさせている。大きく3つのブロックに分かれていて、上ブロックが「画面下側16ドットの上スクロール」、中央が参照する仮想VRAMのアドレス更新、下ブロックが「画面上側16ドットの上スクロール」だ。

 

下16ドットは「lsrd」で16ドット分を一気にシフトしている。この命令でMSBには0が入り、LSBにあったビットはCarryフラグに移動する。

 

そしてこれ以降はCarryフラグが更新されない命令のみで構成されている。中央にある「deca」は仮想VRAMのアドレスを16ドット上に更新している(意味が伝わるかな?)。

 

上16ドットも同じように「lsrd」で一気にシフトしたかったのだが、この命令はCarryフラグを含めたシフトをしてくれない。しかたなく「rora」「rorb」で8ビット単位にローテイトしている。「rord」という命令があったら楽だったんだけど、どうやら存在しないようだ(T-T)

 

この一連の操作を、ゲーム画面の横幅分してやれば、ゲームフィールド全体が1ドット上にスクロールする。速度的に大丈夫だろうか?と思ったが、動画を見てもらったら分かる通り、まぁ許せる範囲の速度となっている。全体の速度に直結する部分なので、もっと良い方法があったらぜひ採用したいところなのだが…。

 

一番下にドットを埋める方法は、仮想VRAMに$80をORしていけば良い。

f:id:PocketGriffon:20210811102418j:plain

またしてもプログラムコードを載せてしまうが、6301には「oim」という命令が存在する。これはレジスタを介さずにメモリとOR演算をしてくれる便利な命令だ。「Or Immediate Memory」の略なんだと思うけど、私は親近感を持って「おいむ」と呼んでいるw

 

6301のインデックスアドレッシングでのオペランド指定が少しややこしい。

Z80や6809では符号付き8ビットの値として扱われるのに対して、6301では符号なし8ビットとして扱われる。他のCPUに慣れた人ほどハマる問題かと思う(案の定ハマったw)

 

キー入力

実はこの部分のみ、メモリ中にあるワークエリアを参照している。HC-20とHX-20とで互換性は保てるのか…と心配になったが、解析してみた結果(たまたま?)同じだった。

f:id:PocketGriffon:20210811103122j:plain

RAMの$0145から上記のキー情報が入っている。資料などを見ると「ROM内ルーチンのKEYSCN($FF6A)を呼び出すと、このメモリにセットされる」と書いてあるのが多いけど、実際には割り込み処理などでここにデータが格納されているようなので、いきなり読んでも大丈夫。

 

あと実装するべきは…

あとはプレイヤーと壁の衝突判定(仮想VRAMのドット情報を見れば良い)、スコア加算&表示、そしてゲームのシーケンスを組み立てたら遊べるようになるかな? もう少し頑張ってプレイヤーの爆発アニメ、サウンドなどを入れたら完璧かも?

 

そこまでの気力&時間がないので、今回はここまで!とする!(一方的w

 

勝手なHC-20総評

正直、HC-20に取り組む前までは「614kHzで動いてる6301CPUでどこまで出来るんだろう…」という不安が大きかった。大好きなEPSON機といっても、HC-40/HC-80とは世代が違うため、内部構造も大きく違うと想像していた。

 

実際に使ってみるとHC-20は本当に良く出来た構造だと感じた。特に感心したのは、この時代において互換性の事を考慮した作りになっていた事だ。実際のROM内ルーチンのアドレスがずれても平気なように、(オーバーヘッドを覚悟した上で)固定の場所を用意したのは素晴らしい。おかげでHX-20との互換性も保たれている。

 

HC-80の時に取り組んだ6301とは一味違った感覚でコードを書けた。HC-80の時は「メインCPUの先にあるモノ」だったので、小さな穴から覗き見をしながら機嫌を損ねないように扱うイメージだった。だけどHC-20はメインCPUが6301だったので、もはややりたい放題だw

書いたコードがダイレクトな動きとして見られる安心感はすさまじい。

まぁこれはHC-80で苦労していたから感じた感想かも知れないw

 

やり残し

やり残した事が1つある。あるけど実際にやるかどうかは分からない(どっち

HC-20はサブCPUにも6301が積まれている。感覚的には6809を2つ積んでいるFM-7などと良く似ている。FM-7などのように脚光を浴びていないのがちょっと残念だ。

 

メインCPUからサブCPUへはSNSCOM($FF19)というROM内ルーチンを介してやりとりをしているのだが、このコマンドが100以上にも達する。その中に「サブCPUのメモリへデータを読み書きする」「サブCPUの実行を指定したアドレスに移す」などの楽しそうなコマンドがあるのだ!

 

大した意味もなく「サブCPUにプログラムを送り込んで実行する」をしてみたいw 誰得な実験にはなるんだろうけれど、HC-20での残された興味はココに集結してるかも!

いつか気が向いた時にチャレンジしてみたい(^-^)

 

補足

今回に限り…だけど、中途半端なゲームでもいいからソースを見てみたいという方がいたらお送りしたいと思う。全てのファイルではなく、あくまでもゲーム本体のみ限定。

しかも特殊な環境でしかアセンブル出来ないので、注意して欲しい。

アセンブラが特殊(自作してるので他のアセンブラでは通らない可能性が高い)

・環境として完結していないので、動くバイナリを得るために努力が必要

・HC-20へRS-232C経由で送り込む環境が必要

・多分増設メモリは必要ないと思うけどテストはしていない

・HX-20でのみテスト済み、HC-20でも動くとは思うけど実験していない

・6301初心者のコードであり、全く参考にはならない

 

要するに手元でアセンブルするためには、相応の知識と手間と根性が必要という事だ。

こんな中途半端なものでもいいよ…という稀有な方は、TwitterのDMでご連絡くださいw

2021年8月中のみ対応します(^^)

 

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

HC-20を使う その5

f:id:PocketGriffon:20210809193025j:plain

先日のHello Worldから1日、ようやくグラフィックスが表示出来るようになった!

想像以上の複雑さに音を上げそうになった(^^;;

しれっと何も無かったことにして次のマシンに行っちゃうのもありだったけど、もう少し6301を楽しみたかったので年甲斐もなく奮起してみた!

 

グラフィック描画のヒントがない!

先日からOh!HCを片っ端から調べて、ROM内ルーチンの情報や解析情報などを読みまくった。解析情報の多さはさすが専門誌と言ったところか!

ほぼ全ての情報が網羅されていると言っても過言ではなかった!

これだけ情報あったら困る事ないじゃーん!

……そう思ってました(T-T)

 

そしたら…グラフィックスに関係する資料を見た事がないと気がついた!

Oh!HC誌上では「SGS-sys6」という、BASICを拡張してグラフィックス描画が出来るシステムで盛り上がっていて、大半のソフトがそれを使って絵を表示していたのだ。

f:id:PocketGriffon:20210809200148j:plain

そのSGS-sys6のソースリストがあれば良かったんだけど、どうも見つけられない。私の探し方がダメなのか、所有していない号に載っているのかはっきりしないけど!

 

それ以外にグラフィックスについて細かく書かれた資料を見つけらなく、どうやって画面に絵を出したら良いのか、方法がさっぱり分からない…。

 

そういえば昔、I/OにHC-20用の「BUG FIRE」というゲームが掲載されていた気がする!しかもマシン語使ってたぞ!ソースは載っていなかったと思うけれども、もしかしたらプログラムの説明などで解説が載ってるかも知れない!そう思ってI/Oを探しまくった!(ToT)

f:id:PocketGriffon:20210809200333j:plain

ようやく探し当てた1983年8月号!

読んでみたけど「画面のスクロールはシフトではなく仮想画面からの…」という説明のみで、アクセス方法については書かれていなかった…orz

ぐぬぬ、残念…

ちょっとだけヒントあった!

Oh!HCをよーく読み込んでいくと、LCDについての記述があるのを見つけた。

f:id:PocketGriffon:20210809201012j:plain

f:id:PocketGriffon:20210809201031j:plain

どうやら「コマンド」と「データ」の設定があるらしい…けど、肝心のコマンドリストは??

そしてなんとなく使うべきROM内ルーチンは想像出来るんだけど、使い方(エントリ時のレジスタ設定など)が書かれていない。うーん、情報が足りない(T-T)

解析していくしかないんだよなぁ…。

 

HC-20のLCD関連

結局、HC-20のROMを解析するのが一番!という結論に至った!

表示周りを中心に解析したので、分かってきた事をきちんとまとめてみようと思う。

かなり複雑な作りになっているので、頭がこんがらがらないようにしたい。

この先、HC-20でプログラミングしようって人が現れるかも知れない(!?)ので、その時の資料となるべく情報を残していこう!

 

HC-20にはμPD7227GというLCDコントローラが6つ搭載されている。

f:id:PocketGriffon:20210809204829j:plain

それぞれ#0〜#5となっているが、実際にレジスタに値を載せる時は1〜6になる。

1つのLCDCには「40ラインx8ドット=40バイトを1つのバンク」として「2つ分のメモリ」を持っている。つまり横40ラインx縦16ドットの領域だ。

そして両方のバンクへの同時アクセスは出来ない。

このLCDCが横に3つ、縦に2つ繋がっていて、表示領域の120x32ドットを形成している。

 

プログラムからどのLCDCにアクセスをするのかを決めるのが、HC-20のポート26に出ている設定。このポートでは「どのLCDCにアクセスをするのか」と「コマンドを書き込むのか、データを書き込むのか」を選択する。

f:id:PocketGriffon:20210809210144j:plain

ここのポートは他にも割り込み系や拡張カートリッジ系の機能が入ってるようなので、直接アクセスするのは危険。ROM内ルーチンWRTP26($FED4)があるので、これを利用する。

 

μPD7227のコマンドリストは以下のようになっている。

f:id:PocketGriffon:20210809215609j:plain

英語で書かれていたμ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の片方のバンクにデータを書き込む。

f:id:PocketGriffon:20210809204829j:plain

↑の図で言うところの「#0 BANK 0」にデータを埋められると思ったら良い。

つまり画面全体を更新するためには、同じことを12回繰り返さないといけないのだ!

 

とっても面倒だったので、テーブルを作ってこれを参照しながら書き込むことにした!

f:id:PocketGriffon:20210809223406j:plain

6301にはインデックスレジスタがあってオフセット指定ができるので、こういう構造体的なデータ構造はとても作りやすい!(^-^)

 

f:id:PocketGriffon:20210809230249j:plain

 

ついでだったので、スクロールさせてみるテストもしてみた。

 これはウェイトも何も入れていない、最高速で動かした状態だ。スクロールは単純なメモリコピーであり、工夫も何もしてないので、慣れた人が書いたら倍速間違いなしw

 

今回作った全画面表示プログラムは、おそらくHC-20でもHX-20でも動くはずだ。

この先もどちらでも動くことを意識しながらプログラムせねば…と思った!

とりあえずひと仕事終えた感じw

 

未定義命令実行で停止した!

ちょっと番外編的な話だけど、この画面を見て欲しい。

f:id:PocketGriffon:20210809225409j:plain

アセンブラのバグを踏んづけてしまって、未定義命令が出力されてしまったのだが、見事にその命令を実行する時にTrapで停止した!

Pにプログラムカウンタの場所が表示されてるので、デバッグがとても楽ちんだった!これは便利機能!(^-^)

 

これは6301CPUに備わっている機能。未定義命令を実行しようとすると、このようにトラップが掛かるのだ。デバッグ時に使えていいかもなぁ…と思っていたけど、このタイミングで発動するとは(^^; ちょっとおもしろかったのでご紹介してみた。

 

通信環境その後

その後の通信環境だけど、転送速度を300bpsから4800bpsへ上げて使えている。

1バイト送るたびに入れていたウェイトは10ms→4msに減少。

この辺りが限界かも。3msにするとIO エラーが出てしまった!

そろそろバイナリ転送プログラムが欲しくなってきますねぇ……(遠い目

 

さて、今回はもう少しだけ頑張ってみる気になってるよ!

久しぶりの6301は楽しいです!(^-^)

 

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