2019年01月
前回のADD編の続き。
μPD8080Aは減算後の十進補正も正しく動作する、ということなので確認。
chkbcdsub.awk
$1 ~ /[0-9][0-9][0-9][0-9]/ {a=substr($1,1,2)b=substr($1,3,2)if (b>a) a=a+100c=a-bif (c!=($4-0)) print $0}
入力データの1カラム目は4桁の16進数で、前2桁から後ろ2桁で減算を行う。その結果を十進補正したものが4カラム目。このスクリプトはこの減算を行い、十進補正値と比較して異なれば出力する。
Intelの8080だと00〜99 - 00〜99の全組み合わせ10000通りですべてエラー。例えば:
0000 00 *Z*H*P** 06 *****P**
0001 FF S****P*C 65 ***H*P*C
...
とこのような感じで1行目は減算時のハーフフラグの立ち方がおかしく、よけいな補正をしている。2行目は"F"から補正値6を引かないといけないところを加算している。ということで減算時の補正についてはまったく考慮していない。
NECのμPD8080AではSUB命令の後の補正後の値はすべて正しかった。ところで十進補正の補正値である"6"をDAA命令で足すのか引くのかはどうやっているのだろうか。おそらくDAA命令の直前に実行した演算命令がADDなら加算、SUBなら減算にしているはずで、もしかしたら未定義のフラグを使っているのか。ここは気になる点。
※8086だとDAA命令とDAS命令でそれぞれ加算後十進補正、減算後十進補正と命令が別れている。
さてここまでやって1加算するINR命令と1減算するDCR命令ではどうだろうか。これも確認してみた。
ADD 1とINR、SUB 1とDCRの比較結果はこちら:
Intel 8080の結果は以下の部分が異なる。2〜5カラム目がADD 1の結果、6〜9カラム目がINRの結果。
INR:
FF01 00 *Z*H*P*C 66 *****P*C 00 *Z*H*P** 06 *****P**
これは値が範囲外、かつキャリーフラグがINRでは立たないので補正されていない。問題なし。
DCR:
0001 FF S****P*C 65 ***H*P*C FF S****P** 65 ***H*P*C
そもそもSUB後のDAAは保証外、値が範囲外、INRでキャリーが立たない。問題なし。
NEC μPD8080Aの結果。
INR:
0F01 10 ***H**** 16 ***H**** 10 ******** 10 ********1F01 20 ***H**** 26 ***H**** 20 ******** 20 ********
2F01 30 ***H*P** 36 ***H*P** 30 *****P** 30 *****P**
3F01 40 ***H**** 46 ***H**** 40 ******** 40 ********
4F01 50 ***H*P** 56 ***H*P** 50 *****P** 50 *****P**
5F01 60 ***H*P** 66 ***H*P** 60 *****P** 60 *****P**
6F01 70 ***H**** 76 ***H**** 70 ******** 70 ********
7F01 80 S**H**** 86 S**H**** 80 S******* 80 S*******
8F01 90 S**H*P** 96 S**H*P** 90 S****P** 90 S****P**
9F01 A0 S**H*P** 06 ***H*P*C A0 S****P** 00 *Z***P*C
AF01 B0 S**H**** 16 ***H***C B0 S******* 10 *******C
BF01 C0 S**H*P** 26 ***H***C C0 S****P** 20 *******C
CF01 D0 S**H**** 36 ***H*P*C D0 S******* 30 *****P*C
DF01 E0 S**H**** 46 ***H***C E0 S******* 40 *******C
EF01 F0 S**H*P** 56 ***H*P*C F0 S****P** 50 *****P*C
0F01 10 ***H**** 16 ***H**** 10 ******** 10 ********
値が範囲外なので問題なし。
DCR:
0001 FF S**H*P*C 99 S**H*P*C FF S****P** FF S****P**
1001 0F ***H*P** 09 ***H*P** 0F *****P** 0F *****P**
2001 1F ***H**** 19 ***H**** 1F ******** 1F ********
3001 2F ***H**** 29 ***H**** 2F ******** 2F ********
4001 3F ***H*P** 39 ***H*P** 3F *****P** 3F *****P**
5001 4F ***H**** 49 ***H**** 4F ******** 4F ********
6001 5F ***H*P** 59 ***H*P** 5F *****P** 5F *****P**
7001 6F ***H*P** 69 ***H*P** 6F *****P** 6F *****P**
8001 7F ***H**** 79 ***H**** 7F ******** 7F ********
9001 8F S**H**** 89 S**H**** 8F S******* 8F S*******
A001 9F S**H*P** 99 S**H*P** 9F S****P** 9F S****P**
B001 AF S**H*P** A9 S**H*P** AF S****P** AF S****P**
C001 BF S**H**** B9 S**H**** BF S******* BF S*******
D001 CF S**H*P** C9 S**H*P** CF S****P** CF S****P**
E001 DF S**H**** D9 S**H**** DF S******* DF S*******
F001 EF S**H**** E9 S**H**** EF S******* EF S*******
00-01から90-01はBCD演算の対象。DCRでハーフキャリーが立っていないのでDAA補正が正しくない。ということはBCDの範囲内ならINR後DAAはIntel、NECとも正常動作する。DCR後DAAはIntelは保証外、NECは被減数が00,10,20,30,40,50,60,70,80,90でDCR後DAAで誤動作する。
惜しい。NEC μPD8080Aの減算後DAAではINRで正常動作するつもりでDCRを使うとハマるんじゃなかろうか。
INR/DCRではキャリーフラグは立たない。フラグのうちS/Z/Pは結果だけから求められるが、CY/ACは演算の種類と値によって決まる。INR/DCRはALUの加減算器のパスを通ってない感じがする。
残りは8085やZ80との比較かな。
おまけ:チェコスロバキアから届いたTESLA MHB8080A動きました。
MHB8080ACデータシート

