SC/MP III

SC/MP IIIは、名称通りSC/MP IIの直接の後継で、SC/MP IIに便利な機能と16 bit演算を付け加えたようなマイクロプロセッサです。もともとSC/MP系列はローコストでちょっとした組み込みに利用しやすくする設計意図がありまして、確かに8080Aなどよりは少ない部品で小規模システムを作成できます。なにしろSC/MPとはSimple Cost-effective MicroProcessorの略とされていますから。組み込み用でスタックを使ったサブルーチン呼び出しができないとか欠点もありますが、インデックスレジスタにも使えるポインタレジスタが3本あるなど、それなりに便利な命令体系を持ちます。しかし、最大の特徴は命令実行の遅さといったら、関係者やファンの人に叱られるでしょうか。内部マイクロプログラム制御で、たぶん回路規模を小さくするのに役立っているのでしょうが、当時の8080AやMC6800と簡単なベンチマークで比べてもSC/MP IIは倍くらい遅いプロセッサでした。その命令実行の遅さをカバーするためか、簡単にマルチプロセッサを構成できるような信号が用意されていましたが、さてどれくらい使われたのでしょうか。
SC/MP IIIは1979年に発表されました。内蔵レジスタが少し追加されて16 bit演算が乗除算も含めて可能になり、サブルーチン呼び出しや割り込みがスタックベースに変更され、割り込みも2レベルとなりました。ハードウェア的にはZ80 CPUと類似の、アドレス・データバス分離のメモリやI/Oを接続しやすいインターフェースで、マルチプロセッサ接続のしやすさなどは従来のSC/MP IIと同様です。アセンブリ言語の記法はSC/MP IIと似ていますが、命令機能の追加や変更でそのままではSC/MP IIのプログラムをアセンブルしなおすことができません。バイナリコードも共通の部分が存在はしますが、SC/MP IIとの互換性はありません。

SC/MP IIIにはいくつかのバリエーションが存在します。
内蔵ROMが0 ByteのINS8070、2.5 KByteのINS8072、4 KByteのINS8074、INS8072の内蔵ROMにNIBLインタプリタを書き込んだINS8073などです。

これが、そのINS8070です。
INS8070
鈴木様よりの頂きものです。

SC/MP IIIのプログラマから見たレジスタモデルはこのようになっています。
SC/MP III registers

ACが8 bitアキュムレータです。基本的に8 bit演算はこのACとメモリオペランドの間で実行されます。アセンブリ言語ではAと表記されます。ERはExtension RegisterでACの補助的な役割をするとともに、ERとACを連結したEAレジスタとしても使われます。アセンブリ言語ではEと略記されます。
EAは16 bitアキュムレータで、16 bit演算の中心的レジスタとして使われます。TはTemporary Registerの略で、乗除算命令でEAと共に利用されるほか、EAの一時退避先としても使えます。
その下の4本の16 bitレジスタはポインタレジスタで、P0, P1, P2, P3という呼称も歴史的な関係で残っていますが、P0とP1は専用レジスタ化しているので、それぞれもっぱらPCとSPとして参照されます。PCは当然プログラムカウンタで、SPはスタックポインタです。どれもメモリ上のオペランドを指示するためのインデックスレジスタとして利用できます。
SはStatus Registerで、フラグ類の集合体です。CY/Lビットはキャリーフラグとシフト・ローテート時のリンクビットとして使われます。OVはオーバーフローフラグです。SAとSBはプロセッサのSense AとSense Bという名称の信号線の状態がそのまま反映されます。入力ポートとして使えるように用意された信号の読み取り用ですね。ただし、Sense AとSense Bはネガティブエッジトリガの割り込み要求信号としての役割もあります。F1, F2, F3はFlag1, Flag2, Flag3というプロセッサの信号線に出力される値を保持します。出力ポート用のビットです。IEは割り込みイネーブルで、1になっているときに割り込み許可を表します。割り込みが受け付けられると自動的にクリアされます。

