Miyoo miniが届いた!

f:id:PocketGriffon:20220409101318j:plain

Miyoo miniというハードをご存知だろうか?(^^)

パット見た感じはゲームボーイみたいな形をしている、少し小型なマシンだ!

名前で検索すると山のようにヒットするので、ちゃんとした使い方を知りたい方はそちらを参照してみて欲しい(^^;;

 

年末から年明けに掛けて、この手のハードが面白いと思っていた時に注文していたが、それが3ヶ月掛かって手元に届いた。

 

サイズ的にはこんな感じ。

f:id:PocketGriffon:20220409102333j:plain

f:id:PocketGriffon:20220409102357j:plain

f:id:PocketGriffon:20220409102413j:plain

手のひらには入り切らないが、十分に握れるくらいのサイズ。

ワリとコンパクトな筐体でありながら、画面サイズやCPUパワーがそれなりにあるため、楽しい使い方ができそうだ!

 

f:id:PocketGriffon:20220409103828j:plain

f:id:PocketGriffon:20220409103848j:plain

届いたときから箱が無く、代わりに専用ケースが付いてきた!

まぁどうせ箱はすぐに処分しちゃうし困る事はないんだけど、なんとなく溢れる中古感…汗

でも新品でしたよ、多分(^^;;

 

ところで……頼んでないSDカードが入ってきちゃったのですが…滝汗

SD無し、保護シート無し、ケースなしの一番安いやつを頼んだはずなのに、なんか全然違う感じに届いちゃうのも、最近の忙しい業者なのかな…。

 

SDカードの中身は送ってはいけない、受け取ってはいけないものが入っているようなので、中のファイルは削除して使う事にする。

 

X68000動くかな?

Miyoo miniの中身がどんな構成なのかを見てみたい!

いつもの流れでsshでログインして…をしてみたかったが、Miyoo miniはWi-Fiがない(T-T)

USB TYPE-Cに有線LANを繋げてみたが、うんともすんとも言わない。

この…肝心なところに手が届かない感覚は…なんとなくFunkey Sを思い起こす…(T-T)

 

仕方ないので、別のアプローチを検討してみる。

試しに付属のSDカードを入れて起動する。

SDカードの中に入ってたイメージファイルは抹消してしまったが、フォルダ構造などは参考になりそうだったのでそのまま残してあるのだ(フォーマットはしていない)。

 

Appというフォルダの中に便利なアプリが入っていたので、これを利用してみる!

f:id:PocketGriffon:20220409105924j:plainf:id:PocketGriffon:20220409105939j:plain

ここにあるRetroArchを利用してX68000を起動してみよう!

#以下、付属のSDカードが手元にある事を前提としていますが、

#後日SDカードが無い状態で起動する方法も模索してみます。

 

フォルダの中を覗いて見ると、RetroArchで使われるコアは、

${SD}/RetroArch/.retroarch/cores 以下に入っている事が分かった。

お!なんとPC-9801エミュレータは入っていた!(np2kai_libretro.so)

じゃあX68000は……と思ったら、px68k_libretro.infoしかなく、肝心のsoファイルが存在しなかった(ToT)

 

うーん……じゃあsoファイルをコピーしてみるか!

np2kai_libretro.soを調べると、32bitバイナリのようだ!

f:id:PocketGriffon:20220409112758j:plain

 

32bitバイナリの px68k_libretro.so は、過去に BananaPie でX68000を動かした時にビルドしている。

pocketgriffon.hatenablog.com

このバイナリを利用して、X68000を立ち上げてみよう!(^^)

 

まず、どのファイルをどこに置いたら良いのかを調べる。

PC-9801エミュレータ(np2kai)があったので、これを参照にしながら設定する。

 

設定ファイルは ${SD}/RApp/np2kai に入っていた。

同じフォルダにある launch.sh とconfig.json を見ると、そこにフォルダ情報が書かれていた。

f:id:PocketGriffon:20220409114422j:plain

↑launch.sh

 

f:id:PocketGriffon:20220409114446j:plain

↑config.json

 

これを見ると、RetroArchはconfig.jsonを参照し、そこに書かれている情報を参照しつつ、launch.shを呼び出す…のかな!?

 

分かった情報と設定する情報は以下の通り。

 

設定ファイル:${SD}/RApp/x68000

libretro.so格納フォルダ:${SD}/RetroArch/.retroarch/cores

romイメージ:${SD}/Roms/x68000

BIOSデータ:${SD}/RetroArch/.retroarch/system/keropi

 

ファイルが足りないもの(アイコンの画像データなど)は、PC-9801のものをそのまま利用してしまった!絵は化けるだろうけど、まずは動かすのが先決よ(^^)

 

あとはプログラム→RetroArchでRetroArchを起動し、それ以降は通常の流れだ。

f:id:PocketGriffon:20220409120528j:plainf:id:PocketGriffon:20220409120604j:plain

f:id:PocketGriffon:20220409120546j:plainf:id:PocketGriffon:20220409120620j:plain

 

驚いたことに、一発であっさり起動してしまった!(^o^)

f:id:PocketGriffon:20220409120756j:plain

f:id:PocketGriffon:20220409120814j:plainf:id:PocketGriffon:20220409120833j:plain

 

Miyoo miniは、CPUクロックが1.2GHzのデュアルコア、メモリは128MBあるのでRaspberryPi Zero2の半分くらいのパワーがある。

X68000がちゃんと動くかな…と思ったが、いくつかのイメージを動かしてみた感じでは、まぁ遊べる…ちょっとだけ遅くなる時がある?くらいの感じだった!(^-^)

 

むしろこのサイズでX68000が動くのが驚く!

サウンドも鳴るし、BGM聞くマシンとしてもいいなぁこれ(^^)

 

試しにPC-9801も動かしてみたが、キーボードが繋がらないので何も出来なかった…汗

f:id:PocketGriffon:20220409121709j:plain

同じような事情で、PC-8801は動くだけ…になるかも。
キーボード繋げる方法はないのかな…??

 

とりあえず今回はX68000動かしてみたよ、的な報告でした!

この先は、SDカード無しで動かせないか試してみようと思う。

 

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

RaspberryPi Picoで動くBASIC その2

f:id:PocketGriffon:20220407201206j:plain

ここんところ、RaspberryPi Picoで遊ぶのが楽しくて仕方がない!ヽ(=´▽`=)ノ

 

半導体不足でRaspberryPiが手に入らない現在であっても、Picoは比較的簡単に手に入る。

しかも税込み550円!(ピンヘッダ付きは990円)

www.switch-science.com

 

そして480x320ドットの大型液晶は税込みで2530円。

www.switch-science.com

 

両方あわせて3000円ほどのマシンで、これほどまで遊べるなんてスゴイ!(^-^)

まだまだPicoを使いこなしてる感覚は無く、いまだに「あ、こんな速度で動いちゃうのね」と驚くことが多い。奥が深いぞ、Pico!(^o^)

 

さて、先日からRaspberryPi PicoにArduino BASICを移植してる!

前回のブログの最後にチョロっと書いた、グラフィック命令の追加をしてみる。

もはや移植というよりは拡張と言った方が良いのかも知れない(^^;;

 

追加できるのか検討

まずは想定しているグラフィック画面を定義をしてみる。

 

グラフィック画面の広さは480x320ドットとする

やっぱり画面全体をグラフィック画面として使えるようにしたい。

ただし下の12ドットはステータス表示がされてしまうので、基本は見えない。

CONSOLE命令でも追加して、ステータスのON/OFFでも入れようかな…?

 

カラーは256色にする

これは主にメモリの制限によるスペックダウン。

480x320ドットで65536色を表示させるために必要なメモリは300KB。

RAMが256KBしかないPicoには残念ながら入らない。

そこで、色数を256色に落とす事で必要なメモリは150KBとなる。

カラー番号と実際の色の対応は、MSXの256色モードを参考にさせていただいた。

 

テキスト画面とグラフィック画面は分離

テキストをスクロールさせてもグラフィックには影響が出ないような構造にしたい。

これはPC-8801を想像してもらえれば良いかなーと思う。

グラフィックとテキストの合成処理が必要となるが、これは難しくない。

 

BASICのコマンドは変更ではなく追加

今ある命令を拡張して機能を追加していくのは、いらぬバグを引き起こす可能性もある。

グラフィックを扱う命令は新規追加する方向で命令を考えてみる。

追加する命令はGCLS、PSET、LINEの3つのみ。

余裕があったらCIRCLEやPAINTも検討したい。

 

実装してみる!

方針は決まったので、さあやってみよう!

150KBのメモリ確保は、固定でしてしまえば良いので簡単としても…

やっぱり気になるのは、256色→65536色の変換が現実的な速度で行う事が出来るのだろうか…という事だ。

 

色数が256しかないので、ここは256個のテーブルを生成してメモリに置いておくのが良いかと思う。気をつけないといけないのは、メモリアクセスはキャッシュから外れると極端に遅くなる場合があり、計算で求められるデータはその都度計算した方が速い場合がある。

コードを想像してみよう。

  uint8_t *gvram = グラフィックRAM;
  uint16_t *buff = 変換後の格納バッファ;
  for(int i = 0; i < 横幅; i++)

   *buff++ = gColorTable[*gvram++];

うん、このくらいプログラムが局所的であればキャッシュの効果は期待できそう(^^)

 

出来上がったバッファの上に、テキストデータを合成していく。

現在のBASICは、テキスト文字が変更されると画面が更新される仕組みになっている。この仕組みを上手に利用しようと思う。

 

グラフィックデータが更新されたらテキストデータを更新しましたフラグを立て、テキストを更新するついでにグラフィックも表示するようにした!(意味通じる?^^;)

 

つまり、絵のデータが1ドット変更されたとしても、縦12ドット横480ドット更新されるw

これで現実的な速度が出るのかなぁ…と思ったが、やってみたら全然平気だった!(^^)

f:id:PocketGriffon:20220407201206j:plain

このテストをしていた時に表示していた画面が↑これだった。

矩形の色はBASICで書いたのではなく、C++プログラムで書いている。画面をクリアするとこの画面が出るようにしておき、テキストとの合成も同時にテストした。

 

よし!これでグラフィック画面が追加できそうな見込みが立った!(^o^)

グラフィック画面をRAMに保持する事で、RAMの使用状況は73%となった。

 

BASIC命令の追加

BASICの命令を追加してみるテストとして、まずはフォントデータ幅の切り替え命令を追加してみた。

 FONT

とすればフォントサイズが横8ドットと6ドットが切り替わるだけの簡単な仕様(^^)

f:id:PocketGriffon:20220407213156j:plainf:id:PocketGriffon:20220407213211j:plain

これでいちいちビルドオプションを変更してビルドし直さなくても、動かしながら動的に変更する事ができるようになった。引数もないので簡単実装(^^)

 

 GCLS

グラフィック画面をクリアする命令を追加。引数はなし。

画面全てをクリアするためにはCLS:GCLSと2つ呼ぶ必要がある。

 

 PSET(x, y),color

これで画面上にドットを打つことが出来る。ドットを消すPRESET命令はないが、PSETでカラーに0を指定すればドットは消える。

 

整数の引数を3つ取る命令が存在しなかったため、新たにParserを書くこととなった。なんか構造的にキレイに書けそうな雰囲気があったのだけど、どうにもうまくいかなかったので、べったりなコードを書くことになった(T-T)

f:id:PocketGriffon:20220407214401j:plain

1000個のドットを描画するのに一瞬!速すぎますよ!!(^^;;

そこで雰囲気を出すために、1ドット描くごとにグラフィック画面を更新するようにしたところ、ちゃんと遅くなったw

 

 LINE(x1, y1)-(x2, y2),color

画面に指定色の線を引く。

うーん…このカッコとマイナスのある文法、BASIC特有かなーと思うけれど、Parser書くのが面倒だ(^^; 今回はソースをベタっと書いたけど、もう1つ命令を追加するチャンスがあったらキレイに直そうと思うほどのコードになった(^^;

f:id:PocketGriffon:20220407214546j:plain

LINEの描画は、有名なブレゼンハムのアルゴリズムを採用した。そのおかげもあってか、めちゃくちゃ速い!(^-^)

こちらも線を1本引くたびにグラフィック画面を更新したら、それっぽい表示になった!

 

おわりに

グラフィック命令が使えるようになると、昔テクノポリスという雑誌に載っていたBASICで描くグラフィック画像とかを試したくなる!

そのためにはPAINTが必要だし、プログラムによってはWINDOW / VIEWPORTなどが必要になりそうで大変だなー…。いや、やりませんよ?(^^;;

 

BASICが動くようになってくると、スプライト命令あったらゲーム作れそうだよね、とかPCG機能は簡単に入りそうだな…とか、もういろんな事を考えてしまう!(^^;

終わりがなさそうな気がするので、一旦キリにしようと思う!

 

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

RaspberryPi Picoで動くBASIC その1

f:id:PocketGriffon:20220406182738j:plain

先日からRaspberryPi Picoに大きな液晶を取り付けて遊んでいる!

 

液晶を取り付けた当初は、Picoが扱えるメモリサイズに比べて画面の画素数が多くて、果たしてPicoで使い切れるんだろうか…とビビっていたが、思った以上に使えてる!

 

ブログには書いてないがBad Apple!!を動かしてみたりもした!

残念ながら画面更新の速度が1/30秒以上掛かってしまい、画像としてはコマ落ち状態となった。そのため自分の中では移植失敗な位置づけ(T-T)

 

Bad Apple!!以降、もっと液晶サイズを活かす何かが出来ないかと実験を続けていた(^^)

 

気になっていたBASIC

以前、SMART Response XEを使った時、良く出来たBASICを使ったことがあった。

このBASICで作れるプログラムサイズは10KBとそんなに大きくないが、実際に使ってみても10KBを超えるプログラムなんてめったに書かない(^^)

それよりも動的にフォントサイズを変えられたりなど、使いやすいカスタマイズが出来たので便利に使っていた。

 

pocketgriffon.hatenablog.com

元がArduino用のBASICらしいので、すでにM5Stackにも移植されてるのかなぁ…まだだったら移植しようかなぁ…とか、いろいろと考えていた。

 

でも…どの機種でもそうなんだけど、CP/Mを移植してMBASICが動くようになると満足しちゃう。これでいっか…ってな感じで移植作業も後回しになりまくり!(^^;; だってMBASICで困る事ってほぼ無いもんねぇ…(-_-;

 

このままだといつまで経ってもBASICの移植が出来ない!(^^;;

…と思ったので、今回気合をいれてRaspberryPi Picoへの移植をしてみた!

 

移植方針

移植元となるBASICは、SMART Response XEで動いてたプログラムを使う事にする。

github.com

SMART Response XEで実際にプログラムをした事もあるので、機種特有の関数にも見覚えがあるのが有利だ。それに実際に動いてるものが手元にあるのはとても心強い!(^^)

 

BASICの命令は極力サポートするけれど、XEにあったSLEEPやTONEなど本体に依存したものは削除する方向。ムリに削除はせず当面は放置だけど!(^^;

 

キーボードによる入力は限定したものとする。

Picoにキーボードが繋げられるらしいんだけど、USBコネクタからの電源供給の兼ね合いがあり、繋げる方法が良くわからない(T^T) 仕方ないので、Arduino IDEのシリアルモニタから入力を受け付ける事にする。これはリアルタイムの入力はできなくなるという意味でもある。

INKEY$命令はおそらく期待通りの動きにならない。

 

プログラムのセーブはSDカードに行うようにする。Picoに載っているフラッシュをファイルシステムとして使う機能があるが、こちらはサポートしない(XEでは使ってるようだったので削除する方向)。

 

液晶は480x320ドットのパネル専用とするけど、多分ちょっとした変更で別のサイズのパネルで動く気がする。

 

出来ればグラフィックスをサポートしたい。してみたい!希望的!(^^)

 

移植作業!

このBASICはとってもコンパクトに作られている。

ソースファイルはbasic.cpp、host.cpp、そしてinoファイルの3つだけだ!

inoファイル  主に初期化のみ

host.cpp   機種依存の処理

basic.cpp   BASIC本体

 

こんな感じになっているようなので、おそらくhost.cppを中心に改造していけば動くんじゃないかな…と予想を立てる。

 

ここで、私が良くやっている移植方法を書いてみようと思う(^-^)

 

まずは必要と思われるファイルをコピーする。最初は足りなくても良いので、とにかく思いつくファイルをコピーしまくる。

そして空のinoファイル(setupとloopは存在する)を用意して、おもむろにビルド。

#includeのファイルが無かったり、文法的に対応出来ないものが出てくるので、必要に応じてファイルをコピーしたりして1つずつ直して行く。

 

この時点ではプログラムの内部構造などは全く理解していない(^^;;

しかも必要なさそうな箇所は条件コンパイルで強制的に外しちゃったりしているので、ビルドが通ったとしてもまーったく動かない状態だ!

特に表示系や外部ハード(SDカードなど)は作り直しになる可能性が高いので、関数名だけ残してごっそり外してしまうケースが多い。

 

移植作業中、タイマー割り込みで何かをしているコードがある事に気がついた。とりあえずはこのコードも外してしまった(^^;

 

頑張ってビルドが通るようになったら、今度はinoファイルのsetupの中身を書いていく。

オリジナルのファイルを参照しながら、必要な初期化を入れていく。一気に処理を追加してしまうと追いにくくなってしまうので、いつも1つずつ入れていってる(^^;;

基本は小心者よw

 

今回のBASICの移植作業では、初期化が終わってオープニングメッセージが表示されるところまでは、そんな難しくなかった。

f:id:PocketGriffon:20220406200941j:plain

少しプログラムコードを見たところ、画面に表示される情報はscreenBufferというバッファに入る事が分かったので、それを可視化してみる。

いきなり画面表示を組み立てていくのは簡単ではないので、まずはシリアルへ出力(^^)

 

当面はシリアルに表示も出していけばいいかと思ったが、この先のデバッグでシリアルへの出力がかなり埋まるはずなので、早めに表示系は液晶に出してしまう事にした。

CP/Mの時に作った表示系があったので、さくっと移植!

f:id:PocketGriffon:20220406202149j:plain

携帯がモロに写っちゃったね…汗

液晶側にスクリーン情報を出せるようになれば、シリアル側は雑多な情報を垂れ流しても邪魔にはならなくなる(^^

 

BASICプログラムが動かない

さて、BASICは起動したけれど……簡単なプログラムすら動かない事がすぐに判明。

 A=10

これが動かない(^^;;

なんぞ??

これじゃあBASICのプログラムどころの話じゃない(TOT)

 

少しだけコードを追ってみて気がついたのは、ポインタをキャストして値を代入している箇所があった!つまりこんな感じ。

 long *p = (long *)&mem[アドレス];

 *p = value;

これ……アドレスが奇数の場合に良くない事が起こる気がする(^^;

 

世の中には奇数アドレスからのワードアクセスを許すCPUと許さないCPUが存在する。

もしかしたらCPU側の設定とかあるのかも知れないが、私が経験したことがあるのは以下の3パターン。

 問題なくアクセス出来る(ただし遅い)

 データの上下がひっくり返る

 そもそもアクセス出来ない

そしてRaspberryPi Picoは「アクセス出来ない」ようだ。

試しにException Handlerを設定してみたところ、見事に引っかかった!

 

Exceptionを起こしたアドレスが分かれば良いんだけど、残念ながら手元にデバッガがない状態で詳しく調べるのが難しい。

 

随分前になるが、仕事でExceptionを捕まえてPCやレジスタの表示、スタックからのバックトレース情報とかその付近の逆アセンブラを…など楽しげに作っていたら、クライアントから呆れられたのは良い思い出だw

 

止まってる箇所(アドレス)は分からないが、それっぽいコードを発見してるので修正してみる事に。結局、short、long、floatで同様のコードがあり、全部で69箇所を修正した!

 

数が多かったため、1度では修正しきれず、ソース(basic.cpp)を2度3度見直す必要があった。そのおかげと言ってはなんだが、内部の構造はかなり理解出来た(^^)

f:id:PocketGriffon:20220406210645j:plain

この修正でかなりのBASICプログラムが動くようになった!

この時点ではまだセーブは出来ず、全部手入力でプログラムを打ち込んでいた(^^;

 

マンデルブロを動かしてみたい!

BASIC自体が動くようになってきたので、やはり私としてはマンデルブロ集合を動かしてみたくなる!動作速度も見てみたいが、小数点を用いたBASICプログラムが動くのかチェックする意味も兼ねている!

 

マンデルブロ集合のBASICプログラムはそこまで長くはない。

Retro PC Gallery

上記URLにあった写真にBASICプログラムが載っていたので、これを利用させて頂いた。

BASICプログラムを文字列のデータとしてcppファイルに埋めておき、キー入力処理を横取りして1文字ずつキーデータとして返してやれば、BASICでキー入力したのと同じになる。

 

いざ動かそうとしたところ、なんと移植したBASICにはCHR$命令が存在しなかった!(@_@;

あらら……ASC命令はあるのに対となるCHR$命令はないのか…

 

他の命令で代用できないかとパズルをしてみたが、MID$を使って文字列を取り出すなど効率がめちゃ下がる方法しか思い浮かばない(^^;;

先のポインタ修正でBASICの内部構造は理解出来ていたので、思い切ってCHR$命令を追加してみる事にした!

 

内部構造的には、引数がスタックに載る(良くある)構造なため、書くべきプログラムは命令の追加命令の中身、そしてその命令の実行結果として何がスタックに載ったのか、という情報くらい。全体を見渡す感じでコードを理解できていたため、あっさり追加出来てしまった(^-^)

 

よし、これでマンデルブロが動くようになるはずだ!

f:id:PocketGriffon:20220406220643j:plain

お……おぅ…(T-T)

なんか…これは…表示が気になる!(ToT)

やっぱり表示幅は切り替えられるようにしよう。

将来的にはFONT命令とかでサイズ変更出来るようにしたいけど、今は固定でサイズ変更!

f:id:PocketGriffon:20220406221139j:plain

よし、これで見慣れた画面になったね(^^)

 

f:id:PocketGriffon:20220406221625j:plain

ちなみに実行速度はこのくらい。

前回のブログでZ80エミュレータ高速化版で1分26秒(86秒)だったことを考えると、さすがにネイティブBASICは速い!(^^)

 

セーブロード、その他

BASICが安定して動くようになってきたので、そろそろセーブとロードを考える。

SMART Response XE版のソースを見る限り、SDカードを使う場合には、まずはMOUNT、その後LOAD / SAVEをするような運用となっている。

これは……なんでだろ?SDカードの活線挿抜を可能にするための仕組みかな??(-_-;

 

PicoではMOUNT / UNMOUNTせずにSDカードを使えるように修正し、DIR / SAVE / LOAD / DELETEの4つの命令を使えるようにした! よっしゃ、これで便利(^^)

 

その他、タイマー割り込みがカーソルの点滅に使われていたので、これも導入。Picoでタイマー割り込みを使ったことがなかったので、まずは調べるところから開始w

 add_repeating_timer_ms

という関数でタイマー割り込みが使える事が分かった。

この関数でタイマー割り込み時に呼び出されるCallBack(関数)を登録する。

注意点としては、CallBackの戻り値で1を返さないと次が呼び出されない。

 

この先は…

ここまでの作業で、だいぶちゃんと動くようになった!(^-^)

この先はRaspberryPi Pico用にカスタマイズ+拡張をしていく。

 

グラフィック画面を追加出来ないかなーとか考えてるんだけど…(^^)

楽しみはまだまだ続くぜー(^^)

 

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

Z80エミュレータを新規開発した!

f:id:PocketGriffon:20220325071612j:plain

ここんところ、ずーっと気になっていたこと……。

それは自作のZ80エミュレータの速度が遅い!…という事(^^;

 

pocketgriffon.hatenablog.com

過去のブログでも嘆いているくらいなので、結構気にしてる!(=_=;

 

この処理が重いの考え方はいろいろあると思うけど、今感じてるのは「自分が想定している以上の速度低下がある」で、それが理解出来ないレベルにまで達しているのだ(T-T)

 

私が使っているZ80エミュレータコアは、私自身が1990年前半にC言語で書いたものが原型となっていて、それをずっとメンテナンスするカタチで使っている。遅いのは紛れもなく自分自身のプログラムが悪いはずだ(ToT)

 

ここ数年で書いた6809CPUエミュレータはARM CPUに特化してカリッカリにチューニングしてあるおかげでかなりパフォーマンスが出るようになっている。それに比較する以上にZ80が遅いなぁ…とか思っていた。

 

今回は意を決してZ80エミュレータプログラムを作り直したお話(^-^)

 

CPUエミュレーション

CPUのエミュレータと聞くと身構えてしまう人がいるかも知れないが、実際にはとても単純な構造でできている。構成としては主に3つかなぁと思う。

 レジスタ

 エミュレータ内で扱えるメモリ

 ハードウェアとのやりとりをするI/O

 

レジスタ

CPU内部にはレジスタと呼ばれるとてもとても小さな変数みたいなものが存在する。これはCPUによって違うため、CPUが変わるごとにエミュレータプログラムを作る事になる。

f:id:PocketGriffon:20220325072948j:plain

Z80の場合は上の写真のような構成になっている。

これをプログラムで表現しようとする場合…

例えばAレジスタは8ビット長なので、

  uint8_t A;

なんてすれば仮想的なレジスタが定義出来る。

 

ただZ80には「8ビット長のAレジスタとFレジスタをくっつけて、16ビット長のAFレジスタとして扱うことができる」というレジスタペアと呼ばれる面倒な仕組みがある。

C言語には共用体という仕組みがあり、コレを利用すればレジスタペアは簡単に実現出来る。

構造体は理解しているけど共用体は知らない…という人は、まずここで躓く(^^;;

 

Z80で面白いなぁ…と思うのは、裏レジスタというレジスタセットがもう1つある事。

メモリよりも高速にアクセス出来るものなので、たくさんある方がプログラムのパフォーマンスが上がりやすい、とても便利なのだ。でもワリと存在自体を忘れがちで、普通にプログラミングしているとほぼ使わない。使う人と使わない人が二分するような気がする(^^)

 

エミュレータ内で扱えるメモリ

f:id:PocketGriffon:20220325093706j:plain

エミュレーションするCPUが使えるメモリを管理する必要がある。Z80の場合は64KBのメモリ空間があり、メモリマップはエミュレーションするマシンに依存する。

このため、メモリアクセス関数はマシンにあわせて作り直す構造にしておく必要がある。

 

MSXの場合はスロット切り替え、PC-8801ならばバンク切り替えなどに対応した、メモリアクセス関数を用意する必要があるだろう。

 

私は1バイト読み込み、1バイト書き込みという2つの関数を別途用意して、これらを利用してエミュレータのメモリへアクセスするようにしている。

速度は速くないがエミュレータの汎用性は保たれる。

 

ハードウェアとのやりとりをするI/O

f:id:PocketGriffon:20220325094009j:plain

Z80はI/Oポートを介して外部のハードウェアとやりとりする仕組みが備わっている。キーボードとかメモリのバンク切り替えとかFDDとか、用途はさまざまだ。

しかもマシンごとにすべて違っている(もっと言えばシリーズ別で違ってたりもする)ので、これもプログラム的には汎用性をもたせる必要がある。

 

エミュレータを作ろうと思った時、CPUのエミュレータを実装するのは簡単なのだが、ハードウェアのエミュレーションを作るのがとても大変だ!エミュレータを作る上での敷居の高さは、95%くらいがこっちの難易度だと思う(T-T)

 

利用してるZ80エミュレータ

上にも書いた通り、今まで使っていたZ80エミュレータは1990年代前半に設計したものだ。当時は68030CPUで動くワークステーション上で開発していた。この頃は「確実に動くもの」を目指していて、実行速度は特に気にしていなかった。

 

それにしても……自分が想像する以上に遅いのがとても気になっていた。プログラマは自分が書いたコードの実行速度は想像が出来る。しかしこのエミュレータはどう考えても遅い。なんでだ??(T-T)

 

そう思って、ながーい事見ていなかった自分のコードを見てみる事に…。そしたら……なんと人の手が加わっていた!しかも実行効率がより悪くなるコードが入っていて、これが想定していない速度低下の原因だと分かった(ToT) 

過去にもプログラムを6行追加されただけで速度が1/3まで落ちるという経験をした事があり、その時にはキャッシュメモリというものを理解していない人が組むとこうなるのか…と思い知らされた(^^;

 

その部分を修正する事で速度低下は回復するだろうな…とは思ったものの、30年くらい使い続けたプログラムを一新するチャンスでもあるな…と思ったので、作り直しを決断!

久しぶりにZ80エミュレータを書くことになった!(^-^)

 

エミュレータの実装

新しいエミュレータを書く上で、いくつか気にした事があった。

 

プログラムサイズをコンパクトに!

昨今ではプログラムがキャッシュメモリに入るかどうかが大きなファクターとなる事が多く、複雑なプログラムであっても全体的に見てサイズが小さい方が速くなるケースがあり得る。

 

特に今回のエミュレータは1つ1つの関数が極単純なので、出来る限りプログラムをまとめて小さくする努力をした。ちなみに6809CPUエミュレータもサイズをコンパクトにする事で、大幅な高速化に成功した経験がある。

 

汎用性を犠牲!

PC-8801のようにCPUが複数入ってるマシンがあるので、プログラム中にCPUが1つという限定をせずに動かすようにしていた。しかし構造体のメンバをアクセスするアドレッシングが足を引っ張るため、少々汚いがグローバル変数をアクセスするようにしてリンク時にアドレスを確定するようにした。

 

CPUが複数ある場合は、グローバル変数に情報をコピーした上でエミュレーションを動かすようにすれば良い。汚い実装だけどここは速度優先だ(T-T)

 

プログラム実行をRAM上で!

f:id:PocketGriffon:20220325101926j:plain

これはRaspberryPi Picoに特化した話だが、プログラムをRAMで実行するようにした。

 

デフォルトのPicoプログラムはFlash上で実行される。Flashからプログラムを読み込まれる際、どうしても時間がかかってしまうはずなので、おそらく少なからずボトルネックになっているのでは?と思ったからだ。

 

しかし実際に試してみると、実行速度はほとんど変わらない事が分かった(ToT)

ボトルネックは別にあるって事なんだと思われる。

 

今は入れてないけれども…

6809エミュレータを書いた際、likely / unlikelyを入れる事でパフォーマンスを上げる事に成功していた。RP2040のコンパイラで有効かどうか不明だが、後ほどコードが固まってきたら入れていきたい(^^)

 

現状の結果

今の時点でのパフォーマンスだけど、大体2.6倍くらいの速度アップになった!

f:id:PocketGriffon:20220325102027j:plainf:id:PocketGriffon:20220325102059j:plain

携帯のストップウォッチで測ってるので正確ではないが、大雑把な数字としてもかなりの違いとなった!

これは嬉しい!(^o^)/

何度も作ってみても毎回思うのだが、エミュレータの開発には根気が必要だ。

ずーっと画面に何も出ない状態でコードを書き続ける必要があり、かつ書くコードは単純なモノばかり。何かまとまったものが動くようになるまでひたすら頑張り続けるのだ(^^;

 

今回は慣れたZ80の実装だったので丸1日頑張ったら動くようになってきたが、一度も使ったことがないCPUだったら数日は掛かる気がする…。

今はまだ8080+αくらいの機能しか入っていないので、これをキレイにZ80まで仕上げていきたい(^^)

 

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

 

 

2020.03.25 追記

RAM上でプログラムを実行したけど速度が変わらなかった件。

もしかしたらプログラム自体がCPUのキャッシュに収まるサイズなのかも知れない。気になってmapファイルを見て見たが、エミュレータ全体でも32KBを超えていなかった。

なので「速くならない」のではなく「遅くなりにくい」だけなのかも知れないです!

 

もひとつ(^^)

Retro PC Gallery

↑のページにマンデルブロ集合のベンチマークがあった。

これを見ると1分26秒という速さはZ80の11〜12MHzくらいの速度になるみたい。RaspberryPi Picoを120MHzで動作させている事を鑑みると、1/10の速度はワリと優秀?

コレ以上の大幅アップはありえないのかもなーと思う。

f:id:PocketGriffon:20220325213738j:plain

↑ちなみにPicoを200MHzで動作させてみると、ほぼきっちりクロック数分だけ速度が上がった!(^-^) 120MHzで1分切るのは夢ですねー(^^;;

 

RaspberryPi Picoと大型液晶で遊ぶ!

f:id:PocketGriffon:20220319165326j:plain

以前、RaspberryPi Picoに320x240ドットの液晶を取り付けてさんざん遊びまくった!

 

pocketgriffon.hatenablog.com

今回はソレを超えるサイズの液晶をRaspberryPi Picoに取り付けてみた。

サイズ的には480x320ドットと、前回よりも一回り大きい。

多分、Pico専用として売られているものでは最大サイズなんじゃない??

f:id:PocketGriffon:20220319170556j:plain

2つを比べてみると、↑こんな感じ!

f:id:PocketGriffon:20220319170855j:plain

ひっくり返すとこんな感じにPicoがついてる。

Picoの大きさから、なんとなくなサイズ感が分かるだろうか(^^;
Picoに取り付けてると言うよりは、もはやPicoがついてる感じ。

 

前回はあお氏(@hd61yukimizake)と一緒にドライバの解析改良に勤しんで、最終的にはかなりの速度が出るようになっていた。しかし毎回巻き込むわけにはいかないので、今回はひとりで踏ん張ってみる!(^^;;

 

表示、SDカード、タッチパネル

Waveshare社から用意されているサンプルは、CMakeを基本とした開発環境用のモノとなっている。これをArduinoIDE環境で使えるように変更していかないといけない。

 

今回はきちんとサンプルコードを探したので、比較的簡単に画像を表示させる事が出来た!

f:id:PocketGriffon:20220319172336j:plain

表示させるだけだったらそこまで難しくない。

プログラムの移植を始めて、30分後には絵が出た感じだ!

だけど……恐ろしく表示が遅い(T-T)

 

画像データは(まだこの段階でSDカードが使えないので)Flashメモリに入れてある。アクセス速度はそこまで遅いはずがないんだけど、サンプルコードを実行すると表示し終わるまでに約1秒掛かる。

 

画像をメモリに置いてあるのに1秒って…orz

さすがにこのままではちょっとアレなので高速化する事に(^^)

転送するビット幅を8bit→16bitに変更、2バイトずつ転送していたのをまとめて転送するように変更、そしてSPIの周波数を60MHzまで上げてみた。

 

この変更で、全画面表示に掛かる時間が0.1秒(100ms)ほどとなった。

さらなる高速化をするためにはDMAを利用するなどの工夫が必要かも?

 

 

前回使っていた液晶(320x240ドット)と、今回の液晶(480x320ドット)で、実はピンの配置が全く同じだと気がついた。ということは、SDカードとタッチパネルのプログラムがそのまま使えるのでは???

 

そう思って移植したのだが、どうやらSPIの競合?が起こるらしくて、動作コアを別にした瞬間に問題出まくりとなった(T-T) うーん、回避するコードを入れてみるが、もう少し素直な(ちゃんとした)方法がある気がしてならない。

 

それでもSDとLCDで同時アクセスしないようにしたらすこぶる安定した!

 

そしてタッチパネルについてはキャリブレーションしないといけないのか、まーったく安定しない…。全体的に不安定になってしまうため、今回は使用を諦めた(T-T)

 

何かを動かしてみたいけれども…

一通りの機能を確認出来たので、せっかくだから何か作ってみたい!

いろいろと検討してみたけれど…画面サイズの480x320というのが意外に難しい!(@_@;

 

例えばPC-8801PC-9801を動かしてみたいと思えば、横640ドットのサイズを480ドットに縮める必要がある。それって横4ドットを3ドッドに縮めないといけない。

さらに縦については5ドットを4ドットに縮めないといけない。

これは……どう考えても簡単じゃないのでは??(T-T)

 

他にもPC-6001とかMSXとかレトロマシンを検討してみても、やっぱり画面サイズがしっくり来ない。大きな画面も良し悪しだと思い知らされた(ToT)

 

CP/M-80を動かしてみた!

もはやワンパターンすぎて飽きてきてる思うけれども…今回もCP/M80を動かしてみた!

せっかくの大きな液晶なので、PC-9801フォントを使ってお気に入り画面にしたい。

ただ…98のANKフォントは8x16ドットサイズと素直に表示すれば60x20キャラクタとなり、480x320ドット液晶とは相性がよろしくない。

 

まず画面に25行を表示させるためには、縦12ドットのフォントを用意する必要がある。キレイに表示させるために、小文字のgやyなどを少し修正した。これで縦方向はキレイに12ドットに収まった!

 

横方向については横6ドットの80桁表示と、8ドットの60桁表示をサポートした。

f:id:PocketGriffon:20220319182322j:plainf:id:PocketGriffon:20220319182341j:plain

こんな感じでどうだろうか?(^-^)

 

CP/Mということで、キー入力は絶対にやってみたいと思い検討してたのだが…PicoのUSBホスト機能を使おうとすると、標準のUSB端子以外から電源を入れないといけないらしい。

 

……どうやって?(^-^;;;

GPIOのピンから電源入れるとかするらしいんだけど、よくわからん(T-T)

 

そんな事を検討している流れから、そういえばArduinoIDEのシリアルモニタから文字を入力出来る事を思い出した!

f:id:PocketGriffon:20220319183638j:plain

これでリアルタイムではないにしてもキーが入力出来れば…目的は果たせそうだ。

Serial.read()という関数を使えば文字取得が出来る。

これを利用してCP/Mへ文字を入れる事が出来るようになった!

 

ちなみにここに漢字を入力してみると、プログラム側にutf-8コードが渡る。

何かに楽しいことに使えないかなぁ…とワクワクしちゃう!(^-^)

 

おわりに

もはや……何度めのCP/M80移植??(^-^;;

 

何度も移植はしているけれども、移植するたびに対象マシンの制限などを考えて実装していくのが楽しい。メモリ、画像、ストレージその他考えないといけないことはたくさんある(^^)

f:id:PocketGriffon:20220319184132j:plain

私的には大好きなスタートレックが動くマシンが増えていくのが楽しくて仕方ない(^-^)

 

f:id:PocketGriffon:20220319184048j:plain

 

 

液晶は単純に大きければいいってワケじゃないんだな…と思いしった!

メモリ、速度、そもそものドット数とやはりバランスは大事だ。

また何か良さげな活用方法が見つかったら試したいと思う。

 

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

Waveshare RP2040-LCD-0.96で遊んでみた!

f:id:PocketGriffon:20220318110005j:plain

今回は、つい先日スイッチサイエンスから発売になったWaveshare RP2040-LCD-0.96を入手したので、これを使ってプログラミングしてみた!

 

www.waveshare.com

見た感じはRaspberryPi Picoに小型の液晶が載った感じで、メーカーとしては「Pico-like」ということでPicoっぽいモノ(つまり互換品)となっている。

 

チップにRP2040が使われている事から、使う側からしたらPicoそのものな感じで、違いを見つける方が大変かもしれない…?

 

f:id:PocketGriffon:20220318110954j:plainf:id:PocketGriffon:20220318111015j:plain

LCDが載ってる分、少しだけ重要があるが、誤差の範囲だ(^^)

いや、そんな違いはどーでも良くて(^^;;

 

使い方はRaspberryPi Picoと全く同じで、bootボタンを押しながらUSBを挿せばホストマシンにドライブとして見えてプログラムを送り込める。

f:id:PocketGriffon:20220318111540j:plain

ちなみにUSBポートはTYPE-Cだ。

Waveshare機にはリセットボタンがついており、これがとても便利!

RESET押す→BOOTを押す→RESETを離す、とすればプログラムを送り込む状態になる。いちいちUSBを引っこ抜いたり、USBの電源を操作したりしなくても済むので、私は毎回活用している!(^-^)

 

LCDに表示させてみたいんだ!

さて、普通に使う分にはRaspberryPi Picoと同じだけど、せっかく液晶が取り付けられているのだから、これを積極的に使っていきたい! 

そうしないと単なるお荷物LCDだ(ToT)

 

この液晶パネル、Sitronnix社のST7735Sというらしい。

www.switch-science.com

↑リンクの資料にST7735SのPDFへのリンクが貼られていた。

 

これを参考にしながらLCD制御プログラムを書いていくんだが…パワーオンシーケンスがまとまって書かれてなくて、とても苦労する!(TOT)

しかも初期化の順番なども分からず、こりはどーしたら良いのか…またしても枕を涙で塗らすのか…orz

 

何時間か格闘したのちに「サンプルがあったらいいのになぁ…」とふと思う。

あれ…そういえばサンプルあるはずだよね…無いなんてことある?

そう思って探してみたところ………

あああああぁぁぁ…(断末魔

www.waveshare.com

↑上リンクのResourcesタブにDemo Codesというのがあった(T-T)

またしても気が付かなかったよ!!(ToT)

 

この中に含まれているLCD_0in96ほにゃららというファイルを見ていけば、LCDの制御方法が書かれている。ファイルはLCD以外のハードも扱おうとしているため少し大きいけれど、液晶部分だけを抜き出して自分用に書き直した。

 

そういえばArduino系のLCDはSPI0に繋がってる事が多い気がするけれど、RaspberryPi PicoではSPI1に接続されているケースが多いような気がする。SPIのポートなんて意識しないと気が付けないYo!(ToT)

 

元のサンプルがすでにハードウェアSPIを使うようになっていたが、もう少しだけ最適化して速度を出せるように改良。

f:id:PocketGriffon:20220318114330j:plain

イッパツでこの絵が出たときは本当に嬉しかった!(^-^)

速度的には160x80xRGB565=25KBを転送するのに3.8msと結構速い。理論的には秒間250回以上も書き換えが出来る!

 

スクロールさせてみる

無事に静止画は表示出来たので、次は大きなマップをスクロールさせてみる実験をしてみる。

実験の目的としては、常時フレームバッファを書き換えつつLCDへ転送を繰り返すのに、どのくらいの時間が掛かるのか…という、まぁ良くやる感じの事をしてみたいだけだ(^^;;

 

手元にXevi○usのマップデータがあったので、これを活用してみる。面倒だったので無圧縮で全データをFlashROMに入れておこうと思ったら、4MBもあって入らなかった…汗

仕方ないので、横160ドットの範囲のみ切り出してROMに載せる。

これだけでも640KBの容量があった!

 

最適化も何もしていない状態だけど、かなり速く動く事が分かった。

フレームバッファ自体が小さい事(25KB)などもあるんだろうけど、毎回表示用のマップデータをFlashROMから引っ張ってきてるのに、この速度で動くんだ…と関心(^-^)

 

ポリゴンぐりぐり

前にSMART Response XEでポリゴンを動かそうと頑張った事があった。

pocketgriffon.hatenablog.com

このプログラムの元は、1992年に某アセンブラで書かれたもので、それを2003年頃にC言語で書き直していた。

 

これをSMART Response XEへ移植しようとしたのだが、CPUのアーキテクチャが違ってて簡単には移植できず諦めていた。

今回のPicoは32bit ARMだし、きっとうまくいくはず…と思い、頑張って移植してみた。

 

1992年当時のプログラミングレベルで書かれているので、とっても素直な3Dエンジンとなっている。久しぶりに見たらクォータニオンでなくて回転行列で書かれてた!(^^;; そんな時代か!!

PicoでOpenGLなどが使えたら超簡単なのに…と思いながらも頑張って移植w

とっても基本に忠実に書かれていたプログラムなので、移植もその流れで直線描画→三角形描画→多角形描画→3D2D変換みたいな感じで進めていった。

 

f:id:PocketGriffon:20220318120707j:plain

上の写真はポリゴンを描画出来るようになった時に撮影したものだが、速度が速すぎてシャッター速度がついていけてない??

 

クリッピングしつつ描画してこれだけの速度が出ると、いろいろと期待してしまう(^^;

 

最終的に出来上がったのがコレ。

めちゃ速い三角形描画処理からみたら、だいぶ遅くなってる…。3D演算を最適化していないので、多分処理が重いんだと思われる(T-T)

最適化してみようとソースを見たら、当時の苦労が忍ばれて涙が頬をつたっちゃいそうだったので、今回は辞めておいた(^^;;

 

夢が広がるけど…

そういえばDMAを使った最適化をまだやってなかったな…と思い、フレームバッファの消去をDMA化してみたところ、速度が2倍になった!

こんな感じに、Picoでの最適化はまだまだ道が残されていそう。

究極を言えばCPUコアが1つ空いたままになってる(^^;;

 

液晶がついたPicoということで、本来の用途はべつのところにあるんだろうけれども、これはこれで本当に面白いマシンだと思う(^^)

使ってみた感じ、Picoとの違いは分からなかった。世にたくさんあるPico用プログラムがそのまま動かせる魅力も大きい!

 

個人的な欲を言えば、LCDのドット数が160x100あればPC-8001が動かせたのになぁ…とは思う。もっともPicoのパワーだったらラクに実機同等の速度で動いちゃいそうだけど(^^)

 

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

RaspberryPi PicoでPC-1360エミュレータ!

f:id:PocketGriffon:20220316214213j:plain

 

今回はRaspberryPi Picoの小型液晶に挑戦してみた!(^-^)

ついでにPC-1360エミュレータも動かしてみたのでご紹介したい。

ちなみに今回もひどーく苦労した(T-T)

 

f:id:PocketGriffon:20220316174009j:plain

今回使ったのは、スイッチサイエンス社から販売されている小型の液晶。

一連のPicoで小型液晶を使うにハマっていた時に、一緒に購入していた。

 

www.switch-science.com

↑これ!(^-^)

 

f:id:PocketGriffon:20220316181759j:plain

裏にひっくり返せば、RaspberryPi Picoが張り付いている。

 

f:id:PocketGriffon:20220316181858j:plain

斜めから見ると下にPicoがついてるのが分かる(^^)

 

このボードのLCDにはAQM1248Aというものが使われているらしい。

ポピュラーな液晶なんだろか??

久しぶりすぎて液晶の制御なんて覚えてないなー(T-T)

不安があるとすればソコだけかも…?

 

画面に何も出ない!

せっかく手に入れたからには使ってみないともったいない!

プログラムを組んでみようじゃないの(^^)

 

そう思って、開発資料が欲しくて↑スイッチサイエンスのページを見に行ったけれど…基板仕様接続ポート一覧という情報のみがあるだけで、サンプルプログラムとか載ってない…。

 

世の中のプログラマさんは、これらの情報だけでプログラム出来るんだろうか…(-_-;

私も1年前だったら「面倒だからやーめた」になっていたかも知れない(^^;;

でも今だったらチャレンジしてみちゃうぜ!!!

 

…と思ってやりはじめたけど、まぁ当初の予想通りうまくいかない(T-T)

相変わらずGPIO、SPIなどの言葉が、概念的にもすっきり頭に入っていないので、何をどうしたら画面が表示されるのか突破口が見えない。

 

スイッチサイエンスのページからAQM1248Aの資料ページに飛べる。

https://akizukidenshi.com/download/ds/xiamen/AQM1248.pdf

f:id:PocketGriffon:20220316181549j:plain

これを見ながら、データの出力方法や初期化などを拾っていく。

そう、これを見ればコマンドやデータの送信方法や、LCD自体の初期化方法は書かれてる。問題はSPIの初期設定をどうすれば良いのかがさっぱり分からないのだ(T-T)

 

Arduinoの資料を見つつ、LCDの資料とにらめっこをしながらプログラムを組み立てていくが、全然うまくいかず改良してるのか改悪してるのかすらもわからない。

画面を見てもピカとも反応せず、挙句の果てにはこの液晶、壊れてるんじゃないかな…と疑い出す始末…(^^;;

 

結局、その晩は何も進展が無く、枕を涙で濡らしつつ寝る事に(T-T)

 

布団に入りながら考えてみたが、そういえばArduinoの資料を見ていたけれど、コントローラはRaspberryPi PicoなんだからRaspberryPiの資料を見ないといけないのでは…と気がついた(^^;

 

それが突破口となり、翌日には無事に画面に絵を表示させる事が出来た!!

f:id:PocketGriffon:20220316184552j:plain

ひー!苦労した!!!(T^T)

やっぱりGPIOとかSPIとか苦手かもなぁ…。苦手というか理解が及ばないというか。

数こなせばもう少し分かるようになるんですかね…?(-_-;;

 

分からない事を少しだけ書いてみると…

例えばSPIの初期化にはSPI.beginとspi_initがあり、どちらもエラー無く呼べてしまう。

同じようにdigitalWriteとgpio_putというのがあり、これらは何が違うのか…。

こういう似て異なりそうなものがさっぱり理解出来てない(T-T)

なかなかハードルは高そうだ!!

 

さて、出来上がったのはハードウェアSPIによるデータ転送プログラム。

全画面を書き換える時間は、約1msとかなりの高速。

データ量が768バイトしかないからそんなモンかも…??

よっし、これで表示に関する不安は無くなった!ヽ(=´▽`=)ノ

 

PC-1360を載せてみる!

せっかくの横長のモノクロ液晶なんだから、ポケコンを動かしてみたいよね!

PC-1360のRAY FORCEが動いたら面白そうじゃん!と、ワリと気軽に検討を始める。

移植し終わってから気がついたが、Picoの小ささよ(^-^;;

f:id:PocketGriffon:20220316215714j:plain

 

ROM

まず最初に気になったのがROMサイズ。PC-1360はシステムが大きくなった分、ROMもでかいサイズを積んでる。16KB * 8バンクで128KBものサイズがある。

これをそのままPicoのRAMに載せる事も出来なくはなさそうだけど…ここはFlashメモリに置いたままにしてアクセスした方が良さそうだ!

Flashは2MBもあるので、今回はどう頑張っても埋められない(^-^)

 

RAM

RaspberryPi PicoのRAMは256KB以上あり、PC-1360の実装では余裕だった!

標準構成のPC-1360は8KBの拡張メモリが添付されているが、今回のエミュレータでは32KBの拡張メモリを(仮想的に)載せている。

それに加えて、$2000からの8KBにウソっ子メモリ(本来ならばPC-1360には存在しないRAM)も載せている。

これらを積んでもメモリ的にはかなり余裕のPico!

いいね!(^-^)

 

表示

PC-1360を動かしてみよう!……って考えてた時、なぜ横幅のドット数が足りないと気が付かなかったのか…(^^;; なんか完全に思考の外にあって「大丈夫!」と思っちゃってたんですよね…汗

 

この液晶、横が128ドット縦が48ドットの構成となっている。PC-1360は150x32ドット。横方向に22ドットも足りなくなってしまった!

仕方ないので、画面の右側は映らない仕様としてしまった…。

こんな重要な部分、割り切って良いところなんだっけ?(T-T)

画面を目一杯使ったプログラムを動かすと、残念ながら右端は見る事が出来ない(T-T)

 

内部的には256x64ドットの表示バッファを確保してある。横方向を256にした意味は正直あんまりない!乗算が出来るCPUなので素直に150にしとけば良かったじゃん…と思う(^^;

LCDのドットフォーマットとPC-1360のソレが同じなため、複雑なドット変換せずそのまま素直に書き込めばドットが表示される。

 

キーボード

今回は完全にノーケアとした。
いつかUSBキーボードに繋げてみたい野望は持ち続ける!(^^)

 

PC-1360の実装!

過去にM5Stackへ移植したプログラムを、ほぼそのまま持ってきた!

M5Stackに比べてPicoはSDカードが無い、RAMが大きくないなど細かな違いはあったけれど、むしろプログラムは楽になる方向だった。

 

SDカードにアクセスしていたものは全てプログラムに内包し、ビルドする事でFlashメモリに配置されるようになった。楽ちんその1。

 

全てのメモリアクセスは1つの関数にまとまっていたので、FlashROMに置かれているPC-1360のROMをアクセスする部分も、この1箇所(しかも1行!)を書き換えるだけで対応出来てしまった!楽ちんその2(^^)

 

PicoはCPUのコアが2つあるので、CPUエミュレーションと画像表示を別コアに割り振った!

……んだけど……速度が速すぎて…なんだこれは???(@_@;;

CPUエミュレーションも画像表示コアも、大体90%が休むという異例の状態に……汗

あれ?Picoってこんな早かったっけ???

PC-1360が遅いのかな…そうかも??

 

おわりに

結局、夜に液晶を取り出して一晩悩み、翌日の夕方にはPC-1360が動いてしまった!

この手のエミュレータは移植がとてもしやすい(^^)

 

まぁサウンドもキー入力も実装していない時点で、人に見せられるものでは本来ないのですが(^^;; 自己満足ということで許してほしい!

 

Picoに関して言えば、まだ他にも周辺ハードをいくつか手に入れてあって、この先も楽しめそうだ!

f:id:PocketGriffon:20220316213952j:plain

それぞれのハードにPicoがつくため、取り外しが面倒で1ハード1Picoにしてしまってる!このご時世で珍しくPicoは手に入りやすいので、ちょっと贅沢だけどこの先もそうするよ!

あと4Picoもすでに手元にある!(^-^)

 

やっぱPico楽しいなぁ!

プログラムしやすいハードだと思う!(^^)

 

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