インテル8080伝説

前回の SBC8080システムROMでBASICから機械語を呼び出す で実チップのテスト環境が整ったので以前から気になっていたIntel 8080とNEC μPD8080Aの非互換部分についての調査を行った。
NEC μPD8080AはIntel 8080のクローンではなく独自に改良し、DAA命令(十進補正命令)の減算対応、実行クロック数の改善がなされた。が、せっかく改善したのに非互換部分が嫌われ完全互換のμPD8080AFに切り替わった。
MCS-80(IC Collection)
まずDAA命令の動作について。DAA十進補正命令はハーフキャリーを参照する。
Auxiliary Carry: If the instruction caused a carry out of bit 3 and into bit 4 of the resulting value, the auxiliary carry is set; otherwise it is reset. This flag is affected by single precision additions, subtractions, increments, decrements, comparisons, and logical operations, but is principally used with additions and increments preceding a DAA (Decimal Adjust Accumulator) instruction
FLAGレジスタのbit4はACフラグ(またはHフラグ ハーフキャリー)で加算時のbit3からbit4への桁上げで立つ。このフラグは加減算/INC/DEC/比較/論理演算で変化するが主に加算とINCの後のDAA命令で使う、とある。
DAA命令の記述。

DAA命令は直前のADD命令について、BCD表現の数値を加算したものとして補正を行う。例えば04H+06Hは0AHだけどこれを10Hに修正する。その手順は以下のとおり:
(1) 下の桁がA-Fになっている、またはハーフキャリーが立っていれば6Hを加算する。
(2) (1)の後、上の桁がA-Fになっていればキャリーフラグを立て60Hを加算する。
もっと詳しい実装の解説はこちら:
ではデータを採取して比較を行う。コードは前回を参照。テスト結果は1バイトの十進数で
数値A 数値B A+Bの結果 加算後フラグ DAA補正後の結果 補正後フラグ
このデータが256×256パターンで65536行。このデータを適当なunix環境に持っていってawkで処理。Excelでもなんでもいいです。
まずは16進に変換。数値Aと数値Bは連結してインデックスとして使えるようにする。フラグは2進数表示。こんな感じになる。
0000 00 01000110 00 01000110
0001 01 00000010 01 00000010
0002 02 00000010 02 00000010
0003 03 00000110 03 00000110
...
あとは任意のフィールドを切り出して比較していくだけ。
対象となるCPUは以下:
(1) INTEL MD8080 A/B インテル純正の安心感。すべての比較元とします

