この文書では,MCS-4の中核をなす4004について説明します.4[bit]というかなり厳しい条件下でコンピュータとしての動作をさせるべく作られている4004の中身にはさまざまな 工夫が存在します.まずは4004に備わるピンを説明したのち,内部構造をブロック図で説明します.その後,タイミングチャートとすべてのインストラクションについて説明していきます.


概要

4004には45個のインストラクション(命令)が備わっています.基本的に1個の命令は4[bit]のOPR部と4[bit]のOPA部で構成されていますが,一部の命令は16[bit]となっています.全部ではありませんが,主にOPRは命令を識別するために用いられ,OPAは引数として用いられます.このOPAをオペランドといいます.

40014002を説明するページで書きましたが,4004には入出力端子も内蔵ROMもRAMもありません.そのため,データバスに4001(ROMと入出力端子)と4002(RAMと出力端子)をつなぐのです.しかも,外部バスとして使用できるのは4ビットだけですので,データとアドレスは同じバスを共用で使わざるを得ません.従って,12[bit]のアドレスを持つROMから8[bit]のインストラクションを得るのに3クロック+2クロック,合計で5クロック必要です.

演算するにも一苦労します.4004のアキュムレータは4[bit]しかなく,4[bit]以上の演算を1サイクルでは行えません.なお,アキュムレータとは演算を行うときに使うレジスタで,4004には1個しかありません.従って,アキュムレータには演算前には被演算数が入っており,演算後には結果が入れられます.また,演算の種類も加算・減算・シフトしかなく,除算を行うには引き戻し法などを使わなければなりません.

以上のような4004について,詳しく以下で説明していきます.


パッケージとピン

4004は当時としては標準的だったDIPの16ピンでした.現在のCPUでは1000ピンを越えるものも珍しくなくなってきていることを考えると,ものすごく少ないですね.このように少ないピンでRAMやROMと接続するにはどうしたらいいと思いますか?これまで皆さんが使ったことのあるマイコンを想像してください.データバスとアドレスバスがあり,SRAMが接続されていましたはずです.この場合,かなりのピン数が必要になってしまいますよね.そこで,これをひとつにまとめてしまいましょう.つまり,データバスとアドレスバスを一緒にし,データとアドレスを交互に入出力します.このように時間によって通信内容を変えることを時分割と言います.4004では,4個の端子をバスに割り当ててあるため,4ビット入出力となります.これに対し,アドレス空間が12ビット,命令のデータ幅が8ビット,命令を実行するときに必要なオペランド(命令の引数)の最大が12ビットとなっているため,それぞれ3サイクル,2サイクル,3サイクル必要うとなります.ここで「サイクル」とは,クロック信号の1周期のことであり,4004では4ビットバスですので,1サイクルで4ビットを送受信できます.従って,1個の命令をこなすのに8サイクルかかります.「CPUの最大動作周波数」という言葉をよく聞くと思います.この周波数はクロックのものであり,速ければ速いほど素早く処理を行えます.そしてその逆数が最小周期となります.4004ではクロックの最小周期が1.35[μs]でしたので,1命令こなすのにはその8倍の1.35×8=10.4[μs]かかったことになります.周期の逆数は周波数ですので,1秒間におよそ92[kHz]であったと言えます.最近のパソコンに入っているCPUだと3[GHz]位でも特段速いとは言えなくなってきています.また,パイプライン処理がついているため1サイクル1命令を行えますし,さらにマルチコアだと単純計算でコア数倍速くなります.例えばクワッドコア(4個)の場合,12[GHz]となりますので,およそ13万倍のスピードと言えます.

4004PinAssign

データバス,電源,クロック信号およびリセット信号はMSC-4で共通ですのでこちらをご覧下さい.ただし,SYNC信号は4004が出力になっており,他の4001や4002が入力となっています.

TEST端子

この端子名だけみると,4004が正しく動いているのか確かめるための端子のように感じますよね.実はこの信号の状態次第で分岐をするかを変えることができるピンなのです.従いまして,入力端子となっています.

