めざせ4004! IC24個で電卓用CPUを作ってみた: Chapter 2-1 RAMの容量拡大に伴う命令コードの変更
ではTD4EX4をベースに全命令を2バイト化し、RAMアドレス指定を8ビット化してみましょう。
表3をご覧ください。RAMアドレス指定を命令の2バイト目に移動して8ビット化してみました。
| 命令 | 1バイト目 | 2バイト目 | キャリーフラグ | 説明 | |
|---|---|---|---|---|---|
| bit 7~4 | bit 3~0 | ||||
| ADD A, [Adr] | 0000 | 0000 | Adr | ※1 | 指定アドレスのRAMの値をAレジスタに加算 |
| ADD B, [Adr] | 0001 | 0000 | Adr | ※1 | 指定アドレスのRAMの値をBレジスタに加算 |
| ADD A, Im | 0010 | Im | 00000000 | ※1 | 定数(Im)をAレジスタに加算 |
| ADD B, Im | 0011 | Im | 00000000 | ※1 | 定数(Im)をBレジスタに加算 |
| LD A, [Adr] | 0100 | 0000 | Adr | - | 指定アドレスのRAMの値をAレジスタに格納 |
| LD B, [Adr] | 0101 | 0000 | Adr | - | 指定アドレスのRAMの値をBレジスタに格納 |
| LD A, Im | 0110 | Im | 00000000 | - | 定数(Im)をAレジスタに格納 |
| LD B, Im | 0111 | Im | 00000000 | - | 定数(Im)をBレジスタに格納 |
| SUB A, [Adr] | 1000 | 0000 | Adr | ※2 | 指定アドレスのRAMの値をAレジスタから減算 |
| SUB B, [Adr] | 1001 | 0000 | Adr | ※2 | 指定アドレスのRAMの値をBレジスタから減算 |
| ST [Adr], A | 1010 | 0000 | Adr | - | Aレジスタの値を指定アドレスのRAMに格納 |
| ST [Adr], B | 1011 | 0000 | Adr | - | Bレジスタの値を指定アドレスのRAMに格納 |
| JNC Adr | 1110 | ROM Adr | - | キャリーがゼロなら指定アドレス(Im)にジャンプ | |
| JMP Adr | 1111 | ROM Adr | - | 指定アドレス(Im)にジャンプ | |
アドレス指定を8ビット化したことにより256語のRAMにアクセスできるようになりましたが、果たしてこれで十分でしょうか? RAMの容量が増えたことで新たな問題が起きていないでしょうか?
検証のため簡単なプログラムを組んでみましょう。単純にRAMを端から端までゼロクリアするプログラムです。以下のコードをご覧ください。
| 000: | 60 | 00 | LD | A, | 0 | ||
| 002: | A0 | 00 | ST | [0x00] | A | ||
| 004: | A0 | 01 | ST | [0x01] | A | ||
| 006: | A0 | 02 | ST | [0x02] | A | ||
| …… | |||||||
| 1FE: | A0 | FE | ST | [0xFE] | A | ||
| 200: | A0 | FF | ST | [0xFF] | A | ||
いやもうこれ馬鹿でしょこれ。
単純にRAMのアドレスを命令中で指定して1個ずつゼロクリアしています。RAMは256語あるのですから同じことを256回行っています。
アセンブラをご存じない方のためにC言語で表現すると以下のようになります。
| int cx[256]; |
| cx[0] = cx[1] = cx[2] = …… = cx[254] = cx[255] = 0; |
あまりにも酷いですね。こんなプログラムを学校で書いたら落第でしょう。職場ならクビですクビ。 表3のCPUではこのようなプログラムしか動作しませんのでCPUとしては論外です。では、どうすれば良いのでしょうか?