操作対象メモリアドレスを指示するアドレッシングモードはかなり高度なものが用意されています。
まず4つのポインタにそれぞれ相対アドレッシングがあります。PCについてはPC相対、他のポインタについてはポインタ相対と呼ばれます。ただし、実際には符号付き8 bitディスプレースメントで修飾されるインデックスアドレッシングに相当するものです。
ダイレクトアドレッシングはオペランドの無符号8 bit定数を0FF00Hと加算してメモリアドレスを計算するもので、ゼロページアドレッシングならぬFFページアドレッシングとでもいうべきものです。ちょうどその部分にはSC/MP IIIの内蔵RWMが配置されていて、そのメモリをスクラッチパッドとして利用しやすくするためのアドレッシングモードです。
さらにオートインデックスモードがあります。このオートインデックスモードはP2かP3と符号付き8 bitディスプレースメントが関係して、インデックス修飾で求めた値をポインタレジスタに書き込んでしまうモードですが、ディスプレースメントの符号によって動作が異なるのが特徴です。ディスプレースメントが負数の場合、参照に先立ってアドレス計算が行われ、計算結果がポインタレジスタに格納されてから、メモリアクセスを行います。ディスプレースメントが正数の場合、計算前のポインタレジスタの指すメモリを参照し、その後にアドレス計算を行って計算結果をポインタレジスタに格納します。なにやらややこしいしくみのアドレッシングモードですが、このメカニズムによってプリデクリメントとポストインクリメントと同じ効果を実現でき、ポインタレジスタをスタックポインタとして使用できるのです。
以上のアドレッシングモードは一般の命令でメモリ参照時に使用できるものですが、特別な命令で利用可能なアドレッシングには次のものがあります。
まずSSM命令でだけで使えるインデックスアドレッシングですが、これは名前から受ける印象と異なり、P2かP3を単なるポインタとして利用するモードです。修飾は行われません。
JMP命令とJSR命令ではアブソリュートアドレッシングが使われます。2 Byte長のアドレスがオペランドにそのまま書き込まれます。なお、条件分岐や無条件分岐にはPC相対アドレッシングとP2, P3相対アドレッシングが可能なブランチ系の命令が用意されています。
あと、インダイレクトアドレッシングという名称になっていますが、CALL命令ではベクトルを利用した1 Byte命令によるサブルーチン呼び出しが行われます。
一般の命令でメモリ参照時に使用されるアドレッシングモードをまとめます。
 
アドレッシングモード ポインタ アセンブリ言語表記 オペコード修飾 加算サイクル数 変位の範囲
PC相対 PC d,PC 0 0 -128 ~ +127
ポインタ相対 SP d,SP 1 0 -128 ~ +127
ポインタ相対 P2 d,P2 2 0 -128 ~ +127
ポインタ相対 P3 d,P3 3 0 -128 ~ +127
ダイレクト -- label 5 0 0 ~ 255
オートインデックス P2 @+d,P2 / @-d,P2 6 1 -128 ~ +127
オートインデックス P3 @+d,P3 / @-d,P3 7 1 -128 ~ +127

アセンブリ言語表記はオペランドとして記入する際の表記法で、dは変位を表す定数値です。たとえばAにP2ポインタ相対で変位5のメモリの内容をロードする場合には、LD A,5,P2と書くことになります。5の代わりに記号名を使用することもできますが。ダイレクトアドレッシングの場合、0FF00H - 0FFFFHという範囲のラベルを直接記入すれば、正しく解釈されます。
表のオペコード修飾とは、後述の命令表でメモリ参照を行うオペコードに加算されるアドレッシングモードを表す定数です。たとえば、LD A, memという命令のオペコードは0D0Hと記載されていますが、PC相対を使うなら0D0H、P2のオートインデックスを使うなら0D6Hというオペコードになります。メモリ参照を行う命令の下位3 bitがアドレッシングモードを表すことになっているので、単にオペコードに加算するだけで済みます。
表の加算サイクル数とは、後述の命令表の命令実行サイクル数に加算すべき数値です。オートインデックスで1サイクル余計なサイクルが必要となるだけですけどね。
なお、イミディエートアドレッシングはオペコード修飾が4の場合に相当し、そのアセンブリ言語表記は=dという記法になります。

