LoginSignup
1
0

ここが変だよ SC/MP-II CPU

Last updated at Posted at 2024-05-13

概要

  • いにしえの 8bit CPU NS製 SC/MP-II に関する記事です。
  • C言語でCPUエミュレータを書いて、NIBL BASICを動かしてみました。
  • ソースコードは公開です。
    https://github.com/iruka-/SCMP2Emulator

SC/MP-II CPUは、どこが変であるかを簡単にご説明

  • 8bit CPUなのに、16bitポインタが4つもある。
  • ところが P0 P1 P2 P3 (と勝手に命名)のポインタのうち、最初のやつ P0 は実はプログラムカウンタであること。
  • これら4つは統一的に扱われている。(PC相対とPTR相対は命令コード内では同じ扱い)
  • 相対オフセット値は命令コードのオペランド(8bit)で指定するので、PTR[127]~PTR[-128]までのメモリーが演算対象になったり、ロード、ストア命令が使えたりする
  • それ以外のアドレッシングモードがない。(即値 8bitは存在)
  • :
  • ところで、相対オフセット値が 0x80 (-128) だけ特別扱いで、その場合のみ PTR相対のオフセットは定数ではなく、Eレジスタ(8bit)で代用されるんだ。(知らんがなそんなこと)
  • また、オートインデックスという不思議なアドレッシングモードを持っていて、相対オフセットでメモリーアクセスしたあとで、インデックスレジスタが実効アドレスに変化する、というやつがある。
  • これは68000やPDP-11などにもみられる奴だけど、一つ注意があって
  • 相対値が負の時はフェッチされるデータはPTR+相対オフセットのメモリーになるんだけど
  • 相対値が正の時はフェッチされるデータはPTR+00 のメモリーになる。
  • もちろん命令実行後は PTR は オフセット値が加減算される。
  • 使い方によってはスタックポインタ的に使えなくはない。
  • :

エミュレータは、なんですんなりと動かなかったの?

  • 上記のオートインデックスの実装が間違っていたこと
  • 相対オフセットが 0x80 のときに相対値をEレジスタにすり替える実装をしていなかったこと
  • ななんと、ステータスレジスタの初期値が 0x20 (out B=1) でないと、NIBL BASICは動きません。(知らんがな)

このCPUのだめなところ

  • 上記の16bitポインタへのアクセス(LD,ST)が存在しない(!??)
  • Aレジスタ(8bit) と、ポインタの上位あるいは下位とをエクスチェンジ(交換)することだけが許されている。(XPAL P1, XPAH P2 など)
  • 8bit オフセットを超えるジャンプ命令が存在しない
  • それどころか、一般的なCPUに存在するはずの、CALL/RET 命令が存在しない
  • (代わりに、ミニコン時代の XPPCという、ポインタとPCを交換する命令だけが存在)
  • 遅い。とっても遅い。どれくらい遅いかというと、外部クロック1MHzで仮に動かした場合、典型的な即値8bit を Aレジスタに与える 2byte命令 (LDI #0xNN) の実行時間は72クロック(72マイクロ秒)・・・絶句します

追伸

  • NIBL BASIC は、ロストテクノロジーで書かれたアセンブラなので、解読はおそらく無理です。(SC/MP-IIのアセンブラをすらすら読める人でも)

  • 上記以外にも変なところはいっぱいあって、たとえば

  • プログラムカウンタはフェッチ直前に+1される。これにより、リセット直後の0番地は永遠に実行されない。

  • XPPC命令でロングジャンプしたときも、飛び先の命令フェッチ直前に+1される。なので、実際のエントリーアドレス-1をPTRに入れておく必要がある。

  • 引き算の代わりにコンプリメンタリーADD(引く数のビットを反転しただけで加算)で代用している(つまり2の補数ではなく1の補数)。なので、キャリーフラグの意味が普通のALUと逆になる。

  • :

で、SC/MP-IIIでは、まともになったの?

  • SC/MP-III用のNIBL BASICをエミュレータで動かせないか試行中です。→うごきました
  • SC/MP-IIIは EレジスタとAレジスタを連結して16bitレジスタとして使えるようになりました。
  • ポインタオフセットが0x80(-128)だったときに、オフセット値をEレジスタの内容に読み替える処理は、無くなりました。
  • 6800/6502系のゼロページアドレッシングに近い、FFxxページの256バイトを直接参照するダイレクトアドレッシングが出来るようになりました。
  • ポインタ P1 がスタックポインタになり、16bit 絶対番地指定のJSR命令やJMP命令 が追加されました。
  • 乗除算用にTレジスタ(16bit)が追加され、16bitの乗算/除算命令がそれぞれ追加されています。

参考

SC/MP使いの憂鬱
https://electrelic.com/electrelic/node/1299

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0