CM-ROM

 この端子は4001(ROM)からインストラクションをフェッチしようとするとアサート(High)されます.そして,この端子は4001のCMに接続されます.4004は自動的にこのような動作をします.何のためにこの端子があるのかというと,4001のグループ(バンクといいます)を切り替えるときに用いられます.1バンクには16個の4001があり,最大で2バンク接続することができます.どのように使うかというと,バンクAとバンクBがあるとして,バンクAのCMはCM-ROMをそのまま接続し,バンクBのCMはNOTを介してCM-ROMを接続します.こうすることで,4001のバンクを切り替えられます.

CM-RAM0~CM-RAM3

 この端子は4002(RAM)にあるデータを読んだり,逆に書き込んだりするときにアサート(High)されます.4本の端子があり,それぞれRAMのグループに対応しています.


ブロック図

4004はシステムの要ですので中身が複雑です.しかし,少しずつ説明していきますので,気負いせずお読みください.下にブロック図を示します.

4004BlockDiagram

タイミング

まずは簡単なところから説明していきます.右上のタイミングブロックをご覧ください.MCS-4の共通端子のところでも説明しましたが,SYNC信号の発信元は4004ですのでSYNCは出力端子になっています.この信号を作り出すためにΦ1とΦ2が入力されています.

チップ管理ロジック&バッファとチップ管理レジスタ

次に左上をご覧ください.チップ管理ロジック&バッファブロックがありますね.ここではROM(4001)とRAM(4002)を制御するための信号であるCM-ROMとCM-RAM0~3が出力端子になっています.これら5本の出力端子からアサート(High)にすることで,その接続されているROMもしくはRAMが動作する仕組みになっています.

データバスI/Oバッファ

次に左下をご覧ください.データバスI/Oバッファブロックがありますね.これはおなじみのデータバスであり,MCS-4では4[bit]バスですので入出力端子D0~3までの4本があります.この端子から,ROMへはアドレスを出力,ROMからはインストラクションを入力,RAMとはデータもしくはアドレスが入出力されていくのです.

プログラムカウンタ

さて,ここからがCPUたる4004の本質的なブロックの説明になります.なるべく処理の順番に従って話を進めていきます.まずは電源投入直後もしくはリセットがかかったところからお話をします.はじめに右中段にあるプログラムカウンタブロックは12[bit]であり,現在実行しているインストラクションのROMアドレスです.このため,電源投入直後にはこのプログラムカウンタの値が0となります.プログラムカウンタに入っているアドレスのうち,まずは下位4ビットをデータバスI/Oバッファに格納します.その後,同様に,中位4ビットと上位4ビットのアドレスがROMに送られます.

OPRとOPA

アドレスをROMに送りますと,そのアドレスに格納されているインストラクションがROMからCPUに送られてきます.インストラクションは基本的に8[bit]ですので,2回に分けてデータバスI/Oバッファを介して送られてきます.はじめに送られてきた4[bit]がOPRに,あとに送られてきた4[bit]がOPAに格納されます.

インストラクションデコーダ

OPRおよびOPAに入ったインストラクションをインストラクションデコーダで復号化し,そのインストラクションが何なのか4004は理解します.

インデックスレジスタ・アキュムレータ・4ビット加算器とシフタ

インストラクションによって処理が変わりますが,まずは計算をする場合を説明します.4004には加算をするインストラクションであるADDというものがあり,その場合,アキュムレータに入っている4[bit]の値とインデックスレジスタに入っている値とを足します.インデックスレジスタは16個あり,0000(2)~1111(2)までのアドレスを持っています.インストラクションレジスタの指定はOPA(オペランド)に記された4[bit]のアドレスにより行うこととなっています.そして,加算した結果は再びアキュムレータに代入されます.もし桁上りが発生した場合,キャリに1が入る仕組みになっているのです.このように16個のインデックスレジスタという,一時記憶領域を使いながら計算をしていくのです.

インデックスレジスタは16個あり,場合によっては2個まとめて8[bit]として利用することもあります.その場合にはアドレスの上位3[bit]を指定することになっています.このような使い方を「インデックス対」と以下では言います.例えば,SRCというインストラクションの場合,OPAはRRR1(2)となっており,この3[bit]のRRRがインデックスレジスタの上位3[bit]となるのです.

インストラクションレジスタ

