標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第327回]
●[5]MOV、MVI、HLT命令回路の動作テストです(操作説明書から)
☆☆☆当初は組立説明書に、動作テストのための操作の説明も一緒にして書いていたのですが、やっぱり操作の説明は別に「操作説明書」としてまとめた方がいい、と考えたので、そのようにすることにしました([第308回][注記])。
今回はその操作説明書の内容になります。
なお[第303回]で説明した、「動作テストの方法」はそのまま「操作説明書」の最初の部分になりました。
今回はその続きの部分、ということになります。☆☆☆
●3.MVI命令のテストプログラムをメモリに書く
MYCPU80組立説明書 V組立 [5]MOV、MVI、HLT命令回路 の組立作業後に行う動作テストの説明です。
●3−1. プログラムの説明
メモリに次のプログラムを書きます。
(リスト1)
0000 0600 MVI B,00
0002 0E01 MVI C,01
0004 1602 MVI D,02
0006 1E03 MVI E,03
0008 2604 MVI H,04
000A 2E05 MVI L,05
000C 3E07 MVI A,07
000E 76 HLT
上のプログラムリストのうち、本当に必要なマシン語の命令だけを取り出すと、06000E0116021E0326042E053E0776だけになります。
この16進数を、メモリの0000番地から順に書くだけでCPUには十分な命令プログラムになるのですが、でもこれでは人間には全く理解ができません。
そこで少しでも人間にも理解しやすいプログラムになるように、上のリストのような表現にするのが一般的です。
リストの最初の4桁はメモリアドレスです。
8080は0000〜FFFFの範囲のメモリアドレスをアクセスしますから、リストのようにメモリアドレスは4桁の16進数で示します。
8080はメモリの0000番地の命令を最初に読み込みますから、普通のマシン語のプログラムは0000番地から書き始めます。
メモリにはマシン語の命令も、 1.メモリにデータを書き込む (注)で説明したデータの書き込みと同じように1バイトずつ書き込んでいきます。
それならば、
0000 06 MVI B,00
0001 00
0002 0E MVI C,01
0003 01
:
:
と書いた方がよいようにも思えますが、マシン語のプログラムの場合には、ニーモニック表現に合わせて命令単位で表記します。
(注)☆当初の「組立説明書」から「操作説明書」に移したため項目番号が変わっていますが、そういう理由ですから気にしないでください☆
MVI命令は、そのあとに続く1バイトのデータをレジスタ(またはメモリ)に書き込む命令です。
命令の詳しい説明とマシン語コードについては、8080命令説明書を参照してください。
(リスト1)のプログラムをメモリに書き込んで実行させると、Bレジスタに00、Cレジスタに01、Dレジスタに02、Eレジスタに03、Hレジスタに04、Lレジスタに05、Aレジスタに07を書き込んだあとHLT命令を実行し停止します。
「停止する」と書きましたが、厳密に言うと、正確な表現ではありません。
正しくは、そのアドレスから先に進まずに、無限にHLT命令だけを実行し続けますから停止しているように見えます。
この状態を解除するにはリセット信号を入力するしかありません(先にEI命令が実行されていれば、割込みは受け付けられます)。
●3−2. ディップスイッチのセット
プログラムをメモリに書くときは必ずディップスイッチDS3をセットします。
セットの仕方は 1.メモリにデータを書き込む で説明していますが、もう一度説明します。
ディップスイッチDS3の一番左側の4のみを、小型のマイナスドライバを使って図のようにON(下側)にセットします。
DS3−4をONにすると、アドレスバス、データバスやその他の制御信号ラインがCPUから切り離されて、外部から直接メモリにアクセスすることができるようになります。
BUSが開放されたことを示すLED(BUSAK)が点灯します。同時にメモリがREADアクセス状態になるため、MRD(Memory Read)も点灯します。
●3−3. アドレスのセット
まず最初のアドレス0000を、ディップスイッチDS1、DS2とアドレス用のトグルスイッチを使ってセットします。
セットの仕方は 1.メモリにデータを書き込む で説明していますが、もう一度説明します。
図のようにディップスイッチのDS1、DS2とトグルスイッチのA3〜A0の全部を下側にします。スイッチを上側にすると"1"、下側にすると"0"がセットされます。
これでアドレスが2進数表示の0000 0000 0000 0000(16進数表示の0000)にセットされたことになります。
ディップスイッチは小さいので、小型のマイナスドライバを使ってセットします。
トグルスイッチは普通に指でセットできます。
アドレスバスの状態を示すLED(ADDRESS BUS)のA15〜A0は全消灯します。
このときデータ入力用のトグルスイッチが全部上側になっておれば、メモリのアドレス0000の値がデータ表示用LED(DATA BUS)に表示されます。
●3−4. 命令コードをセットする
アドレス0000に命令コード06(00000110)を書き込むため、データ入力用トグルスイッチをセットします。
1.メモリにデータを書き込む で説明した方法と全く同じです。
図のように、トグルスイッチのD7〜D0のうちのD2とD1を上に、その他を下にします。
この段階では、まだデータスイッチの状態はメモリに反映されていません。
メモリからはアドレス0000の現在の値(現在メモリに書き込まれている値)がデータバスに読み出されています。
データバスの状態は、LED(DATA BUS)のD7〜D0に表示されます。
たまたまデータスイッチとメモリからの値とが一致したビットはスイッチの状態がそのままLEDに表示されますが、スイッチとメモリからの値が一致しないビットは、スイッチとメモリからの値がショートするため、LでもなくHでもない中間的な値になりますから、LEDは薄く点灯するかまたは消灯します。
●3−5. MEMWRSWを押す
MEMWRSWを押すと、データスイッチでセットした値がメモリに書き込まれます。
その瞬間にメモリから出力される値がデータスイッチでセットした値と一致しますから、LED(DATA BUS)の表示がデータスイッチで設定した値の通りになります。
●3−6. 次のアドレス(0001)をセットする
3−3.で説明したのと同じ方法で次のアドレスをセットします。
アドレス0001は2進数では 0000 0000 0000 0001 ですから、トグルスイッチのA0だけを上にします。
●3−7. データの00をセットする
アドレス0001には命令MVI B,00のデータ部分00を書き込みます。
3−4.で説明したことと同じですが、今度は00(00000000)ですからデータ用のトグルスイッチを全て下にします。
●3−8. MEMWRSWを押す
MEMWRSWを押すと、データスイッチでセットした値00がメモリに書き込まれます。
その瞬間にメモリから出力される値がデータスイッチでセットした値と一致しますから、LED(DATA BUS)の表示がデータスイッチで設定した値の通りになります(全部消灯します)。
このあとも同じようにして、アドレス0002〜000Eまで命令コード、データを書き込みます。
●3−9. メモリに書き込んだプログラムを確認する
メモリにプログラムが正しく書き込まれたかどうか、念の為に確認をしておくとよいでしょう。
確認の仕方は、2. メモリからデータを読む (注)で説明していますから、そちらを参照してください。
(注)☆当初の「組立説明書」から「操作説明書」に移したため項目番号が変わっていますが、そういう理由ですから気にしないでください☆
●4.テストプログラムを実行する 4−1. ディップスイッチ(DS3)のセット
プログラムを実行するときは、ディップスイッチDS3を図のように全部OFF(上側)にセットします。
[注意]必ずRESETSWを押しながらディップスイッチをセットしてください。
メモリにプログラムを書き込んだあとは、いきなりディップスイッチを切り換えると、CPUがただちに実行を開始します。そのときの状態によっては正しく実行されないで、暴走してしまう可能性がありますから、必ずRESETSWを押したまま、DS3を切り換えるようにします。
●4−2. リセットスイッチを離す
ディップスイッチDS3を全部OFFにしてから、RESERSWを離します。
するとただちにプログラムが実行され、最後のHLT命令で停止します。
最後にHLT命令を書き忘れると、プログラムが暴走してしまうので、正しい結果が得られません。
レジスタのLEDは次のように表示されます。
[注]図のサイズと用紙サイズの関係で、実際の基板上のレジスタの配置とは異なっています。
このときPC(プログラムカウンタ)とアドレスバスのLEDは下のように表示されます。
アドレス000EのHLT命令が繰り返し実行されているからです。
データバスLEDとOPコードレジスタの表示は、下のようにHLT命令のコード76(01110110)になっています。
実はこのときCPUは完全に停止しているのではなくて、アドレス000EのHLT命令の、T0〜T3のステップを繰り返し実行しています。
その様子は、クロックLEDのE〜Aの状態から知ることができます。
図のように、AとBだけが点灯しているように見えます。
マシンクロックの00000〜00011(T0〜T3)が高速で実行されているため、このように見えます。
☆☆☆ここまでが操作説明書のコピーです。
●テストプログラムを実行後の写真です
リスト1のテストプログラムを実行した後の基板の写真です。
写真をクリックすると拡大画像を見られます。サイズが大きい(約3.7MB)ので、インターネットの低速接続環境では、ダウンロードに時間がかかります。ご注意ください
この写真は前回お見せした写真よりも前に撮った写真です。
左下のWKHレジスタ部分はまだ実装されていません。
前回の説明の中で出てくる、WKHレジスタとWKLレジスタを間違えていたためのトラブル、というのはメモリに対するMVI M命令のテストをした時点で発生したもので、その結果WKHレジスタの回路も実装してしまうことになったのですが、この時点(リスト1のテストプログラムを実行した時点)では、リスト1にはMVI M命令が含まれていなかったので、そのこと(WKHとWKLの間違い)にはまだ気がついていなかったのです。
R51は実装済みです。
あ。MVI M命令他のテストについては、また次回に説明いたします。
●8080命令説明書(1)
「8080命令説明書」を作成中です。
本当に説明書だらけ、です。
ものにもよりますが、本体そのものの製作よりも、説明書の作成作業の方が手間取ることもままあると思います。
こういう作業はホント、面倒なもので、つい手を抜きたくなってしまいます。
でも、そこで手を抜くと、「仏を作って魂を入れず」ということにもなりかねません。
しんどいことですけれど、やらずばなるまい、ということでしょうねぇ。
とほほ…、ですけれどもうひとがんばり、です。
組立作業の説明の途中ですが、それと並行して、命令説明書の内容も何回かに分けてUPしていきます。☆☆☆
(以下は8080命令説明書からのコピーです)
●[1]レジスタについて
8080には8ビットレジスタB、C、D、E、H、L、A、Fと16ビットレジスタSP、PCがあります。
Aレジスタは、レジスタを必要とする全ての命令で使われます。ADD、SUBなどの加減算命令やORA、ANAなどの論理演算命令は、2つのレジスタ間で演算を行いますが、演算の結果を格納するレジスタはAレジスタに限られます。
F(フラグ)レジスタはS、Z、H、P、Cの各フラグをビット情報として格納しているレジスタですが、PUSH PSW、POP PSW命令でAレジスタとともにスタックへの格納、取出しが出来るほかは演算などの命令の対象にすることはできません。
RALなどのローテイト命令や、I/O制御命令IN、OUTでは、Aレジスタのみが使われます。
8ビットのレジスタBとC、DとE、HとLはそれぞれ結合して16ビットのレジスタBC、DE、HLとして使うこともできます。
16ビットのレジスタHLはメモリアドレスを示す間接アドレッシングレジスタとしても使われます。
8080ニーモニックでメモリを示すMは、HLレジスタで示すメモリアドレスの意味で使われます。
BC、DEレジスタも限られた命令(STAX、LDAX)においてのみHLと同じように間接アドレッシングでメモリアドレスを示すために使われます。
●[2] 8ビット転送命令(この命令群はフラグに影響を与えません)
以下の説明中、クロックというのはその命令を実行するのに必要なマシンクロック数のことです。
MYCPU80のCPUクロックは2MHzですから1クロックは1/2μS(0.5μS)になります。
したがってたとえばクロック=6の命令の実行時間は0.5×6=3.0μSになります。
MYCPU80は8080の全ての命令を、同じように実行しますが、回路の違いにより、その命令を実行するのに必要なクロック数は8080とは異なっています。参考までに8080のクロック数を、MYCPU80のクロック数のうしろに()で示しました。
1. MOV r1,r2 コード (表1) クロック6(5)
r1、r2はB、C、D、E、H、L、Aを表します。r2の内容をr1に転送します。r2の内容は変化しません。
(表1)
r2 | ||||||||
B | C | D | E | H | L | A | ||
B | 40 | 41 | 42 | 43 | 44 | 45 | 47 | |
C | 48 | 49 | 4A | 4B | 4C | 4D | 4F | |
D | 50 | 51 | 52 | 53 | 54 | 55 | 57 | |
r1 | E | 58 | 59 | 5A | 5B | 5C | 5D | 5F |
H | 60 | 61 | 62 | 63 | 64 | 65 | 67 | |
L | 68 | 69 | 6A | 6B | 6C | 6D | 6F | |
A | 78 | 79 | 7A | 7B | 7C | 7D | 7F |
2. MOV r,M コード (表2) クロック6(7)
MはHLレジスタで示されるメモリを表します。Mの内容をrに転送します。Mの内容は変化しません。
(表2)
r | |
B | 46 |
C | 4E |
D | 56 |
E | 5E |
H | 66 |
L | 6E |
A | 7E |
3. MOV M,r コード (表3) クロック6(7)
rの内容をMに転送します。rの内容は変化しません。
(表3)
r | |
B | 70 |
C | 71 |
D | 72 |
E | 73 |
H | 74 |
L | 75 |
A | 77 |
4. MVI r,B2 コード (表4) クロック6(7)
B2はこの命令コードの次のアドレスに書かれたデータを示します。8ビットデータB2をrに転送します。
(表4)
r | |
B | 06XX |
C | 0EXX |
D | 16XX |
E | 1EXX |
H | 26XX |
L | 2EXX |
A | 3EXX |
5. MVI M,B2 コード 36×× クロック8(10)
B2をMに転送します(××は任意の8ビットデータを表します)。
6. LDAX B コード 0A クロック10(7)
BCレジスタで示されるメモリの内容をAに転送します。メモリの内容は変化しません。
7. LDAX D コード 1A クロック10(7)
DEレジスタで示されるメモリの内容をAに転送します。メモリの内容は変化しません。
8. LDA B3B2 コード 3A×××× クロック10(13)
命令コード3Aに続く2バイトデータで示されるメモリの内容をAに転送します。メモリの内容は変化しません。
この命令のように2バイトのデータを扱う場合には先に来るほうが下位アドレスであとに上位アドレスがきます。たとえば1234番地の内容を転送する場合のコードは3A3412になります。
9. STAX B コード 02 クロック10(7)
Aの内容をBCレジスタで示されるメモリに転送します。Aの内容は変化しません。
10. STAX D コード 12 クロック10(7)
Aの内容をDEレジスタで示されるメモリに転送します。Aの内容は変化しません。
11. STA B3B2 コード 32×××× クロック10(13)
Aの内容をB2B3で示されるメモリに転送します。Aの内容は変化しません。
B2B3については 8.LDA B3B2 の説明を参照してください。
2009.9.6upload
前へ
次へ
ホームページトップへ戻る