(2) CCCP KP580BM80 (USSR KR580VM80) ソ連製8080クローン

(3) CCCP KP580BM80A (USSR KR580VM80A) ソ連製8080Aクローン

(4) NEC μPD8080A 今回の主な調査対象

(5) NEC μPD8080A-T -Tサフィックスはなんだろう?

(6) NEC μPD8080AFC Intel 8080A完全互換にしたもの

テスト結果:(HフラグはACフラグと読み替えて)
a. 加減算後のDAAについて
(1) (2) (3) (6) はまったく同じ。DAA動作は完全互換
(4) (5) はまったく同じ。NEC μPD8080AとμPD8080A-Tは同じもの
b.加算後のDAAについて(1)と(4)を比較
・演算結果の数値は一致
・フラグが異なる
・NEC μPD8080Aは未定義フラグbit3が常に"1"。INTEL 8080Aは常に"0"
・NEC μPD8080AはDAA命令の前後でHフラグの状態は変わらない
・INTEL 8080AのDAA命令前後でのHフラグの動作:
DAA前にHフラグが立っているとDAA後にHフラグは落ちる
DAA前にHフラグが落ちているとDAA後に補正前の演算結果の下1桁がA~Fだった場合に立つ
DAA補正後のHフラグに関しては定義されていないのでこれらは未定義動作として済ませるんですが、続きがあります。
Dr.Dobb's Journal 1976/11/12 によると"IMSAI INCOMPATIBILITY"というのでNEC製8080Aの挙動についてメーカーに質問が出ている。本来 XRA Aの後にDAAはやらないんだけどやってみたら結果が0のはずが6になっている。これって十進補正をやっているように見えますね。
確認コードはこちら:
ここでIntelのユーザーズマニュアルでXRA命令を確認してみる。

