68系の旅もついに原点の6800へ。
ということで、今回は6800です。
以下のマニュアルを見ながら書きました。

http://www.bitsavers.org/components/motorola/6800/Motorola_M6800_Programming_Reference_Manual_M68PRM(D)_Nov76.pdf

いつもはクロスコンパイラで軽くデバッグしてからエミュレータに載せていたのですが、今回はまずソースが公開されていてmacOSで動くエミュレータがあるかどうかから調べました。
というのも、CMOCやcc65のように現在もアクティブに開発されているクロスコンパイラがなく、うまく動かないときにコンパイラのバグも疑わしく作業量が増えるからです。

そんなわけで検索したところ、ベーシックマスターJr.のエミュレータを見つけました。

http://ver0.sakura.ne.jp/pc/#bm2

ありがたいことに、#includeを追加するだけでIntelでもApple Siliconでも走りました。
早速CompareProcess.hと、以前書いた(6800と類似性が高い)6502エミュレータをリネームして組み込み、6800になるように書き換えていきます。
難なくプロンプトまでたどり着いたのですが、なぜかテープが読めません。無限ループになっているようです。
トレースするとNOPを連ねてタイミングを取っている辺りで失敗しているようで、エミュレータのソースを見るとテープの再生個所をクロック数に応じて厳密に決めていることが判明。
とりあえずロジックが合っていればいいだろうとクロック数を全命令同じにしていたため、タイミングが取れていませんでした。
クロック数をちゃんと実装するとテープを読めるようになりました。

CC6303によるクロス開発

コンパイラは、前もって探したときに見つけたCC6303を使います。

https://github.com/EtchedPixels/CC6303

6303というのは、6800のバイナリ上位互換MPUだと知りました。
6800のバイナリを吐くように指定して試してみると、コンパイラのバグを踏まないように書くのは結構大変でした。

仕方がないので内包するアセンブラas68を使ってサンプルを作りました。
お題はMMLプレイヤー。"ceg"と書くとドミソと音を出す、8ビットPCの頃よくあったやつです。
アセンブラでMMLの解釈をするのは面倒なのでホストで演奏用バイナリを生成することにしました。
play()により単音でメロディーを奏でることができます。

ところで、ベーシックマスターJr.のサウンド出力は5ビットのDACになっています。
ということは、和音やエンベロープに対応できるんです。
実機相当の速度では単音が精一杯ですが、エミュレータなのでクロックを上げればいいということで作ってみました。
play3()で3和音を奏でることができます。playnoise()でノイズも出せます。

https://github.com/kwhr0/bm2-mml-demo

makeするとバイナリa.binができます。
~/.bm2configに
load_bin /path/to/a.bin
のように書くと起動時にバイナリを読み込みます。モニタのGコマンドで実行できます。
さらに、rom_dirをコメントアウトするなどしてROMを読まないようにすると自動実行します。
実行すると単音のデモがループします。

MakefileのPOLY = 0を1に変更し、make cleanしたあとmakeすると和音のデモになります。
このとき、~/.bm2configに
clock 3000
を追加してください。

CC6303の改善

まともに走るようになると、やっぱりCで書きたくなります。
ソースを書いてコンパイル、動かないとトレースダンプを見ていつの間にかコンパイラのデバッグをしていました。
直ったものをプルリクエストで(Linux界隈では有名な人なのでちょっと恐る恐る)投げると、取り込んでくれました。
調子に乗ってさらにいくつかのバグを修正して送りました。
そして、まあまあ実用的なレベルになったのでベアメタルライブラリのデモを作りました。

https://github.com/kwhr0/bm2-baremetal-demo

文字表示とグラフィック表示(line/box/boxfill/circle)のデモです。
main.cの#if 1を0にするとキー入力のデモになります。
Nキーロールオーバー対応で、過渡的に複数キーを押下しても入力できます。

ところで、6303って6800とどう違うんだろう。
以下のマニュアルを見ると、多少の追加で6303になることがわかり、最終的に6303エミュレータになりました。

https://www.jaapsch.net/psion/pdffiles/hd6301-3_handbook.pdf

# MMLのデモが3MHzなのは、6303で実際に走るかも、と思ったからです
そして、CC6303は6303のバイナリを指定するとかなりまともに使えることがわかりました。
ただ、やっぱり6800のコードっていうのが味があるんですよねぇ。

エミュレータの変更点

エンコーディングをUTF8に
コメントなどを、現時点で扱いやすいUTF8に変更しました。また、改行をLFだけにしました。

サウンドの待ち合わせ
サウンドの生成と消費は別スレッドで、オリジナルではタイミングの誤差によりプチプチとノイズが乗っていました。
これを、セマフォを使って待ち合わせをすることで解消しました。

ROMなしで実行できるように
.bm2configのload_binにより、クロス開発したものを読んで実行できるようにしました。
デフォルトの読み込みアドレスは0x4000ですが、load_bin_adrで変更できます(16進表記)。
また、バイナリを更新してウィンドウをアクティブにするとリロード&リセットします。

https://github.com/kwhr0/bm2

古いOSにも対応しています。
OS X Lionで実行してみるとSDL2.frameworkが最新の場合、ウィンドウがアクティブになりませんでした。
SDL2.0.8くらいがいいようです。