RaspberryPi Picoで液晶パネルを使う!

f:id:PocketGriffon:20211124075841j:plain

今から1ヶ月以上前、RaspberryPi Picoに小型の液晶モニタを取り付けて、PC-8001エミュレータを動かすということをやってみた。

 

あれからもう1ヶ月以上も経つのか…と驚きを隠せない!(^-^;

 

扱った液晶パネルが240x135ドットということもあり、画面解像度的にはPC-8001が限界でそれ以外の機種はPC-8801を試す程度で終わっていた。

どちらかといえばPicoの性能よりも液晶サイズの問題が大きくて、もっと大きな液晶が繋げられたらチャレンジしてみたい事はいくつかあるなぁ…とか思ってた。

 

そしたら!

先日なにげに秋葉原マルツ電波に行ってみたら、Pico用の大きなモニタが置いてあった!

f:id:PocketGriffon:20211124080617j:plain

え!?こんなの出てたの知らなかった!!!

この前、Picoを5個セットのシート買いしてしまった事もあり、Pico本体には余裕がある。

使い方その他が全く不明なままだったが、えーいままよ!とばかりに衝動買いしてしまった(^^;;

 

とりあえず動かしてみたい!

手に入れたからには、カタチはどーあれ動かしてみたい!

まずはPicoを取り付けるところから始める事に!(^^)

f:id:PocketGriffon:20211124082626j:plain

Picoにピンヘッダをはんだづけし、液晶パネルの裏側にあるソケットに挿し込む。

これだけでOKらしい!

あとから気がついたけれど、SDカードも入れられるようだ。これは便利!(^^)

 

何年か前だったら「ピンヘッダをはんだづけ?無理ムリ!」って感じに諦めているところだけど、ここ数年ははんだづけに対する敷居がどどーんと下がっていて、こういう楽しげなモノにもチャレンジ出来るようになったのは喜ばしい(^-^)

 

さて……物理的に繋がったは良いけれども、これってどうやって制御するん??(@_@;

知識情報その他が全くない状態で手に入れてしまったので、正直困った!

 

 

ここのサイトに商品に対する情報がたくさん載ってた!

ここの「Resources」タブにサンプルプログラムも置いてあった。これは助かる(^-^)

さっそくダウンロードして、試しにビルド環境を作ってみた。以前作った環境も使いやすいとは到底言えなかったが、そこに入れるカタチになるのでさらに使いにくく…汗

 

そして動かしてみたところ……

f:id:PocketGriffon:20211124092456j:plain

画面は表示されたけれども、更新速度がめちゃくちゃ遅い…。全画面書き換えに0.5秒くらい掛かってる気がする。あれれ?そういうモンなの??

この速度だと頻度の高い画面更新を必要とするものは作れないな…

 

そんなこんなで悪戦苦闘していたところ、あお氏(@hd61yukimizake) から

Arduino IDEでRaspberryPi Pico の開発環境が構築出来る事を教えてもらった!

なんと!そんな便利なことが出来たなんて!!

tomosoft.jp

そしてST7789(今回の液晶パネルの型番)のライブラリも存在する事が判明!

これは勝つる予感!!(^-^)/

 

……と、だいぶ楽観視していたのですが、実際に試してみると全く動かず(T-T)

そして動かなかった時に、何も出来ない自分が居た…orz

 

うーん…これは(T^T)

そもそもSPIってなんだろ?GPIOじゃなくて?(こういう混同も普通に起きてる)

何をどうしたらこうなってるのかがさっぱり理解できてない…。

 

これはもう……理解するために作るしか無いでしょう、最初から!!!

 

無謀な挑戦!

使ったこともない液晶パネルのドライバを作るなんて、そんな壮大な事が出来るはずがない。

私の使い方限定で良いので、自分自身が使いやすければいいや的な発想。

私が作るものと言えばエミュレータ系が多いわけで、そうなると「フレームバッファの内容をLCDへ送り込めれば良い」という事になる。

ドライバというよりは、ライブラリ群だ。

よし、これのみに限定して動くものを作ってみよう!

 

幸い、速度は速くないけれども動くサンプルが手元にあったので、これを元にLCDの初期化ルーチンを組んでいく。

SPI通信というものを根本的に理解しているわけではないけれども、サンプル的なものがM5Stack環境にもたくさんあったため、似たような感じで実装していった。

 

f:id:PocketGriffon:20211124101329j:plain

サンプルが置いてあったサイトにST7789のデータシートへのリンクもあったため、それとサンプルプログラムをにらめっこする事数時間、ようやく画面に矩形が表示出来た!

この段階では、画面の左下が起点となっていて、気持ち的には横方向に200ドット、縦方向に100ドットの青い矩形を書いたつもりが、こういう(回転した)カタチとなって表示された。

 

青い矩形以外のノイズみたいなモノは、おそらく電源入れた際のメモリ内容がそのまま表示されてるもので、初期化しない状態はこんな感じに見えるようだ(^^)

 

その後、ネットから画像を拾ってきて(ごめんなさい!)適当に表示させてみた。

f:id:PocketGriffon:20211124102016j:plain

これはjpegファイルを表示しているのではなく、jpegファイルを外部ツールで都合の良いデータ形式に変換し、そのままプログラム内に組み込んだ。

同時にLCDの初期化部分を変更して、画面の左上が起点となるようにする事が出来た!

これで脳内のイメージと映像の方向が合致した(^-^)

 

そして気になる画面更新速度は、当初のものよりも約10倍速となり、秒間20回以上書き変えることが出来るようになった!

それでもM5Stackに比べるとだいぶ遅いんだけど、そういうモノかしらん?

PicoのCPU速度をオーバークロックしてみても更新速度は速くならなかったので、現状のプログラムでは限界なのかも知れない。

 

よーし、とりあえずここまで動いたら何か作ってみるよ!

タッチパネルやSDカードへの対応とかはまーったくしていないけど、必要になったら取り組もうかな…うん(-_-;;

 

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

SMART Response XEを使う!その4

f:id:PocketGriffon:20211120104258j:plain

SMART Response XEでプログラミングを続けてる!

でもそろそろ区切りをつけようと思っているので、取り組んだことをご紹介。

 

XEのCPUであるAVRは、8bit長レジスタ構成になっていて16MHz駆動らしい。

そして多くの命令が1クロックで実行できるっぽい。

ということは、ざっくりとZ80で換算したら64MHzくらいの速度になるんだろうか?

もっともAVRの命令自体がRISCなので、Z80の1命令=AVRの1命令とはならない。

その辺りを鑑みたとしても、感覚的な速度は意外と速い。

 

SMART Response XEでどんなものが動くんだろうか?

思いつく いくつかの実験を繰り返した。

 

Bad Apple!!

私と言えばBad Apple!!??

そういうつもりでは無いのだが、大容量データ、データ転送速度、圧縮データの展開速度、画面更新などをまとめて試すには良い題材なのだ!(^^)

 

絵のデータについては最初から全部入れるのを諦めていた。

PC-1600Kのサイズ(64x32ドット)ですら全データで884KBもあるシロモノなのだ!それよりも画面サイズの大きなXEで、かつFLASHメモリは128KBしかない。

 

試してみたところ、配列を格納しているデータサイズが32KBを超えたところでエラーになってしまうようだ。アドレッシングの問題かも知れないが、どうもそういう仕様なのだと思う。32KBに分割したデータをいくつか持てば良いのだろうけれども、そのデータをアクセスするプログラムコードはちょっと面倒になる。

 

結局、32KBに収まるだけのデータ(100枚)で気持ちが萎えてしまった(^^;

FLASHに置いてあるデータから読み出す」→「圧縮データを2ビット1ドットのデータに展開する(ランレングス圧縮されている)」→「2ビット1ドットのデータを、8ビット3ドットのLCDデータに変換しつつ転送」という面倒な事をやっているにも関わらず、それなりの速度で動く。立派にアニメーションして見えた。

結構速いよ、AVR!(^-^)

 

8色表示+三角形描画

当初の予定では、立方体(ポリゴン)を描画してグルグル回そうと考えていた。

フラットシェーディングにしようと思っていたので、色は多い方が良いだろう…と思い、4色のデータをタイリングする事で中間色っぽく表示させてみた。

f:id:PocketGriffon:20211120111732j:plain

……それっぽく見えない!?(^-^;

拡大してよーくみてみると、タイリングになっていることがわかるはずだ。

これを利用して、正面を向いている面(面の法線ベクトルの向きで判断)は白、横に向くごとに色を黒くしていけば、それっぽく見えるはずだ!

 

この上に2次元の三角形を描画するプログラムを載せてみる。

f:id:PocketGriffon:20211120112055j:plain

三角形を描画してくれるような便利な関数は存在しないので、自前で書いている。

昔書いたコードを利用しているのだが、日付を見たら2003年になっていた。

 

そしてこの上に3次元計算をするコードを載せていくわけだが…

これも同じく2003年に書いたコードを流用してみたのだが、ARMが載ったマシンを対象としたプログラムだったため、一部レジスタが32bitである事を期待したコードになっていた。これを8bitレジスタのマシンに移植するのは…うむむ結構骨が折れる(T-T)

 

結局、計算精度の問題、巨大な除算テーブルが乗せられないなどがあり、うまく移植する事が出来なかった。

仕方ないので三角形を回して終了となったw

 

試しに三角形を3枚表示するようにもしてみたが、意外にも速度が出てる。

やっぱりAVR速いよね?!

 

PC-8001エミュレータ(未完)

やっぱチャレンジしてみないとなぁ…と思い、途中までコードを書いていた。

結果的にいえばメモリが足りず動かす事が出来なかった(T-T)

 

ROM動かそうとするゲームプログラムなどはFLASHへ置くようにしていたのだが、PC-8001のRAM自体が16KB必要なこと、これを部分的に分割して持つようになど省メモリ化をしてみたのだが……

 

無理と判断する決定打となったのが、エミュレータのプログラムが入らない事!(T-T)

データは頑張ったら省メモリ化する事が出来そうだけど、プログラムコードを小さくするのは並大抵ではない…。ビルドも最後まで通らずあえなく撃沈(T^T)

 

コレで終わり?!

なんとなく一連のやってみたい事が終わってしまった…(^^;;

まとまった動くものを作りたいというよりは「このハードでこんな事したらどうなるんだろ?」的な実験ばかりしているので、最終的に残る成果がない(-_-;

 

せっかくなので日本人らしく花札こいこいとか麻雀とかのソフトの1本でも作ってみたいところだが…その辺りのやる気スイッチが入るのは当面先になりそうだ(T^T)

 

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

SMART Response XEを使う!その3

f:id:PocketGriffon:20211118081632j:plain

SMART Response XEでプログラムを組める環境が整い、いくつかのコードを書いてみた。

ある程度作れるようになってくると、今度は「どうやったら速いコードが組めるのか」「何をしたら遅くなるのか」が気になってくる。

レトロプログラマたるもの、常にコードサイズと速度は気にしておきたい(^^)

 

SMART Response XEのCPUは?

Arduino IDEを利用することもあり、てっきりCPUはARM系の何かかと思いこんでいたら、どうやらAVRというらしい。恥ずかしながらAVRというプロセッサを知らなかった。

おそらくCPUと周辺機器を含んだチップになってるんだろうと勝手に想像。

 

どんなCPUなんだろうな〜…と思い、データシートを調べてみたら……

f:id:PocketGriffon:20211118084635j:plain

なんとレジスタ長が8bitのRISC CPUだった!!

30年近く前に同じく8bitレジスタRISC CPUを扱った事があったけれど、またしてもこんな楽しそうなCPUに巡り会えるとは!!(^-^)

 

これを見る限りXYZは16bitのレジスタペアとして使えそうだけど、実際にはこのレジスタだけでなくペアで使う事が出来るっぽい。XYZレジスタを用いることで、一部の命令が便利に使えるみたい?

RISCプロセッサらしく割り切ったアドレッシングのみとなっている。

XEはこのCPUが16MHzで動いているらしい。

 

アセンブラコードを見てみたい!

CPUの素性が分かってくると、今度はどんなコードが出力されているのかを見てみたくなる衝動に駆られる!そりゃそうでしょう!(^-^)

 

Arduino IDEから呼び出されているコンパイラはavr-gccという。

f:id:PocketGriffon:20211118091338j:plain

avr-gccコマンドの置かれている場所(パス)は、Arduino IDEでビルドした後にウィンドウ下側(赤で囲った部分)に出力されているログを解析すれば良い(^^)

 

パス/avr-gcc -S p.c

これでp.cのアセンブラリストを見ることが出来る。

 

unsigned char func(unsigned char a, unsigned char b, unsigned char c)
{
  return a + b + c;
}

このソースリストが……

f:id:PocketGriffon:20211118092457j:plain

こんな風に変換される。

おそらくR24:a、R22:b、R20:cという感じで引数が渡り、戻り値がR24に入るのだろう。

 

この例では8bit長の値を渡しているが、これをint長(sizeof(int) == 2)で渡してみる。

 

int func(int a, int b, int c)
{
  return a + b + c;
}

f:id:PocketGriffon:20211118093110j:plain

わかりやすくコード部分のみ抜き出してみたが、8bit長ならば2命令で済んでいたところ、int長にしたら倍の4命令となった。

 

avr-gccのint型は16bitサイズであり、8bitレジスタのAVRではこのような結果となる。

同様な事はZ80でSDCCやLSIC80といったコンパイラを使った時にも起こり、int=4/8のCPUと比べて、より一層の意識が必要となる……気がする(^^)

 

ちなみにアセンブラリストを見るのはavr-objdumpでも可能だ。

しかし最適化が強烈に掛かるせいかソースと混在表示させると非常に分かりづらい。AVRアセンブラに慣れている方ならまだしも、私のような初心者では逆に解析がしづらい気がする。

 

処理時間の測定

書いたコードが速くなったのか遅くなったのかを知りたかったので、処理時間を測定する方法を調べてみた。

……と思ったら、すでにM5Stackなどで試した方法と同じだった!(^^;;

micros()を呼び出すと、その時の経過時間を返してくれるので、それを利用する。

戻り値の単位はマイクロ秒で、1000でミリ秒、1000*1000で1秒だ。

 

例の1バイト4ドット構成のフレームバッファから、データ変換しつつLCDCへ転送する関数に掛かる時間を図ってみたら55916マイクロ秒だった。つまり55.9ミリ秒。

ということは1秒間で17.9回の画面更新が出来るって事ね。

もう少し速くしておきたいけれども、これはあとの楽しみ…(^-^)

 

C言語で気をつける点など

C言語で記述する際、気をつけている点などを書いてみようと思う。

あくまでもAVR-CPU限定の話だ。

実際には最適化は最後の最後で良いと思うし、動けば正義!とも言えるので細かい点は気にしなくても良いとは思う。究極の最適化は趣味レベルでやりたいけど!(^^)

 

intが16ビット

↑にも書いているが、sizeof(int)は2であり、16ビット長となっている。

AVRのマシン語的には8ビットサイズが一番扱いやすいので、もしも数値が8ビット長に収まるのであれば積極的に使っていきたい。

派手にやりすぎると融通効かないコードになるし読みづらくなる!

あくまでもここぞ!ってコードに適用していきたい。

 

mul命令が使われない?

マシン語レベルでは存在する乗算命令(mul)なんだけど、8ビット同士の乗算(a * b)をしても乗算命令が出力されない。乗算関数を呼び出すコードが出てしまう。呼び出された先ではmul命令が使われているんだと思うけど、CALLする分もったいなく感じる…。

 

ループの奥の方では乗算命令を使わないアルゴリズムを検討した方が良さそうだ。

もっとも、私のコードの書き方が悪いのかも知れないが…汗

 

除算命令がない

AVR自体、マシン語レベルでの除算命令が存在しない。

以前、Raspberry Pi Picoでも同じ感じでハマったけれども、最近は意識してない事が多かったので油断大敵!(^^;;

 

シフト回数は1回ずつ

最近では複数回を一気にシフトしてくれる(バレルシフタを積んだ)CPUが多い印象があるけれども、AVRのシフト命令は1回ずつシフトする。

例えば3回シフトするプログラムを書いた場合には、きっちりと3回のシフト命令が出力される。4回になるとswap(上位下位の4ビットを入れ替える命令)が出るので最適化はされてるみたいだ!

ARMでプログラムを組み慣れていると、なんとなくシフトはタダみたいなもんのイメージで使ってしまう(^^;; 気をつけなくちゃ!

 

さて……

ここまで作れるようになってくると、なにかまとまったものを作ってみたい気もするけれども……いつものパターンだとここで……飽きる(^^;;

でも頑張って何かひとつ作ってみましょうかね…(遠い目

 

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

SMART Response XEを使う!その2

f:id:PocketGriffon:20211116175404j:plain

前回のブログで、SMART Response XEでプログラムを開発する準備が整った。

編集は外部のEmacsエディタ、ビルドと実機への書き込みはArduino IDE

ほんの少し前までは「これどうやるんだよ…」って感じの環境しかなかったのでモチベーションも上がらなかったけれど、ここまで環境が出来上がればコッチのもの!

なにはともあれ何か画面に表示させてみたい。

 

これまでSMART Response XEの解析をしてくれた方々が、素晴らしいライブラリを開発されていた。

GitHub - bitbank2/SmartResponseXE: Arduino library with LCD, Keyboard and SPI Flash support for the SMART Response XE classroom communicator

 

このSmartResponseXE.{cpp,h}を使わせてもらっている。

本来であればブート部分からプログラムを組まねばならないところを、このライブラリのおかげで相当ラクをさせてもらっている。

本当に感謝だ!(^-^)

 

画面にドットを打ちたいんだ!

この手のハードの多くはVRAMがLCDC側にあり、本体からはリニアに触れないものがほとんどだ。そして今回のXEも同じような構成になってる。

あんまり詳しい事は理解していないけれども…

・ドットを打つためにはデータを用意して…

・SRXESetPositionを呼び出して表示位置(と範囲)を確定し…

・SRXEWriteDataBlockを呼び出せば良い…

みたいだ。

単純明快!(^-^)

 

LCDはモノクロ4値のグレイスケール表示となっている。

普通に考えたら1ドット2ビット構成で、横4ドットが1バイトだろうか(^-^)

そう思って調べ始めたら……

……ちょっと待って(T-T)

 

f:id:PocketGriffon:20211116191752j:plain

………

f:id:PocketGriffon:20211116201034j:plain

3ビット3ビット2ビットの、1バイト3ドット構成!?

え?え?(@_@;;;

3ドット??

 

……どうやら図を見る限り、入力時は332の構成だけど、DDRAM(Display Data RAM)の中では222の構成になる……らしい?

あらやだなにこの変態仕様!(^-^)

謎パーの本領発揮って感じでタマランです!!!

 

…いろんな情報の理解が及ぼないけれども……とにかく入力は332が必要みたい。

横3ドットという時点でなんとなく計算に除算が入りそうな気がするのと、ドット単位で動かそうとするのとかめちゃくちゃ大変じゃないのさ、これ…汗

 

もうひとつ面倒な問題が。

このXE、液晶の解像度が384 x 136ドットある。

この手のマシンはメモリにフレームバッファを用意して、そのフレームバッファを書き換えた後にLCDCへ転送…という方法で使いたいんだけど…困った事にメモリが足りない。

SRAMのサイズは16KB、横を3ドットとして計算すると384/3=128、縦が136なので128 * 136=17,408バイト。

16KB超えちゃうじゃないのさ…orz

 

仕方がないので…こんな感じの構成にしてみた。

やはりドット構成は2ビット1ドット、つまり1バイト4ドットの考え方が使いやすい。

これならば384/4=96、136 * 96=13,056バイトでSRAM容量に収まる。

作るモノによっては画面全体をバッファする必要のないものが多いと思うので、その場合は適宜サイズを小さくすれば良い。

MAXで必要なのが12.75KB、と考えたらそこまで無茶じゃないかも?

 

そして横2ドット構成のフレームバッファを、表示する際にデータをDDRAMフォーマット(上記の332)に変換しながら転送してやればどうだろう…。

データ加工の利点は計り知れないと思うので、あとの問題は速度かな。

 

実際にそれで試してみた動画がコレ↓。

……思ったよりも速くない?!(^-^)

 

4ドット(1バイト)単位の横スクロール、ランダムサイズの矩形を描画、全画面再描画をしてこの速度。

コンパイラの最適化はしているけれど、アルゴリズムの最適化も何もしてない状態!

これは……なんとなく行ける予感(^-^)

 

いくつか表示実験をしてみる

メモリ上のフレームバッファにデータを書き込むことで絵が表示出来るようになった!

せっかくなので、なにか意味のある絵を出してみたい。

 

というわけで、私としてはワンパターンな花札こいこいの絵を表示してみた!

f:id:PocketGriffon:20211116211035j:plain

f:id:PocketGriffon:20211116211053j:plain

花札のカードデータは、工学社から発売されていたI/Oに掲載されていたMZ-80B用のゲームソフトからお借りした。MZ-80B用ということで、色は白黒の2色データだ。

液晶が繊細なせいか、とってもキレイに見える!

 

カードデータは32 * 48ドットのサイズで48枚あり、1枚が192バイトなので9,216バイトある。サイズ的にSRAMには載せられないのでFLASHに置いた状態にしつつ、必要に応じて1バイトずつ読み込んでいる。それでも十分な速度で表示してくれるのは頼もしい!

 

f:id:PocketGriffon:20211116211658j:plain

f:id:PocketGriffon:20211116211715j:plain

こちらは日本語表示テスト。

漢字ROMは、昔PC-8801MCから吸い出したものを利用させていただいた。

面倒なので漢字ROM全体をFLASHに置きたかったが、あいにくFLASHメモリのサイズは128KBしかなく断念。

テキストデータの中に含まれている文字データのみを抜き出してデータ化した。

こういうちまちましたツールを作る作業は面倒だけど大好きだ!(^^)

 

というわけで、フレームバッファに絵を描く事は出来るようになった!

今のところ、CPUの速度に助けられているところが多いけれど、AVRというCPUはどんなコードで動いてるんだろう…。

興味がそっち方面へ行きつつあるので、脱線しつつももう少しだけ触ってみたい。

X68000もMZ-2500も中途半端になっているので、近々戻らないとw

#マシンをセッティングしたままなので場所がない…汗

 

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

SMART Response XEを使う!その1

f:id:PocketGriffon:20211115180816j:plain

SMART Response XE……

このハードが出ている事自体を知らなかった。

どうやら海外の学校で使っていた端末らしい。どんな感じに使っていたのか調べてみようと思ったけれど、学校で利用されていた画像が出てこない。ハッキングの画像ばっかりがヒットする!みんなどうかしてる!!←お前が言うな的な…

 

というわけで、盛り上がってからだいーぶ遅れての参戦ですが、私も遊んでみようと思う(^^)

本体はeBayでまとめ売りしているものを購入してもらい仲間内で分けた。

 

ちなみに普通に起動するとこんな感じの画面が出る。

f:id:PocketGriffon:20211115182009j:plain

この先はネットワークに繋げて何かをやるらしい。2台あるので試してみようとも思ったけれど、その先が広がらないのでやめてしまった(^^;;

 

本体をひっくり返すと電池カバーが見える。それを外すとこんな感じ。

f:id:PocketGriffon:20211115183029j:plain

単4電池4本を使う構成だけど、なんとなく電池はすごく持ちそうな雰囲気。

あ、WiFi繋げたらそうでもないのかな…。

そして注目のココ!↓

f:id:PocketGriffon:20211115193226j:plain

意味深な穴が10個空いてる!

この穴の奥に通信に関する端子が出ているようで、ハッキングされた方々はそこを利用してデータやプログラムを送り込んでるらしい。

 

f:id:PocketGriffon:20211115232712j:plain

ピンヘッダの幅と同じみたいなので、うまく加工してやれば外部からデータを書き込めるようになりそう!よーし、やってみるかとばかり材料を手に入れる。

 

f:id:PocketGriffon:20211115232933j:plain f:id:PocketGriffon:20211115232953j:plain

うーん、ピンが奥まで届かないなぁ…長さどのくらいなんだろ…とかやってたのだが……

あやまってピンを本体内部に落としてしまった!!!!!

本体内部で横に向いてしまったようで、本体を振るとカラカラ音がする…

こうなるともう分解しなければ取ることができない(T-T)

 

仕方なく(本当に仕方なく!)分解してみることに。

f:id:PocketGriffon:20211115233908j:plain

無事にピンは取り出せたけど……もういいや、このまま直にはんだ付けしちゃえ!(^^;;

 

f:id:PocketGriffon:20211115235555j:plain

というわけで、フタは出来なくなっちゃうけれど安定した通信環境が整った!

 

ソフトウェアの開発環境を整えるのはとても大変だった!

なんだか気分が全く乗らず、約2週間ほど手つかず(T-T) 最終的には手コピーでライブラリなどをセッティングした!うむむ…これで本当に正しいんだろうか(TT)

 

とりあえず、有志が開発してくれたプログラムを実行させてみることに。

f:id:PocketGriffon:20211116000900j:plain

これがTinyBASIC。

 

f:id:PocketGriffon:20211116001116j:plain

こちらがArduino BASIC。

なんとなくこちらがお気に入り!

 

f:id:PocketGriffon:20211116001105j:plain

フォントサイズも変えられるので、小さい字が読めない世代には使いやすいw

 

f:id:PocketGriffon:20211116001256j:plain

SmartResponseXEというライブラリに同梱されていたHello World

ライブラリのサンプルにもなっていてとても見やすい(^^)

このソースコードを参考にしながらプログラム作っていってみるよ!

 

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

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

X68000を使う!その1

おまたせしました…なのかな?(^^;;

マイナー路線ばっかりを突っ走ってる私がX68000を使うとは……汗

いや、過去には使ってた事あるんですよ???

ということで、思い出しながら使っていこうと思う!

f:id:PocketGriffon:20211018210003j:plain

 

我が家のX68000

うちには2台のX68000がある。

1台目はACEで、1988年に購入。ちょうどACEが発売されたタイミングで(安くなったであろう)初代を買おうとしてお店へ行ったところ、計算をしてみたらACEの方が安く買える事が分かり、その場でACEに変更。

本体+モニタのセットで購入した。

 

その後、メモリを2MBに増設をしてXC CompilerとSX-Windowを購入しているが、手に入れた時系列がはっきりしない。

 

その当時、何かプログラムを作ろうと思ったが、自分の想像以上に68000は手強く、アセンブラで画面クリアプログラムを書いた程度で終わってしまった。

 

1990年代に入りハードディスクが一気に値下がりをしたタイミングで40MB HDDをACEに取り付けた。同時に4MB増設メモリも手に入れた気がする。

 

1992年頃、仕事でX68000を使う機会があり、チャンスとばかりにアセンブラC言語を使いバリバリとプログラムを組んだ。メモリもディスク容量も目一杯まで使うモノだったので、それなりの規模だったとは思う。アセンブラ主体だとメンテナンスがやりづらいので、C言語メインで作ったが、表示に関わる部分はアセンブラ化して68000を堪能した。意味もなく文字表示は直接VRAMアクセス+4プレーン同時書き込みをするなどして楽しんでいた(^^;;

この時に仕事で使ったX68000が、Compact XVI(会社所有)だった。

 

その後、仕事にも趣味にもX68000を使う機会はなく、手持ちのACEも箱に入ったままだった。3年ほど前に試しに電源を入れてみたが、残念ながら起動しなくなっていた。

そして1年ほど前、X68000 Compact XVIを手に入れた。起動はするものの電源が落ちないなどの不安定さがあったため、1ヶ月ほど前に外部へメンテナンスをお願いした。

そこでコンデンサ交換やFDD清掃をしてもらい、別途購入してあったメモリ(6MB:合計8MB)も増設していただいた!

 

ずっと触れていなかったX68000だけど、いつか使いたいという気持ちだけはあった。そのため、ソフトや周辺機器など手に入れるチャンスがあった際には逃さないようにゲットしてた。

おかげで所有しているものは意外にも充実している(ゲームを除く)。

f:id:PocketGriffon:20211021095550j:plain

私自身の趣味がソフトウェア開発に傾向しているため、ハード寄りの事(クロックアップや周辺機器の充実など)はあまり興味がない。そんな人がどんな感じにX68000を使っていくのか、書き記していこうと思う!

 

なにはともあれ開発環境!

ここのところTwitterなどでX68000関連の事をつぶやいていたが、Windowsを常用していない私の環境は少しだけ面倒らしいという事を理解した。

 

別にWindowsが嫌いとかではなく、単にUNIXMacと流れる過程でWindowsを使う機会がなかっただけの話。一応WindowsでもVCを使ったプログラム経験ありますぞ(^^;;

 

でも…可能ならば慣れ親しんだMacでの開発環境を整えたいところ。ネットで情報を調べてみたが、Mac単独で開発環境を構築している人が見当たらなかった…。

ちなみにMac用のエミュレータはいくつか見つかったが、M1 Macでは起動しなかった。うむむ…Parallels Desktopとか使わないとダメなのかな…。

Linux+X68000という組み合わせはいくつか見つかったので、そっちに逃げようかとも思ったが、もう少しだけ頑張ってみる事に。

 

Mac単体で、X68000のX形式ファイルが作れればいいのだが…。

とりあえずアセンブラは以下のクロスアセンブラを使わせてもらっている。

Frank's Cross Assemblers

68000以外のコードも出力出来るので、今後も便利に使えそうな予感!(^^)

 

このアセンブラが出力したバイナリを、Z形式に変換しつつBASICにするコンバータを作成した。このファイルをRS-232C経由でX68000本体に送り込み、X-BASICで実行する事でZファイルが作成される。

Human68kへ戻り、出来上がったZ形式ファイルを実行する事で結果が得られる。

…うん、手順がめちゃくちゃ面倒だ(T-T)

 

バイナリファイルを転送するプログラムを作り始めようかと思ったが、その前にやってみたい事があったので、そっちを先にやってみる!

 

RaSCSIの設定

f:id:PocketGriffon:20211021111531j:plain

うちにあるRaSCSI対応の変換アダプタは、GAMERnium版。当時、手元にあったPC-9801UV11でHDDを使うべく、多分…2年くらい前に入手した。

当時、頑張って設定をしてみたのだが、SCSIボードとの相性なのか98との相性なのかわからなかったが、SCSIとして認識されなかった(T-T) 悲しみに暮れてそのまま保管となった。

 

今回、手元にFDX68があるなぁ…とか変換番長を検討しないといけないかなぁ…思った流れで、そういえばRaSCSI機器があったと思い出した!

元々がX68000用に開発されたものだし、きっとX68000の方が相性が良いはずだ!

 

手元のアダプタは、前回テストした時のまま残っていたため、RaspberryPiと一体化していた。これってこういうキットだったんだったかなぁ…記憶が曖昧。

f:id:PocketGriffon:20211021113421j:plain

そしてハーフピッチのSCSIコネクタ。確かPC-9801と接続テストをした時に、SCSIケーブルもあったはずなんだけど、部屋の引っ越しなどで紛失してしまった。ケーブル類をひとかたまりにしたんだけど、その段ボールごと行方不明(T-T)

f:id:PocketGriffon:20211021113747j:plain

しかたないので秋葉原BEEPに行った時に、ついでに入手してきた。

新品を買ったら高いケーブルも、手軽な金額で扱ってくれるのは本当に感謝だ!

 

さあハードの準備は整った!RaSCSIを使えるようにしていこう!

私は以下のページにある「はじめてのRaSCSI導入マニュアル」を参考にさせて頂いた!

「RaSCSI」を使えるようにする(導入方法)

 

ベアメタル版、OS版の2種類があったけれど、私はプログラムを開発してそのファイルを送り込みたい希望があるので、これは迷わずネットワークの使えるOS版を選択。いつか環境が固定されてきたらベアメタルにもチャレンジしてみたいけど、しばらーく先になりそうな予感(^^)

 

基本的にここに書かれた情報の通りにセッティングしたら問題なく動いた!

f:id:PocketGriffon:20211021115507j:plain

OSは指定されたページにあった最新版(2021-05-07)を使用した。

SDカードへの書き込みはMacという事もありddを使用。この辺りはネットで調べたらたくさん出てくるので参照していただきたい。

 

SSH接続の有効化、ネットワーク接続の設定などは書いてある通り。SSHクライアントは特別に準備すること無く、bashからsshコマンドで接続した。

 

「半自動実行スクリプト」で表示されるメニューが変わっていた。

f:id:PocketGriffon:20211021120318j:plain

メニューが1つ追加されている。

最初の選択で「1:All Install」を選択、次の選択も「1:RaSCSI」を選択、ボードの選択はウチの場合はGAMERnium版なので4を選択した。

 

sambaの設定も書いてある通りにしたところ、Macintosh HDを開くと右のタグにRaspberryPiのディスクが見えるようになった。これはWindowsのネットワークドライブを見られるように設定してあるMac本体だからかも知れない。

f:id:PocketGriffon:20211021121052j:plain

X68000側にもRASDRV.SYSを入れる事で、RaspberryPi側のファイルが見えるようになった。これは……これはめちゃくちゃ便利!!!(^o^)

Macからファイルをcp出来るし、X68000側も普通にCOPYで持ってこられる。

データ受け渡し時のメディア変換どうしようとか思っていたが、一気に解決してしまった!

 

今の現状で、Macで編集したファイルをX68000実機でビルドする事が出来る環境が整った!あとはどこまでMac単体で動かしたいのか…かなぁ…。

気持ちがそっちへ行ってしまったので、気の済むまでやってみようとは思う(^^)

 

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

RaspberryPi Picoでプログラミング!

f:id:PocketGriffon:20211012180518j:plain

間違いなくRaspberryPi Picoを作った方は「違うんだよ…そういう使い方をするハードじゃないんだよ…」って思ってるに違いない!(^-^)

 

今回はRaspberryPi PicoでPC-8001エミュレータを動かしちゃったお話!(^^;;

一応、反省はしてるw

 

事の発端は……

MI68で手に入れたX68000 Compact XVIの形をしたRaspberryPi Zeroケースに、Zeroを入れるべくお店まで出向いていった時に、何気に目に入ったのがコレ。

f:id:PocketGriffon:20211012181341j:plain

サイズと名前から想像するに、RaspberryPi Picoに取り付ける液晶ユニットっぽい。

解像度は240x135ドットと、M5Stickと同じ。

そうかー、これがあったらPC-8001エミュレータ動くのかな…と何気に頭をよぎる。

よぎっちゃったら……やるしか無くない?!(^-^)

そんな単純な理由でパーツを買ってくる私であったw

 

液晶ディスプレイの中身は…

f:id:PocketGriffon:20211012185343j:plain

写真ではPicoも一緒に映っちゃってますが、別売りですw

そうか…Picoって薄っぺらい基板だけだから、ピンヘッダをはんだづけしないといけないのか…。うーん、久しぶりのはんだづけ。

f:id:PocketGriffon:20211012185705j:plainf:id:PocketGriffon:20211012185854j:plain

ブレッドボードを利用しつつはんだづけをしていく。

どうも私はピンヘッダが苦手で……その…節足動物みたいに見えるよね?(T-T)

今にも動き出しそうでちょっとイヤなんですよねー…(TOT)

 

f:id:PocketGriffon:20211012191137j:plain

Picoと液晶を合体させるとこんな感じ!

Picoの上に固定されるので、変にケーブルが伸びたりせず液晶が邪魔にならずに済む!

 

f:id:PocketGriffon:20211012191538j:plain

サイズ的に……えーと、ほぼいっしょ?

液晶サイズも同じに見えるので、何を作っても見た感じの驚きはないかも(T-T)

まぁでもPicoで何かが動くってのは重要でしょ?! ←そうなの?

 

MacでPicoの環境を整える!

これが一番大変だったかも知れない!

今まで、RaspberryPi用のプログラムを組む場合、完成までMac上で開発して、最終的な動作確認のみをRaspberryPi実機でビルドするようにしていた。それで問題がなかったし、むしろそれが普通な感じだった。

 

しかしPicoの場合は本体にOSというものが載ってなく、セルフビルドが現実的ではない。どうしてもホストマシンでのクロスビルド環境が必要となる。

そのため、私自身も手持ちのMacで環境を整えた。

 

ネットに書かれていた記事を参考にしつつ環境をダウンロードした。

その後、独自であれこれ触ってしまったために、だいぶオリジナル環境になってしまったかも。

ビルド環境全体がCMakeに依存しているので「CMakeってなんぞ?」って方には厳しいかも…。でもなんとなくファイルを触ってたら分かるよ、うん(^^;;

 

もうひとつ大変だったのは↓こっち!

f:id:PocketGriffon:20211012210603j:plain

ちょっと分かりにくいけれど、基板上にある「BOOTSEL」と書かれたボタンを押しながらUSBケーブルを挿し込むと、Picoにデータを書き込めるようになる。これが結構辛い。

ピンヘッダがついてるので指に刺さるし、その状態でボタン押しながら差し込みづらいUSBケーブルと格闘する事数回。

f:id:PocketGriffon:20211012210735j:plain

何かのはずみでボタンが壊れてしまった!

私が壊したんじゃない!壊れちゃったんだと言いたい!!(^-^;;

結局、これはボタンそのものが完全に壊れてしまったので、別のPicoを使うことに(T-T)

ダウンロード回数5回ほどの寿命でした(ToT)

 

この故障を教訓に、いくつかの対策を施した。

まずはUSBコネクタの挿抜回数を減らすために、スイッチ付きのUSBハブを用意。

f:id:PocketGriffon:20211012211625j:plain

USBの線を抜かなくても、スイッチをパチパチすれば電源のON/OFFが出来る!

これは本当に便利だ!

さらに!!!

f:id:PocketGriffon:20211012211820j:plain

ネットでこんなPicoカバーを見つけた!これがあれば、あの忌まわしいボタンを直接触らなくても、間接的にポッチン出来る!

実際に取り付けてみてから気がついたが…

f:id:PocketGriffon:20211012211921j:plain

液晶がついている面の、反対側にぼっちょがついてるので、液晶を上にした状態でPico自体を下にぐっと押す(意味分かる?)と、ボタンが押される。この状態でUSBハブのスイッチをONにすれば書き込みモードで起動する…というワケだ。

 

実際にやってみると、格段に使いやすくなった!これであのボタンも勝手に壊れる事はないだろう!(あくまでも壊してないと言い張る)

 

PC-8001エミュレータの移植

今回のPicoは、M5Stickに構成が近く載っているメモリはM5Stickの半分の264KB。

そのため、M5Stickからソースコードを移植するのが簡単だと判断した。

 

Z80エミュレータなどのファイルを何も考えずにコピーしてきて、CMakeLists.txtに必要なファイルを書き加えていくだけの作業だ(^^)

M5Stick特有な機能は、pc8001.inoファイルに集めてあったので、このファイルの代わりになる、Pico用のC++ファイルを用意すれば良いだけの話である。

 

エミュレータ初期化、エミュレータ駆動、表示系実装という感じに順を追って動作確認をして行ったが…驚いたことに、メモリ確保(malloc)と表示系(LavyanGFX)を数行書き替えただけで動いてしまった!(^-^;;

Picoのビルド環境が出来上がってから、ほぼ1時間でエミュレータが動いた!

 

M5StickとRaspberryPi Picoはライブラリ的には互換性がないので移植は大変かと思われていたが、そもそもMac環境からM5Stickへ移植してるくらいなので、元々のソース自体が環境に依存している部分が少なかった。

 

Pico側の勉強については、表示サンプルファイルを1つ読んだだけだった。

でもそれで十分だったよ!(^-^)

 

 

Picoにコアが2つあることをすっかり忘れていて、最初に動かした時は秒間2コマくらいしか表示されず、まぁ133MHzだったらこんなモンかも?と思い込んでしまった。

 

その後、コアを2つ使うように修正し、必要な箇所のみ画面更新するようにしたところ、実機よりも速く動くようになった!

 

ちなみに、Picoでマルチコア対応をする時は CMakeLists.txtのtarget_link_librariesにpico_multicoreを追加する必要がある。

 

 

終わりに

完全に手探り状態で移植したワリには、それなりに動いてしまった事に驚く!

特に表示系が思った以上に速いのは、可能性が広がる(^-^)

メモリの空き情報など分かってない事が多いけれど(特に意味もなく)他の機種を動かしてみても楽しいかもね…と思った!

 

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