2021-10-24 22:57 — asano
カテゴリー:
CP-1600を実際に動かしてみるとなると問題になるものの一つとして開発環境をどうするかというのがあります。
ざっと探してみましたが使えそうなアセンブラが見当たりません。
Cコンパイラなどが無いのはともかく、アセンブラも無いのはさすがに困ります。いくら昔を懐かしむといっても今さらハンドアセンブルはしたくありません。
というわけで以前ASをMN1610対応させたようにCP-1600対応のコードジェネレータを書いてみました。
16ビットワードマシンであることなどMN1610に似ている点もあり、基本的な枠組みはMN1610とほぼ一緒です。
続いて各命令のデコーダを書いていきますが、結論から言うととても楽でした。
MN1610ではアドレッシングモードのデコードに苦労しましたが、CP-1600ではアドレスレジスタが決まるとアドレッシングは自動的に決まるのでデコードの必要がありません。レジスタ名(R0
~R7
)のデコードを書いたのみで、数値・アドレスは標準のルーチンを呼び出すだけです。
ちょっと面倒だったのは分岐命令ぐらいですね。
絶対分岐では飛び先のアドレスをビット9~0に詰め込むため(理由は後述)にちょっと変なことになっています。
相対分岐も一般的な2の補数形式ではなく符号と絶対値になっています。
とりあえず一通りの命令のデコーダを書くのに約1日でした。
その後テスト用のソースを用意して各命令が正しく変換されているか確認していきます。ここでレジスタ番号を埋め込むビットがずれているといった間違いがいくつも発見されました。
このデバッグ作業と平行して、あまり重要ではないと先送りした問題に対応していきます。
その一つがSDBD
命令です。いや命令というよりはプレフィックスと呼んだほうが良いかもしれません。
これをメモリへのアクセス命令の前に置くと、通常はデータバスの16ビットを使ってアクセスするところを下位8ビットで2回のアクセスが行なわれます。
アドレッシングモードによっては期待する動作をしないものもあるので注意が必要です。
これはMC68000系のMOVEP
命令のようにペリフェラル用というわけではなく、このプロセッサのちょっと面白い特徴が関係しています。
CP-1600は16ビットのプロセッサでデータバスは当然16ビット分ありますが、必須なのは下位10ビットのみで上6ビットは省くことができます。なので命令コードも下位10ビットのみを使用し上位6ビットは無視されます。
ただし命令コードの2ワード目以降は16ビットをすべて使っているものも何種類か存在します。
- イミディエイト値
これはSDBD
を使って分割することで16ビットの値が使用できます。 - ダイレクトアドレス
救済手段は用意されていないのでビット幅を超えたアドレスにはレジスタを使用したインダイレクトを使うしかありません。 - ディスプレースメント
相対分岐のディスプレースメントも救済手段はありません。遠くに飛べなくなりますので絶対分岐に置き換える必要があります。とはいえディスプレースメントは8ビットというプロセッサも多いなか、10ビットあれば十分なのではないでしょうか。
CP-1600はデータバスが何ビット分接続されているか知るすべは無いので、未接続のビットはプルダウンしておかないと不都合が起きるでしょう。相対分岐が変なフォーマットなのも符号拡張が不要なように配慮しているためではないかと思います。
純正のクロスアセンブラはBITS
擬似命令で対応しているようなので次のような処理を追加しました。
- イミディエイト値が指定されたビットに収まらないときは
SDBD
を付加して合計4ワードの命令を生成する。 - ダイレクト・ディスプレースメントが指定されたビットに収まらないときはエラーを発生する。
- 明示的に
SDBD
が使われたら次のイミディエイト命令を3ワード命令として生成する。
まぁ現時点で16ビット未満で使う理由は無いでしょうね。
もう一つがMVOI
命令です。これはソースがレジスタ、デスティネーションがイミディエイトの転送命令です。
さすがにデコーダ回路の都合でできてしまっただけだろうと当初は無視していたのですが、マニュアルにも明記されていたので一応対応しました。これも使うことはまず無いと思います。
コメントを追加