インストラクションによっては,16[bit]となっているものもあります.その場合,1サイクルではすべてのインストラクションを持ってこられませんので2サイクルでフェッチします.その場合,インストラクションレジスタが使われ,最初のサイクルでフェッチしたインストラクションの半分をインストラクションレジスタに入れておき,次のサイクルでOPRとOPAに入れておきます.その後,デコーダでインストラクションを解析するのです.

インクリメンター

プログラムカウンタに入った値は,分岐命令でなければ次に進みます.その時に使われるのがインクリメンターであり,プログラムカウンタに入った値を1増やします.

スタック

プログラムカウンタの下にあるスタックに注目してください.3個のスタックがありますが,これらはサブルーチンを呼び出すときに使います.これまでのアドレス,つまりプログラムカウンタに入っている値をスタックに入れておき,サブルーチンのアドレスをプログラムカウンタに入れてあげます.その後,サブルーチンの処理が終わりましたら,スタックから前のアドレスをとり出し,プログラムカウンタに入れます.このようにすることで,サブルーチン処理が行えます.スタックは3段になっているので,サブルーチンのネストは最大で3段階といえます.

以上ですべてのブロックについて説明しました.上記のブロックはこのあとも常に説明で出てきますのでよく理解しておいてください.


タイミングチャート

1サイクル内で行うことを理解するため,タイミングチャートを下に示します.Φ1の立ち上がりでバスの値を取りこみ,Φ2の立ち上がりで値を変化させます.ここではバスの値をを便宜上,A1~3,M1~2,X1~3で表すことにします.

TimingChart

ROMアドレス送信A1~3

MCS-4には4[bit]幅のバスしかないのに対し,ROMアドレスは12[bit]ですので,3個に分割して4004から4001にアドレスを送信します.その段階を上記のタイミングチャートではA1からA3で表します.メモリサブサイクルの行をご覧ください.A1からA3があるのが分かりますね.送信する順番はアドレスの下位4ビット(A1),中位4ビット(A2),上位4ビット(A3)となります.なお,A3で送られる4ビットは16個ある4001のチップそれぞれに設定されている固有の4ビットアドレスと対応しており,A3と同じ固有アドレスを持つ4001のみが反応するようになっています.

インストラクションコード受信M1~2

前述のROMアドレス送信の結果,ROMからのインストラクションコードを受信するのがM1とM2です.インストラクションコードは8[bit]であり,前半のM1でOPR,後半のOPA(オペランド)を受信します.OPAは4004だけでなく,現在インストラクションを読んでいるROM以外のROMにも送られます.また,IO関連のインストラクションの場合にはRAMにもオペランドが送られます.このように書くと,RAMがインストラクションをデコードしているように感じられますが,実際にはRAMはM2のときには常にOPAを受信しており,この後に行われるX1~X3の時にRAMがOPAを使うということです.IO関連のインストラクションの時にはRAMはOPAを無視するに過ぎません.

実行もしくはデータ送受信X1~X3

このサブサイクルでは,4004で演算を行ったり,RAMやROMに対してアドレスなどを送信したりします.X1からX3までの3クロックを使いますが,このうちX1では4004のバスから出力されるOPAは特に使われていません.X2ではI/Oのリード命令の場合には,選択されたROMもしくはRAMがバスを占有してCPUへデータを送り,それ以外の場合にはCPUがバスを占有します.X3ではCPUが占有し,RAMアドレスをRAMへ出力します.

RAMやROMのタイミングチャート

下の図はRAMやROMとデータをやり取りするときのタイミングチャートです.この例ではRAM0グループに変えてRAM1グループをDCL命令で選択し,SRC命令でRAM1グループ内のRAMとそのRAMアレイ,さらにRAMアレイにあるメインメモリ文字を指定して,最後に入出力・RAM命令群の命令を実行しています.選択されているRAM群に対応するCM-RAMxのみ,A3でアサートされているのに加え,SRC命令ではX2,入出力・RAM命令群ではM2でもアサートされています.なお,すべてのCM-RAMxを論理積した信号をCM-ROMに送られています.

CommandControlLine


インストラクション

ここでは,4004に備わる45個のインストラクションについて1つずつ説明していきます.


マシン命令群

NOP(No OPeration)

D3 D2 D1 D0 D3 D2 D1 D0
0 0 0 0 0 0 0 0

このインストラクションを行うと,CPUは何もしません.このため,ウェイトをするときに用いられます.


