プラスチック28ピンDIPに納められています。これは久我様よりいただいたものです。
ピン配置は次のようになっています。
I1/D1 1 28 DA1
I2/D2 2 27 DA2
I3/D3 3 26 DA3
I4/D4 4 25 DA4
I5/ADR* 5 24 I6/JC
SYNC 6 23 BR*
OSC 7 22 DAS*
ISEL 8 21 VDD
HOLD 9 20 DO4
R/W* 10 19 DO3
POR 11 18 DO2
RDY 12 17 DO1
ERROR 13 16 F1
F2 14 15 VSS
双方向の信号は存在せず、入力信号か出力信号かのどちらかしかありません。
VSSとVDDが電源ピンで、VSS - VDDが7.9 Vから9.5 Vで動作します。通常、TTLとインターフェース可能にするため、VSSに+5
V、VDDに-4 Vを与えて、9 Vの電源電圧で動作させます。以後、入出力電圧範囲について触れる場合には、この条件で考えることにします。
クロックはOSC端子から与えます。+4 Vから-2.5 Vまでの振幅を持つ320 kHzから400
kHzの間の周波数のクロック信号が必要です。動作周波数範囲が狭いのもp-MOSの特徴ですね。
PORはパワーオンリセット信号、HOLDはホールド信号で、ともに入力信号ですが、この2本だけ入力電圧レベルが特別で、Hが2
V以上、Lが-2.5 V以上となっていて、クロック信号と同様に通常のTTL出力を接続することができません。HOLD信号は命令実行を一時停止させるための信号です。
SYNC信号はマイクロサイクルごとにLパルスを出力する信号で、このLSIの内部処理の区切りを示しています。400
kHzクロック時に1マイクロサイクルは10 usとなります。後述しますが、四則演算には約5000マイクロサイクル必要だったりします。
RDY信号はHOLD信号と対になる出力信号で、次の命令の実行準備ができたときにHになります。HOLDがLなら8マイクロサイクルだけHになって、Lになる時に次の命令を読み込んで実行します。HOLDがHなら、HOLDがLになるまでHを出力し続け、それから命令読み込んで実行します。メモリないしCPUとの同期のために使います。
BR信号は分岐を意味する出力信号で、Lパルスで外部に用意したプログラムカウンタに分岐先アドレスをロードするタイミングを示します。
ISEL信号はI1/D1 - I4/D4およびI5/ADR*とI6/JCに命令を与えるべきかデータなどを与えるべきかを指示する出力信号です。
R/W*信号はOUT命令などで外部メモリやレジスタにデータを書き込むタイミングでLパルスを出力する出力信号です。
I6/JC信号は入力信号で、ISEL信号によって命令のMSBを読み込むかTJC命令の分岐条件を読み込むかが決まります。
I5/ADR*信号も入力信号で、ISEL信号によって命令の第5ビットないしAIN命令に対するデータ準備完了ステータスが読み込まれます。
I4/D4 - I1/D1信号は同じくISEL信号によって命令かデータのどちらかが読み込まれる入力信号です。
DA4 - DA1信号は出力信号で、デジットアドレスの意味です。AIN, IN, OUT命令の時に、データの桁アドレスを出力します。
DAS*信号はデジットアドレスストローブで、DA4 - DA1信号が有効であることを意味します。
DO4 - DO1はOUT命令のときにデータが出力されます。
F1とF2は命令でパルス出力を自由に出すことができるフラグ出力です。
ERROR信号は演算エラーのときセットされ、ECLR命令でリセットされるエラー出力です。
D4 - D1信号やDO4 - DO1信号で入出力されるデータはBCDデータで、命令に応じて入出力が行われます。命令は、CPUの出力ポートからRDY信号とHOLD信号でタイミングを作成して与えることもできますし、MM57109外部に用意したプログラムカウンタによって自動的にメモリから読み込むこともできます。プログラムカウンタを用意すれば、条件分岐命令なども使えて、複雑な計算をCPUを介さずに自動実行することすら可能ですが、その分岐命令時のアドレスを与える回路などもすべて外部で用意しなくてはならず、かなり複雑な外部回路が必要となります。また、CPUがいちいち制御するにしても、単なる数値の入力だけで4
msくらい必要になったりして、タイミングが中途半端に遅くてプログラムを組みにくかったりします。よくあるパターンだと、命令については出力ポートからCPUがタイミングをとって与えるけれども、数値の入出力については外部に小容量のメモリを用意して、そこからMM57109が自分で読み込んだり逆に書き込んだりできるようにして、演算や入出力が終わったタイミングで割り込みを要求するようなインターフェース法が使われます。
入出力がBCDデータというのも特徴的で、サイズは大きくなりますが、演算結果をLEDや端末へ出力するのには便利です。なお演算の有効数字は8桁で、さらに指数部はBCDで2桁分。まさに関数電卓的なLSIです。
内部レジスタとして、演算データを格納する内部スタックとしてX, Y, Z, Tの4個のレジスタがあります。スタックトップがXで、スタックの底がTとなっていて、一般の2項演算命令ではXとYの二つをポップして演算を行い、結果をXにプッシュしなおすことになります。そのとき、1レベルだけスタックの深さが変化しますから、Tレジスタには0が入ります。このほかにMレジスタがあって、関数電卓の「メモリ」と同じように使えます。スタックに対して演算を行いますから、ちょうど逆ポーランド式入力の電卓と同じ形の命令体系ですね。
次は命令についてですけど、大きく分けると、置数入力、移動、数学演算、クリア、分岐、入出力、モード制御の7種類に分類できます。
まずは置数入力命令。
Mnemonic code 実行時間 動作
0 00
/238 数値入力0。最初の桁が入力されたときにスタックプッシュが行われる。
1 01
/238 数値入力1。2桁目からはプッシュ動作はせずにXの数値が一桁上位にシフト
2 02
/238 数値入力2。されてから、その新たな最下位桁に追加される。
3 03
/238 数値入力3。
4 04
/238 数値入力4。
5 05
/238 数値入力5。
6 06
/238 数値入力6。
7 07
/238 数値入力7。
8 10
/238 数値入力8。
9 11
/238 数値入力9。
DP 12
/152 Decimal Point, 小数点入力。
EE 13
/151 Enter Exponent, 指数部入力指示。
CS 14
/166 Change Sign, 仮数部ないし指数部の符号を変更する。
PI 15
/1312 Constant pi, 3.1415927 -> X, スタックはプッシュされない。
EN 41
/552 Enter, 数値入力後処理を行い、次の数値入力の準備を行う。
NOP 77
/122 No Operation, 数値入力後処理のみ行う。
HALT 17
/134 Halt, RDY = 1としHOLD = 1を待つ。NOPと同動作だが入力後処理を行わない。
Mnemonicは命令ニーモニックを意味し、codeの欄にはI6 - I1に与えるべき命令コードを8進数で書いてあります。実行時間は命令実行に必要な平均マイクロサイクル数と最大マイクロサイクル数を平均/最大の形で記入してあります。前述のように400
kHzクロック周波数のとき1マイクロサイクルは10 usですから、大まかに命令実行時間がわかります。
このグループは、最初は把握しにくいですが、要は電卓のキーをたたく動作とまったく同じ動作を行うようになっています。
0 - 9, DP, PI命令が最初に実行されるとスタックが1レベル移動して、空になったスタックトップのXレジスタに数値が入れられます。そのあとで続けて0
- 9, DP, PI命令などが実行されると、スタック操作は行われずにXレジスタの数値が変化します。すると、23を入力するときと、2と3の二つの数値を入力するときにはどうするかという問題が生じますが、その場合には二つの数値の区切りとしてEN命令を実行します。EN命令では数値を内部形式に正規化するとともに、スタック操作をあらかじめ行ってしまいます。したがって、EN命令の直後に0
- 9などの命令を実行すると、スタック操作を行いません。スタック操作を一切行いたくない場合はEN命令の代わりにNOP命令を利用します。HALT命令は実際には何も行わない命令で、たとえば1
HALT 3の順に命令を実行しても13という数値がXレジスタに入ります。
なお、たとえば最初の数値入力で行われるスタック操作などの前処理には、上記の表で示した以外にさらに多くのマイクロサイクルが必要とされます。
移動関係の命令には次のものがあります。
Mnemonic code 実行時間 動作
ROLL 43
/905 スタックの内容を回転する。X -> T, T -> Z, Z -> Y, Y ->
X
POP 56
/448 スタックポップ。Y -> X, Z -> Y, T -> Z, 0 -> T
XEY 60
/652 X exchange Y, X <-> Y
XEM 33
/812 X exchange M, X <-> M
MS 34
/839 Memory Store, X -> M
MR 35
/1385 Memory Recall, M -> X
LSH 36
/168 Left Shift, 仮数部を1桁だけ左にシフトする。
RSH 37
/173 Right Shift, 仮数部を1桁だけ右にシフトする。
まぁ、特に解説もいらないでしょう。
数学演算命令はMM57109の目的ともいえるもので、四則演算から関数までそれなりに充実しています。
Mnemonic code 実行時間 動作
+ 71
2200/6600 X + Y -> X, スタックはZ -> Y, T -> Z, 0 -> Tとなる。
- 72
2200/6600 X - Y -> X, スタックはZ -> Y, T -> Z, 0 -> Tとなる。
* 73
3200/22700 X * Y -> X, スタックはZ -> Y, T -> Z, 0 -> Tとなる。
/ 74
7800/22300 X / Y -> X, スタックはZ -> Y, T -> Z, 0 -> Tとなる。
YX 79 55400/99500
X**Y -> X, スタックはZ -> Y, T -> Z, 0 -> Tとなる。
INV + 40 71 1700/5500 M + X -> M
INV - 40 72 1700/5500 M - X -> M
INV * 40 73 2700/21400 M * X -> M
INV / 40 74 7300/21100 M / X -> M
1/X 67 4500/22800
1 / X -> X
SQRT 64 7000/30200 Square
root, SQRT(X) -> X
SQ 63 3000/21900
Square, X**2 -> X
10X 62 27400/96500 Ten
to X, 10**X -> X
EX 61 30800/93900
E to X, Exp(X) -> X
LN 65 24800/92000
Natural log of X, ln(X) -> X
LOG 66 30700/92600 Base
10 log of X, log(X) -> X
SIN 44 56200/95900 Sine
X, sin(X) -> X
COS 45 56200/95900 Cosine
X, cos(X) -> X
TAN 46 35000/97600 Tangent
X, tan(X) -> X
INV SIN 40 44 54000/93900 Inverse Sine X, Asin(X) -> X
INV COS 40 45 54000/93900 Inverse Cosine X, Acos(X) -> X
INV TAN 40 46 30200/92900 Inverse Tangent X, Atan(X) -> X
DTR 55 9600/41700
Degrees to Radians, 角度を度からラジアンに変換。
RTD 54 9600/41700
Radians to Degrees, 角度をラジアンから度に変換。
四則演算はスタックトップへの操作のほかにメモリとの四則演算も用意されています。まさにメモリは関数電卓のメモリの役目を果たしています。ニーモニックにも注目してほしいのですが、メモリへの四則演算はINVというものが
前置されています。後の方のINV SIN命令なんかでもわかるように、このINVというのは関数電卓にありがちなINVキーと同じもので、特殊な操作であることを示す前置コードになっているわけです。コードのほうを見ると、INV部分が40に対応していることがわかります。40
71などの40が前置された命令は2 Byte命令になります。
それにしても、乗算で最悪22700マイクロサイクル、つまり0.2秒以上、初等関数の場合には最悪で1秒弱の計算時間が必要になるというのは、あまりに遅いと感じられるかもしれません。8
bitマイクロプロセッサのソフトウェアによる浮動小数点演算より1桁くらいは遅い計算速度です。内部は一種のp-MOSプロセス低速低機能プロセッサのマイクロプログラム制御によるソフトウェア処理ですから、普通のマイクロプロセッサより遅くなってもしかたありません。まぁ、当時の関数電卓用LSIの演算性能も似たりよったりでした。=キーを押してから表示まで1秒くらいかかっても、関数電卓なら気にもならない時間です。しかし、たとえばある計算のために四則演算が10回程度に三角関数計算が3回ほど必要だとしたら、5秒くらい待たされてしまうかもしれません。そんなとき、ユーザがコンピュータも頑張っているなぁと感心している人ばかりならかまいませんが、そんな人でもじきに不満に思うようになりそうです。とはいえ、このMM57109が使われていた1970年代後半ではEPROMが2
KByte分で1 - 2万円くらいしていたうえに、組み込み用機器のプログラミングを浮動小数点演算が自由に使えるコンパイラで行うこともできないような時期でしたから、数千円で購入できたMM57109は結構便利に使えたりしたのです。まさに関数電卓並みの速度で、比較的単純な計算しかしないのなら、プログラマブルな電卓を利用すればよさそうですが、関数電卓にセンサ類をインターフェースしたりはできませんから、低速でもかまわない計測機器や自動制御装置で、センサの値をなんらかの数式で補正して表示したり、その補正結果をもとに制御を行うような場合、MM57109はそれなりに便利に使えます。同時期にAm9511という、8
bitプロセッサのソフトウェア演算よりは一桁高速に演算を行う浮動小数点演算LSIもありましたが、価格もMM57109より一桁は高価なので、本当に高速演算が必要な用途以外にはおいそれと採用できません。関数電卓用LSIと同程度の性能ではあっても、関数電卓用LSIに近い価格で入手できる利点はあなどれません。それにしても、実行時間の項にこれだけ桁の多い数字の並ぶのも珍しいかもしれませんね。繰り返しになりますが、400
kHzクロックのとき実行時間の項の単位は10 usとなります。
クリア命令には次の2種類があります。
Mnemonic code 実行時間 動作
MCLR 57
/734 Master Clear, 前レジスタの初期化および有効数字8桁の浮動小数点モードに設定。
ECLR 53
/163 Error Clear, エラーフラグのクリア。
MCLR命令はパワーオンリセットと同じことを行う命令です。あとは自明ですね。
XやMの内容だけをクリアする命令は存在しません。それも後述のIN命令などで0をXに入力したり、あるいはPOP命令でXの内容を捨てることによって代用できるでしょう。
分岐命令については次のものがあります。
Mnemonic code 実行時間 動作
JMP 25 xx
/186 Jump, 2 Byte目のアドレスにジャンプする。
TJC 20 xx
/208 Test Jump Condition, JC = 1のときにジャンプする。
TERR 24 xx /191
Test Error, エラーフラグがセットされているとジャンプする。
TX=0 21 xx /278
Test X = 0, X = 0ならジャンプする。
TXF 23 xx
/277 Test |x| < 1, abs(x) < 1ならジャンプする。
TXLT0 22 xx /197
Test X < 0, xが負の数ならジャンプする。
IBNZ 31 xx /2314
Increment memory and Branch if M != 0, Mをインクリメントして0以外なら分岐する。
IBNZ 32 xx /2314
Decrement memory and Branch if M != 0, Mをデクリメントして0以外なら分岐する。
これらの分岐命令はすべて2 Byte命令で、2 Byte目にジャンプ先アドレスを指定します。しかし、2
Byte目はMM57109によって読み出されても、MM57109自身は利用しません。ちょうど、2
Byte目のデータを読み出しているタイミングで、分岐する場合に限ってBR*パルスを出力しますから、そのBR*パルスを利用して外部プログラムカウンタにデータをロードすることによって分岐命令の機能を実現します。逆にいえば、プログラムカウンタをMM57109外部に用意したインターフェース以外の、メインのCPUのI/Oポートから直接MM57109を操作したりするインターフェースの場合には、ほとんど役に立ちません。もちろん、その場合でもBR*パルスをメインのプロセッサの割り込み信号などに使用すれば、条件成立によってプロセッサに割り込みをかけることも可能ですけど。
入出力命令には次の命令があります。
Mnemonic code 実行時間 動作
IN 27
/395 Multi-digit input to X, Xに数値を入力する。スタックはプッシュされる。
OUT 26
/583 Multi-digit output from X, Xの内容を出力する。
AIN 16
/284 Asynchronous Input, 1桁ずつ読み込む。
SF1 47
/163 Set Flag 1, F1に1を出力。
PF1 50
/185 Pulse Flag 1, F1に1パルスを出力、すでに1のときは0を出力。
SF2 51
/163 Set Flag 2, F2に1を出力。
PF2 52
/185 Pulse Flag 2, F2に1パルスを出力、すでに1のときは0を出力。
PRW1 75
/130 Pulse R/W* 1, R/W*に0パルスを出力。
PRW2 76
/130 Pulse R/W* 2, R/W*に0パルスを出力。
置数関係の命令では1桁ずつ電卓のキーを押すのと同じようにして数値を入力していましたが、メインのCPUから数値を与えるためには不便です。やはりひとまとまりの数値を一度に与えたいわけで、そのための命令がIN命令です。IN命令を実行すると、特定のタイミングで数値の各桁を入力するように信号が出力されます。それに合わせてCPUからデータを順番に与えたり、メインのCPUとMM57109とのローカルな共有メモリを用意しておいてそこから自動的にMM57109が読み込むような外部回路を付加させることもできます。
IN命令の逆がOUT命令です。
また、置数命令で1桁ごとに数値を入力するのと同じように、1桁ずつデータとして数値を与える命令がAIN命令です。
その他、MM57109の特定の端子を操作するための命令も、このグループに含まれています。
モード制御命令には次の3種類があります。
Mnemonic code 実行時間 動作
TOGM 42
/157 Toggle Mode, 浮動小数点とEタイプの間のモード切り替え。
SMDC 30 xx /163
Set Mantissa Digit Count, 仮数部の有効桁数を指定する。
INV 40
/166 Inverse Mode, INV命令を構成する。
IN命令やOUT命令で使用される入出力データフォーマットには、浮動小数点タイプとEタイプの2種類があります。そのどちらを使うか指示するのがTOGM命令です。なお、リセット時ないしMCLR命令後には、浮動小数点タイプを利用するモードになります。
SMDCは2 Byte目で仮数部の有効桁数を指示します。1から8までの値を指示できます。リセット後ないしMCLR命令後には8桁まで有効という設定になります。
INV命令はINV SIN命令とかINV +命令に使われているプリフィックス命令ですね。
入出力に使われるデータ形式には浮動小数点タイプとEタイプがあります。その形式について、それぞれ説明します。
浮動小数点タイプはこのような入出力形式となります。
DA4 - DA1 | 小数点位置 | D4/DO4 D3/DO3 D2/DO2 D1/DO1 |
2 | S 0 0 0 | |
3 | 小数点位置 | |
4 | 11 | 最上位桁 |
5 | 10 | ... |
... | ... | ... |
MDC + 3 | 12 - MDC | 最下位桁 |
この表の上から下へ入出力が行われます。DA4 - DA1は、IN/OUT命令実行時にMM57109が出力する桁アドレス信号で、何番目のデータを入出力しているか外部に通知する信号を10
進数表示してあります。MDCはSMDC命令で指定される有効桁数で、通常は8です。Sは数値の符号ビットで0が正、1が負を意味します。
IN命令による入力時には、D4 - D1端子から、まず符号ビットを含む4 bitデータが読み込まれ、次に小数点位置が読み込まれます。小数点位置は10進数で4から11までの範囲の値を指定でき、表の第2列目に記入されている値と同じ数が入っている欄の桁と次の桁の間に小数点があると解釈されます。つまり小数点位置が11で最上位桁のデータが1、次の桁のデータが0だとすると、1.0xxxxxxという場所に小数点があると解釈されます。最上位桁からMDC個数分の4
bit BCD表示のデータが読み込まれて、数値がMM57109内部で組み立てられます。
OUT命令の場合には、データがDO4 - DO1端子から出力されることを除いて、IN命令と同じように出力が行われます。
Eタイプはこのようになっています。
DA4 - DA1 | D4/DO4 D3/DO3 D2/DO2 D1/DO1 |
0 | 指数部上位桁 |
1 | 指数部下位桁 |
2 | Sm 0 0 Se |
3 | - - - - |
4 | 最上位桁(小数点はこの直後) |
5 | ... |
... | ... |
MDC + 3 | 最下位桁 |
ここでSmは仮数部の符号、Seは指数部の符号で、ともに0が正、1が負を意味します。第4語目は無視されます。
指数部も仮数部も、すべてBCD表示のデータとして扱われます。
このように、どちらのデータ形式もBCD表示を基本にしているので、非常に簡単にLEDに数値を表示したり、文字コードに変換して入出力を行うことができます。反面、A/D,
D/Aコンバータを用いて外部の何かを制御するための関数計算に利用しようとすると、BCDコード入出力のA/D,
D/Aコンバータは種類が少なく価格が高めなこともありますし、少し余計な手間かコストが必要となります。
Return to IC Collection