では命令表を見ていきましょう。まずは一般的なメモリ参照命令やインヘレントアドレッシングを使用する命令をまとめてといきたいところですが、表が大きくなりすぎるのでLD命令とST命令だけ。
Instruction  Mem.     Imm.     Imp.   COI  動作
LD  A, s   C0  7 2  C4  5 2                A <- (s)
LD  EA, s  80 10 2  84  8 3                EA <- (s)
LD  T, s   A0 10 2  A4  8 3                T <- (s)
LD  SP, s           25  8 3                SP <- im16
LD  P2, s           26  8 3                P2 <- im16
LD  P3, s           27  8 3                P3 <- im16
LD  A, E                     40  4 1       A <- (E)
LD  E, A                     48  4 1       E <- (A)
LD  A, S                     06  3 1       A <- (S)
LD  S, A                     07  3 1  ***  S <- (A)
LD  EA, PC                   30  4 1       EA <- (PC)
LD  EA, SP                   31  4 1       EA <- (SP)
LD  EA, P2                   32  4 1       EA <- (P2)
LD  EA, P3                   33  4 1       EA <- (P3)
LD  PC, EA                   44  5 1       PC <- (EA)
LD  SP, EA                   45  5 1       SP <- (EA)
LD  P2, EA                   46  5 1       P2 <- (EA)
LD  P3, EA                   47  5 1       P3 <- (EA)
LD  T, EA                    09  4 1       T <- (EA)
LD  EA, T                    0B  4 1       EA <- (T)
ST  A, d   C8  7 2                         (d) <- (A)
ST  EA, d  88 10 2                         (d) <- (EA)

最初に命令表の見方ですが、Instructionが命令のアセンブリ言語表記です。オペランドの大文字表記はレジスタニーモニックですが、小文字はメモリ参照などのオペランドを意味します。アドレッシングモードによって、固有の表記と置き換わります。Mem.は上記のアドレッシングモード表に掲載されているメモリ関係の命令を意味しています。3組の数字が書かれていますが、左から16進数表記の命令コード、命令実行サイクル数、命令のバイト数です。SC/MP IIIの最高クロック周波数の4 MHzで動作させた場合に1命令実行サイクルは1 usとなります。なお、命令実行サイクル数はコードもデータもSC/MP III内蔵メモリに対する場合に表中の数値に一致します。外部メモリを参照する場合は1回のアクセスにつき、ウェイトサイクルの挿入がない場合で1 usだけ加算する必要があります。たとえばLD A,0,P2でコードもデータも外部メモリに存在すると、3サイクル余計に必要となります。Imm.はイミディエートモードの命令に関する項目、Imp.はインプライドアドレッシングの命令に関する項目です。COIはフラグ変化を示す項目で、CはCY/Lフラグ、OはOVフラグ、IはIEフラグを意味します。フラグ変化がなければ空白のまま、命令実行の結果によって変化する場合は*が書き込まれています。動作は簡単に命令の動作を記述しています。
原則として、LD命令やST命令ではフラグは変化しません。Sレジスタに対する転送時にのみ、変化します。なお、命令表には記入していませんが、Sレジスタ内のF1, F2, F3ビットも同時に変化しています。
命令コードを眺めると、PC, SP, P2, P3が同等に扱われているのがよくわかると思います。命令ニーモニックが異なるので、この表には含めませんでしたが、JMP命令もイミディエートモードで定数をロードするLD PC, =labelに相当する命令コードとなっています。LD PC, EAも実質的にはジャンプ命令です。
ポインタレジスタに対するイミディエートデータのロードには2 Byteのデータが命令コードのあとに続きますが、このとき、命令直後にデータの下位バイトが、第3バイトにデータの上位バイトが、配置されます。Intel社の8080などと同じ配置です。