JCN(Jump CoNdition)

D3 D2 D1 D0 D3 D2 D1 D0
0 0 0 1 C1 C2 C3 C4
A2 A2 A2 A2 A1 A1 A1
A1

このインストラクションを実行すると,プログラマによって書かれた条件によって分岐をします.条件は下表の6種類で,いずれかに当てはまるとジャンプします.C1はC2C3C4の条件を反転させます.たとえばC3(キャリが0の場合ジャンプ)が1のときにC1が1であれば,キャリが1の場合にジャンプすることを意味します.ジャンプ先アドレスであるA3A3A3A3A2A2A2A2A1A1A1A1(12[bit])のうちA2A2A2A2A1A1A1A1はJCN命令にあるものであり,A3A3A3A3はJCN命令が存在するアドレスの上位4ビットです.したがってJCN命令では違うROMにあるアドレスにはジャンプできません.

条件 C1が0の場合 C1が1の場合
C2 アキュムレータの値が0の場合にジャンプします アキュムレータの値が1の場合にジャンプします
C3 キャリが1の場合ジャンプします キャリが0の場合ジャンプします
C4 テスト端子の信号がLow(=-15V)の場合ジャンプします テスト端子の信号がHigh(=0V)の場合ジャンプします

FIM(Fetch IMmediate)

D3 D2 D1 D0 D3 D2 D1 D0
0 0 1 0 R R R 0
D2 D2 D2 D2 D1 D1 D1
D1

この命令は,ROMにある8[bit]のデータD2D2D2D2D1D1D1D1を取ってきて,レジスタ対RRRに代入するときに用いられます.ROMからデータを取ってくることをFetchといい,それをすぐに行うことから,Fetch Immediateというニーモニックになります.取ってきたD2D2D2D2とD1D1D1D1がレジスタRRR0とRRR1のどちらにはいるかということはデータシートに書かれていませんので,ここではD2D2D2D2をRRR0に,D1D1D1D1をRRR1に代入することとします.


SRC(Send Register Control)

D3 D2 D1 D0 D3 D2 D1 D0
0 0 1 0 R R R 1

この命令について説明するのに先立ち,上記の表にあるRRRについて説明します.これはインデックスレジスタ対を表しており,例えばRRR=110だとするとインデックスレジスタ1100と1101に入っている8ビットのデータを表しています.

この命令には2種類の用途があります.一つ目はRAMのアドレスを指定するときに用いられます.RAMアドレスはX2とX3のサイクルで送られ,X2の上位2[bit]でチップ番号,下位2[bit]でRAMアレイ番号,X3でメインメモリ文字のアドレスを指定します.指定されたアドレスをRAMは記憶しておき,このあと行われるRAMに対する読み書き命令で用います.

もうひとつの用途として,ROMのチップを指定するときに用いられます.ROMに備わる入出力端子を指定するとき,ROMの指定をあらかじめしておく必要があります.その指定するとき使われるのです.ROMは4001が16個で構成されていますから4[bit]あればよく,従いましてX2サイクルで4001のA3(アドレスの上位4[bit])を送ります.なお,X3サイクルに送られてくる情報をROMは無視します.


FIN(Fetch INdirect)

D3 D2 D1 D0 D3 D2 D1 D0
0 0 1 1 R
R
R
0

この命令は,インデックスレジスタ0000の値をROMアドレスのA1A1A1A1(下位4[bit])とし,同じくインデックスレジスタ0001の値をROMアドレスのA2A2A2A2(中位4ビット)とした時のROMの値を取ってきて,レジスタ対RRRに入れます.ROMアドレスにはA3A3A3A3がありますが,この値はFIN命令のあるアドレスと同じものを用います.従いまして,FIN命令で取得できる値は同じROMチップ(4001)内に限られます.FIN命令は主に定数のテーブルをROMに格納しておき,それを参照するときに用いられます.