XRA命令実行後にAC(ハーフキャリー)はクリアされると書いてあるが、NEC μPD8080Aではクリアされずにセットされたままになっている。この部分は未定義ではないのでIntel 8080とNEC 8080Aの非互換部分と言える。これはXRA命令の実装でACフラグを操作するパスがなさそうに見える。さらに想像するとNEC 8080AではANA以外の論理演算命令ではACフラグは変化しないのかもしれない。
※追記 XRAをANA/ORA命令に替えて実験
ANA命令 Intel 8080でACフラグクリア 仕様書の誤記?
ORA命令 Intel 8080でACフラグクリア
NEC 8080AではANA/ORAともACはクリアされずそのまま
SUB後のDAA命令編に続く
SBC8080ルーズキット用のSBC8080システムROMは電脳伝説(@vintagechips)さんの手によりPALO ALTO BASICに独自の機械語モニタを拡張してあり一行アセンブラが使えて大変便利。MONでモニタにはいりSYSTEMでBASICプロンプトに戻る。EXEC 番地で番地+8000Hに飛んでRET命令でプログラムに戻ってこれるのだけれどもPEEK/POKEがないのでパラメータのやりとりがそのままではできない。
そこでSBC8080技術資料の記述からPALO ALTO BASICの資料をたどって調べてみた。
SBC8080システムROM(電脳伝説)
Astrocade Machine Language Source Code Palo Alto Tiny BASIC, Version 3 よりPDFを取得
TINY BASICなので変数名はA〜Zのみ、@は配列。BASIC変数/バッファ領域はSBC8080システムROMの場合F000HからF087Hまで。適当に変数Aに代入してMONで覗いてみると値が変化しているところがある。調べた結果、
F002H 変数A
F004H 変数B
F006H 変数C
F008H 変数D
F00AH 変数E
F00CH 変数F
...となっていた。数値は2バイトでリトルエンディアン。ということはここを機械語とのパラメータ受け渡しに使える。
実際に作ってみた例はこちら:TeraTermに送信するときは設定(S)→シリアルポート(E)... で送信遅延を10ミリ秒/字 100ミリ秒/行にするのを忘れずに。
これは十進補正命令DAAの動作を確認するテスト。変数Aと変数Bの値を加算し結果を変数C、フラグを変数Dに格納。その後DAA命令を実行し、結果を変数E、フラグを変数Fに格納する。いずれも下位1バイトしか使わない。8080アセンブラで初めて書いたのでみてみて。
8000 LXI D,F002 変数AへのポインタDE 8003 LXI H,F004 変数BへのポインタHL 8006 LXI B,0000 BC←0 これはAFのクリア用 8009 PUSH B 800A POP PSW AFクリア 800B LDAX D Accに変数Aの内容をコピー 800C ADD M Acc ← Acc + 変数B 800D PUSH PSW いったん結果を保存 800E DAA 十進補正 800F PUSH PSW 8010 POP B AFのペアをBCにコピー 8011 MOV A,B 8012 STA F00A 変数Eに十進補正後の結果を返す 8015 MOV A,C 8016 STA F00C 変数Fに十進補正後のフラグを返す 8019 POP B 801A MOV A,B 変数Cに補正前の結果を返す 801B STA F006 801E MOV A,C 801F STA F008 変数Dに補正前のフラグを返す 8022 RETこれをBASIC側から変数Aと変数Bを0〜255の範囲で変化させてEXEC 0で呼び出し、結果を含めて画面出力するだけ。文字出力はBASIC内のサブルーチンを呼び出せばできそうだったが手を抜いてBASIC側でやった。ループも同様。どのみち9600bpsの端末への出力なのでいくら高速化してもそこで律速となる。
なんでこれを作ったかというとIntel純正8080に対してNEC 8080Aは独自改良でDAA命令を修正したが、非互換ということでNEC 8080AFでIntelとまったく同じ動作に戻したという話があったので調べてみようと思ったからだ。次回お楽しみに。
前回の続き。
さて、KP580BM80Aの動作が怪しいので確認用にebayでもう1個購入。2週間程度で届いた。
マークが{S}みたいなのは製造元(工場?)が異なるため。
で、問題なく動作。ということはKP580BM80Aは個別故障ということになる。
PALO ALTO BASICで5.09V/0.51A、BASICでA=A+1しながら数字を表示するループ実行で0.53A。電圧高めなのはスマホ用のUSB電源アダプタを適当に使ったせい。
これでおしまい、でも良かったのだけれどももうちょっとだけ調査。
割り込みの観測のため8080のINTE(pin16)にLEDを追加。電流制限抵抗は大きめ(8.2kΩ)にしたので駆動力ヨワヨワの8080でも問題ないでしょう。
INTEは故障と思われるKP580BM80Aでもリセット後は点灯。ただし端末側のキーを押してINTを発生させるとLEDで消え、画面に連続した文字は出なくなる。つまりPALO ALTO BASICのROMで割り込みを受けるまでは画面に連続して文字が出ているので、CPUはなにかしらの命令を実行しているのだが、どこかで暴走しループしているように見える。