次は算術論理演算を紹介します。
Instruction  Mem.     Imm.     Imp.   COI  動作
ADD A, s   F0  7 2  F4  7 2           **   A <- (A) + (s)
ADD A, E                     70  4 1  **   A <- (A) + (E)
ADD EA, s  B0 10 2  B4 10 3           **   EA <- (EA) + (s)
SUB A, s   F8  7 2  FC  7 2           **   A <- (A) - (s)
SUB A, E                     78  4 1  **   A <- (A) - (E)
SUB EA, s  B8 10 2  BC 10 3           **   EA <- (EA) - (s)
MPY EA, T                    2C 37 1  **   EA <- [(EA)*(T)]32:16, T <- [(EA)*(T)]15:0
DIV EA, T                    0D 41 1  **   EA <- [(EA)/(T)]15:0, T <- (EA)%(T)
AND A, s   D0  7 2  D4  7 2                A <- (A) & (s)
AND A, E                     50  4 1       A <- (A) & (E)
AND S, s            39  5 2           ***  S <- (S) & (imm8)
OR  A, s   D8  7 2  DC  7 2                A <- (A) | (s)
OR  A, E                     58  4 1       A <- (A) | (E)
OR  S, s            39  5 2           ***  S <- (S) | (imm8)
XOR A, s   E0  7 2  E4  7 2                A <- (A) ^ (S)
XOR A, E                     60  4 1       A <- (A) ^ (E)

加減算は8 bit幅でも16 bit幅でも同じように可能です。フラグの変化も同じ。しかし、CYも含めた加減算命令がありませんから、16 bitを越える数値の加減算は手間がかかります。しかも、後述しますが、直接CYフラグの状態に応じて条件分岐を行う命令は存在しませんから、桁上がり分を加算するだけの作業に意外に多数のステップが必要となります。ついでにBCDデータに対する加減算命令とか、加減算の結果補正命令もありません。まぁ、乗除算命令がありますから、バイナリデータとBCDデータの相互変換プログラムはそれほど長くはなりませんけど。
乗算命令MPYはEAとTの内容を乗じて上位16 bitをEAに、下位16 bitをTに入れます。演算は符号付きで行われます。
除算命令DIVはEAの内容をTの内容で割ります。EAには0から65536の値が、Tには1から32767までの範囲でEAより小さな値が入っていなくてはなりません。数値は符号なし、もしくは符号付きなら両方とも正の範囲でなくてはなりません。演算結果として商がEAに、剰余がTに入ります。ともに正の数です。
論理演算は8 bit幅のみが可能で、フラグ変化はありません。ただし例外として定数とSレジスタのANDとORだけは行えて、もちろんフラグが変化することもあり得ます。F1, F2, F3端子の出力を変化させるのにも使えます。