FIN命令は,一見すると1インストラクションサイクルのように見えますが,FIN命令を実行するインストラクションサイクル内だけで完結しません.なぜなら,ROMからデータを取ってくるのは次のインストラクションサイクルで行われるからです.FIN命令によってROM内のデータを取ってくるまでの流れを下に示します.

  1. ROMからFIN命令自体を取ってきます.このインストラクションサイクルでは,ROMからデータを取って来ずに終わります.
  2. 次に実行するインストラクションサイクルにおいて,A1およびA2をインデックスレジスタ0000と0001に置き換えます.なお,A3はプログラムカウンタにある値をそのまま用います.
  3. M1およびM2サイクルでROMからデータを取ってきて,X1サイクルでレジスタ対RRRに格納します.
  4. プログラムカウンタをFIN命令があったものの次のものにします.

JIN(Jump INdirect)

D3 D2 D1 D0 D3 D2 D1 D0
0 0 1 1 R
R
R
1

この命令は,レジスタ対RRRにある8[bit]の値をROMのアドレスA1A2としてジャンプします.A3はJIN命令のあるアドレスと同じです.従いまして,ジャンプ先は同じROMチップ(4001)内に限られます.なお,FINとJINは同じOPRであるため,OPAのD0で区別します.


JUN(Jump UNconditional)

D3 D2 D1 D0 D3 D2 D1 D0
0 1 0 0 A3 A3 A3 A3
A2 A2 A2 A2 A1 A1 A1
A1

この命令は,指定されたアドレスA3A3A3A3A2A2A2A2A1A1A1A1へ無条件にジャンプします.ジャンプしたのち,もとのアドレスへ戻ってくることを想定していません.


JMS(JuMp Subroutine)

D3 D2 D1 D0 D3 D2 D1 D0
0 1 0 1 A3 A3 A3 A3
A2 A2 A2 A2 A1 A1 A1
A1

この命令は,指定されたアドレスA3A3A3A3A2A2A2A2A1A1A1A1へジャンプします.ただし,ジャンプしたのちに再びもとのアドレスへ戻ってくることを想定しているため,もとのアドレスをプログラムカウンタのスタックに格納します.なお,もとのアドレスに戻るにはBBLを用います.


INC(INCrement)

D3 D2 D1 D0 D3 D2 D1 D0
0 1 1 0 R
R
R
R

この命令は,インデックスレジスタRRRRにある値を1増やします.


ISZ(Increment and go Same rom if Zero)

D3 D2 D1 D0 D3 D2 D1 D0
0 1 1 1 R R R R
A2 A2 A2 A2 A1 A1 A1
A1

この命令は,インデックスレジスタRRRRの値を1増やし,その結果,0でなかったらプログラムカウンタをA3A3A3A3A2A2A2A2A1A1A1A1にし,0であったら通常と同様にプログラムカウンタを1増やして次の命令を行うようにします.A3A3A3A3はISZの命令があるROMのアドレスと同じですので,同じ4001チップ内しかジャンプすることはできません.ISZ命令は主に繰り返し処理を行うときに用いられ,インデックスレジスタが4ビットであるため最大16回繰り返すことができます.もし,それ以上の繰り返し処理を行う場合には,多重ループにする等をして対処する必要があります.


ADD(ADD)

D3 D2 D1 D0 D3 D2 D1 D0
1 0 0 0 R
R
R
R

この命令は,インデックスレジスタRRRRの値とアキュムレータの値,またキャリが立っていた場合にはさらに1を足し合わせ,結果をアキュムレータに入れます.もしけた上がりが発生した場合には,キャリに1が立ちます.


SUB(SUBtract)

D3 D2 D1 D0 D3 D2 D1 D0
1 0 0 1 R
R
R
R

この命令は,アキュムレータの値 + インデックスレジスタRRRRの値を反転したもの + キャリを反転したものを行い,結果をアキュムレータとキャリに入れます.これはアキュムレータ-インデックスレジスタRRRRを表しています.ただし,キャリ(この場合には桁借りが発生している=1)の場合にはその数から1を減らします.また桁借りが発生した場合にはキャリには0が設定され,反対に桁借りが発生しなかった場合には1が設定されます.

分かりづらいので4個の例を挙げて説明します.

例1:アキュムレータの値=7,インデックスレジスタの値=5,キャリ=1(下からの桁借りあり)とすると,0b0111+0b1010+0b0000=0b10001となり,アキュムレータの値が0b0001(=1),キャリが1となります.つまり,7-5-1=1で桁借り無しであったことを表しています.

