ホバーアタックを動かしてみた!

多忙な状態が続く毎日!

そこにストレスフルな事件が起きちゃった日には、もうこれは仕事にならない!(TT)

またしても丸24時間をレトロにさわる時間と割り切っちゃう事にした!

いつも思うんだけど、チャレンジ開始時には脳みそがパチっと切り替わる。

この瞬間がたまらない!(^^)

 

今回は人生で1度も触ったことの無いマシン、SHARP X1にチャレンジ!

知ってる知識といえば…

・クリーンコンピュータ

・カセットが2700ボー

・VRAMがI/Oにある

・8色使えるPCGがある

くらいの情報のみ。

 

動いてるところを見たことがないマシンのエミュレータなんて、JR-300みたいなモノじゃないか!しかも今回は手元にX1の資料がいくつもある!

昔から「マシンは買えないけど本ならば…」と所有してないマシンの本を買ってました!

これだけあったら作れるかなぁ…と思ったけど、まだまだ懐疑的(TT)

だって起動した直後の画面すら想像できてないんだよ?(T-T)

 

まずはプログラムリスト!

資料があろうがなかろうか、手元にないと困るのがプログラムリスト!

何を動かしたいのかを決めて、限定的にエミュレータを作るのが勝利への道だ!
手抜きとも言う、いや言わない!言わないで!(TT)

まず動かすゲームソフトは、工学社ホバーアタックに決定!

これが出た時、8色出るPCGってステキ!!!と心底思った(^-^)

ただ、当時(作り始める今も!)の私では、ホバーアタックのどこがPCGで、どこがGVRAMなのか区別がついてなかった。

普通に考えたらスクロールするマップはPCGだよね…上に表示されてるテキストは??

 

そんな秘密も探りつつ、エミュレータを作っていくのが良いだろう!

ちなみにBASICプログラムのほぼ全てはPCGの定義命令だったため、このためだけにBASIC起動させるのは厳しいなぁ…と思い、別の形式で持つこととした!

このホバーアタック・エミュレータは、IPL-ROMもBASICも載っていない!

 

マシン語ダンプリストは1CA0h〜68FFhまでと少し長めだったが、お得意の自作ダンプエディタで楽しみながらOCRしまくったよ!(^^)

 

何も考えずに起動してみる!

メモリの中身をホバーアタックが起動出来る状態にして、おもむろにPCの値を1CA0hに設定してプログラムを起動してみる。

 

すると、どうやら何かのエントリを呼び出してるもよう。

