セグメント版は追加されたセグメント信号7本を出力するため、48ピンパッケージでした。外付けのメモリ管理ユニットでアドレス変換を行うためにあるのがセグメント信号の本来の本来の意味ですが、そのままアドレス拡張部に使うと8 MByteのアドレス空間になります。
セグメント版のレジスタはこのようになっています。
汎用レジスタは16 bit幅のものが16本あり、R0からR15まで順番に名前が付けられています。この内のR0からR7までは8
bit単位でアクセスが可能で、R0 - R7の上位バイトにはRH0 - RH7、下位バイトにはRL0
- RL7という別名が付けられています。さらに汎用レジスタは2本ずつペアにすることができて、32
bitデータやアドレスポインタとしてのセグメント・オフセットペアを保持することができます。レジスタペアを表すには、RR0,
RR2, RR4, ..., RR14という名称を使用します。さらに乗除算命令の結果を格納するために64
bit一組のレジスタ4個組みが使われることがあり、RQ0, RQ4, RQ8, RQ12という名称で呼ばれます。
R14とR15のペア、つまりRR14はスタックポインタとして使用されます。Z8000にはオペレーティングシステムのカーネルを動作させるためのシステムモードと、一般プロセスを動作させるためのノーマルモードのふたつのモードがありますが、それぞれに専用のスタックポインタを持たせているため、RR14は2重構造になっています。
RR14がスタックポインタとして使われることとバイトアクセス可能なのがR0
- R7であること、後で触れますがインデックスレジスタの類としてR0ないしRR0が使用できないこと、TRT*命令でRH1が特別扱いされることを除けば、各汎用レジスタは完全に同等です。
プログラムステータスレジスタはフラグ類や制御ビットの入ったフラグ制御語とプログラムカウンタ、さらに全体を64
bit境界に整合させるための予約語によって構成されます。このプログラムステータスレジスタは、割り込み時などに自動的にスタックに退避され、プログラムステータス領域内のメモリに格納された値と入れ換えられるようになっています。セグメント版ではプログラムカウンタは16
bitオフセットと7 bitのセグメント番号のペアで構成されます。
フラグ制御語の意味を上位ビットから順に説明すると、上位バイトは制御ビットとなっていて、SEGビットはセグメントモードで動作するかノンセグメントモードで動作するかを決めるビットで、1ならセグメントモードになります。EPAビットは拡張プロセッサアーキテクチャビットの略で、要はコプロセッサが外付けされている場合に1にセットすれば拡張命令を外部の拡張プロセッサが解釈するように動作します。0ならば拡張命令でトラップ割り込みが発生して、ソフトウェアでエミュレーションできます。S/N*ビットはシステムモードとノーマルモードを切り替えるビットです。このS/N*ビットが反転されたものがプロセッサの端子にも出力されていて、外部回路も連動させられます。VIEはベクタ割り込みのイネーブルビットで、NVIEはノンベクタ割り込みのイネーブルビットです。ビット7から下は演算フラグの類で、Cがキャリーフラグ、Zがゼロフラグ、Sが符号フラグ、P/Vがパリティとオーバーフローフラグ、DAが加減算命令のどちらが実行されたかを示すフラグで次のHフラグと合わせてBCD補正に用いられます。Hはハーフキャリーフラグで、加減算のBCD補正に用いられます。
プログラムステータス領域ポインタは割り込みなどの例外処理に用いられます。まぁベクタ領域を指すためのポインタと言って間違いはないでしょう。
リフレッシュカウンタもZ80 CPUから強化されていて、内蔵リフレッシュ機能を禁止したり、リフレッシュの頻度を設定できるようになっています。最上位のREビットがリフレッシュイネーブルビットで、このビットが1ならリフレッシュ機能が有効になります。Z8000
CPUのリフレッシュ機能はZ80 CPUと異なり、命令フェッチサイクルの一部としてリフレッシュが行われるのではなく、独立したバスサイクルとして実行されます。ですから命令フェッチと無関係にリフレッシュサイクルを決定することが可能で、そのためにリフレッシュカウンタ内に6
bitのRateフィールドが用意されています。このRateフィールドの値が0なら256クロックサイクルごと、それ以外ならRateフィールドの値の4倍のクロックサイクルごとにリフレッシュサイクルが挿入されます。通常の4
MHzクロックのZ8001 CPUなら、1 usから64 usまでのリフレッシュ周期を設定できることになります。リフレッシュカウンタの下位9
bitはDRWMのリフレッシュアドレスが入っていて、リフレッシュサイクルごとにインクリメントされます。プログラムから初期値を設定したり、現在のリフレッシュアドレスを読み出すことも可能で、Z80
CPUと同様に簡単な乱数の種に使用することもできます。Z80 CPUと異なり9 bitに拡張されているため、64
Kbitや256 Kbitや1 MbitのDRWMにも対応できます。
さて、こちらがノンセグメント版のZ8002 CPU。上からZilogオリジナルとセカンドソースのAMDとSHARP製のもの。SHARP製はプラスチックパッケージが使われている。
Z80 CPUと同じ40ピンパッケージで、ノンセグメントということからわかるようにアドレスバスはセグメント信号の7本がなくなって16本だけですから64
KByteのメモリ空間。データが16 bitになっているし命令も強力になっていることからZ80
CPUよりも高速でプログラミングしやすいわけで、Z80 CPUでは少しだけ力が足りないところに使ってもらおうというところですか。しかし、たとえば1981年の時点では、Z80A
CPUが秋葉原店頭で1個売り1800円、入手困難なZ80B CPUですら7000円だったのにZ8002
CPUは44800円だったりしましたし、ソフトウェアの開発環境もZ80ならば出はじめのPCなんかを使って30万円くらいで揃えられたのが、Z8000では数百万円の開発ツールしか存在しないというのも問題になることがあるでしょう。高速の8
bit CPUという使い方のできるIntelの8088は、すでに15000円程度にまでコストが下がっていましたし。
コストの話が出たついでにセグメント版の方もコメントすると、1981年でZ8001
CPUが70000円、MC68000が95000円。これらは高価な応用にしか(当時は)使えませんでしたから、価格的な差はほとんどありません。Z8000ファミリの通信制御LSIなど、それを使うと使わないとでは性能や設計開発に大きく差が出る周辺LSIを使う予定がなければ、性能面から見てMC68000が有利というところでしょうか。LANとかHDLCプロトコルの通信とかが一般的でなかった時代ですから、特にその方面の周辺LSIの開発に長けていたZilog社にはつらいところです。というより、そういったものが一般的でなかったからIntelやMotorolaやNEC、その他の大手半導体メーカーが力を入れていなかったと歴史認識すべきですかね。
話が横道にそれましたが、ノンセグメント版の方のレジスタセットを次の図に示します。
汎用レジスタで変更があるのはR14の機能で、メモリ空間を指すのにセグメント番号の分が不要になって16
bitレジスタひとつでアドレスを保持できるため、スタックポインタにはR15しか使われなくなり、R14は普通の汎用レジスタとして使用できます。
同様にプログラムステータスレジスタも縮小されていて、PCは16 bitレジスタひとつに、フラグ制御語もパディング用の予約語が不要になり、結局32
bit分となっています。さらにフラグ制御語の最上位ビットはセグメント版ではSEGビットでセグメントモードとノンセグメントモードの切り替えでしたが、Z8002
CPUではセグメントモードが最初から使えませんので、常に0と固定されています。
プログラムステータス領域ポインタもオフセット指定が不要となり、16 bitレジスタひとつとなりました。しかも、このポインタで差されるプログラムステータス領域のデータ構造もセグメント版とノンセグメント版とで異なります。
リフレッシュカウンタには変更はありません。
アドレッシングモードには、次の8種類があります。
記号 | 名称 | 対象データ |
R | レジスタ | レジスタの内容 |
IM | イミディエート | 命令直後の値 |
IR | レジスタ間接 | レジスタ内容で指示されたメモリ |
DA | 直接アドレス | 命令直後のアドレスで指示されたメモリ |
X | インデックス | レジスタの内容(オフセットのみ)と命令直後の定数を加算したアドレスで指示されるメモリ |
RA | 相対アドレス | PCの内容に命令直後の変位を加算したアドレスで指示されるメモリ |
BA | ベースアドレス | レジスタの内容(セグメント込み)と命令直後の定数を加算したアドレスで指示されるメモリ |
BX | ベースインデックス | レジスタの内容(セグメント込み)とレジスタの内容を加算したアドレスで指示されるメモリ |
レジスタ、イミディエート、レジスタ間接、直接アドレス、相対アドレスについてはそのまま理解できるはずです。難しいのはインデックスモードとベースアドレスモードの差で、事実上、ノンセグメント版のZ8002
CPUでは同じ動作となります。ただし、セグメント版のZ8001 CPUでセグメントモードの場合には、重大な違いが生じます。インデックスモードでは、16
bitレジスタがインデックスレジスタとして使われて、インデックスレジスタの内容はアドレスのオフセット部分だけと解釈されてセグメント番号は定数として命令の方に含まれています。しかし、ベースアドレスモードでは、レジスタペアがベースアドレスの指示に使われて、こちらのほうにセグメント番号が含まれています。ベースインデックスモードも同様に、ベースアドレスを供給するのはレジスタペアでセグメント番号込みです。
さらに、セグメントモードでは、インデックス、相対アドレス、ベースアドレス、ベースインデックスの各モードでアドレス計算に関係するのはオフセット部分だけであり、仮に16
bitオフセット部分の計算で桁上がりが生じても無視されて、セグメント番号は影響を受けません。セグメント番号はMMUに与えるためのメモリブロックの識別子という考え方からすると当然ですけど、MMU無しで単純なアドレス拡張のつもりのハードウエア用のプログラミングの際には注意しないと失敗するかもしれません。
もう一つ注意すべきことがあります。レジスタ間接、インデックス、ベースアドレス、ベースインデックスの各モードでは、インデックスレジスタやベースレジスタとしてR0ないしRR0を指定することは禁止されています。逆にスタックポインタとして使われているレジスタは使用可能です。
以上の8種類のアドレッシングモードは、任意の命令で自由に利用できるわけでなく、命令の種別によって使用可能なアドレッシングモードが細かく規定されています。つまり命令とアドレッシングモードの直交性はそれほど高くありません。
命令セットを種類別に紹介していきます。
まずは算術演算命令から。
命令 型 アドレッシングモード CZSVDH 意味
ADD BWL R IM IR DA X
****BB Add
ADC BW R
****BB Add with Carry
CP BW
IR DA X **** Compare
(immediate)
CP BWL R IM IR DA X
**** Compare (register)
DAB B R
*** Decimal Adjust
DEC BW R
IR DA X ***
Decrement
DIV WL R IM IR DA X
**** Divide
EXTS BWL R
Extend Sign
INC BW R
IR DA X ***
Increment
MULT WL R IM IR DA X
***0 Multiply
NEG BW R
IR DA X **** Negate
SUB BWL R IM IR DA X
****BB Subtract
SBC BW R
****BB Subtract with Carry
命令の欄はニーモニックが、型の欄にはその命令で使用可能なデータサイズが記入されています。バイトデータはB、ワードデータはW、ロングワードデータはLの文字で表現されます。たとえばADD命令はバイト、ワード、ロングワードすべて使用可能ですが、DAB命令ではバイトデータしか扱えません。アドレッシングモードの欄にはその命令で使用可能なアドレッシングモードの記号が記入されています。CZSVDHの欄は命令によって影響を受けるフラグを意味していて、*が記入されているフラグが変化し、空欄なら影響を受けません。Bが書かれている部分はバイトデータ型の場合に限り影響を受けます。0は必ずクリアされることを示します。
ADD, ADC, SUB, SBCが加減算命令ですが、ADD命令とADC命令、およびSUB命令とSBC命令は使用可能なアドレッシングモードやデータサイズが異なります。
CP命令はイミディエート値とメモリ内容の値との比較が可能な命令と、オペランドの片方がレジスタに固定されている命令のふたとおりがあります。
INC命令やDEC命令でキャリーフラグが変化しません。ゼロフラグなどは変化するんですけど。メモリデータの操作もできるようになっています。
MULT命令は16 bit×16 bitないし32 bit×32 bitの符号付き整数乗算を行います。DIV命令は32
bit÷16 bitないし64 bit÷32 bitの符号付き整数除算を行います。結果はレジスタの上位に商が、下位に余りが入ります。例によってどちらも実行時間の長い命令で、ワードの乗除算はそれぞれ約70クロックと110クロック、ロングワードで約300クロックと750クロック必要とされます。
次にビット操作命令です。
命令 型 アドレッシングモード CZSVDH 意味
BIT BW R
IR DA X *
Bit Test (static)
BIT BW R
* Bit Test (dynamic)
RES BW R
IR DA X
Bit Reset (static)
RES BW R
Bit Reset (dynamic)
SET BW R
IR DA X
Bit Set (static)
SET BW R
Bit Set (dynamic)
TSET BW R IR DA
X *
Bit Test and Set
BIT命令は特定のビットの値を調べる命令で、ビット番号を定数で指定するかレジスタで指定するかのふたとおりの命令があります。ビット番号をレジスタ指定する場合にはレジスタアドレッシングモードしか使用できません。
RES命令とSET命令は特定のビットのセットとリセットで、フラグが変化しませんがBIT命令と同じ形式で使用できます。
TSET命令はマルチプロセッサ対応の排他制御を行うための命令です。オペランドの最上位ビットをSフラグにコピーして、オペランドの全ビットを1にセットします。このオペランドの読み出しと書き込みは不可分バスアクセスで実行され、その途中に割り込みはもちろんDMAも生じないようになっています。
Z80 CPUで特徴的だったブロック転送命令のバリエーションも増えてストリング操作命令も追加されています。
命令 型 アドレッシングモード CZSVDH 意味
CPD BW
IR
-*-* Compare and Decrement
CPDR BW
IR
-*-* Compare, Decrement, and Repeat
CPI BW
IR
-*-* Compare and Increment
CPIR BW
IR
-*-* Compare, Increment, and Repeat
CPSD BW
IR
-*-* Compare String and Decrement
CPSDR BW
IR
-*-* Compare String, Decrement, and Repeat
CPSI BW
IR
-*-* Compare String and Increment
CPSDI BW
IR
-*-* Compare String, Increment, and Repeat
LDD BW
IR
- * Load and Decrement
LDDR BW
IR
- 1 Load, Decrement, and Repeat
LDI BW
IR
- * Load and Increment
LDIR BW
IR
- 1 Load, Increment, and Repeat
TRDB B
IR
- * Translate and Decrement
TRDRB B
IR
- 1 Translate, Decrement and Repeat
TRIB B
IR
- * Translate and Increment
TRIRB B
IR
- 1 Translate, Increment and Repeat
TRTDB B
IR
* * Translate, Test, and Decrement
TRTDRB B
IR
* * Translate, Test, Decrement and Repeat
TRTIB B
IR
* * Translate, Test, and Increment
TRTIRB B
IR
* * Translate, Test, Increment and Repeat
フラグの欄で-は不定値になることを、1は必ずセットされることを意味します。
CPD命令はCPD dst, src, r, ccの形式で、dstとrはレジスタを指定し、srcはレジスタ間接アドレッシングでメモリ内のデータを指示します。ccには条件を指定します。動作としてはdst
- srcの演算を行った後、srcで使用したレジスタの内容を、バイトデータの場合は-1、ワードデータの場合は-2して、カウンタとして使用されるrも-1します。フラグは条件ccが満足された場合にZフラグがセットされ、カウンタが0になったらVフラグがセットされます。
条件ccとして指定できる略称には、次の22種類があります。
略称 | コード | フラグ | 意味 |
F | 0000 | - | Always false |
T | 1000 | - | Always true |
Z | 0110 | Z = 1 | Zero |
NZ | 1110 | Z = 0 | Not Zero |
C | 0111 | C = 1 | Carry |
NC | 1111 | C = 0 | Not Carry |
PL | 1101 | S = 0 | Plus |
MI | 0101 | S = 1 | Minus |
NE | 1110 | Z = 0 | Not Equal |
EQ | 0110 | Z = 1 | Equal |
OV | 0100 | V = 1 | Overflow |
NOV | 1100 | V = 0 | No Overflow |
PE | 0100 | P = 1 | Parity even |
PO | 1100 | P = 0 | Parity odd |
GE | 1001 | S ^ V = 0 | Greater than or Equal |
LT | 0001 | S ^ V = 1 | Less than |
GT | 1010 | Z | (S ^ V) = 0 | Greater than |
LE | 0010 | Z | (S ^ V) = 1 | Less than or Equal |
UGE | 1111 | C = 0 | Unsigned Greater than or Equal |
ULT | 0111 | C = 1 | Unsigned Less than |
UGT | 1011 | (C = 0) & (Z = 0) = 1 | Unsigned Greater than |
ULE | 0011 | C | Z = 1 | Unsigned Less than or Equal |
略称が違うだけで動作が等しいものも含まれていますけど。
CPDR命令はCPD命令を繰り返し実行する命令で、条件が満足されるかカウンタが0になるまで比較動作を繰り返します。
CPI命令とCPIR命令はsrcレジスタを+1する点がCPD命令やCPDR命令と異なります。
CPSで始まる4命令は、dst側もレジスタ間接アドレッシングを用い、dstとsrcのレジスタを同じようにデクリメントないしインクリメントする命令です。CPD命令などはdstがレジスタで、メモリ上に並べられたデータとレジスタ内のデータとの比較ですが、CPS*命令は両方のデータともメモリ上に配置されているものを比較します。
LD*命令はLD* dst, src, rの形式で、比較を行わずにsrcレジスタでポイントされるメモリからdstレジスタでポイントされるメモリへ転送を行います。ブロック転送命令ですね。当然ながら条件の指定は不要です。リピート型の命令はカウンタが必ず0になってから終了するので、命令実行後にはVフラグがセットされています。
TR*系の命令はTR* dst, src, rの形式で、dst <- src[dst]を行いながらdstのポインタだけデクリメントやインクリメントを行います。srcで変換用のテーブルをポイントしておいて、dstで指された配列をテーブルに従って書き換える命令です。バイトデータ型しか扱えません。
TRT*系の命令はTRT* src1, src2, rの形式で、RH1 <- src2[src1]を行います。src1のレジスタだけがデクリメントかインクリメントされます。RH1の内容が0ならZフラグがセットされます。リピート型の命令だとZフラグがリセットされるかrが0になってVフラグがセットされるまで、変換操作が繰り返されます。
以上の命令でレジスタ間接アドレッシングで使われるレジスタがデクリメントやインクリメントされる場面では、たとえセグメントモードで動作していてもセグメント部分は変化しません。オフセットを表す下位16
bitだけが変化します。
CPU制御命令には次のものがあります。
命令 型 アドレッシングモード CZSPDH 意味
COMFLG
???? Complement Flag
DI
Disable Interrupt
EI
Enable Interrupt
HALT
Halt
LDCTL BW R
?????? Load Control Register (from register)
LDCTL BW R
Load Control Register (to register)
LDPS
IR DA X ****** Load Program Status
MBIT
-* Multi-Micro Bit Test
MREQ R
** Multi-Micro Request
MRES
Multi-Micro Reset
MSET
Multi-Micro Set
NOP
No Operation
RESFLG
???? Reset Flag
SETFLG
???? Set Flag
フラグの欄で?が書き込まれているフラグは命令によって変化する場合があることを意味しています。
COMFLG, RESFLG, SETFLG命令はCZSPのフラグの任意の組み合わせをまとめて反転したりリセットしたりセットする命令です。
DI命令とEI命令はベクタ割り込みとノンベクタ割り込みをそれぞれ禁止したり許可する命令です。
HALT命令やNOP命令はZ80 CPUと同様、プロセッサの停止や何もしない命令です。NOP命令のオペコードは8D07Hで、オールゼロではありません。
LDCTL命令はFCW, REFRESH, PSAPSEG, PSAPOFF, NSPSEG, NSPOFFの各特殊レジスタと汎用レジスタ間のデータ転送命令です。転送先がFCWの場合にのみフラグが変化します。
LDPS命令はプログラムステータスのロードで、システムモードからノーマルモードへの遷移とかZ8001
CPUにおいてセグメントモードとノンセグメントモードの間の遷移に使用されます。
MBIT命令はマルチプロセッサの同期用入力端子であるMI*信号の状態をSフラグに反映させる命令です。
MRES命令はマルチプロセッサの同期用出力端子であるMO*信号をHに、MSET命令はLにします。
MREQ命令はMI*信号とMO信号を用いて一種のタイムアウト付きのセマフォ動作を行う命令です。
入出力命令にもZ80 CPUと同様にブロック転送命令が存在します。このほか、特殊入出力アドレス空間に対する専用命令も用意されています。
命令 型 アドレッシングモード CZSVDH 意味
IN BW
IR DA
Input
IND BW
IR
* Input and Decrement
INDR BW
IR
- 1 Input, Decrement, and Repeat
INI BW
IR
* Input and Increment
INIR BW
IR
- 1 Input, Increment, and Repeat
OUT BW
IR DA
Output
OUTD BW
IR
* Output and Decrement
OUTDR BW
IR
- 1 Output, Decrement, and Repeat
OUTI BW
IR
* Output and Increment
OUTIR BW
IR
- 1 Output, Increment, and Repeat
SIN BW
DA
Special Input
SIND BW
IR
* Special Input and Decrement
SINDR BW
IR
- 1 Special Input, Decrement, and Repeat
SINI BW
IR
* Special Input and Increment
SINIR BW
IR
- 1 Special Input, Increment, and Repeat
SOUT BW
DA
Special Output
SOUTD BW
IR
* Special Output and Decrement
SOUTDR BW IR
- 1 Special Output, Decrement, and Repeat
SOUTI BW
IR
* Special Output and Increment
SOUTIR BW IR
- 1 Special Output, Increment, and Repeat
Z8000 CPUには通常のI/Oポートが配置される入出力アドレス空間のほかに、Z8010
MMUといったCPU機能を拡張するためのLSIのレジスタが配置される特殊入出力アドレス空間が存在します。それぞれの入出力アドレス空間ごとに専用の命令が存在します。特殊入出力アドレス空間用の命令には、ニーモニックの先頭にSが付いているだけの違いのようにも見えますが、一部の命令にアドレッシングモードの相違があります。IN命令とOUT命令は直接アドレッシングのほかにレジスタ間接アドレッシングも利用可能ですが、SIN命令とSOUT命令にはレジスタ間接アドレッシングは使えません。
どちらにしろ、すべての入出力命令は特権命令でシステムモードのみ使用可という制約があります。
ブロック転送系の命令は、I/Oポートアドレスを保持するレジスタは変化させずにメモリを指すレジスタを変化させるという点がメモリブロック転送と異なります。
論理演算命令は、次の基本的なものだけです。
命令 型 アドレッシングモード CZSPDH 意味
AND BW R IM IR DA X
**? And
COM BW R
IR DA X **?
Complement
OR BW R IM IR DA X
**? Or
TEST BWL R IR DA X
**? Test
TCC BW R
Test Condition Code
XOR BW R IM IR DA X
**? Exclusive Or
AND, OR, XORの各命令は一般的な二項論理演算をレジスタと、レジスタあるいはメモリとの間で実行します。COM命令はビット反転命令です。TEST命令は指定したオペランドと0とのORを行い、フラグに演算結果を反映します。
TCC命令は少し変わった命令で、TCC cc, Rというような命令形式でccに条件を指定します。指定した条件が満足されるとレジスタRの最下位ビットが1にセットされます。満足されない場合はクリアされるのではなく、レジスタの内容は何も変化しません。あらかじめレジスタに0を入れておくのが一般的な使用法でしょう。条件ccにはブロック転送命令のところで説明したものと同じものが使えるため、複数のフラグが関係した条件を指定できます。
なお、論理演算命令では、加減算命令などでオーバーフローを示すVフラグがパリティを表すPフラグとして機能します。ただし、Pフラグが変化するのはバイトデータ型の場合のみで、他のデータ型のときには影響を受けません。8
bitデータとPフラグを合わせた9 bitデータで常に1のビットが奇数となるようにPフラグが変化する奇数パリティです。
次はブロック転送以外のデータ転送系の命令です。
命令 型 アドレッシングモード CZSVDH 意味
CLR BW R
IR DA X
Clear
EX BW R
IR DA X
Exchange
LD BWL R IM IR DA X BA BX
Load into Register
LD BWL
IR DA X BA BX Load into
Memory (store)
LD BW
IR DA X
Load Immediate into Memory
LDA W
DA X BA BX Load Address
LDAR W RA
Load Address Relative
LDK W IM
Load Constant
LDM W
IR DA X
Load Multiple
LDM W
IR DA X
Load Multiple (store)
LDR BWL RA
Load Relative
LDR BWL RA
Load Relative (store)
POP WL R
IR DA X
Pop
PUSH WL R IM IR DA X
Push
データ転送だけではフラグ類が変化しないのは8080以来の伝統ですね。
CLR命令はレジスタやメモリに定数0を入れるもので、EX命令はレジスタと、レジスタないしメモリの内容を入れ換える命令です。
LD命令は表の中に3種類ありますが、データの転送先がレジスタの場合とメモリの場合、さらに定数をメモリに書き込む場合の3種類です。
LDA命令はメモリの内容をレジスタにロードするのでなく、アドレッシングモードにしたがって求めたメモリアドレスそのものをレジスタにロードする命令です。形式的にワードデータ型の命令となっていますが、セグメントモードのときはレジスタペアにセグメント込みのアドレスをロードします。そのLDA命令のPC相対アドレッシングバージョンがLDAR命令です。PC相対アドレッシングモードはニーモニックから特別扱いするのもZ80
CPUからの伝統でしょうか。
LDK命令は1から16までの定数に限って1 Word命令でレジスタにロードする命令です。それ以外の数値はイミディエートモードの普通のLD命令か、0に限ってはCLR命令でレジスタにロードできます。イミディエートモードだと2
Word命令になるので、目的の数値が範囲内に納まっていればLDK命令を使う方がプログラムが短く高速になります。
LDM命令は複数のレジスタとメモリ間の転送を行います。LDM dst, src, nの形式で、たとえばLDM
R2, @R9, 3ならR9の指すメモリからR2, R3, R4へと3 Wordのデータが転送されます。このとき、R9の内容は変化しません。
LDR命令はPC相対アドレッシングによるレジスタとのデータ転送命令です。
PUSH命令とPOP命令はスタックへのプッシュとポップを行いますが、CALL命令などで使用されるスタックポインタ以外にもR0(またはRR0)以外の汎用レジスタをスタックポインタとして指定できます。
プログラム制御命令は相対CALL命令などが強化されています。
命令 型 アドレッシングモード CZSPDH 意味
CALL
IR DA X
Call Procedure
CALR RA
Call Procedure Relative
DJNZ W RA
Decrement, Jump if Not Zero
DBJNZ B RA
Decrement, Jump if Not Zero
IRET
****** Interrupt Return
JP
IR DA X
Jump
JR
RA
Jump Relative
RET
Return from Procedure
SC
IM
System Call
CALL命令はサブルーチン呼び出し命令で、CALR命令はそのPC相対アドレッシング版ですが特に12
bitディスプレースメントで1 Word命令となっています。8080とは異なり共に条件指定はできません。
DJNZ命令はZ80 CPUと同様のループ用命令ですが、カウンタとして任意の汎用レジスタが利用可能です。この命令は1
Word命令でディスプレースメントは7 bitが使用でき、DJNZ命令のアドレスから-252
Byteから+2 Byteの範囲に分岐可能です。通常、Z8000 CPUの命令のバイトデータ型は命令ニーモニックの最後にBが付きますがDJNZ命令に限ってはDBJNZ命令となっているのも少し変わっているでしょうか。デクリメントするレジスタだけがバイトデータというわけですけど。
IRET命令はSC命令によるものなども含む割り込みからの復帰命令です。
JP命令とJR命令は分岐命令で、条件を指定することもできます。特にJR命令は1
Word命令で8 bitディスプレースメントを持ち、-254から+256 Byteの範囲に分岐することができます。
RET命令はサブルーチンから戻る命令ですが、8080からの伝統にのっとり条件を指定することができます。
SC命令はシステムコール用の、一種のソフトウェアトラップ命令です。8 bitの定数をオペランドとして持ち、それが命令の下位8
bitに埋めこまれた1 Word命令です。この命令の実行時には普通の割り込みと同様にプログラムステータスレジスタがスタックに退避され、割り込み識別語がスタックにプッシュされますが、この割り込み識別語がSC命令そのものとなっています。したがって、システムコールエントリでは、スタックトップの割り込み識別語の下位8
bitを調べると何番のシステムコールが呼び出されたか、判別できます。
ローテート・シフト命令はメモリオペランドは許されずレジスタアドレッシングだけしか存在しません。
命令 型 アドレッシングモード CZSVDH 意味
RL BW R
**** Rotate Left
RLC BW R
**** Rotate Left through Carry
RLDB B R
*- Rotate Left Digit
RR BW R
**** Rotate Right
RRC BW R
**** Rotate Right through Carry
RRDB B R
*- Rotate Right Digit
SDA BWL R
**** Shift Dynamic Arithmetic
SDL BWL R
***- Shift Dynamic Loghcal
SLA BWL R
**** Shift Left Arithmetic
SLL BWL R
***- Shift Left Logical
SRA BWL R
***0 Shift Right Arithmetic
SRL BWL R
***- Shift Right Logical
RL, RLC, RR, RRCの各命令はローテート系の命令で、レジスタの内容を1 bitないし2
bitだけローテートさせることができます。シフト系の命令と異なり、任意のビット数のローテートができるわけでなく、1
bitと2 bitのどちらかしか許されないということに注意が必要です。
RLDB命令とRRDB命令は4 bitのデジット単位のローテート命令で、8 bitレジスタに格納された2デジット分のデータと、もう一つの8
bitレジスタの下位4 bitに納められた1デジット分のデータのローテーションを行います。
SDA命令とSDL命令は、シフト量をレジスタで指定できます。シフト量を指定するレジスタの内容は符号付き整数として扱われ、その絶対値はシフトされるレジスタサイズ以下でなくてはなりません。つまりワード型の場合は+16から-16の範囲でなくてはなりません。そうして、正の数値の場合には左シフト、負の数値の場合には右シフトを意味します。無効なシフト数を指定した場合には結果は不定となります。
SLA, SLL, SRA, SRLの各命令は定数によってシフト量を指定するシフト命令です。シフト量は0からデータサイズ以下の範囲でなくてはなりません。
なお、Z8000 CPU発表と同時に、周辺LSIとしてZ80 SIOをZ8000バスインターフェースにして機能強化したZ8030 SCCなどが発表されています。こちらは、Z8000 CPU, 8086など用のZ8030と、Z80 CPU, MC68000など用のZ8530という形で、バスインターフェースの違いにより2種類が用意されていて、Z80の周辺LSIのようにZ80 CPUと組み合わせなければ使えない設計にはなっていませんでした。おかげでMacintoshのシリアルインターフェースにZ8530が使用されるなど、今でも利用され続けています。
Return to IC Collection