例2:アキュムレータの値=7,インデックスレジスタの値=5,キャリ=0(下からの桁借り無し)とすると,0b0111+0b1010+0b0001=0b10010となり,アキュムレータの値が0b0010(=2),キャリが1となります.つまり,7-5=2で桁借り無しであることを表しています.

例3:アキュムレータの値が5,インデックスレジスタの値=7,キャリ=1(下からの桁借りあり)とすると,0b0101+0b1000+0b0000=0b01101となり,アキュムレータの値が0b1101,キャリが0となります.つまり5-7-1=-3(2の補数表記では1101)で桁借りありであることを表しています.

例4:アキュムレータの値が5,インデックスレジスタの値=7,キャリ=0(下からの桁借り無し)とすると,0b0101+0b1000+0b0001=0b01110となり,アキュムレータの値が0b1110,キャリが0となります.つまり,5-7=-2(2の補数表記では1110)で桁借りありであることを表しています.


LD(LoaD)

D3 D2 D1 D0 D3 D2 D1 D0
1 0 1 0 R
R
R
R

この命令は,インデックスレジスタRRRRの値をアキュムレータに代入します.


XCH(eXCHange)

D3 D2 D1 D0 D3 D2 D1 D0
1 0 1 1 R
R
R
R

この命令は,インデックスレジスタRRRRの値とアキュムレータの値を入れ替えます.


BBL(Branch Back and Load)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 0 0 D
D
D
D

この命令は,サブルーチンを呼び出すときスタックに格納しておいたアドレスをポップし,プログラムカウンタへ格納します.ポップした結果,スタックの位置は1段階上がります.また,アキュムレータに値DDDDを格納します.多くの場合,サブルーチンの計算結果(つまり戻り値)をインデックスレジスタに格納していますので,そのインデックスレジスタのアドレスをDDDDとしておけば計算結果を得ることができます.


LDM(LoaD Memory)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 0 1 D
D
D
D

この命令は,アキュムレータに値DDDDを代入します.


入出力・RAM命令群

WRM(Write Ram Main memory character)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0
0
0
0

この命令は,アキュムレータに書かれている値をRAMのメインメモリ文字へ書き込みます.RAMのメインメモリはSRC命令とDCL命令であらかじめ指定しておく必要があります.


WMP(Write raM output Port)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0
0
0
1

この命令は,4002(RAM)に備わる出力ポートからアキュムレータの値を出力します.このRAMはSRC命令とDCL命令であらかじめ指定しておく必要があります.


WRR(WRite output port in Rom)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0
0 1 0

この命令は,4001(ROM)に備わる出力ポートからアキュムレータの値を出力します.このROMはSRC命令であらかじめ指定しておく必要があります.


WR0(WRite status character 0)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0
1
0
0

この命令は,アキュムレータに書かれている値をRAMのステータス文字0へ書き込みます.RAMのメインメモリはSRC命令とDCL命令であらかじめ指定しておく必要があります.


WR1(WRite status character 1)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0
1
0
1

この命令は,アキュムレータに書かれている値をRAMのステータス文字1へ書き込みます.RAMのメインメモリはSRC命令とDCL命令であらかじめ指定しておく必要があります.


WR2(WRite status character 2)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0 1 1 0

この命令は,アキュムレータに書かれている値をRAMのステータス文字2へ書き込みます.RAMのメインメモリはSRC命令とDCL命令であらかじめ指定しておく必要があります.


WR3(WRite status character 3)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 0
1
1
1

この命令は,アキュムレータに書かれている値をRAMのステータス文字3へ書き込みます.RAMのメインメモリはSRC命令とDCL命令であらかじめ指定しておく必要があります.


SBM(SuBtract Main memory character)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
0
0
0

この命令は,アキュムレータからRAM内のメインメモリ文字の値を引き,結果をアキュムレータに代入します.もし桁借りが発生した場合にはキャリが1になります.


RDM(ReaD Main memory character)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
0
0
1

この命令は,RAMのメインメモリに書かれている値をアキュムレータへ書き込みます.RAMのメインメモリはSRC命令とDCL命令であらかじめ指定しておく必要があります.


RDR(ReaD Rom input port)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
0
1
0

