Wio TerminalでCP/M80を動かしてみた!

Wio Terminalで遊んでみた第2弾!(^-^)

今回はCP/M80を動かしてみたよ!

f:id:PocketGriffon:20220315105729j:plain

 

先日、Wio Terminalで何かを作ろうと思いつつ情報を探していたら、USBキーボードが繋がるっぽい記述を見つけた。

Keyboard - Seeed Wiki

へ??キーボードが繋がるの??USBの??

……どうやって??(@_@;;

 

Wio Terminalはバッテリーを積んでいないので、USB TYPE-Cを引っこ抜いた瞬間に電源が落ちてしまう。電源を確保したままキーボードを繋げようとしたら、電源供給のついたUSBハブとか使うんだろうか…?? …謎だ(-_-;;

 

そんな事を思ってスイッチサイエンスのページをみたら、バッテリーが発売されていた。そうか、そういう事なのか…と、ひとり納得(^^)

それで前回のブログでバッテリーが…みたいな事を書いていたのだ!

www.switch-science.com

急ぎバッテリーベースを入手したので、キーボードを使った何かを作ってみようと検討した結果、CP/M80を移植してみる事にした!(^^)

ええ、ワンパターンですよ、はい(T-T)

 

移植検討

移植に関してはM5Stackで動かしていたものをベースにしようかと考えていたが、メモリの都合で構造が大きく変わりそうだったので、オリジナルのMac版を移植する流れとした。

f:id:PocketGriffon:20220315135102p:plain

Macのオリジナル版はこんな感じ。今回の移植をやりやすくするために、cursesベースで動いていたものをSDL2で動くように改造した。

 

メモリ

CP/M80を移植する場合、メモリ的に大きいのはZ80のメインメモリ64KBくらいだ。エミュレーションでもたいしたメモリは使わないので、この点は問題なさそう(^-^)

 

ディスク

サイズの大きな仮想ディスクをどうするか。

オリジナルのMac版では、ディスク全体を大きなメモリにどーんとロードしていていたが、Wio Terminalのメモリ事情でそれは無理だ(T-T)

 

そこでWio Terminal版ではディスクのファイルはSDカードへ置いたままにしておき、メモリ中には1セクタ分(128バイト)のバッファを持つ事にした。

同じセクタをアクセスしている間はSDカードの読み込みは無く高速に処理される。

書き込みがあった場合にも、別のセクタをアクセスされた際にSDカードへ書き戻すようにした。

読み込み速度がだいぶ遅くなるのでは…と思ったが、エミュレータの速度も速くないので気になるレベルではなかった(^^)

 

表示

Mac版では内部に仮想スクリーンを保持していて、VT100サブセットの機能を自前で書いていた。これをそのまま移植する事で、内部的には80x24の画面を扱う事が出来る。

Wio Terminalは画面サイズが320x240ドットと、縦方向が30行確保できそうだったので、少し拡張をした。#define定義を変更するだけね(^^)

 

この仮想スクリーンはZ80のメモリ上に置かれていて、CP/M80からもバンク切り替えをしてアクセスする事が出来る。何か面白い使い道があれば…と思って実装してあるんだけど、今のところは宝の持ち腐れだ(^^;;

 

液晶への表示はLavyanGFXのスプライト機能を用いている。320x8ドットの大きさを持つスプライトに文字フォントを書き込んで表示。文字が書き換わったラインのみを描画対象にすれば、表示も最小限で済むはずだ(^^)

f:id:PocketGriffon:20220315140854j:plain

↑開発中はこんな感じに色つけたりして分かりやすくしてたw

 

実装していくよ!

まずはCP/M80本体を移植していく。今回のWio Terminalで動かすためだけにオリジナル版をSDL2対応したのだが、その時に移植しやすい構造にしておいた。

 

基本的には「あるものは消さず、呼び出さないだけ」という感じにしていく。どこからも呼ばれていない関数はリンクされないので、メモリ的な無駄になることはない(^^) 消しちゃった後に必要だって分かったら復活させる(コピーして持ってくる)の面倒だし(T-T)

 

Z80エミュレータが動き出せば、CP/M80起動にともなって仮想スクリーンに文字情報が出力される。それをメモリダンプで目視したのち、表示系を実装していく。

……が、その前にそろそろ肝心のUSBキーボードを動作確認した方が良さそうだ!

 

USBキーボードの実装

この手のハードを何度となく扱ってみて理解したのは、対象となるハードのみを使ってる場合はちゃんと動いても、それとあわせて別のもの(例えばSDカードなど)を触ろうとすると、うまく動かない可能性があるって事だ(T-T)

 

今回の場合、SDカードがそれに該当するかも知れない。ハード屋さんから見たら「え?ぶつかってないから大丈夫だよ」で済む話なのかも知れないけど、その辺りの事情を理解できてない人から見たら疑うべきところが山程ある(^^;;

 

今回はハードの競合でハマるところは無かったのだが、以下ハマり道的なお話(^^;

f:id:PocketGriffon:20220315123033j:plain

サンプルにあったこの一連の初期化処理、一気にコピーしてもってくれば良かったものを、動作確認を1つずつ進めていた関係で、delayの上、delayの下とコピーしていた。

で、どうやらこのdelay(20)に大きな意味があるとも気が付かず、USBキーボードの初期化が進まなくてとてもハマった!(T-T)

 

きっと何かハードの準備を待つとか、USBキーボードからの返事を待つとか、そういう意味で重要なdelayだったんだろうけど、理屈とセットになってないので理解が及びにくい(T-T)

delay(20)を入れたところで、ようやく安定してUSBキーボードが動くようになった!

 

USBキーボードのテストには以下のような手順で行っている。

コツというよりは手順?が必要なんだと思われる。

 

f:id:PocketGriffon:20220315132831j:plain

↑バッテリーベースを取り付けたWio Terminalを用意。

この状態で、バッテリーベースの底面にあるスイッチを押して通電スタート。この底面にあるスイッチ、ものすごーく押しづらくないですか??(T-T)

f:id:PocketGriffon:20220315133441j:plain

この(↑電源が入った)状態で、開発のホストマシン(私の場合はMac)に繋がっているUSB TYPE-Cケーブルを繋げつつ、本体左のスライドスイッチを2回下にスライド(ブートローダー)。

 

f:id:PocketGriffon:20220315133812j:plain

ホストマシンからプログラムを書き込むと自動的に実行が始まる。
↑の写真では、CP/M80が起動してるけれどキーボードの初期化で停止してる。

 

この状態でおもむろにホストマシンと繋がってるTYPE-Cを外し、キーボードを繋げる。

電源はバッテリーベースから供給されているので、電源はついたまま。

f:id:PocketGriffon:20220315134210j:plain

キーボードを繋げたら、本体左にあるスライドスイッチを下へ動かしてリセット。

これでキーボードが認識されて打ち込めるようになる。

 

開発中は毎回これをやるのが面倒なので、キーボード有り版とナシ版をビルドで切り替えている。キーボードなしの場合は、プログラムで生成した文字列を自動的に入力して動作確認を行うようにした(例えばmbasic asciiart[RET]と入力された風に振る舞うなど)。

 

USBハブを取り付けた状態でのテストもしてみたかったが、今回はチャンスもなく出来ていない。この先、取り組む機会があればぜひ試しておきたい!

 

表示系

今表示されているのはPC-8001のフォントを拝借した(ごめん)。

8x8ドットフォントなので、320x240ドット = 40x30キャラクタの表示が出来る。

 

だがCP/M80は横が80キャラクタあることが望ましいと思えるようなプログラムがたくさんある。特にゲーム系では画面が崩れる(T-T) 大好きなスタートレックをちゃんと表示させるためには、どうしても横80文字が必要だ!

f:id:PocketGriffon:20220315153820j:plain

というわけで、横を4ドットに縮める表示も行うようにしてみた。

このCP/M80は内部的に横80キャラクタの仮想スクリーンを持っているので、表示さえ工夫すれば実現出来る。

 

横4ドットフォントについては、元フォントを機械的に縮めてみた。横2ドットを1ドットに変換するのだが、カラーが使えるので両方ドットがあれば白、片方だけなら灰色、ドットがなければ黒という感じで変換した。

f:id:PocketGriffon:20220315142522j:plain

元からこういう文字が書かれている…と知っていれば、なんとなく読めるレベルかなww

本体上部にある3つのボタンでスクロールさせてみようかと思っていたけど、これだけ読めればいいやってなった(^^;;

 

フォント描画は結構頑張ったので、切替速度は速いと思う!

 

気になってるところ

ここはもう自分の備忘録なんだけど…いくつか気になったことがありまして(-_-;

 

USBキーボードは英語配列が基本らしい。私は普段遣いが英語キーボードだが、外付けの英語配列キーボードを持ってなかった。

日本語配列に切り替えられるかな…と思ってあれこれ探してみたけれど、見つけられず。

今後のことも考えて手に入れておきたい。

 

無線で繋がるキーボードも試してみたい。Bluetoothじゃなくて(^^)

電流的?電気的?に繋がるのかわからないけれど、無線で繋がったら相当ラクな気がする(^^)

 

あと……ここんとこずーっと気になってる事が……

それは……Z80のエミュレーションコアが遅い!(T-T)

FM-7(6809)は2つのコアを動かしても実機よりも速く動くくらいなのに、Z801コアで速度が出ないのはどー考えてもエミュレータの実装が良くない気がする…。

今使ってるZ80コアは私が1990年代前半に作ったもので、当時の環境にあわせられている。最新の環境でパフォーマンスが出る道理もないので、今にあわせて作り直そうかなぁ…。

 

うーん、今年のどっかで頑張る(^^;;

 

終わりに

CP/M80は何度と無く移植したり開発したりしているけど、環境が出来上がるたびに「コレは使えるかも!遊べるかも!」という感覚がある(^^)

 

自身が初めて触れたOSということもあるんだろうけれど、思い入れがある分、どんなマシンで動いても嬉しいものは嬉しいね!

 

なんとなくCP/MFM-7X68000は移植ベンチマーク的な役割になりつつあるけど!(-_-;

 

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