残りの普通のアドレッシングの命令です。
Instruction  Mem.     Imm.     Imp.   COI  動作
XCH A, E                     01  5 1       A <-> E
XCH PC, EA                   4C  7 1       PC <-> EA
XCH EA, SP                   4D  7 1       EA <-> SP
XCH EA, P2                   4E  7 1       EA <-> P2
XCH EA, P3                   4F  7 1       EA <-> P3
SR  A                        3C  3 1       Shift Right A
SR  EA                       0C  4 1       Shift Right EA
SRL A                        3D  3 1       Shift Right with Link
RR  A                        3E  3 1       Rotate Right
RRL A                        3F  3 1 *     Rotate Right with Link
SL  A                        0E  3 1       Shift Left A
SL  EA                       0F  4 1       Shift Left EA
PUSH A                       0A  5 1       (--(SP)) <- (A)
PUSH EA                      08  8 1       (--(SP)) <- (E); (--(SP)) <- (A)
PUSH PC                      54  8 1       (--(SP)) <- (PCH); (--(SP)) <- (PCL)
PUSH P2                      56  8 1       (--(SP)) <- (P2H); (--(SP)) <- (P2L)
PUSH P3                      57  8 1       (--(SP)) <- (P3H); (--(SP)) <- (P3H)
PLI P2, s           22 15 3                (--(SP)) <- (P2); P2 <- imm16
PLI P3, s           23 15 3                (--(SP)) <- (P3); P3 <- imm16
POP A                        38  6 1       A <- ((SP)++)
POP EA                       3A  9 1       A <- ((SP)++); E <- ((SP)++)
POP P2                       5E 10 1       P2L <- ((SP)++); P2H <- ((SP)++)
POP P3                       5F 10 1       P3L <- ((SP)++); P3H <- ((SP)++)
RET                          5C 10 1       PCL <- ((SP)++); PCH <- ((SP)++)
ILD A, d   90  8 2                         A <- ++(d)
DLD A, d   98  8 2                         A <- ++(d)
NOP                          00  3 1       (PC)++
XCH命令はExchangeで、ふたつのレジスタの内容を交換します。16 bit幅のポインタレジスタはEAとの交換になりますが、その中にしっかりとPCも入っています。XCH PC, EAは分岐命令の代わりにもなりますが、単なるLD命令と異なり戻りアドレスがEAに入ることからサブルーチンやコルーチンの呼び出しにも使えます。
SR命令は右シフトで、MSBには0が入ります。SRL命令はMSBにCY/Lフラグの内容が入ります。
RR命令はAの内容を右シフトすると同時に、MSBに元のLSBの内容を入れます。RRL命令は右シフトと同時にMSBにCY/Lフラグの内容が入り、さらにCY/Lフラグに元のLSBの内容が入ります。
SL命令は左シフトで、LSBには0が入ります。
その他のシフト・ローテート命令はありません。また16 bitシフトはもっとも単純な左右シフトしかありません。
PUSH命令はスタックにレジスタの内容を押しこむ命令です。スタックポインタはデータの格納に先立ってデクリメントされます。ここにもPC対象のPUSH PC命令がありますね。POP命令は、その逆です。なおPOP PC命令に相当するコードにはRETというニーモニックが割り当てられています。
PLI命令はPush and Load Immediateの略で、P2ないしP3ポインタレジスタをスタックに退避させると同時に定数値をロードできます。複合命令の一種で、一時的なポインタが余計に必要になったときには便利だと思われます。しかし、PUSH P2とLD P2, =imm16という命令列とPLI P2, =imm16命令とでは、1 Byteの命令コードの短縮と1実行サイクル分の高速化しか得られず、それほど有利になったとは感じられません。まぁ内蔵ROMぎりぎりまでコードをつめこむときには役立つのかもしれませんが。実際には後述の別の理由で命令セットに含まれたのでしょう。
ILD命令はIncrement and Load、DLD命令はDecrement and Loadの略で、メモリ内の8 bitの値をそれぞれインクリメントかデクリメントしてから、インクリメント後の値をAにロードする複合命令です。メモリ上の変数をループカウンタに使用する場合などに便利です。しかし、AにロードしてはAの内容が破壊されてしまって、不便に思えるかもしれません。ところがSC/MP IIIにはゼロフラグもないですし、直接CYフラグの内容を判定する条件分岐命令もないため、Aに結果をロードしておかないと、仮にフラグ類が変化してもループの終了を判定できません。SC/MP IIIに存在する条件分岐命令はAの内容を直接見るものばかりですから。
NOP命令は何もしない命令で、コードは00になっています。SC/MP IIでは00はHALT命令でしたから、これで晴れてEPROMの中のつぶしたい命令を00に書き換えることができるようになりました。

最後に特別なアドレッシングモードを持つ命令です。
Instruction PC Rel. P2 Rel.  P3 Rel.   Other   動作
SSM                                  2E/2F ? 1 Search and Skip if charactor Matched
BND d      2D  ? 2                             Branch if Not Digit
BRA d      74  5 2  76  5 2  77  5 2           PC <- (Ptr) + d
BP  d      64  5 2  66  5 2  67  5 2           if (A) > 0 then PC <- (Ptr) + d
BZ  d      6C  5 2  6E  5 2  6F  5 2           if (A) == 0 then PC <- (Ptr) + d
BNZ d      7C  5 2  7E  5 2  7F  5 2           if (A) != 0 then PC <- (Ptr) + d
JMP                                   24  8 3  PC <- imm16
JSR                                   20 15 3  (--(SP)) <- (PC); PC <- imm16
CALL x                                1x 17 1  (--(SP)) <- (PC); PC <- (20H + 2*x)