この命令は,ROMに備わる入力端子情報をアキュムレータへ書き込みます.ROMはSRC命令であらかじめ指定しておく必要があります.ROMの端子は出力端子にすることもできますが,その端子についてどのようになるかデータシートには書かれていませんのでここでは0と読み込まれることとします.


ADM(ADd Main memory character)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
0
1
1

この命令は,メインメモリ文字の値とアキュムレータの値を足し,結果をアキュムレータに代入します.もし桁上りが発生した場合にはキャリが1になります.


RD0(ReaD status character 0)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
1
0 0

この命令は,RAM内のステータス文字0の値を読み込み,アキュムレータに代入します.


RD1(ReaD status character 1)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
1
1 0

この命令は,RAM内のステータス文字1の値を読み込み,アキュムレータに代入します.


RD2(ReaD status character 2)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
1
1 0

この命令は,RAM内のステータス文字2の値を読み込み,アキュムレータに代入します.


RD3(ReaD status character 3)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 0 1
1
1 1

 この命令は,RAM内のステータス文字3の値を読み込み,アキュムレータに代入します.


アキュムレータグループ命令群

CLB(CLear Both accumulator and carry)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
0
0 0

この命令は,アキュムレータとキャリの値を0にします.


CLC(CLear Carry)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
0
0 1

この命令は,キャリを0にします.


IAC(Increase ACcumulator)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
0
1 0

この命令は,アキュムレータの値を1増やします.桁上がりが発生した場合にはキャリが1となります.


CMC(CoMplement Carry)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
0
1 1

この命令は,キャリを反転させます.


CMA(CoMplement Accumulator)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
1
0 0

この命令は,アキュムレータの値を反転させます.


RAL(Rotate Accumulator Left)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
1
0 1

この命令は,キャリを最上位ビットとした,アキュムレータと連結したもの(5[bit])を循環左シフトします.


RAR(Rotate Accumulator Right)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
1
1 0

この命令は,キャリを最上位ビットとした,アキュムレータと連結したもの(5[bit])を循環右シフトします.


TCC(Transmit Carry to accumulator and Clear Carry)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 0
1
1 1

この命令は,キャリをアキュムレータに入れたのち,キャリを0にします.


DAC(Decrement ACcumulator)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 1
0
0 0

この命令は,アキュムレータの値を1減らします.


TCS(Transfer Carry Subtract)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 1
0
0 1

この命令は,キャリが1ならアキュムレータを10,キャリを0にし,キャリが0ならアキュムレータを9にします.これにより,10進数の引き算を簡単に行うことができます.ある桁の引き算でマイナスになると上位から10を借りてきて引き算をしますが,その下の桁で桁借りがある場合は9と引き算することになります.このときTCS命令は大変役立ちます.


STC(SeT Carry)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 1
0
1 0

この命令はキャリを1にします.


DAA(Decimal Adjust Accumulator)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 1
0
1 1

この命令は,アキュムレータの値をBCD(Binary Coded Dicimal)にするときに使用します.BCDとは,十の位と一の位のに分けて表現するものです.このうち,一の位のみにしてくれるのがDAAなのです.例えば十進数で12という値であれば,2にしてくれるのです.このためには,10以上の値の場合には6を足し,10未満の場合特に何もしません.先ほどの例の12を例にとると,12+6=18となりますので,二進数では10010となりますが,最上位ビットはアキュムレータからあふれるため,結果として「2」となります.


KBP(KeyBoard Process)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 1
1
0 0

この命令は,キーボードが押された結果をRDR命令によってアキュムレータに格納されていることを前提に,それを数値化します.アキュムレータが4[bit]であるため,スイッチ押下の有無は4種類しかありません.また,同時に複数のスイッチが押下されることをそうていしていません.従いまして,KBP命令を実行するとアキュムレータは下表のように変化します.

実行前 実行後 
0000  0000 
0001 0001 
0010 0010 
0100 0011
1000 0100
上記以外 1111

DCL(Designate Command Line)

D3 D2 D1 D0 D3 D2 D1 D0
1 1 1 1 1
1
0 1

この命令は,アキュムレータに書かれているワンホット(ひとつのビットだけ1となっており,他のビットは0となっている値のこと)の値に基づきCM-RAM0~3の信号を制御します.最下位ビットがCM-RAM0,最上位ビットがCM-RAM3というように割り当てられています.