CM4Stackで遊んでみる!

 

今回は、新しく発売されたCM4Stackのお話(^^)

 

 

なんとなくの見た感じ、サイズ感がM5Stackを彷彿させるもので、まだ発売されたばかりのマシンだ!

M5Stack CM4Stack 開発キット CM4104032搭載www.switch-science.com

 

おそらくArduinoからの流れを組む、比較的簡単にハードウェア制御が出来るミニコンピュータという位置づけなのだろう。

ハードウェアを全く理解していない私にとっては、小さな液晶とコンピュータがパッケージングされたモノ、という感覚だ(^^;;

多分、ポケコンなどからの流れでこういう(CPU、キーボード、液晶がついてる)マシンが好きなんだろうなーと思う。

M5Stack系の良さをほとんどと言って良いほど使えてないのは自覚してる!(^^;;;

 

CM4Stack

初めにCM4Stackの名前を見てピンときた。

この界隈でCM4といえばRaspberryPi Compute Module 4が思い浮かぶ(^-^)

身近なところではreTerminalだったりDevTerm RPI-CM4 Liteに入ってたりする。

このボードがM5Stackの筐体に入っちゃうんだろうな…。

 

そして実際に販売されたCM4Stackの中身にはCM4が入っているんだと思う。

分解してないから見てないけど(^^;;

ということは中身はLinuxマシンなんだろうな…と予想がつく。

 

TwitterなどにCM4Stackの映像が流れるたびに「どうしようかなぁ…」と悩んでいた。

なぜかと言えば、私は小型のLinuxマシンをいくつも所有してる!

すぐに使える形になっているものもあれば……

箱に入ったままの新品も多数所有している。

つまりいつでもLinuxマシンは使える状態にあるのだ!

こんな状態なのに、さらに新しいマシンを手に入れる必要はあるのか…と葛藤!

 

散々葛藤した挙げ句、決めた!

一個だけ手に入れよう!(^-^)

よし、一件落着♪(^o^)

 

届いたCM4Stack

CM4Stackが届いてからの開封の儀式はいろんなところに出ていると思うので、私は使い始めるところから!(^^)

 

最初はHDMI経由のモニタ、USBにマウスとキーボードを繋げて、付属の電源と本体を繋げる。HDMIで繋げたモニタにはRaspberryPiで見慣れたデスクトップ、液晶にはCM4 STACKの表示が出る。

ネットワークケーブルを接続しておけば、液晶画面にIPアドレスが表示される。

HDMI側のモニタを操作をしてSSHを有効にすれば(raspi-configを使うのが楽ちんだよ!)、その後はssh経由でログインする事が出来る。

 

そしてログイン出来てしまえば………あとは普通のLinuxマシンだ(@_@)

おもむろに cat 適当なファイル > /dev/fb0 としてみる。

お、液晶画面側の絵が壊れた!(^-^)

よーしよーし!!(^o^)

…と思ったら、メモリ使用量とロードアベレージの数字だけが再表示されてしまった…。

(ここの写真を取り忘れる痛恨のミス!)

 

どのプロセスが表示させてるんだろう…とあれこれ探すが見つからない…。

うーん、どうしようかな…。

でも先にOSの再インストールをしてみる事した!

 

docs.m5stack.com

基本的には書いてある通りの手順で問題なく進んだが、私は過去にreTerminalのOSをアップデートする際、rpibootをMacにインストールしていた。

その部分は手間が省けたので楽チンで済んだ(^-^)

 

OSをインストールし直したら、液晶画面に表示されているCM4 STACKの表示が消えた!

私の使い方だったら復活させる必要もないかな…って事で、このまま使う!(^-^;;

 

とりあえずX68000

今回はX68000エミュレータを動かしてみたら、それで満足しそう!

だってFM-7とかPC-8801とかCP/M80とか、もはや動くのが当然なスペック…。私としては「メモリもない、CPUパワーもない。でも動かしてみる!」が好きなので、CM4Stackではスルーしようかなーと思ってるw

 

フレームバッファへ直描きするX68000エミュレータと言えば、過去にポメラDM250や、電子手帳Brainなどで何度も挑戦している!

pocketgriffon.hatenablog.com

pocketgriffon.hatenablog.com

pocketgriffon.hatenablog.com

pocketgriffon.hatenablog.com

このプログラムをssh経由で持ってきて、なーんも考えずにmakeってすれば、一発で動いたりしないだろうか…?(^-^;;

 

あー……さすがにそこまで甘くなかった(^^;;

CM4Stackのフレームバッファは深度16bitだったので、(最初のポメラ用に書かれた)深度32bitを前提に書かれたプログラムの一部は修正をした(^^)

 

どうやら画面を90度回転させてやる必要があるみたいだ!

単純に縦横を入れ替えるだけなのでプログラムは超単純だけど、離れた位置にあるメモリを頻繁にアクセスするためキャッシュがミスしまくって劇遅になる…とかないだろうか??

… → やってみたら全然気にする感じでは無かったんだけどね(^^;;

 

無事に横向きに表示された!(^-^)

 

ちなみに画面に入り切らない部分については、無理に圧縮して表示などはせずはみ出たところは表示しないという消極的な方法を取ったw

実用性よりも動くことを優先させた結果だ!←言い方

 

サウンドジョイスティックに対応させた。

この辺りは普通のLinuxプログラムなので、目新しいところが何も無い…(-_-;;

 

おわりに

とにかく速いCM4Stack!

このサイズでこのメモリとパワー……かなりのオーバースペックなのでは?(^^;

 

使っていると動いてる時間の半分くらいはファンが回りっぱなしとなる。今の時期でも回ってるので、夏場は熱対策が厳しくなるかも知れない。私は小型のファンを回して冷気をCM4Stackにあてながら作業をしていた。
そうしないと大変熱くなるのだ(^^;;

 

M5Stackの最新ハードという事でいそいそと手に入れてみたけれど、私のような明確な目的も無く手に入れてしまうと、過去の資産を動かして終了となってしまう(^^;;

 

 それよりもCM4Stackの魅力は外部ハードとの連携があるんだろうから、そちらに強い方が触ったらもっと魅力を発揮できるんだろうなー…汗

 

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

16進ダンプ入力ツールを作り直した!

先日からはてなブログのランキングというのに参加している!

特になにかあるわけではないけど、せっかくなので…という程度の理由!(^^;

よかったら上のバナーをクリックしてくれると嬉しいです!(^o^)

 

先日、ブログやTwitterでダンプリスト入力ツールを作ったというご報告をした。

趣味…というよりは、とある件で必要になってしまったため、急遽作成って感じだ!!

 

pocketgriffon.hatenablog.com

仕様検討もせず急いで作ってしまったからか、使い始めてみると色んなところに不満を感じるようになった!

 

 拡大表示は必要なかった!

 右側のアスキー文字は見る機会がない

 画面に並べた時、小さいウィンドウの方が扱いやすい

 OCRでの取り込みがツールの外でしか出来ない

 ページの関係でダンプが2〜3つに分断してる事がある

 

これら以外にもプログラムの内部構造が良くなかったりなど、不満を上げたらキリがない!

こんなたくさんの改良をするのならば、いっそ作り直そう!となった(^^)

 

そして新規に開発したのが↓コチラ↓

見た目はそんな変わんないじゃん!と言われそうだけど、まさにそう(^^;

でも内部構造は大〜きく変わった(^-^)

描画に対する処理負荷もかなり改善された!

 

まず大きさだけど、こんな感じの違いがある!

ダンプリストの編集を見つつ、撮影したダンプリストの写真を同一画面で見ていたりすると、そのたびに大きな編集ウィンドウが邪魔になっていた。

アスキー文字は思ったよりも見てなかったので、思いきって削った(^^)

 

OCRはYao Tadahito(八尾 唯仁)さん(@eighttails)のHEXモデルを使ったら、精度が爆上がりする事がわかった!

 

このおかげもあり、この先は手入力よりもOCRが中心となるであろう未来が見えたので、拡大文字自体が必要なくなってしまった!

前回の目玉機能だったのにww

 

まずは素の状態で起動するとこんな感じの画面が出る。

前作にあったEmacsバインドのカーソル移動はそのまま継承している。

テンキーには対応して無く(ウチのMacBookProにはテンキーがそもそもない…)、あくまでもフルキーでのみ入力が可能だ。

 

一番下の「読んでいるファイル」の表記は、撮影用に名前消し機能をつけた!

私の名前限定だ!ww

 

↑ESCキーを押すとメニューが表示される。

1980年代のメニューっぽく見えるが、完全に作者の趣味だねw(^o^)

実はMacのメニューバーにメニューを追加する方法を知らないのですわ…orz

SDLで(ソースレベルで良いので)Mac/Linux/Windowsの互換性を保ちつつ、どうやったら出来るんだろ??(-_-;

 

大した意味もなくAbout画面も用意した!

こういうのにも凝りまくってテンションあげていくぜーw (^^;;

 

メニューからOCRを選ぶと、こんな画面が出る。

このためだけにファイラー作った!(^-^;;

それっぽいファイラーを作るのって1992年以来なので30年以上ぶりだ!

当時はX68000で作ったなぁ…(遠い目

 

そしてカーソルを動かしていくと、右側に画像を表示する機能をいれた。

これはOCRするたびに「あれ??次はどの画像ファイルだっけ?」と中身を覗いていた苦い経験からだ(TT)

主にアドレスが確認出来れば良いので、画像の左上しか表示させていない(^^)

 

↓リターンを押せばOCRが実行されて……(画面上部にメッセージ)

 

↓終わるとこんな感じに、認識した文字列がずらずらーっと表示される。

実際のOCR処理は、

OCRで認識されやすいように画像加工

・tesseract実行

・出力されたテキストデータをもう1段階加工

などをしてデータを整頓している。

一応、tesseract以外でも認識率があがる努力はしているつもり(^^)

 

アドレスで入力状態になっているのは「OCRで認識したアドレスはコレだけど、ホントにあってる?間違ってたら修正して」という意図だ。

 

いったんデータをメモリに書いてしまうと取り消す事が難しいため、ここで使用者のチカラをアテにして、確実にアドレスを確定させる。

 

メニューを終えて戻ると、さっきOCRで読み込んだデータが見える…という感じだ。

ちなみにこの画像だと認識率100%!

100%ってすごくない???(@_@;;;

 

データとチェックサムが違っていると、こんな感じに赤文字でどこが変か教えてくれる。

この場合、データもそうだけどチェックサム自体が間違ってる可能性もある。

 

そこで使うのがメニューにあるCheckSumモード。

ここで正しいチェックサムを入力する。

そうするとデータがおかしいのか、チェックサムがおかしいのかがわかる…という事だ(^^)

 

あとダンプリストの掲載で良く見かけるのが、ページをまたいだブロック!

今までは複数ページにまたいでる部分は、素直に手入力をしていた。

そんな数が多いわけじゃないからいいでしょ…と(^^;;

でもコレも可能ならばOCRで読み込んじゃいたい!

そこで、今回はこのページに跨いだデータもOCR出来る機能を入れてみた!

 

↑こんな感じに切り取った写真データを用意する。
縦横の幅は特に意識しなくても良い(ツール側でよしなに合わせてくれる)

 

↑ファイルの上でスペースを押すと、そのファイルが選択される。

選択された画像を合成することで、一気にOCR処理をしようって魂胆だ(^^)

ファイルの頭に番号がついているのは、どの順番で画像を合成するのかの指定。

この辺りの実装のダサさも良い感じだw

 

ぐは!

合成したデータであっても認識率100%が出た!(^o^)

 

おわりに

手入力が好きなんだぜ!

……と言い張って開発したダンプリスト入力ツールだったけど、気がつけばOCRに便利なツールが出来上がってしまったw

 

実際に使ってみると…これだけダンプの認識率が高いと、すごく手軽に入力が出来る。

写真さえ撮ってしまえば、あとはほぼ単純作業だ!

むしろ写真を撮って加工する方が圧倒的に時間がかかる!(^-^)

 

横8バイト並びのダンプなどにはまだ対応していないが、プログラムのいたる所に布石だけは残してあるので、対応する事自体はそんなに難しくない…と思われる!(^^)

 

よーし!今まで入力を控えてたゲームも入力してみるぞ!(^^)

…はて、入力したデータって、どうやってエミュレータに入れ込むんだっけ?(^-^;;

 

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

 

MacでMSXのプログラムを作る!

2023年3月12日に秋葉原UDXにて行われた、MSX DEVCON3に参加した。

その時、会場にM5Stack Core2を持参すれば、今現在のMSX0を書き込んで送り返してくれるということだったので、私もお願いする事とした。

 

よくよく考えてみると、MSXでキチンとプログラムを作ったのは1990年が最後。

それ以降、3年くらい前にFS-A1ST(TurboR)が出土するまでの間、触ったことがなかった。

 

思えばMSXで初めてアセンブラというモノを使った(それまではハンドアセンブル)。

自分にはマシン語プログラムで256バイト以上のものは作れないだろうと思い込んでいたが、アセンブラを使用する事でこんな簡単になるんだ!と驚いた覚えがある(^^)

 

当時入っていた大阪のマイコンクラブで行われていたプログラムコンテストに参加するために奮闘したのをきっかけに、Z80アセンブラがスラスラ書けるようになった。

 

その後、なにかのきっかけがあり、マイコンBASICマガジン1982年11月号に掲載されていたPC-8001用のCOSMO MISSILEというゲームを、目コピーでMSXへ移植した。

オールマシン語のプログラムもこれが初めてだった!(^^)

↑今でもソースファイルは手元に残っている。

アセンブラソースファイルで57KBにもなった(コメントが多い)。

当時は中二病のようなペンネームを使っていたので、自己保身のために隠したww

 

MSXでCコンパイラ

今の時代にアセンブラZ80をバリバリ書くのも楽しいけれど、もう良いお年頃でもあるので、速度を要さない部分などはできるだけ手軽に書きたいのがホンネだ(^^;;

 

そこで、今使えるZ80のCコンパイラを探してみる事。

 

まず有名なのはMSX-C

今回のMSX 0 M5Stackにも入れると西和彦さんが表明してくださっている。

せっかくあるツールならば使わない手はないだろう(^-^)

ちなみに製品版の場合、MSX-Cを使うためにはMSX-DOS2 TOOLSが必要で、さらに日本語MSX-DOS2も必要になり、当時だいぶ泣いた(T-T)

MSX-Cを活用する場合には、実機(MSX0 M5Stack)上で動かす必要がある。現在の開発環境としてはどうだろうか…。

 

ちなみにMSX-CはZ80のコードを出力するんだろうか?それとも8080コード限定なんだろうか…。使っていた当時、あんまり気にした事が無かったけれども…汗

 

 

次に思い浮かんだのはSDCC

sdcc.sourceforge.net

SDCCは、2008年頃に某書籍を執筆しようとしている時に利用していた。

結局、書籍自体が頓挫してしまったため世には出なかったけれど…汗

 

そして2020年、HC-40のプログラムをするためにも活用した。

pocketgriffon.hatenablog.com

2008年頃に使用したSDCCとはオプションの表記が変わっていて、全部調べ直す事となった。コレは想像よりもだいーぶ苦労したよ…orz

 

今であればSDCCを利用するのがオススメだと思う。

WindowsでもMacでもLinuxでも使用できるメリットは計り知れない(^-^)

 

 

そして私が大好きなLSIC-80

これは商用コンパイラなんだけど、長年(少なくとも20年以上!)使っている。

そのおかげで初期のセッティングに慣れている事や、コンパイラが出力するコードを理解しているため、人間最適化がしやすかったりして、個人的に気に入っている。

 

ただ、問題があるとすれば(私が所有しているパッケージでは)Windows環境でしか動かない事だ…。MS-DOS環境ではなくてWindows環境だ。これはMacユーザーには敷居が高い。

 

だけど!

今回はWineを利用する事で、M1 Mac上でWindowsアプリを動かす事が出来た!

思ったよりも快適に使えているので、備忘録を含めて残しておこうと思ったのだ!

この記事は誰得?!(^^;;

 

M1 MacWineを使う

今回やりたい事は、M1 Mac上でIntelコードで書かれたWindowsアプリを動かしたいだ。

異なるアーキテクチャのものを動かすので、結構厄介かも知れない…(^^;;

 

zenn.dev

M1 MacにWineをインストールする方法は、上の記事を参考にさせていただいた!

有益な情報を残してくださった筆者様には感謝しまくりだ!(^-^)

 

インストールしたWineでLSIC-80が動くか試してみる。

よしよし、なんとなく動きそうな予感だ!

実際にコンパイルしてみよう。

あら??cppがないと怒られた。

 

実はlcc80.exeはコンパイラドライバであり、内部でプリプロセッサやパーサーなどを順次呼び出すようになっている。

そのため、実行パスを通しておかないとコマンドを見つけられないようだ。

 

Wineプログラムへパスを渡すためにはWINEPATHという環境変数を設定するらしい。

ここでハタと困った…。

WINEPATHへ渡すのは、Macから見た絶対パス?それともWineから見たパス??

どちらも試してみたところ、どうやらWineから見たパスを渡すようだ。

 

Wineから見たCドライブは、~/.wine/dosdrives/c:/ となる(実態はdrive_c)。

そこにLSIC-80本体を入れつつパスを通す。

 export WINEPATH=C:/lsic80/bin; wine lcc80.exe hello.c

 

これらの情報を暗記したままにするのは無理なので、急いでMakefileを書いていく!(^-^;

 

プログラムを作る

さて……MSXのプログラムを作るのは、以前turboRを発掘して以来だ!

出てきたturboRはFDDが空回りする現象が出ていた。修理してみようと頑張ったけれど、当時の私の修理技術ではまともに直す事が出来なかった…orz

仕方ないので、SDカードが刺さるカートリッジというのを手に入れた!(^o^)

そこにFlashAirというWiFi付きのSDカードを差し込んで、最新の開発環境を満喫した!

 

「FiashAir MSX」で検索したら、当時のツイートが出てきた(^^;;

 

出来上がったCOMファイルを、単純にファイルコピーしてMSX側で実行する事が出来たので、本当に便利だった!

 

この本を参考にしながらFlashAirのセッティングをしていた。
FlashAir側にこんな設定が出来るなんて知らなかった!この本に出会わなかったら、便利な環境は作れなかっただろう!(^-^)

 

今、このカートリッジは親しい友人に貸してしまっているため手元にはない。

そんな状況でどうやってMSXの開発をするか…。

というわけで、今回はエミュレータ(fMSX)を使うことにした!(^^)

 

作ったプログラムをディスクイメージに固めてMSX側でコマンド名を入力して実行して…という過程を想像していたら、ちょっとコレは面倒カモ??と思ってしまった。

ROMカートリッジのヘッダを付けるなりして、なんとか自動起動が出来ないだろうか…。

久しぶりにテクニカルハンドブックを引っ張り出す!

この本には本当にお世話になった!(^-^)

使いすぎてボロボロになってしまっているけれど、まだまだお世話になりそうだ!

 

これを見る限り、ROMヘッダを偽装(偽装?!)するのは簡単そうだ!

 

…あれ?
アセンブラってこれだけで済んじゃう??(^-^;;
あ、アセンブラ自体はLSIC-80付属のrz80.exeを利用している!
 

ちなみにスタック領域については、テクニカルハンドブックに載っていたワークメモリマップを見て、F380h以前ならば大丈夫なのかも…と思って設定している。
もっと適切な場所があるようならば助言いただけると助かります!(^^;;
 

C言語で書いたプログラムはこんな感じ。
 
MSXのブートシーケンスはちゃんと理解していないけれど、カートリッジプログラムに制御が渡ったタイミングでBIOSは使えるらしい。
_chputや_initxtはBIOSコールを呼び出すdefineマクロで、定義自体は自分で書いている。
 
コードは4000h、ワークエリアはC000hのアドレスに生成されるよう、リンカのオプションを設定してコンパイル!これで無事に似非ROMカートリッジが出来上がる(^-^)
 
fMSXを起動する時のオプションとして、出来上がったバイナリを指定してやれば、起動した瞬間にプログラムを実行する事が出来る!

最初から最後までタッチパッドを触ること無く作業が進む環境に大満足だ!(^-^)

 

おわりに

今回はLSIC-80を動かすという、おそらく日本でやろうとする人はいないであろう事を題材としたけれど、Windowsでしか動かないソフトをMacで動かす良い例になるだろう(^^)
 
これまでWindowsでしか使えないソフトがあるたびに悲しい思いをしてきた。我慢しきれなくなって、開発環境をWindowsへ移行するか…と決意し、2022年12月にWindowsマシンを購入した。
 
でも私は長年Macを使い続けてきたせいで、もはや指がMacのショートカットを覚えきってしまっている状態。些細な違いでもイラっとしてしまい、Windows環境が合わず2ヶ月もしないうちにMacに戻ってきた(T-T)
 
そのWindows環境でしか動かないというツールの代表格がLSIC-80だったのだ。
しかしこれがM1 Macでも問題なく動く事が分かった今、Windowsを使う必要性が全く無くなってしまった!(^^;;;
 
MSX0 M5StackはIoTの活用に振ったものだとは理解しているけれど、ネットワークはまだしもGroveに接続される機器は得意とは言えない(T-T)
せめてソフトウェア側で頑張るよー!(^-^;;
 
ではまた次回!(^-^)ノ

ダンプリストをOCR!

今も細々と開発中のダンプリスト入力ツール!

pocketgriffon.hatenablog.comダンプリストも、基本的には手入力が好きな私。

OCRで文字認識をさせてみても、その間違いを探してどうせ256バイト全部見るくらいだったら、最初から手で打ち込んだ方が早いじゃん…と思ってしまってる。

 

2017年に一度だけOCRに挑戦してみたが、この時は4%くらいの間違いで済んでいた。このくらいの間違い率だったら使ってみても良いかな…と思っていたが、この当時使っていたタブレットのカメラが高性能だったのか、iPhoneに変えてからはだいぶ間違いが多い。

 

あの時は既存のツールを使うだけの方法だったけど、今回は認識率を上げるために自分で努力してみる事にした!

 

どんなツールがある?

今までOCRのツールに何があるのかなんて気にした事もなかった…。

真っ先に出てきたのが、Google DriveによるOCRだった。

へー、知らんかった!そんな機能あるのね(^^)

これでそれなりの文字列に変換されたら、もうコレでいーんじゃね?(^-^)

……うーん、想像してたのとだいーぶ違う(T-T)

順番とか揃えたらそれっぽく出てるんだろうか??
並べ直してみようと思ったが、この並び替えを毎回手作業でやるの?と思ったら気が萎えてしまった(^^;

ほかを探す流れに……。

 

OCRで検索するとPythonがやたら出てくる。機械学習とか出てくるけれど、正直良くわかってない(^^;; とりあえず文字へ変換できればいいんだけど…くらいのイメージで探す。

 

OCRの作業自体はMacで行うので、Macで動くツールが良い。

そうして探していると、どうやらtesseractというツールがあるらしい。

この名前も初めて聞く(^^;;

よし、当面はtesseractを使ってOCRにチャレンジしてみるよ!

 

まずは試す!

この手の事は、過去の歴史がたくさんあるだろうから調べていくと正解?に近いものは出てくるだろうけれど、それだと仕組みやらなにやらを理解しないまま終わってしまいそう。

無駄とは思いつつも、自分なりの方法で試してみる(^-^)

 

まずは元となるダンプリストの写真を用意する。

なんとなく白黒がはっきりした方が文字として認識しやすいんだろうな…という勝手な解釈により、ある閾値で白黒を分けるプログラムを組んでみる。

この辺りは、過去にjpegを扱うプログラムを何度も組んでいたため、簡単に作れた。

自分jpegライブラリがあると便利だよ!(^^)

tesseract -l eng --psm 6 -c tessedit_char_whitelist="0123456789ABCDEFSumd:+O " out.jpg out

 

コマンドラインはこんな感じで設定している。

画像に含まれている文字は英語のみ(-l eng)、横書きの文字(--psm 6)、この画像に含まれている文字の種類(tessedit_char_whitelist)という感じだ。

 

ホワイトリストの最後にアルファベットのO(オー)が入っているのは、ダンプリストによっては数字の0(ゼロ)が飾り付きと無しの場合があるから。O(オー)としてご認識されたものを、あとのツールで0(ゼロ)に変換しようという魂胆だ!(^^)

 

tesseractのフォントをPC-9801に!

 

理屈で言えば文字自体が似ていれば、さらに認識率が上がるはずだ!

じゃあ…という事で、tesseractにPC-9801フォントを学習させてみる事にした。

ネットでいろんな情報を探してみたところ、分かりやすい例を見つけられた!

danglingfarpointer.hatenablog.com

↑ここに書かれている手順で、tessaractに学習させてみる。…学習というよりは、文字認識用のデータを用意するイメージかも知れない。

 

-l eng としていたところは jpn などの指定も出来るのだが、このオプションで文字学習データセットを用意するイメージだ。

私はdumpリスト専用という意味で、dmpというフォントセットを用意した。

PC-9801用のフォントがちゃんとBOX判定されているのが分かる(^^)

しかし結果は散々で、0(ゼロ)がすべて9に認識されてしまった(T-T)
うーん…これは結構厳しいぞ!

 

仕方ないので、PC-9801のフォントを改造して、ダンプリストに寄せたフォントを作った!

お、これでだいぶ認識率が上がった気がする!

 

1文字ずつ認識してみる

tesseractのモード(psm)に「この画像には1文字だけ含まれている」という指定がある。複数の文字じゃなくて1文字だけだからねーとあらかじめ教える事で、認識率をあげようって事だと思う。これを使ったらもっともっと正解率が上がるんじゃね??

 

今まで一度も使ったことのないOpenCV(+Python)を利用して、画像の抽出に挑戦だ!

…と気合を入れてみたけれど、世の中にチャレンジされていた方が多かったので、基本部分を参照にさせてもらってサクっと作ってみた!

むしろPythonが久しぶりすぎて大変だった(^^;;

おおおお……めちゃくちゃ正確に分別できてる!

これを各エリアごとにtesseractに送り込めば良いわけだな……(^^)

それにしても、PythonOpenCVを利用したプログラムが簡単に書けるのは便利だ!!

さて、1文字ずつ抜き出して処理するんだけども……どんな順番で出てくるの?(@_@;

左から、通し番号、X座標、Y座標、横幅、縦長、認識した文字。

データの並びを見てみると、どうやら右下から左側へ向けて処理が走ってるっぽい。

Python側で処理順番を逆にすればいいのかな…と思ったけど、どうもそこまで簡単な話ではなさそうな雰囲気。

出力された座標情報に基づいて、左上から出力するツールをサクッと作成。

あれ……???認識率落ちた??(T-T)

 

この後、フォントを変更したりサイズを変えてみたりするけれども、認識率が上がらない。

フォントを変更すると確実に認識する文字が変わるので効果はあるっぽいけれども、それでもどどーんと上がりませぬ…。うむむ…。

 

機械学習とかしていけばもしかしたら??とは思うけれども…(^^;;;

 

あと同じ工学社の雑誌でもダンプリストのフォントが大幅に違っていたりして、その都度調整をしていかないと認識率が上がっていかない事も分かってきた。

奥が深いぞ、OCR!!(T-T)

 

おわりに

とりあえず現状ではこんな感じ!

ブログにまとめておかないとあっという間に忘れそうだったので急いで書いてみた!

書いてみたけど参考になる事は無かったかも…汗

 

もっと良い方法が分かったら再チャレンジ案件ですな、これは!(^^)

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

M5Stackでゆみみみっくす!

みんな大好きM5Stackで、みんな大好き?ゆみみみっくすのオープニングムービーを動かしたお話!

 

このところ、レトロPC上でゆみみみっくすのオープニングムービーを動かしているツイートを連続して何件か見た!懐かしいなぁすごいなぁ…と思ってしまったら……自分でもやってみたくなるw

 

そういえば、過去にBad Apple!!を動かした際、グレースケール版も作ってみようと思って頓挫してた事を思い出した。ビット深度が深いという意味ではグレースケールもカラーも同じようなもんよ…という理不尽すぎる解釈から、いっちょやってみるか!となった(^^)

 

日曜(サンデー)プログラムの感覚でいるから、1日または長くても2日で作りたい!

 

そういえばゆみみみっくすは、メガドラCD版をゲームの最後まで終わらせているはずだけど、ストーリーを全く覚えてない…うむむ??

ゲームそっちのけでCinepakの解析をしてたからかな……

 

とりあえず机上で検討

そもそもムービーをどこから持ってきたら良いのか…というところで、まずはつまづく。

メガCD版のソフトは持っているけれど、動かせる実機がない。

実機があったとしても撮影する機材もない。

 

今回はYoutubeにあった動画を利用させてもらうことにした(ごめん)。

[MD]ゆみみみっくすオープニング - YouTube

 

動画自体が3分34秒あるので、214秒=6420フレームくらいのデータ量になる事が見込まれる。これをどう管理するか…。

データはどう圧縮するのか…。

 

メガドライブの色は512色中64色が表示可能らしい。…ということは64色で表現しても遜色ないという事か。

 

SDカードからの読み込み速度も気になるところ。過去の実験で1024KB/秒ほどの読み込み能力があるのは分かっているけれど、あの時の高性能SDカードはいずこへ…orz

 

うん、検討してみた結果、作ってみないとわからないとなった!(^^;;

↑無計画すぎる

 

まずは動かしてみる!

仕組み的には、1つの動画ファイルをそのまま再生するのではなく、1枚1枚の絵を高速に表示させる事でアニメーションっぽく見せる。

 

動画ファイルをjpegに分割するのは、ffmpegコマンドを使えば簡単に出来る。

  ffmpeg -i yumimi.mp4 -vf scale=320:-1 data/%04d.jpg

 

そして出来上がった、おびただしい数のjpegファイル…その数6411枚!

このファイルをどうにか加工してM5Stackへ入れなくてはならない…。

 

まずはjpegファイルを320x240x24bitのRAWデータに変換して加工しやすいようにする。

jpegファイルは、libjpegというライブラリを利用すればワリと簡単に扱う事が出来る(^-^)

 

このRAWデータのままだとサイズが225KBもあり、そのままM5Stackに置いとく事も難しい。減色および圧縮の方法を考える。

 

方法としてはこうだろう。

まずは64色まで減色してみる。

その上で出来上がったデータを圧縮する流れだ。

元絵が64色で描かれているのならば、遜色のない絵ができあがるはずだ。

 

減色

私の時代(?)にはカラーリダクションとか言ったけど、今はなんて言うんだろ??

そういえば減色ツールなんてエラい昔に仕事で開発したっきりやってなかったっけ…。アルゴリズム含めてすっかり忘れてる(^^;;;

 

当時のプログラムを見てみるとmediancutなる名前が関数名につけられていた。うーん、苦労した覚えはあるけれども、ソースみてもアルゴリズムが思い出せんw

まぁ動けばいいっしょ!←をぃ

 

↓こちらが元絵

↓こっちが減色後の絵

ちょっと気になるところはあるけれども、M5Stackの小さな画面で見たらきっと気にならなくなる……はずだ!(^^;;

 

ちなみに減色後のデータを見るツールも即席で作った!

タイトルがFont Viewerのままになってる辺りで急ぎ加減が分かるw

ツールも含めて土日で作り終わらなければ日曜プログラムとは言えないのだ!!

 

データ圧縮

データ圧縮については少し困ってしまった(T-T)

Bad Apple!!の時は基本的に白黒しかなかったので、圧縮アルゴリズムはランレングス一択だったのだが、今回は色情報を持っている事からデータが複雑だ!

↑こんな感じの絵は、横方向へのランレングス圧縮が効きにくい。

 

仕方ないのでいくつかのアルゴリズムを組み合わせた圧縮ツールを作る事にした!要は一番効率の良いアルゴリズムをその場その場で採用するような感じの手法。かつ展開速度を担保するために、ビット単位ではなくバイト単位での圧縮とした。

 

圧縮後のデータサイズを小さくするため、データのMAXを64KBという制限にした。そのため、320x240のデータを上下分割して、320x120のデータ2つとして扱う。

M5Stackで画面描画を行う際、320x240を一気に描けない制限ともマッチするので、これで良いか、となった。

 

元絵のデータが320x240(75KB)+パレットデータ64色(128バイト)で76,928バイト。

圧縮後のデータは最低で746バイト、最大で35,772バイトとなった。

 

そしてすべてのデータを1つのファイルにまとめた事により、127,007,871バイト(121MB)という巨大なアニメデータが完成した!元のmp4が10MB無いのに!(T-T)

1つ前の絵との差分を取れば小さくなるのは分かってたけど、今回はスルー(^^;;

 

そして出来上がったのがコレ。

コア0で圧縮データの展開、コア1でSDカードからの読み込みと描画を担当。

コア0の方がちょっとだけヒマな感じ。

描画にはLovyanGFXを活用させて頂いてます!

 

圧縮データと圧縮を展開したデータは、大きさ的な関係で内部RAMに置けなかったので、(速度の遅い)PSRAMに置いた。

画面の端にノイズが乗る事が多くてチカチカしてしまうので、画面の上下をデータ上で黒に塗りつぶした。

 

SDカードは高性能なタイプが手元になく、ノーブランドのモノを使用。おそらくブランドのものよりも2割くらい読み込み速度が遅いと思われる…。

 

ツイートして完了!と思ったけど、なんだかモヤモヤしたものが…。

もっとキレイに作れるのではないか……と思ってしまったのだよ…。

 

作り直してみる!

プログラマたるもの、気になる事が残っていたら直さないわけにはいかないだろう!

たとえ日曜プログラムであっても避けられない習慣なのである!!

 

 表示領域を280x224にしてるけど、実はこれだと64KBに収まる

 コアを2つ使うためにダブルバッファリング化してけど必要?

 減色プログラムを改良したい

 表示までに掛かる手間を減らしたい

 

↑で「画面端にノイズが出たので消した」と書いたが、実はデータ上では単に黒い領域として残ったままになっていた。

 

表示サイズを計算してみたところ、280x224 = 62,720バイトとなり、パレットのデータを含んでも64KB(=65,536バイト)に収まるじゃん!となった。

これをやると……データ生成ツールまですべて作り直しになるんだけど…orz

 

……うーん…でもやるか!

フォルダも新しく作り直してyumimi2とした!(改造ではなくて新作成!)

 

この際なので……ノイズが微妙に乗って気になってた減色ツールも改良した!

25年以上前に書いてたツールという事もあり、当時のコンピュータで現実的な速度で動かすために精度を犠牲にしていたところが多々あったのだ。

精度を上げるようにコーディングし直したところ、ノイズが出にくくなった!

 

そしてツール類を一新した。

前のバージョンでは、減色、圧縮を別のツールにしてて手順も面倒だったが、新しくしたツールでは減色と圧縮を同時に行うようにした。このおかげで6411ファイルの更新に30分くらい掛かっていた作業時間が、19分まで短縮された!

土日しか時間がないから、何度もテストが出来ないのだ(T-T)

 

コアを1つで実行するようにした。

このおかげでバッファを複数持たなくて済むようになったため、すべてのバッファを内部RAMに入れる事ができるようになった!

複雑なシーケンス制御が無くなった事もあり、68msくらい掛かっていた表示が、35msくらいまで速くなった!(^-^)

 

そして出来上がったのがこちら↑

ツイートしてみたが、見る側にとってはほとんど何も変わってないという…orz

いいのだ、これぞ日曜プログラムの醍醐味だ!←多分違

 

おわりに

データの用意から減色、圧縮、実機へ持ってきての表示という作業を、はからずしも2度やってしまったワケだけど、意外に出来ちゃうもんだなーと思った!(^^)

しかも土日の用事もしっかり済ませた上で作業してるので、実質はもっと短い。

このくらいの作業量が老体にはしっくりくるかも!(^^;

 

あと気になってるのは音楽ですねー……。

M5Stackでどうやったら鳴るんだろ??意識した事すら無かったよ。

 

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

 

16進ダンプ入力ツールを作った!

16進ダンプリスト、入力してますか?(^-^)

 

私は気圧の変化による頭痛がひどい時や、仕事で必要となった時に入力してる(^^;

何も考えない状態(無心)で打ち込みたい時や、逆に集中したい時とかにも入力したくなるw

今回、気圧の低い日が頻繁にあって集中出来ない期間があったため、ちょこちょこダンプリストを入力しては気を紛らわせていた。

 

そんな時、もっと効率の良い入力環境を作りたいなぁ……なんて思ってしまった!(^-^)

思ってしまったならば作るしかないだろう!w

 

今までのダンプ入力事情

今までも手入力でダンプリストを打ち込む環境を手元に用意してあった。

↑こんな感じのテキストを用意しておいて、コンバートするだけの簡単な環境。

 

バイナリに変換するツールはPythonで書いてあり、バイナリ化とチェックサムを計算するだけのごくごく簡単なもの。

 

このPythonツール自体は2017年11月頃作ったもので、当時開発をしていたFM-7エミュレータでテスト用のプログラムを準備するために用意した。

この当時、手元にバイナリデータを打ち込む環境が無くて、当時のプログラムを入力するのはどうしたらいいんだ??となったのがきっかけだ。

FM-8活用研究に掲載されていたギャラクシアンを打ち込んだのが最初だった!(^^)

 

テキストデータで打ち込むようにしたのは、単純に整形する際の利便性のよさと、OCRした後のテキストを簡単に扱えるようにしたかったためだ。

 

そしてギャラクシアンOCRを利用してデータを作成していた。

タブレットで写真を撮る

OCRでテキスト化

・テキストをダンプ形式に整形

・誤字を修正

チェックサム確認→修正を繰り返す

・256バイト終了

 

……入力する手間は無かったけれど、全体的な時間はかえって掛かったイメージ。

16進数ダンプ専用のOCRとかあったら認識率上がりそうだけど、(当時の感じでは)使いにくいかもなーって印象だった。

 

試しにダンプリストを手入力してみる事にした!(^-^)

テンキーをA〜Fに変換するプログラムもないけれど(そもそもうちのMacにはテンキーがない…)、フルキーで打ち込んだらどのくらいの速度になるんだろうか??

当時、256バイトを打ち込むのに約10分掛かった記憶がある。1ブロック10分、1時間で6ブロック打ち込める!みたいな感じで気合を入れていた記憶が蘇る(^^;;

 

そしたら…今フルキーでタッチタイピングすれば、256バイトを2〜3分で入力出来た!

考えてみればテンキーをA〜Fに割り当てて打ち込んだとしても、効率の良い片手打ちだ。

タッチタイピングすれば両手で高速に打ち込むことが出来る。

そりゃそうか!(^-^)

コレ以降、OCRに頼らずに手入力をするようになった!

 

↑昔は書籍を広げてカセットテープのレーベルをあてがう感じで入力をしていたが、今の時代にこれをやると広げ続ける本が傷んでしまう(T-T)

 

↑そこでダンプリストを写真に撮るようにした。

これで本の痛みは最小限に済む!

さらにガイドとなるものはダンボールを切り貼りして手作りした!

しっかりと固定して置けるので両手が空き、タッチタイプが可能となった!(^-^)

 

便利な入力ツールが欲しい

「自分が使う」を大前提として、使いやすいツールが欲しい!

ダンプリストを入力するたびに、そんな事を思うようになった。

 

不満のひとつに、アドレスを自動発生させる機能がない事があった。

ダンプを入力するたびにアドレスを手で書いてたのだ。

これは効率が悪い上に間違いが起こる。

さらにADRSSumなどの雛形を自分でコピーしたテキストを作らねばならず、ダンプを打ち込む際の面倒事項となっていた。

 

今の感じだとOCRを試すこともしばらくは無いだろう。

そうなると手入力を大前提に使いやすいツールが欲しい!(^-^)

 

昔、Oh!FMだったと思うけど、FM-7で動くとても使いやすい入力ツールがあった。

フルスクリーンでダンプ入力が可能であり、しかも入力していくとチェックサムがリアルタイムに表示される!

そんな感じのツールが手元にあると良い!(^-^)

 

なんとなく想像で以下のような仕様を考えてみた!

 256バイトのブロックを表示

 チェックサムはリアルタイムに更新される

 カーソル移動はEmacs準拠

 入力部分が拡大表示される

 セーブされるファイルは常に64KBのRawファイル

 

テキストベースで画面構成も考えてみる。

 

ふむ、こんな感じで入力できるのならば画面は80x25固定でも良さそう。

1980年代風の入力ツールでいいじゃん!(^-^)

拡大表示するためにはフォントを変えるかドットで打つか…。

せっかくなのでSDL対応してグラフィックで描いちゃう!

よし、そうなったらフォントはPC-9801だよなー!

……って感じでだんだんとワル乗りしてきたww

 

最初に作ったのがコレ。画面構成はほぼそのまま作っている。

拡大表示はカーソルを中心として前後を見えるようにしてみた。

この状態で16進数を打ち込むと、チェックサムがリアルタイムに更新される!

 

その後、アスキー文字領域にもカーソルを表示してみたり……

入力対象となっているラインにアンダーラインを引いてみたり…

 

背景を淡い青にしてみたり…と改良を重ねてみた!

 

SDL対応なのでMacだけでなくWindowsLinuxでも動くはずだ。

ポメラDM250に入れておけば、旅先でダンプリストを入力しちゃう事だって可能!

電子辞書Brainに入れておけば、授業中のヒマな時間にダンプ入力出来る!

おお、意外に使えそう!(使う人は限られるが…)

 

使い方のクセが強すぎるため(だってカーソル移動がEmacs準拠よ?)配布する予定はないけれども、使ってみたーい!という話が多数上がるようであれば公開も考えていきたい。

何度も書くけど、高機能ではない(^^;;

セーブ(CTRL-X + CTRL-S)されたファイルは64KBのRawデータなので、独自でデータ加工のプログラムが書けない人にはお手上げツールなのだ(^-^;;

 

おわりに

昔から自分の環境は自分で作りたい派の人だったけれど、まさかこの時代にダンプ入力ツールを作るとは思ってなかったw

でもいいね、自分環境!

もっともっと整えていきたいと感じた!(^-^)

 

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

JR-300エミュレータの続編その1

ほそぼそとJR-300エミュレータの開発を続けている!

ここんところ実務でバタバタしてるので、1日で取り組める時間が1時間も無い(T-T)

でもちょっとずつでも続けていられればいいかな!

飽きっぽい性格なので、どこでやめちゃうかドキドキしてる(T-T)

せめてエミュレータのバイナリ公開まで行けるといいなぁ…。

 

でもJR会が予定された事からエミュレータを作る気になり、それをツイートした流れからJR-300をお持ちの方まで現れた!

JR-300本体の写真も載せてくださったのは本当に感謝でしかない!

写真や資料はどれも果てしなく参考になる!!

想像していたJR-200とJR-300の切り替えはディップスイッチで行うみたいだ。

 

RS-232Cがついているのは分かったけれど、BASICインタプリタの中にはシリアルっぽいファイルディスクリプトが存在しない(存在するのはCAS0:のみ)。

ということはプログラムのロードとかが出来ない???

うーん、謎ましい感じだ!(^-^)

 

JR-300の情報については本当に欲しい!

動く実機があれば開発してるエミュレータの答え合わせも出来るのだけど…うぬぬ。

 

デモンストレーション

JR-300のデモンストレーションの気になるところを修正した。

もちろん修正したのはデモプログラムではなく、エミュレータ側だ(^^;

 

円グラフの色がおかしい。

多分、グラフの中に色が塗られるのが正しいんだと思うけれど、なぜか塗られない。

 

その前に……実は円の描画が正しく実装されていないのだ(^^;

Xデー(JR会)に間に合わせるため、エミュレータの実装をズルしてる部分があった!

まぁこの手のズルっこはどこかでダメになるものだ(^^;;;

 

計算式を見直したところ、最後の1ドットが描画されていなかった!(T^T)

急いでると些細な事でバグが出る…orz

おっしゃ!ちゃんと直った!(^-^)

 

ちなみに棒グラフの一番下、赤い帯しか見えてないんだけど、ここは赤の背景、赤の文字で「ソノタ」とかかれているらしい。アトリビュートと文字の色解釈が間違っているのかと思ったが、どうもそうではなさそう…。

この謎はもう少し引きずりそうだ!

 

画面に飛行機が横切ると、テキストで青が残ってしまう問題。

 

これはスペース(' ')[$20]が背景色青で設定されている。

この場所以外でもスペースを別アトリビュートで置いてたりする。

わざわざ色を設定して置いてることから、なにか意味がありそうなんだけど…。

でもスペースが置かれてるし…。

デモの開発途中で仕様変更になった名残なのかも…??

 

仕方ないのでスペースは何色の背景で描画されようとも透過するようにしてみた。

してみた…というのがアレですが、正解がわからないので仕方がない(T-T)

 

飛行機の後方にカーソルが表示されちゃってるけど、これは気にしないで(^^;;

デバッグで動かしてるとカーソルが消えないのだw

 

一通り動いてるデモをツイートしてみたので、ぜひ見てみてほしい(^-^)

 

速度について

上のツイートに速度について書いているが、ここで詳しく説明をしたい。

Z80CPUのエミュレーションは大雑把ではあるが4MHzくらいに調整した。

 

サブCPU(おそらく6802)はフルスピード、つまりZ80側から見るとノーウェイトで動いてる。

Z80の1命令でどんな処理も終わってしまっているのだ(^^;;

デモの中にあったスプレッドシートの画面が瞬時に表示されてるのは、このせいだ。

この先、きちんとサブCPU側の処理遅延を入れていけば、上から下にだららーっと表示されていくのが見えるほど遅い…と思う!

 

さらにGDCもすべてノーウェイト動作だ。

LINEはコマンド発行後はGDC側で全処理が行われるので、Z80側から見たらノーウェイトで線が引かれている。

PAINTが遅く見えるのは、処理の途中でZ80側の処理が挟み込まれるから。Z80がちゃんと遅いのでPAINT自体も遅くなる…という事だw

 

この先、エミュレータをちゃんと作り込んでいくと、全体的にどんどん遅くなる(^^;;

デバッグ中はもちろんフルスピードだよ!(^o^)/

 

この先はBASICでのPCG定義(おそらくDEF CHR?)など、まだ解析できてない部分がたくさんあるので、その辺りを確認していこうと考えている!

のんびり行くよー!(^^)

 

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