この命令表だけ、各アドレッシングモードの欄が異なります。PC相対、P2相対、P3相対、さらにそれ以外のアドレッシングモードの4欄が並びます。
SSM命令はインデックスアドレッシングの唯一の命令です。P2インデックスアドレッシングの場合に2EH、P3インデックスアドレッシングの場合には2FHがコードです。で、実際に何を行う命令かというと、Aレジスタに文字コードを入れ、P2かP3にメモリ上の文字列の先頭アドレスを入れてSSM命令を実行すれば、Aに入っているコードが文字列内に存在するかどうかサーチを行います。同一の文字が見つかると、SSM命令の直後にある2 Byteのコードをスキップします。256 Byte内に同一の文字が存在しないと直後の命令コードが実行されます。一致しない場合には、ポインタレジスタの内容も+255と更新されていますから、SSM命令を繰り返せば256 Byteを越える文字列検索も行えます。資料には命令実行サイクル数が明示されていないのですが、どうやら1回の探索操作に4サイクル必要なようです。
BND命令はPC相対アドレッシングのみ可能な命令で、ASCIIコードの数字を検出するための、一種の条件分岐命令です。Aレジスタに0から9までの文字が入っていない場合、分岐命令として動作します。数字が入っている場合、それを2進数の0から9に変換してAレジスタに格納し、分岐を行わずにBND命令の直後の命令を実行します。複合命令ですね。ただし、あるプログラム中で何回BND命令が使われるかを考えると、はたして専用命令を用意する必要があったのだろうかと思います。このBND命令も実行命令サイクル数は不明です。
BRA命令は無条件の分岐命令で、SP相対を除くポインタ相対アドレッシングが使えます。普通はPC相対アドレッシングを使って、近い場所への分岐に便利に使えることでしょう。このほか、後述のように絶対アドレッシングのJMP命令もありますから、遠方への分岐に不便なこともないでしょう。
条件分岐命令にはBP, BZ, BNZの3命令がありますが、これらの命令はフラグの状態によって分岐判定を行うのではなく、Aレジスタの内容に応じて分岐することに特徴があります。それぞれAが正、Aが0、Aが非0の条件が満足された場合にSP相対以外のポインタ相対アドレッシングで分岐します。条件がこの3種類しかないため、いくつか不便な点があります。まず、CYフラグやOVフラグの状態に応じて条件分岐したい場合、Sの内容をAに転送してからAND命令などで必要なビットだけ残してから、BZ命令やBNZ命令で判定を行うことになります。次に16 bit演算の結果の判定です。あくまでAレジスタしか条件分岐には関与できませんから、EAレジスタで簡単に16 bit幅の演算ができるといっても、その結果が0かどうかですら、OR A,E命令を実行してからでないと判定できません。どちらの場合でも演算結果がそのままでは破壊されてしまいます。必要に応じて退避する必要があります。
JMP命令は絶対アドレッシングを用いた無条件分岐命令で、16 bitのアドレスを直接オペランドに持ちますから、全メモリ空間の任意の場所に分岐できます。前述のようにPCにイミディエート値をロードする命令に相当するバイナリ表現を持ちます。
JSR命令はサブルーチンの呼び出しを行う絶対アドレッシングモードの命令です。実はPLI PC, imm16という命令に相当するバイナリコードです。というか、JSR命令を実装するついでにP2やP3の内容をスタックにプッシュして定数をロードする命令もできてしまったので、それにPLI命令という名称をつけたのが本当のような気がします。
CALL命令はベクタを用いた一種の間接アドレッシングによるサブルーチン呼び出し命令です。CALL xという形式で、xには0から15までの数値を指定できます。2進数で表示すると4 bitで表現される範囲の数値です。命令コードは上位4 bitが1、下位4 bitがxに相当する数値となっています。この命令を実行すると、xを2倍して20Hと加算したアドレスのメモリから16 bitのアドレス値を採りだし、そのアドレスへのサブルーチン呼び出しを行います。たとえばCALL 4という命令なら、28Hのメモリからアドレス下位を、29Hのメモリからアドレス上位を取り出して、そのアドレスへのサブルーチン呼び出しを行います。命令コードは1 Byteだけなので、ひんぱんに使われるサブルーチンアドレスを20Hからのテーブルに登録しておけば、プログラムの長さを短縮することができます。

