70年代のCPUで、68系でも80系でもなく、クロスコンパイラがあるものを探していたら、
RCAのCOSMAC(CDP1802)というのを見つけました。
https://iccollection.try.mydns.jp/miscproc/CDP1802.html
これを読むと、かなり変わったアーキテクチャだとわかります。
まず、メモリをポイントするレジスタが16個もあります。
レジスタが多いZ80で、裏レジスタを合わせてもBC,DE,HL,IX,IY,BC',DE',HL',PC,SPの10個ですから。
PCはなく、どれでもPCになれるというのが斬新です。
また、SPがないのでCALL/RETURNに相当する命令はありません。
RCAが標準的な手段を提供していますが、よくこれで行こうと思ったな、と思うくらい面倒です。
それを使わずに済む、いくつかのPCを切り替えてサブルーチンに代える程度のアプリケーションを想定してのことでしょうか。
1802のマニュアル
http://www.bitsavers.org/pdf/rca/1802/MPM-201A_CDP1802_User_Manual_1976.pdf
丁寧なんだけど、なんかわかりにくい...
最初に紹介したページの方が簡潔にまとめられていたので、それを元にコマンドラインで使えるエミュレータを作りました。
クロスコンパイラ
Macで使えるように多少改造しました。
https://github.com/kwhr0/lcc1802
のCodeからZIPファイルをダウンロードします。
unzip lcc1802-master.zip
cd lcc1802-master
make
でコンパイラをビルドし、/usr/local下にコピーします。sudoしますのでlcc1802/Makefileを確認してください。
アセンブラは以下からC Sourcesのlatestをダウンロードします。
http://john.ccac.rwth-aachen.de:8000/as/download.html
tar xf asl-current.tar.bz2
cd asl-current
cp -p Makefile.def-samples/Makefile.def-arm-osx Makefile.def
make
sudo cp -p {asl,p2hex} /usr/local/bin/
(Intelの場合は代わりにMakefile.def-x86_64-osxをコピーします)
エミュレータ
https://github.com/kwhr0/emu1802
のCodeからZIPファイルをダウンロードします。
unzip emu1802-master.zip
cd emu1802-master
make
emu1802をパスの通ったところにコピーします。
サンプル
マンデルブロ集合のテキスト描画です。
cd lcc1802/examples/mandelbrot
make
emu1802 mandelbrot.hex
最初、エミュレータで実行してみると、Macで実行した場合と異なる結果が出ました。
どうもfloat演算のコードが怪しい。
ということは、楽しいデバッグの時間です。
float演算はinclude/LCC1802fp.inc(アセンブラ)に実装されており、乗算(fp_mul)に問題があるとわかりました。
エミュレータのトレースダンプを見ながらアセンブラを修正していきます。
1802への理解が深まります。
最終的にMacで実行したものと同じ結果を得ることができ、本家にプルリクエストを出したところ、即座にマージしてくれました。
https://github.com/bill2009/lcc1802/pull/8
1802の1GHz相当で3秒以内で実行できました。
1802は一命令あたりのクロック数が16または24と多く、その分エミュレータのクロックはかなり上げられます。
M1 Macで5GHz相当まで上げることができました。
(2024/12/22更新)
新たなサンプルとして、MIDIプレイヤーを実装してみました。
そのためにエミュレータに機能を追加しました。
CDP1861で64x32ドットのグラフィックを表示したような画面と、キーボード、PSGに対応しました。
CDP1861のエミュレーションはせず、0xff00-0xffffをビットマップVRAMとし、書き込むだけで表示するようにしました。
キーボードは入力ポートから直接、キャラクタコードが読めます。カーソルキーはPC-8001相当のコードにしてあります。
PSGは32音ポリで、いくつかの波形を選べます。
ついでに、プロファイル機能も入れてみました。終了したときに実行時間の割合を関数単位で表示します。
MIDIファイルはディスクイメージから読みます。
ChaNさんのPetit FatFSを試してみたのですが、コンパイラのバグを踏みまくりで諦めました。
機能は限定されますが、以前FM音源ジュークボックスで作ったものをベースにCで書き直して使っています。
ファイル名順にソートしたり、lcc1802標準だけでは不足するものを補うために以下のklibcを導入しました。
https://mirrors.kernel.org/pub/linux/libs/klibc
Linux用ですが、それに依存しない部分は標準ライブラリとして使えます。
lcc1802(で使うアセンブラ)はリンカに対応していないので、一つのファイルに全て書く必要があります。
実際は機能ごとにソースを分けて#includeしています。
メモリは32kバイトくらい使用しました。
C言語向きではないCPUなのでコード効率は悪いですね。
SDL2を使用するようになったので、
$ brew install sdl2
でインストールしてからmakeしてください。
Makefile内のパスはApple Silicon Macに合わせてあるので、環境によって変更してください。
ディスクイメージはFAT16でフォーマットし、/MIDIの中にSMF0のMIDIファイルを入れます。
起動すると/MIDI下にあるMIDIファイルとディレクトリのリストを作成し、ASCIIコード順で最初のものが表示されます。ディレクトリの場合は反転表示になります。
カーソル左右で選べます。数字またはアルファベットで頭文字がその文字のところまでジャンプできます。
ディレクトリの場合はカーソル下で降り(4階層まで)、上で戻れます。
MIDIファイルの場合はカーソル下またはリターンキーで演奏を開始します。
演奏中は画面上部にファイル名を表示し、下部にPSG各ボイスのレベルを表示します。
# スペアナではありません。1802にはきついので
演奏中もカーソル左右で曲を選べます。カーソル上またはエスケープキーで演奏を終了して選択に戻ります。
レベルメーターは時間に余裕があるときだけ更新するので、クロックが低いとあまり更新されません。
# もちろん、演奏テンポも遅くなります
300MHz以上だとスムーズです。
https://github.com/kwhr0/midiplay1802