これが…何なのかさっぱり分からない(^^;;

BASICインタプリタ自体が載っていないため、もしもBASIC内部のルーチンを呼び出していたらアウトだ(TT)

 

調べてみると、6つのエントリが呼び出されていた。

  1文字表示

  テキスト画面クリア

  グラフィック画面クリア

  ベルを鳴らす

  サブCPUからのデータを受信

  サブCPUにコマンドを送信

 

……サブCPUってなんだ?!(@_@;;;

え、CPU2つ載ってるんだっけ、X1って…?

いきなり知らない話が出てきて焦る焦る!!

 

とりあえず呼び出されたエントリを片っ端からC9(RET)に置き換えていく!

プログラムを1周回す(と私は表現してるが…)のが大事なので、解決したい気持ちはあるけれども後回しにする!

 

そうこうしているうちにプログラムが止まらなくなり、何かを実行し続ける状態になった。

この状態でI/Oのメモリダンプを見ると、なにやらグラフィック領域にデータが書き込まれていた!VRAMの内容を可視化してみたところ、見えたのがコレ。

うーん……何か幾何学的な???

HISCOREとかWAITはグラフィックで表示されてるんだ!?それにしても、この模様はなんだろう…うむむ、何か意味がありそうでなさそうで、これは悩む(^^;;

 

あと、テキストがWIDTH40の時は、グラフィックも320x200になるらしい!

テキストとグラフィックは分離しているのに影響を受けるのかー、これは面白い(^^)

 

あれ??テキストとグラフィックは、グラフィックの方が手前に表示されるんだ??
感覚的にテキストが前!っていうイメージがあったので、ちょっと驚いた(^^;

 

テキスト画面を表示!

グラフィックが化ける件は少し時間がかかりそうだったので、テキスト画面の表示を先にやっちゃおうと思った!

………なんか可愛いんですけど…(^-^;;;

色が変なのがあるけれども、PCGキャラクタをノーマルフォントで表示しちゃったら、こんな可愛い感じになってしまった!動画を撮っておけばよかったと後悔w

 

その後もPCG表示が化けてみたり……

色が緑一色になっちゃったりと紆余曲折ありましたが、ようやくなんとか…

ようやくそれっぽく表示された!!!

グラフィックのゴミは、どうやらパレットを反映させたら消えることとなった。

GVRAMをワークにでも使ってるんだろうか…??

 

これでよしよしと思いつつデモを見ていたら……

なんか画面が激しく壊れる…orz

BIOSなのかIOCSなのか、それともBASICのルーチンなのか不明なのだが、1文字表示処理を独自で実装してる。

しかし肝心の使い方が分からないため、座標はワークエリアから直接取ってきたり、座標更新の仕方など分からない事が多すぎる…。

 

何か別のエントリを呼び出しているのかなぁ…とか思いつつ、そういえばテキスト画面クリアの処理を入れてないままだった事に気がついた!

これで解決かと思ったが、画面は壊れたまま…なんじゃー(TT)

 

結局、突破口になったのは画面左上に表示されてるCLの文字。

これは多分キャラクタコードの12 が表示されてるんだな…と思った時、PC-8001の画面クリア(PRINT CHR$(12))を思い出した。

それと同時に1文字表示処理はコントロールコードが有効なのかと気がついた!

 

と…なると、画面クリアやカーソル移動などのコントロールコードも対応させる必要があるって事か…うん、きっとそうに違いない!

いくつかのコントロールコードを実装する事で、ようやくちゃんとした画面が出るようになった!

 

フォント問題

私はX1を所有しておらず、本体からフォントデータを抜き出す事ができない。

同様の理由でIPL ROMも使えないしBASICにいたってはカセットすら持っていない(TT)

フォントについては、実はPC-8001のものを流用させてもらっている。

大体は同じ配列なんだけど、肝心なところが違ってるケースもある。

7、4,1の枠がバケバケ(TT)

これはフォントを入れ替えないと対応ができない。

仕方ないので、フォントデータを読み込んだのちに、グラフ文字を入れ替える事にした。

フォントデータは著作物でもあるので、元データを変更するなどは極力さけたい(TT)

これでようやく表示がちゃんとできた!

 

おわりに

まだキー入力がまともに入らないのと、音が鳴らない。

音は24時間以内に対応が難しいので、ハナから入れる気はなかったが、キー入力はもう少し頑張りたいところだった!

 

24時間でダンプ入力からエミュレータの開発まで楽しんでみたけれど、今回は良く知らないマシンのエミュレータだったので、楽しさも倍増だった!

 

よーし、またこれでお仕事頑張れるよ!(^-^)

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

 

Cardputerでプログラミング!

前から少しだけ気になっていたCardputerを手に入れた!

 

少しだけ…という書き方がアレだけど、私の印象は「この小さな液晶と小さなキーボードで何かやる気が起きるんだろうか?」だったからだ。

でも、いざ買えるチャンスが訪れたら迷うこと無く手に入れてしまった(^^;;

 

SNSでの盛り上がりも後押ししたのかも知れないが、あとづけの理由としては某原稿の締切が近かったけどネタが無かったという事情もあるw

#本当は某原稿のためにギガンテスを動かしたはずなんだけど…orz

 

実際に手に入れてから、ようやくスペックを調べ始めた。

本体右上にM5StampS3がペタンと載っているのと、画面サイズが240x135ドット。

あれ?この解像度はM5StickC Plusと同じだ!うむむ、過去にM5Stickを触った時には、効果的な使い方が出来た覚えがない…。

pocketgriffon.hatenablog.com

過去のブログを参照してみたけれども、やはり画面の狭さに四苦八苦している様子がうかがえる。うーん、やっぱり今回も画面サイズで苦労しそうな予感…汗

 

開発環境の準備

まずは開発環境の整備だけど、これはM5Stackで使っているArduino IDEを利用すれば簡単に構築出来る事がわかった!特に悩むこともなくインストール出来た!

開発環境が一本化されてるのは本当に助かる(^^)

docs.m5stack.com

新規で環境を構築する場合でも、上のドキュメントに詳しく書かれているので、チャレンジしてもらいたい(^^)

 

動作確認

とりあえず、画面表示とキー入力、SDカードからの読み込み辺りをテストしてみよう。

 

表示系はM5Stackを扱ったことがある人ならば悩むことは無さそう。

setRotationで画面を回転させないと、左側が上になってしまい期待した感じの表示にならない。そのままでもテト◯ス作る分には良さそうな気がする(^^)

 

キーボードはサンプルをそのまま使っているが、特に困った点は見受けられない。

ANK文字は普通に取得できるけれど、okやoptなどは違う方法で得る。この辺りはサンプルとライブラリのソースを見てもらうのが確実かと思う(^^)

 

SDカードはサンプルが存在しなかったが、我らがNochiさん(@shikarunochi)がソースを開示してくれた。これをそのまま使えばSDカードへのアクセスが問題なく出来る。

ファイルをフルパス指定にしないと書き込み時に失敗する現象が出た。単にフルパス指定をすれば済む話なので特に問題はないと思うけど、念のための注意喚起(^^)

 

他にもCardputerは多彩なハードウェアが載っているみたいだけど、私の用途ではあまり使わ無さそうな気がしていて調査をしていない…汗

マイクとかスピーカーとかBluetoothとかWiFiとかを使って、優れたソフトウェアを作れる人が羨ましい(^-^;;

 

念のため、ライブラリのソースは読んでおくと良さそうだ。

github.com

 

どのくらいのサイズまでmalloc出来るかを知りたかったのでメモリマップを探してみた。

https://dl.espressif.com/public/esp32s3-mm.pdf

コレを見て「あ、メモリがワリと素直」と思ってしまった(^^;;

命令キャッシュが32KB、データキャッシュが64KB、汎用的に使える領域が416KB…と解釈したら良いのかな…?

まぁでっかいメモリ領域をアロケーション出来そうな雰囲気があって、かなり安心した!(^^)

 

知れば知るほど、潤沢なCPUパワーと大きなメモリ、適度な表示サイズのバランスが良いのかも…と思うようになってきた!(^0^)

 

CP/M80の移植

てっとり早く何かを動かしてみようと思ったので、過去に作ったCP/M80を移植してみた。

ここのブログでは何度も何度も出てきているので詳細は省くけれど、何年か前に私自身がスクラッチから開発したプログラムだ。

 

開発当初はcursesライブラリを用いていたが、その後SDL2へ移行し、フレームバッファ直アクセス版やM5Stack版など、多岐に渡る改造がされている。ソースもちゃんとまとめていないので、全部書き散らかした感じだ(TT)

 

今回はM5Stack版を元にCardputerへ移植してみた。移植と言っても画面サイズの違いとキーボードからの読み込みの違い、そしてSDカードに関しては初期化さえきちんとすれば、あとのアクセスはライブラリが吸収してくれた。

「動かすぞ」と思ってから30分掛からずに動いてしまったCP/M80。むしろ画面解像度の狭さから、表示をどうしようか…と悩む方が時間かかったかも?

ちなみにフォントはPC-8001のモノを利用している。

 

悪ノリしてPC-6001のフォントに変更して、ついでに背景もそれっぽくした!

BASICの画面とあいまって、PC-6001が動いてるようで楽しい(^-^)

 

Arduino BASIC

同じく、過去に移植してあったArduino BASICをCardputerへ移植してみた。

Arduino BASIC」→「SMART Response XE」→「RaspberryPi Pico」と何段階にも渡って移植されてきていて、特に私の代(Pico以降)はソースを適当に書いているため、とてもひどい(TT)

 

Picoからの移植はちょっと大変だった。

元々、PicoではLCDへのアクセスを独自で書いていたので、gpioやspiといったハードベタベタなソースコードになっていた部分が多かったが、これを全てM5ライブラリに置き換えた。

 

BASICの命令にグラフィック命令を拡張する改造もしてあった。

個人的な好みによりテキストとグラフィックを完全分離した。

内部でフレームバッファを3つ持っていて、それぞれテキスト用、グラフィック用、合成用としてある。

 

240x135x16bitの大きさを持つバッファを3つも確保したが、内部メモリの多さに助けられた。

BASICの駆動およびフレームバッファ生成はCore0で動かし、スクリーンを合成してLCDへ出力(push)するのはCore1で実行している。そのため、BASIC側の動作状況に関わらず、画面は定期的に更新される。

ただしSDカードがアクセスされた時は画面更新が止まる。

キーボードは本体付属の実キーがリアルタイムに読めるのに加え、Arduino IDEからのシリアル入力にも対応してみた。

実キーボードからの入力は、思ったよりも使い勝手は悪くなく、むしろ楽しんでプチプチ打ち込める感じだ!(^-^)

 

さすがにESP32-S3ネイティブで動くBASICはめちゃくちゃ速い!

もう少しBASICの命令数が充実していたら、大きめのプログラムも作れそうな気がするんだけどなぁ…。これはもう独自で作るしか…(^^;

 

おわりに

せっかくのCardputerなのに、機能を活かしたアプリが作れていないのが残念だ(TT

こんな大きさで、キーボードと画面が付いた立派なコンピュータであることを考えると、妄想は果てしなく広がってしまう(^^)

 

きっと画面を縦方向に対応したテ◯リスあたりは、どなたかが作られるのではないかと思う(^^)

 

無事に原稿も書けたので、これにてCardputerは封印するけれども、ちょっと使っただけでも楽しいマシンだと思った!

また次に使う機会があれば…それまでにアイディアを温めておきたい(^^)

 

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

 

 

 

 

ギガンテスを動かしてみた!

このところ、実務が異常なほど忙しくて、全くレトロを触れていない…。

このままではいかん!胃に穴が空いてしまう!(ToT)

丸24時間をレトロさわる時間と割り切って、休息=プログラミングをする事にした!

 

……と言っても、24時間で作れるようなものなんてたかがしれてる。

でもせっかくやると決めたのならば、ある程度まとまったサイズのものを作りたい。

いろいろと思いを馳せてみたが、やはり私はエミュレータ作るのが楽しいなぁ……。

でもPCのエミュレータなんて24時間で作れるわけないじゃん…orz

 

唐突に話は変わるが…

PC-9801用の「ギガンテス」というゲームをご存知だろうか?

工学社I/Oの1985年5月号に掲載されていた、縦型のスクロールシューティングゲーム

タイトルにもある通りタイニー版という事で、ダンプもたったの50KB!(泣

この見開きページで10.5KB。これの5倍くらいの量がある…。

当時であっても「これを打ち込む人いるんだろうか?」とマジで思った(^^;;

でもきっと打ち込んだ方いたよね!マジですごいです!(^o^)/

 

これを打ち込むとして……動かすとか?動かしちゃうとか?そんな事出来る?

そんな事が脳裏に浮かんでしまったから、さー大変だ!!(@_@;;

こんな強引な流れからエミュレータ開発へとなだれ込んで行くのでした…w

 

エミュレータ構想

ダンプリストを打ち込むのは根性があれば出来る気がするけど、問題はコレを動かすエミュレータだ!

残念ながらPC-9801エミュレータは開発経験が無く、これを1から作るのなんて24時間で出来るワケがない!

 

ただ…ちょっと思うところがあって。

ギガンテスの掲載記事を見てみると、なーんとなくだけど…PC-9801というよりは、8086+GDCという構成であれば動くような気がしてる。

PC-9801アーキテクチャには依存度が少ない雰囲気というか。

 

つまりPC-9801のBASIC ROMは極力使ってない感じがするのだ!

だとするとN88-BASIC(86)は起動する必要がなく、それならば開発するエミュレータの敷居はどどーんと下がる。
汎用エミュレータを作るのに比べたら労力は1/100以下だ!(適当なる当社比)

 

そう、目指すべき方向はPC-9801というハードをエミュレーションするのではなく、ギガンテスを動かす最低限のハードエミュレータだ!(^-^)

これは……ギガンテエミュレータとでもいうべき?!

 

まずはダンプ打ち込み!

何はともあれ、掲載されているダンプを打ち込まなければ話が始まらない!

ここで!我が家でのダンプ入力方法をご紹介してみたい!(^-^)

つい最近までの私は、ダンプリストを手入力する事をモットーにしていたが、ここ最近は独自で開発をしたダンプリスト入力ツール(OCR対応)を使って楽してる!(^^;

 

OCRするために、まずはダンプリストの写真が必要だ!

なんともシュールな……w

ダンプリストの上に透明のアクリル板を乗せて歪みを無くし、タンブラーの上に乗せたiPhoneでピントを合わせて写メを撮る!明るい方が良いと思ってライトも装備!

我が家にある何の変哲もない道具を使って写真撮ってるよw

 

撮った写真がこんな感じ。この写真を……

 

iPhone上の写真アプリで大雑把に枠を合わせ、色彩を「自動」「コントラスト最大」「明るさ最大」にすると、こんな感じのパキっとした写真になる。

 

この写真をダンプリスト入力ツールでOCRする。

あ、惜しい!ちょっとだけ読み取り間違いがあるようだ。

取り込んだ写真とバイナリエディタのウィンドウを並べたら比較も簡単!

どうやら13→18、00→09の読み取り誤認のようだ!

256バイトのうち3つが間違いということは、認識率98.8%!

ちなみにこれは認識率が悪い方で、全く誤認ナシというのが多かった!

全体での認識率は99.9%超えてると思う!すごい!(^-^)

 

こんな感じの工程で作業を進めていき、約5時間で50KBのダンプリストを入力出来た

一番長いのは写真を加工している時間だ!(ToT)

これが自動化出来たら2時間以下になるんじゃない?

ダンプリストの入力革命まであと少しだ!(今の時代に?

 

エミュレータ作成開始

目的はシンプルに「ギガンテスが動けば良い」だ!(^-^)/

それ以外の機能は全て対応しない事を心に決めて作業を進める!

手抜き作業は得意中の得意だ!←自慢していーんだろうか?

 

アセンブラ

解析用に念のため準備をしておいた方が良いだろう。

過去に文豪ミニ5を解析する際に新規開発をしていたV20用逆アセンブラをそのまま使うことにした。

ギガンテスのプログラムはいたってシンプルで、テーブルジャンプは2箇所のみだった。おかげでプログラムがとても追いやすくて助かった!(^^)

 

CPU

まずはCPUエミュレーションの準備。

これは過去に開発していたV20エミュレータをそのまま使う。

ギガンテスはPC-9801/E/Fが動作対象となっていて、この頃のPC-9801はCPUが8086だ。V20は8086との互換性があるので、そのまま流用が可能というわけ(^^)

 

ギガンテスのプログラムは、初期状態ではVRAM領域に配置される。プログラムが実行されると、内部で自分自身をメインメモリへコピーして動き出す。

 

雑誌掲載時の原稿に書いてあったが、ゲームのキャラクタは4ドット単位、弾は2ドット単位に描画される。これは実行時にリアルタイムにドットをずらしているのではなく、プログラムの初期化部分であらかじめドットをずらしたデータを用意するみたいだ。

そこの処理でシフトとローテイトがたくさん出てくる!

こういう部分でバグが出ると原因が分かるまでがとても長いので、慎重に確認作業を進めていく。

 

そしたら……案の定、動作が変になるバグが発生!

あれれ…ダンプリストの入力間違いか、それともV20エミュレータのバグ???

動作を追っていくと、どうやらV20エミュレータのバグが発覚(T-T)

うむむ…CP/M-86とかもちゃんと動いていたのに、まだバグは残ってるのねー(T^T)

 

そんな事を考えつつ修正をしていくと、今度は実装されていない命令に遭遇w

AAAとAAS!見た覚えあるけど動作を暗記してない(^^;;;

わーん!ぼろぼろじゃないかー!と泣きながら対応を進めるハメに(^-^;;

 

ソフトウェア割り込み

ギガンテスで呼び出されているソフトウェア割り込みはINT18のみで4種類ある。

1、CRTモードの設定

2、表示領域の設定

3、テキストVRAM初期化

4、ユーザー文字定義

1と2はそれっぽい動きをしてやれば良いだけ、3はメモリクリアすればOK!

 

問題は4の文字定義。

これは16x16ドットの文字を定義するものだけど、PC-9801って文字定義をどのメモリに格納してるの??(@_@;

よくわからんけど、テキストVRAMを描画する時に処理を横取りすればなんとかなりそう!

解析してて気がついたけど、ゲーム中には使われていないであろう「PLAYER 2」という文字の定義もあった。パッケージ版では2人(交代)プレイが出来たんだろうか(^^)

 

ハードウェア割り込み

ギガンテスで使われているハードウェア割り込みは2種類。

・タイマー割り込み

・キーボード割り込み

これらをそれっぽくエミュレーションしてやる必要がある。

 

ちなみにだけど、タイマー割り込みは何の対応もせずに動いてしまった。

プログラム中にCPUのクロックが5MHzなのか8MHzなのかをチェックしている箇所はあったが、タイマー割り込み自体がどこに使われていたのか謎(^^;;

素直に考えれば、画面切り替え時に参照しているはずなんだけど…汗

 

キーボード割り込みは、キースキャンを行い必要なデータをゲームの都合よくワークエリアに格納する構造になっていた。

本来であればPC-9801のキー入力をエミュレーションするべきなんだろうけど、それはちょーっと面倒くさい!

最低限の対応のみやろうという事で、SDL2のキーイベントをそのままゲーム中のワークエリアに入れ込む事にした!絶対アドレスに直接データを入れる暴挙!(^^;;

該当のキーが押されたらビットを立て、離されたら落とすだけの簡単処理! (^^)

 

GDC(Graphic Display Controller)

ギガンテスでGDCの対応が必要なのは、表示領域の設定とスクロール処理だ。

PC-9801の640x400ドットという画面構成に対し、ギガンテスではタイトル表示に512x400、ゲーム中は512x200ドットという構成になっている。

そしてゲーム中はVRAMを2つに分割し、2画面切り替えという方式も行っている。

 

初代PC-9801は画面が640x400の1画面しか無く、はてどうやって2画面切り替えをしてるんだろう…と思っていたが、画面を640x200ずつに分割をしてスクロールの値を操作する事で切り替えを行っていた。なるほど、確かにこれなら実現出来るね!(^^)

 

これらの機能をそれっぽくエミュレーションしてやれば、GDCモジュールを全部持ってくるなんて大掛かりな事をしなくても良い事に気がついた!(^^;

手を抜けるところはトコトン抜くよw

 

タイトル画面と自機がやられた時に表示される画面で、文字がラインごとにちょっとずつ表示される演出、実はこれもGDCの機能だ。「1行(=16ドット)のライン数を設定」というコマンドを使っている。

ゲーム中、ここでしか使われていない機能だけど、せっかくだったので対応してみた(^^)

 

開発は続くよ…

ギガンテスの内部説明をたくさん書いたけど、これだけ解析したら作るのは簡単!

……なんて思っちゃダメよ(T-T)

最初に表示された画面なんてこんなんよ?(^^;;;

これを見て「よーし画面が出た!お楽しみはこれからだ!」って前向きに思える人でないと、エミュレータを作るのは厳しいのかもしれない(^^;;

ようやくそれっぽい画面が出た頃。

横を512ドットにした時、VRAMの扱いをどうしたら良いのかが分からず試行錯誤してたw

メモリ的に640ドット分のサイズがあって次の行へ行くのか、それともメモリ自体も512ドット分になっているのか…。

実験してみた結果、どうやら横512ドット分のVRAM容量しか無いらしい事が判明。

 

↑ゲーム画面の縦が200ドットだと気づかずに実験してたあたり。

パレットをあわせる事で、なんとなくそれっぽいゲーム画面が出てきて嬉しい。

 

画面を512x200に合わせられたところ。まだスクロールを実装していないので画面の途中が描き換わって見える。

 

縦を引き伸ばして描画するのが面倒だったので、1ラインごと飛ばして描画してる。画面で見るとそれっぽいけど、写真に撮ると色が薄くなるね…汗

 

ゲーム開始時の文字の色もちゃんとした気がする。

雑誌掲載版のギガンテスはタイトルが表示されないらしいけど、これが正解??

 

画面下の水色文字部分は点滅するらしいけど、テキストVRAMのブリンク機能を上手に使って実現してるっぽい。

でもテキスト画面のブリンクを実装するのは面倒なので、ここは点滅せずで諦め(をぃ

 

GDCコマンドの表示範囲設定をちゃんとしていないので、本来見えてはいけない左側が丸見えな状態(^^;; 画面下17ドットが表示されない不可解なバグに悩むも突破口が見えない…。

 

テキストVRAMも反映されるようになり、スコア、残機、ダメージゲージが表示された!

テキストVRAMは、横を32文字と設定してもメモリ上は40文字分が確保されるみたい。それに気づかなくてしばらく悩んだ!(^^;;

 

完成したギガンテエミュレータ

こんな出来で「完成した」と書いて良いんだろうか…(^^;;

適当にも適当すぎる実装なのにw

でも作ろうと思ってから24時間経たずにして動いてしまった!

書いたソースコード量で言えば(V20エミュレータを除くと)1000行程度とコンパクト。コメント抜かしたら700行程度に収まっているのかも?

 

思った通りPC-9801に依存している部分は限定的で、これならば同じく8086+GDCという構成のMZ-5500などにも移植は難しくないだろうなーと思った(^-^)

ちなみにPC-9801のROMは一切使わずに動いてます!

 

M1 Mac+SDL2という環境で開発しているので、同じような構成(Windows+WSL、Linux)であればコード無変更で動くかも?(^^;

 

よし!納得の行くところまで作れて満足した!

仕事に戻りまーす!(^-^;;;

 

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

 

2023.11.19追記

ついでだったのでSHARPの電子辞書Brainでもギガンテスを動かしてみた!

しれっと動かしてみたけれども、実はけっこう大変だったw

SDL2→フレームバッファ直描きに修正するのは簡単だったんだけど、実はプログラム中にお作法の悪いメモリアクセスをしている箇所が多々あって、それの修正が大変だった!

 

これは「Brainで何か動かすと楽しい!」という実験という事で!(^^)

 

CASIO FP-1100覚え書き!

FP-1100をげっとした!

最近、ブログを書いてる余裕すらないほど実務が忙しいんですけど、それでもやりたい事と、ちょっとやっちゃったけど忘れそうな事とかがいっぱいあるんですよね!(^^;

というわけで、今回はFP-1100の備忘録を書いてみる!

 

今回入手したFP-1100は、友人と共同で購入したもの。

今までは友人が使っていたが、もう思い残すことはない!?という事で私の手元に来た(^^;

 

そして私は、たまたまだけどFP-1100で使える拡張メモリパックを持っていた。

容量としては16Kバイトしかないメモリバックだけど、16KBって大きいよ!(^^)

これは秋葉原にある神田装備というお店のショーケースに展示されていたもの。

型番を見てすぐに「あ、これはFP-1100用だ!」と思ってげっとしていた!

 

脅威のバッテリーバックアップ機能付き!(^-^)

そういえばCASIOさんはFX-9000Pの頃からデータが消えないってのをウリにしてたね!

サイズ的にぴったりだったので、単5電池を2つ繋げて入れていた。

本当の電池は違うものを入れるんだろうなぁ……多分。

しかし電池ホルダのホールドが弱く、中で電池が外れてしまってバックアップが上手くできないという問題が発覚した。見栄えは悪いけれどテープでがっちり固定するよ!(^^;;

メモリパックへのアクセスはファイルディスクリプタPACK0:でアクセス出来る。

よし!これで安心してプログラム開発が行えるってモンですよ(^-^)

 

FP-1100の魅力

私自身、過去にFP-1100を使ったことはないけれど、いつかは使ってみたいと思っていたマシンの、かなり上位に君臨していた!

工学社のPIOという雑誌に書かれていた「サブCPUを制御して高速に画面描画を行っている」という情報を見て以来、いつかやってみたいと思っていたのだ!(^^)

こういう特殊な構造に魅力を感じる辺りがアレですが…(^^;;;

 

FP-1100付属のハードウェア解説書を見ると、C82-BASICは起動時にROMからRAMへコピーされ、それ以降はRAM上で動作しているらしい。ということはBASICの改造も比較的簡単にできそうな気がする!(^^)

 

メインCPUは言わずと知れたZ80で動作クロックは約4MHz。

VRAMが分離していることから、ノーウェイトで動いている気がする(勝手な予測)。

全体的にもっさり動く印象があるのは、おそらくBASIC内部でBCD演算をしているのと、表示が遅いせいなんだと思う。

 

そして表示系を司ってるサブCPUは、NECのμPD7801Gで動作クロックは約2MHz。

型番からZ80互換?と期待してしまったが、どうやら違うものらしい。

サブCPU側の事情については少しずつ書いていこうと思うけれど、噂ではかなり制限があるようで、こういった事情のあるマシンは大好きだ!(^-^)

なんとなくだけど、HC-80以上に苦労しそうな予感がバリバリにするw

 

メインのROMげっと大作戦!

何を解析するにも本体内部のROMをゲットしないことには始まらない!

まずは、FP-1100からROMを抜き出す方法を考えてみる。

てっとり早い方法はRS-232C経由でホストマシン(ここではMac)にコピーしちゃう事だけど、残念ながら我が家のFP-1100にはRS-232Cが付いていない(T-T)

 

じゃあ…というワケで、過去にJR-800で試してみた方法はどうだろうと検討。

pocketgriffon.hatenablog.com

この時はJR-800に表示させたダンプリストを、手作業で打ち込む方法を取った!

ROM容量は20KBだったけれど、かなーりの時間を要した覚えがある!

出張の移動時間にもJR-800とMacを広げ、ぷちぷちと打ち込んでいった(^^;;

 

今回、FP-1100のBASIC ROMは36KB分ある。

倍近い容量だよ!!無理でしょ…orz

この方法は努力と根性で出来そうな気もするが、失うもの(寿命とか)も多そうだ(T-T)

 

うーん、何か良い方法はないか…と考えていたところ、そうか画面に表示させたダンプリストを写真撮って、それをOCRしてみたらいいじゃん…!と思いついた!(^-^)

さっそく試してみるか!とやってみたところ……

めちゃくちゃ認識率が悪い!!(ToT)

これはなぜなんだ??あれだけ雑誌の写真をOCRしまくってるというのに…。

もしかして……これはフォントの問題だろうか??

CASIOフォントではなくてNECフォントにしてみたら認識率が上がるかも?

よし、PC-8001のフォントを利用してダンプ表示をしてみよう(^^)

 

FP-1100にはPCG定義命令があるので、これを利用して解決する(^^)

PCG定義が出来る文字は$E0〜$FFまでの32文字!

X1などのようにハードウェアで実現しているPCG機能ではなく、あくまでもソフトウェアで頑張るPCG機能のようだ!

試してみた結果、OCRの認識率が爆上がりすることが確認できた!(^^)

 

FP-1100のフォントとPC-8001のフォントの違いはこんな感じだ!

並べてみると結構違うんだなー(^^)

 

問題としては……1ブロック(256バイト)を表示するのに猛烈な時間がかかる。

動画で時間を確認してみたところ、256バイトを表示するのに約23秒!

写真撮って合計30秒。

36KB=144ブロックを写真撮るだけでも、休み無しで作業をしたとしても、最低で80分くらい掛かりそうな見込みだ(ToT)

これは……気が滅入りそうなので、時間があるときにちまちま進めるしか無いね(T-T)

 

でもこれでZ80側のROMはダンプできそうなメドがたった!(^-^)

これは一歩前進♪

 

サブCPU側のROMげっと大作戦!

次はサブCPU側のROMだ!

でも……サブCPU側のデータを読む方法なんてさっぱり分からぬ…orz

なんとなくだけど、サブCPU側にプログラムを送る必要がありそうな予感!

 

我が家にある唯一と言っても過言ではない技術資料を引っ張り出して読み漁る!

アセンブラも何もない環境で長いプログラムを作るわけにはいかないので、マシン語が極力小さくなるプログラムを考えてみた。

テストで以下にある写真のようなプログラムを作ってみた。

やってる事は、サブCPU側の任意のアドレスにある1バイトを表示する、だ。

 

70行80行がサブCPUに送るプログラムとなっている。

今回はハンドアセンブルしているが、プログラム的には以下のような感じ。

                mov a,nnnn

                mov $A000,a
                ret

指定されたアドレスの1バイトを、サブCPUのメモリ空間の$A000に書き込んでいるだけのプログラムだ。$A000は緑VRAMの先頭を指していて、これで画面上に緑のドットが表示される!

120行目からのプログラムで画面上のドットを1つずつ調べ、1バイトのデータに再構成する。VRAMは世にも珍しい反転型というもので、例えば$00を書き込むと$FFが入るという奇抜なものだ!そのため、BASICのプログラムで反転している。

これでメインCPUサブCPU側の特定のアドレスのデータが取得できる!

これを256回繰り返せば、任意の1ブロック分が表示できるという算段だ!(^^)

 

ちなみにNECの文豪ミニ5ZCという機種も反転型VRAMが使われている。

FP-1100だけではないということは、きっと何か反転型であるメリットがあるんだろうね…汗

 

おわりに

いまだかつて無いほど生活が忙しくなってしまい、なかなかレトロを触ってる時間が確保できなくなってしまった。

このFP-1100も取り組むまでに長い時間が掛かってしまいそうな予感がする。

気長に見ていってもらえれば…と思います!(^^)

 

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

PC-98HA(HANDY98)を使う!その3

せっかくPC-98HAが動くようになっているので、何か動かせないかと考えていた。

640x400ドットで、カラー使って無くて、プログラムが小さくて、簡単に入手できるヤツ……要はできる限り手抜き出来るものを探していた(^^;;

 

ふと…そういえば昔のI/Oに3Dパッケージが載っていたことを思い出した。

確かPC-9801とMZ-5500、そして後にFP-3000に移植されていた気がする。

ということは、計算部分と表示部分がキレイに分離されているような予感。

これならば移植がしやすいかも!という安易な理由でチャレンジしてみた!w

 

月刊I/O1984年1月号に掲載されていた「8086 3Dパッケージ」。

ローダーとして存在する数行のBASICプログラムと、マシン語ダンプが3KBほど。

これはもうOCRしちゃえばあっという間にバイナリ化出来る!

印刷の状態が良かったおかげか、間違いも数か所程度で済んだ!

 

解析開始

残念ながらアセンブルリストが載っているわけではないので、マシン語ダンプリストを解析していくしか無い!

こういうバイナリの解析って…週に何回ってレベルでやってる気がするんだけど、なんでだろ?(^^;; 既視感がスゴいw

 

以前にも何度と無くご紹介しているけれど、今回も書く!w

私は逆アセンブラに自作のものを使っている。

↑こんな感じのエントリアドレスやコメントデータを逆アセンブラに食わせると…

アセンブル時にコメントとして書き込んでいってくれるモノだ!(^^)

こうする事によって、解析できたところに逐次コメントを入れてけば、逆アセンブルするたびに読みやすい状態となって出てくる!

 

この時代のプログラムなので、あまり凝った作りにはなってないだろう…という勝手な想像の元、解析を進める。

 

I/OポートのアクセスはGDCだろう、INTxx(ソフトウェア割り込み)は何かの初期化なんだろう、積和演算してる辺りはおそらく行列計算、除算してるのはきっと透視変換…等々、さんざんっぱら仕事で3D計算してたのが今になって生きてくるww

 

軽く解析してみた結果、

・1周を256度ではなく360度として計算してる素直な実装

・テキスト画面はOFF

・LINE描画はGDCのコマンドを発行している

・画面切り替えはパレット操作

という感じが読み取れた。

特に高速化などを行った感じはなく、素直でキレイなプログラミング。

 

プログラムの開始アドレスが0100から始まる辺り、MS-DOSで開発していた可能性を感じる。おかげでMS-DOSのCOMファイル形式のコマンドとして改造する事も簡単だった!(^-^)

 

これ、3Dパッケージとして利用してもらいたかったのならば、アセンブラソースを公開した方が良かったんじゃないのかなぁ…と強く思う(^^)

 

なんでも良いけれども……

8086のアセンブラを完全に暗記しているわけではないので、取り組む時には机に資料が散乱するw

とりあえずこのくらいあったら作業はできそうかな…(^^;;

 

PC-98HA対応に改造

アセンブルリストからアセンブラファイルを作り、その上でプログラムを改造していく手法でも良かったのだけど、やはり作者様の著作物であるという事は意識したい。

いつもの通り、プログラムのバイナリにパッチを当てて行くよ!!(^o^)/

 

たくさんのコードを書くとバグが出る可能性が高くなるので、最低限のパッチ当てだけで動かすことを目標にしてみたい!

その流れから最初に決めた方針は「コードサイズが大きくなりそうなLINEルーチンはBIOSを利用する」という事だった。

 

まず、PC-9801特有の初期化をなくす。

VRAM各プレーンのクリア、パレット初期化は何もせずRETにする。

 

スクリーンの切り替え(パレット操作)は、VRAMクリアに置き換える。

画面は点滅しまくってしまうけれど、それは後で対応すれば良い。

まずは動かすのが優先よ(^-^)b

 

そしてLINE描画は、HAのBIOSに用意されている INT 1Dh(AH=07h)を使うように改造。

XY座標が格納されているワークから、BIOSが参照するワークへコピーしてBIOSを呼び出す。

 

初めてPC-98LT系のBIOSを使ってみたが、DS(データセグメント)の先頭から600バイトくらいがワークとして利用されるという不思議な仕様となっていて、これはとても困惑した(T-T)

 

そして動かしてみたのが、こちらのツイート。

バリバリに点滅しまくっているけれど、なんとなく飛行機が飛んでるのが見える!

まぁとりあえず移植は出来たから、これで良いか!

……とはならなかったww

 

点滅しない画面が見たいんだ!

やっぱり画面がビカビカ点滅してしまうのは気になる!

でもコレを直すのは簡単じゃない!

 

簡単ではない理由はすごく簡単で(どっち?)、BIOSのLINE描画がVRAMへ行われるためだ。

本来であれば、画面に見えない部分で描画をしておいて、そこで作られた画像情報をVRAMへ転送する事で、画面の点滅を防ぐ。

しかしBIOSの描画対象がVRAMである以上、これは出来ない。

 

BIOSの描画対象を動かす(VRAM以外のメモリを指定する等の)方法があるのかなぁ…と思ってみたが、それはBIOSを解析する事になるので手間が爆増する(T-T)

もしもその結果、ROMにハードコーディングされていたら手が出せない。

 

それだったら……LINE描画処理を独自で書いちゃう???(@_@;;

いやまて、LINEを描画するプログラムをアセンブラでごりごり書くのは簡単じゃないぞ!そんな若くもないww

 

そう思いつつ、ChatGPTに教えてもらった(!?)ブレゼンハム線分発生アルゴリズムを、LSI C-86(試食版)で書いてみる。

うーん……悪くないww

BASICでも同じ処理を書いてみた。

お、BASICと遜色ない速度でLINE描画が出来てるって事がわかった!

うーむむむ……悪くないなぁ…(^^;;

 

パッチ当てふたたび!

このLSI C-86(試食版)で作ったLINEルーチンを、3Dパッケージに載せてみる!

 

8086の場合、プログラムを実行するアドレスがズレる事について、そこまで神経質である必要がない。いろんなコードが相対アドレッシングで出ているので、まとまった単位で移動させる分にはアドレスはズレない。

 

問題はデータを参照するためのDSの状態が違うために、グローバルなワークエリアのアドレスがずれたり、関数外にデータを参照するような時もずれてしまう。

この2つを解決するためには、使用するワークエリアはauto変数のみ、外部のデータは参照せず計算で作り出せるものは作る、という対処をした。

パッチを当てる部分は、こんな感じでハンドアセンブルしたデータを上書きしてる!

実際にはMS-DOS上でSYMDEBを利用したワンラインアセンブルしたものを取り込んでいる。

使えるツールはなんでも使ってラクするのがポリシーだww

 

そして画面を切り替えるのは、

・描画したバッファをVRAMへ転送した

・次の描画のためにバッファをクリア

…というコードを追加する。

8086で領域クリアってrep stoswが最速??

V30シリーズはストリング系命令が速かった記憶がある!(^^;

元々のエリアが小さくてプログラムが入り切らないので、適当なアドレスにプログラムを配置して、そこへジャンプさせるようにした!

メモリの中はわりかし適当でぐちゃぐちゃだ(^^;;

 

そして出来上がったのがこちら!(^-^)

LINE描画と転送&クリアの速度が遅いけど、むしろ速すぎてウェイトを入れたいと思っていたくらいなのでちょうど良い!(^^)

画面が点滅しないだけでもこんな見やすくなるのかーw

いいね!いいね!!(^o^)

 

おわりに

今回はPC-9801のソフトを移植するということをやってみた。

元のプログラムがすっきり作られていたおかげで、解析&移植は楽しめる範囲で出来た!

 

そもそもソースが存在しないものを移植するというのが簡単じゃないと想像していたけど、意外にも簡単に出来ちゃうんだなーと驚いた(^^)

 

PC-98HAはこれからも安定して動きそうな気がするけど、こればっかりも触っていられないので、一旦キリを付けます(^^)

 

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

PC-98HA(HANDY98)を使う!その2

ふいにPC-98HA(HANDY98)が起動するようになってから1週間が経つ。

当初は「きまぐれに電源が入るいつもの感じ」と思って期待もしていなかったけれど、まさか1週間連続して動くようになるとは想定外だった!

 

ちゃんと動くようになった原因はなんだろう??

思い当たるのは、専用のACアダプタ(PC-98HA-12)を使ってる…くらいしかない。

その後、レジューム機能(電源切る直前の状態を覚えてくれてる)も使えるようになり、本体としてはかなり安定した状態だ(^^)

このHANDY98、ずっと安定して使えるといいなぁ…!(^o^)

 

これだけ安定していると、せっかくだから何か作りたくなるよね!

ちょうど週末に差し掛かるところだったので、いっちょ環境整えてみるか!(^-^)

 

PC-98HA開発環境

開発言語

PC-98HAの開発環境としては何が考えられるだろうか?

PC-9801互換ではないけれど、MS-DOSという意味ではきちんとしたものが乗っている。

そしてMS-DOS汎用であれば、開発言語は山のような選択肢がある。

それでもパッと思いつくのはMASMによるアセンブラ、そしてC言語による開発かな…。

16ビットCPUなワケだし、基本はC言語での開発を主体にしつつ、どうしてもってところだけアセンブラ化するのが良いだろう!

よし、開発言語はC言語を中心としよう(^-^)

 

開発環境

MS-DOSで使用できるC言語としてはLSI C-86(試食版)がある。

LSI C-86(試食版)自体はMS-DOS上で動くソフトウェアだ。

Windows上ではなく、素のMS-DOSだ。

 

そうなるとここんとこお気に入りのWine上で動かす事が出来ない…多分(T-T)

MS-DOSの環境を用意するとなると、私的にはDOSBoxが慣れている。

DOSBoxは、Mac上のファイルを読み書きできる機能があってとても便利だ!

Macで編集、DOSBoxでコンパイルって方法がなんなく出来る。

 

実行環境

DOSBoxでコンパイルして出来上がったEXEファイルを、どうやってPC-98HAへ持っていくか…。これはもうエミュレータを使うのはラクなのは分かるけれど、そのエミュレータへデータを渡す方法が簡単ではない。

 

エミュレータを試してみたが、メモリカードやRAMディスクへデータを置く方法もぱっと分からなかったので、これはもうフロッピーディスクイメージ(D88)の中にファイルを入れて渡すのが簡単だと判断した!

 

つまりコンパイルして出来上がったEXEファイルを、D88ファイルの中にコピーしてエミュレータにセットすれば、エミュレータからはフロッピードライブの中にファイルがある…という事だ(^-^)

 

D88ファイル自体はフォーマットが公開されている。

ツールを作るためにはD88のフォーマットとは別に、FAT12の構造を知る必要がある。

これはもう1980年代に散々実験を繰り返していたので、暗記とまではいかないが悩むことがないくらいの理解力はあった(^^)

画像

画像

よっしゃ、Macで編集DOSBoxでビルドエミュレータで実行の環境が出来た!

 

なにか作ってみたいけど…

せっかく開発環境の用意が出来たんだから、何か作ってみたくなる!

最近は平日が激務状態になっているので、時間は土日しかない(T-T)

じっくり作る時間もないので、過去に作ったとか、データのみを利用するか、どうするか…。

そんな事を考えてる時に、はたと1980年代にモノクロ640x400環境で作ったものがある事を思い出した!

 

8086(というかV20)のアセンブラで書いてあるものだけど、これをC言語に置き換えてみたらどうだろう…と思った。

3x年前とはいえ、自分が書いたものなので解析は必要ないし、アルゴリズムは頭に入ってる。

よーし、これを移植してみるかー!(^-^)

 

ぐはっ!!!

久しぶりに当時のソースコード見たけど……うん、思うところあるよねww

今コレの中身を参考にしても仕方ないので、用意されてる関数を参考にしながら作っていこう(^^;

 

アセンブラで書いていたものをC言語に移植していくと、とにかくアセンブラでは面倒な計算が、C言語では演算子1つ2つで解決してしまうのが簡単で良い!(^^)

15分もしたら文字が表示出来るようになってきた。

作っていくと、デバッガが使えないのをどうしようかと悩むようになってきた…。

SYMDEBを使うかprintfでデバッグしていくしかないが、不用意に画面にprintfしてもかき消されてしまうのでどうしたものかと…(^^;;

仕方ないけど、今回は小規模という事もあって「なるべくバグが出ないように」気をつけながら作業する事としたww

 

ある程度ゲームが動くようになってきたところで、実機で動かしてみたくなった!

実機で動かすためには、コンパイルして出来上がったEXEファイルをPCMCIAのSRAMカードへコピーする必要がある。うちではMacから直接SRAMカードへ書く方法がないので、一旦PC/AT互換機を経由してコピーする事になる。

手順が面倒なので、あんまり何度もしたくない(^^;;

おお〜!実機で動いた!速度もエミュレータで動かした時と一緒だ!

 

おわりに

それなりの規模となるものをエミュレータおよび実機で動かす事が出来た!

プログラムとテキスト化したデータを含めても1200行前後のモノ。

出来上がったEXEファイルは13KB程度だ(^^)

土日でやる作業としては、まぁこんなもんだ(^^;;

 

その後、友人がモノクロ背景のデータを作ってくれたので、それはぜひ入れなくては…と思っているが、ゲームとして完成まで作り込むことはしないかも(^^;;

 

細かいレポートは書ききれていないので、別ブログか、ここに追記していこうと思う。

 

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

祝!30万PV達成!

本日でこのブログのアクセスが30万PVを達成しました!(^-^)

毎回書きますけど、こんなヘンテコなブログを御覧くださってありがとうございます!

毎度趣味の垂れ流しで失礼してます(^^;;

 

ブログ始めて3年弱での達成でしたが、特に数字にはこだわって無くて(^^)

毎回ネタが出来ると、かなーり適当に編集してブログに出すという、ゆるーい感じで続けているのが良いんだと思っています!

 

前回の20万PVから今回の30万PVまで、実はブログを25回しか書いてなかった!(@_@;;

なんとなくJR-300以外、あんまり頑張ってない気が…(^^;;

 

段々と実務が厳しくなってきていますけど、週末中心にのーんびり更新していきまーす!

今後ともよろしくお願いします♪(^o^)

 

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