なお、PCと命令フェッチの動作には、SC/MP系列以外にはみられない変わった点があります。通常のプロセッサでは命令をフェッチしてからPCをインクリメントしますが、SC/MP系列ではPCをインクリメントしてから命令をフェッチします。順序が逆なのです。特にリセット時にこの違いが色濃く出ます。リセット時にはPCが0にクリアされ、それから命令フェッチと実行を繰り返します。そのため、SC/MP系列のプロセッサがリセット後に最初に実行する命令は0001番地に格納されている命令となっています。
このほか、同じことがJMP命令やJSR命令にもいえて、機械語では本来ジャンプすべきアドレスより1だけ小さなアドレス値をオペランドに用います。つまり、0ABCDHというアドレスにジャンプしたければ、その機械語は24 CC ABとなります。このあたりはアセンブラが勝手にやってくれますから、プログラム時には気にはならないでしょうが、機械語を直接眺めながらデバッグする場合には違和感があるかもしれません。
BRA系列の命令でPC相対アドレッシングを行う場合、BRA命令などの次の命令の先頭アドレスがオフセット0となります。この点についてはM6800系列などのプロセッサと同じですね。

さて、プログラマの視点で全体を眺めてみると、複数のポインタとオートインデックスを含む強力なアドレッシングモードを備えた、強力な命令体系のように思えます。しかし、16 bitを越える数値の扱いは困難で、条件判定も不便なうえに、256回を越えるループには工夫が必要です。また、1979年頃の同世代のマイクロプロセッサ、たとえばMC6809とか8088とかと比べると、SC/MP IIIになっても命令実行時間が長めです。
しかし、SC/MP IIIはROM内蔵モデルが標準ですし、本来はシングルチップマイクロコンピュータと比べるべき小規模組み込み用のプロセッサだと思われます。そうしてみると、16 bitで表現可能な範囲の数値しか扱わない応用も多いだろうし、扱うデータも内蔵RWMの64 Byteに収まる程度のものなら、256回を越えるループは不要かもしれません。メモリ類まで集積する必要がありますから、同時代の一般のマイクロプロセッサより命令の解釈実行回路に割り当てられるトランジスタ数は少なくなってしまうでしょう。すると、ひとつの命令を実行するにも多くの段階を踏む必要があるため、遅くなってしまうのかもしれません。
とはいえ、シングルチップの仲間と考えると、内蔵I/O機能が少なすぎます。さらに8051と比べても、ほとんどの命令を8051では1 usで実行できますし、さらに高速バージョンも用意されていたりと、プロセッサ部の性能で負けています。プログラムの作りやすさではSC/MP IIIかもしれませんけど。8085やMC6802クラスの、3チップ程度での組み込み用に相当するのかもしれませんが、このどちらもROMまでは集積せずにI/Oチップ側にROMを集積していましたから、大きめの応用にも汎用マイクロプロセッサとして使いやすくなっています。
SSM命令やBND命令のような高機能命令が追加されていても、組み込み用では文字端末のようなものでないと使う場面も少ないでしょう。そもそもSSM命令は検索するデータが見つからなければ、80 Byteだけ探したくても256 Byte分調べおわるまで次の命令に進みませんから、なんか中途半端な命令です。もちろん、番兵方式で探索範囲を限定することもできるのですが、その場合には一致した場合の命令スキップ機能がよけいです。
結局、どこをとっても中途半端なマイクロプロセッサのように感じます。価格も秋葉原の店頭のばら売り単価ではずっと10000円を越えていたりして、安くありませんし。