故障箇所は前回の調査でわかった「INT信号で割り込みが発生し割り込みがマスクされるが38Hには飛んでいない」以外にもあり特定の命令の実行またはジャンプ先が変わるような動作でおかしくなっているようだ。少なくとも00HのNOP連続による動作はできた。
横井与次郎著 マイクロコンピュータ・ハードウェア基礎技術 のp.156にある3.1.3 8080Aの絶対最大定格によると-5V側の電流は1μA〜1mAとあるが、ここの電圧が0Vだと+5V/+12Vの電流が非常に大きくなるので長時間-5Vを与えない状態で使うのはしてはいけないと書いてある。ということは何らかの原因で-5Vが印加されなくなったら動くことは動くけれども発熱で8080が故障するのであろうか。
まあ良品を壊してまで調べようとは思わないので故障調査はこれでおしまい。ということでソ連製の8080クローンでもSBC8080は動作します。
SBC8080ボードができたので手持ちのコレクションについて動作確認。
まずはソ連製の8080クローン、580GF24(8224)/580BK38(8238)/580BM80(8080)。
SBC8080+SUBボードで 5.03V 0.31A。PALO ALTO BASIC動作した。
では、CPUを8080AクローンのKP580BM80Aに交換してみる。
すると、このような表示に。最初はカタカナが連続して表示される(途中で繰り返すように見えるのはリセットを1回かけたため)。
これはどういうことだろう。SBC8080ボードではCPUの周りのアドレスバスはHC541×2、データバスと制御信号は8238(8228)でガードされている。ということでまずはアドレスバスを疑いHC541→LS541に交換してみたが現象変わらず。次にデータバスと制御信号について、NEC uPB8228C / NEC uPB8224Cに交換してみたがこれも現象変わらず。
SBC8080ボード用フリーランテストボードで確認してみたが00H(NOP)によるフリーランはできている。
さて、どうしようか。の前にソ連製の8080クローンについて。
USSR 8080 microprocessor family(CPU-World) によると、3種類の8080/8080Aクローンが存在する。
・580VM80 8080のクローン
・KR580IK80A 8080Aのクローン
・KR580VM80A 8080Aのクローン、2.5MHz動作
独自に作られたものもあるようだ。ソ連はずっと8080互換でやってたんだろうか。
・KR580BM1 5V単一電源、5MHz動作、ピン非互換
なおKR580VM80Aはアルファベット表記で、本来は КР580ВМ80А とキリル文字で表記するらしい。キリル文字の方で検索するとロシア語のドキュメントに当たりやすい。
580BM80Aについてはビデオゲームの修理にそのまま交換部品として使われていたりリバースエンジニアリングでVerilogソースまで調べられているので、論理的には同一のはず。
PALO ALTO BASICでは調査も難しいのでもっと簡単なテストプログラムで確認してみる。SBC8080 CPUルーズキットで提供されているSBC8080データパックにある、TEST80というプログラムを使用する。これは8251を使ったエコーバックテスト。で、TEST80.HEXをROMに焼いて電源をいれると580BM80Aではプロンプト">"は出るがエコーバックせず。キーを押しても応答なし。いきなり当たりか?念のためSBC8080SUBボードの82C51を8251に変えてみたが現象変わらず。まあ文字の送信ができているということは8251の初期化はできているっぽい。
端末からデータを受信すると8251はRXRDY信号を上げる。これは8080のINT入力に接続され、RST7割り込みが発生する。TEST80プログラムは割り込み発生後、38H番地からのコードで8251から1文字読んでメモリ上のバッファに書き込み、割り込みを再度許可する。TEST80プログラムはメインルーチンではバッファに何か文字があるとそれを送信し、バッファを空にする。
ということで割り込みの状態を監視してみる。8080のINTE(pin16)を観測。以前作ったロジックチェッカーを使用した。で、NEC 8080Aでの結果はINTEは一瞬LになるがすぐHにもどる。つまり割り込みを受け付けられる状態になる。580BM80Aはリセット直後はINTEはHだが、キー入力があるとLになりそのまま。これ以降は割り込みを受け付けない。
ここからはTEST80にパッチを当てながら確認していく。最初は38HにEI命令を入れてすぐに割り込みを許可するようにした。NEC 8080Aでは連続して割り込みが発生。これは8251の割り込み要因を落としていないので期待通りの動作。580BM80AではINTE信号がH→Lとなりそのまま。
8080は割り込みが発生するといったんINTEをLにする。割り込み処理のプログラムで割り込み要因を落とした後、最後で割り込みを許可する。なので割り込み自体は受け付けている。あとは本当に38H番地に飛んでいるかどうかだ。
さてそれをどう確認するかだが、SBC8080SUBボードにちょっとLEDを追加した。8251のTXRDY端子にLEDカソード側を接続、アノード側をVccへ。これで送信バッファがフル(=1文字送信中)の時に光るはず。
パッチは38H番地にOUT C0Hを書き込む。これはAccにあるダミーデータを1文字送信する。580BM80Aでは一瞬も出なかった。念のためロジックチェッカーで監視しても同じ。つまり38H番地には飛んでいないということになる。
以上から手持ちのKP580BM80Aは
・INT割り込みで割り込みをdisableするが38H番地へは分岐していない。
・別の番地へ飛んでいるのかHALTしているのかはバスの観測が必要。
・CPUの差し替え事例から個別故障の可能性がある。
ということで別に手配したKP580BM80Aを使って確認する予定。
記事検索
最新記事
----------
電子部品通販リストなど
- 秋月電子通商
- マルツパーツ
- 鈴商
- 千石電商
- 若松通商
- サン・エレクトロ
- 共立電子
- DigiKey(日本)
- DigiKey(US)
- チップワンストップ
- RSコンポーネンツ
- Mouser Electronics 電子部品ディストリビュータ
- オリジナルマインド
- 樫木総業株式会社
- アロー電子(水晶)
- マスターエレク株式会社
- ミスミ
- エレポート
- 九州電気株式会社
- 梅澤無線電機株式会社
- ダイセン電子工業
- Elecrow
- ヒューマンデータ
- 妙楽堂電子パーツショップ
- ITショップえとせとら
- DF ROBOT
- E-JUNCTION
- Octpart
- androciti
- ネジクル
- ランニングエレクトロニクス
- ビットトレードワン
- 板金工房
- makebooth
ーーーーーー
- TechShare Store
- 日昇テクノロジー
- きばん本舗
- 部品屋ドットコム
- スイッチサイエンス
- aitendo
- ストロベリー・リナックス
- solitonwave
- エムエーアイ電子
- アイテムラボ 電子キット通販
- 中日電工
- なひたふ電子
- Maker SHED
- NKC Electronics
- メカロボショップ
- アールティロボットショップ
- 赤ふぐ
- アセンブリーデスク
- 楢ノ木技研
- emerge+
- galileo7
- http://www.csun.co.jp/
- Extreme Parts
- HarpyHack(株式会社鳥人間)
- sparkfun electronics
- Bit Trade One Shop
- マイクロファン
- サンハヤト
- シーズンプロショップ
- 電子部品ショップ一覧(NAVERまとめ)
プロフィール
hardyboy
カテゴリ別アーカイブ
月別アーカイブ
タグクラウド
- 32U4
- 6502
- 8080
- 8080A
- 86Duino
- Altera
- Arduino
- ARM
- AVR
- BASIC
- BD
- BeagleBoard-xM
- CADR
- chibi:bit
- CPLD
- CTIA
- Davinci
- DE0
- Digispark
- Energia
- FizzBuzz
- FM-11
- FM77
- FM77AV
- FMTOWNS
- FONTX
- FPGA
- GAL
- Galileo
- GPS
- Grove
- HID
- I2C
- IDE
- Ir
- Keyboard
- KiCad
- Lattice
- LaunchPad
- lcd
- LCD
- LED
- Leonardo
- LM35DZ
- MacOSX
- mbed
- micro:bit
- MSP430
- MSX
- MZ-80C
- OldPC
- OMTP
- PASOPIA
- PASOPIA7
- PC
- PC98
- PCG6500
- PET2001
- PIC12F1822
- PIC32
- PIC32MX
- PIR
- PROM
- PS2
- QuartusII
- RGB
- RJ45
- RTC
- SBC6303
- SBC6800
- SBC8080
- SBCZ8002
- Serial
- SMC-777
- SMI-733
- SORDM5
- SORDm5
- Stellaris
- STM32F4
- TFT
- TRRS
- TRS-80
- USB
- verilog
- VGA
- WindowsXP
- X1
- YIS
- ZX81
- キーボード
- センサ
- データセット
- バレルシフタ
- マイコン
- レトロPC
- レーザーカッター
- ロジアナ
- 修理
- 変換基板
- 治具
QRコード



















