使ったことがないCPUのエミュレータを作る、今回はSC/MPです。
このCPU、クロスコンパイラがありません。
しかし、2024年に新たに書き直されたというBASICインタプリタがありました。
https://github.com/ekuester/SCMP-INS8060-NIBL-FloatingPoint-TinyBASIC-Interpreter
の中のNIBLFP_2024です。
これをエミュレータで走らせて久しぶりにBASICでも書いてみよう。
ということで、まずはSC/MPのマニュアルから。
https://archive.org/details/bitsavers_nationalscammingAndAssemblerManualFeb76_5163861
レジスタセットを見ると8ビットのAC(アキュムレータ),E(補助),SR(ステータス)と、ポイント用の16ビットレジスタが4つ(内1つはPC)。
6800に似ています。
ところが、インストラクションを見ていくと異変を感じます。
大抵のCPUは演算結果でフラグが変化し、それを見て条件分岐しますが、
SC/MPはフラグはあるのですがACの値による条件分岐しかできません。
フラグで分岐したい場合はSRをACにロード、キャリーならMSBなので非負で分岐、オーバーフローならマスクしてゼロかどうかで分岐するという...
メモリ空間は4kバイトのページx16個に分かれており、
ページを跨ぐ条件分岐ができないのはもちろん、インストラクションフェッチもページ内でラップアラウンドしてしまいます。
これではコンパイラがないのも仕方ありません。アセンブラでも書きにくそう...
エミュレータ
https://github.com/kwhr0/emu8060
からCodeのZIPファイルをダウンロードします。
unzip emu8060-master.zip
cd emu8060-master
make
とし、 出来上がったemu8060をパスの通ったところに置いておきます。
BASICインタプリタは前述のURLのCodeのZIPファイルをダウンロードします。
unzip SCMP-INS8060-NIBL-FloatingPoint-TinyBASIC-Interpreter-main.zip
展開した中のNIBLFP_2024/NIBLFP.hexをemu8060と同じディレクトリにコピーします。
サンプル
サンプルを作ろうとしたのですが、行番号を書かなければいけないのがなんとも面倒です。
そこで、ラベルを使えるようにして行番号を廃止しました。
エミュレータに内蔵したプリプロセッサで行番号を付加し、ラベルを行番号に置換してゲスト側に渡すことにします。
このBASICはGOTO/GOSUBの行番号に変数も使えるのですが、残念ながら使えなくなります。
この機能を使いたい、あるいは通常のBASICテキストを試したい場合、ソースの先頭が数字だと行番号有りとみなしてそのまま渡します。
サンプルは定番のライフゲームです。
em8060 -r life
変数名が一文字なのは、元々Tiny BASIC用に書いたものだからです。
BASICに内蔵されているRNDは、初期値を与えることができず、明らかに模様が見えるような品質なので、xorshift相当のものを書きました。
走らせてみると、すごく遅いです。
全力で走らせても目で追える程度の更新頻度でした。