NS社はMICROBUSというバス規格を提唱しています。といっても、MultiBusとかVME Bus、あるいはPCI Busのように複雑なバス規格でなく、標準的なメモリや入出力LSIを接続するための信号とタイミングを規定したものです。標準的なメモリの信号タイミングはIntel系のプロセッサなどにも適合していますから、ほぼ8080Aと同様の信号タイミングを標準規格化したものだということができます。SC/MP IIIもMICROBUS互換をうたっています。
具体的に信号を見ていきましょう。
NENOUT 1      40 VCC
NENIN  2      39 SB
NBREQ  3      38 SA
NRDS   4      37 NRST
NHOLD  5      36 F3
NWDS   6      35 F2
XOUT   7      34 F1
XIN    8      33 D0
A15    9      32 D1
A14   10      31 D2
A13   11      30 D3
A12   12      29 D4
A11   13      28 D5
A10   14      27 D6
A9    15      26 D7
A8    16      25 A0
A7    17      24 A1
A6    18      23 A2
A5    19      22 A3
GND   20      21 A4
NS社の表記では負論理の信号名はNで始まることになっています。
VCCとGNDが電源です。A0 - A15がアドレスバスでD0 - D7がデータバスで、マルチプレクスされてないアドレスとデータが得られます。
XOUTとXINがクロック発振回路で、水晶発振子と数個のCRの外付け、あるいは水晶不要のCR発振回路として数個のCRだけの外付けで、クロック信号を発生させられます。NRST信号は負論理のリセット信号で、シュミットトリガ入力になっているので、CR回路の外付けだけでパワーオンリセット回路を構成することができます。
NRDS, NHOLD, NWDSがデータの読み書きに関する制御信号です。NRDSはリードストローブ信号で、NWDSがライトストローブ信号になります。NHOLDは遅いメモリやI/Oのためのバスサイクル延長要求信号で、他のマイクロプロセッサではWAIT*信号のような名前で呼ばれるものに相当します。
NENOUT, NENIN, NBREQはDMAやマルチプロセッサのための制御信号で、ちょうどZ80ファミリの割り込みやDMA制御信号のようにディジーチェーン接続するだけで、多数のマイクロプロセッサのバス調停が自動的に行えるように考えられています。
SA, SBはセンス入力で、Sレジスタの対応したビットに入力された値がそのまま反映されるほか、割り込み入力にもなります。
F1, F2, F3はフラグ出力で、Sレジスタの対応したビットの値がそのまま出力されます。
なお、SC/MP IIIはメモリマップトI/Oのため、I/O空間に対する読み書きストローブなどはありません。
メモリを内蔵した組み込み用マイクロプロセッサにしては、汎用8 bitマイクロプロセッサと同じような使いやすいバスインターフェースと使いやすそうなピン配置になっていますが、逆に内蔵I/Oが2入力3出力しかなくて、普通に使おうとすればどうしても外付けLSIの数が多くなりそうです。

内蔵のROMはINS8072, INS8073では0 - 09FFHに、INS8074では0 - 0FFFHに存在します。また、内蔵RWMが0FFC0H - 0FFFFHに割り当てられています。
リセット時にはPC, SP, Sレジスタがすべて0クリアされて、それから命令フェッチに入りますが、前述のように変わった命令フェッチサイクルとなっているので、最初に実行される命令アドレスは0001番地の命令です。またSA端子からの割り込み要求INTAによってPCが0003にセットされるので、INTAの割り込みサービスルーチンの先頭は0004番地から、同様にSB入力のINTB割り込み要求による割り込みサービスルーチンの先頭は0007番地から、CALL命令のアドレス表は0020H - 003FHに配置されます。以上がSC/MP IIIにおける特別なアドレスです。割り込みを利用する場合、リセットや割り込み時の先頭アドレスは3 Byteおきに決められていますから、そこにはJMP命令しか配置できません。

Return to IC Collection