i8080のDAA回路について
8080のDAAについては、きちんと説明された資料が無い。また、インテルとNECではDAA実行後のAC(Auxiliary Carry またはハーフキャリーとも言う)の挙動に違いがあり、非互換部分と言われている。DAA命令の動作の詳細と共に、この非互換部分について考察する。
DAA
DAA命令は、直前のADD、INCなどの加算の結果をPackedBCD補正する。
以下、Accの下位4ビットを下位桁、上位4ビットを上位桁と呼ぶ。
※直前の演算はADD、ADC、INR Aなど、加算であればよいが、加算する数値それぞれがPackedBCDとして適切な内容である必要がある。
動作は次の通り
1.DAA命令実行前にACが立っているか、又はAcc(アキュムレータ)の下位4ビット(下位桁)が0xA~0xFの場合Accに0x06を加算する。
2.その後CY(キャリー)が立っているか、又は上位4ビット(上位桁)が0xA~0xFの場合Accに0x60を加算し、CYを立てる。
解説
DAAの前にACが立っている時、下位桁同士の加算の結果は10進で16~19(最大で9+9+CY=19、ADCの場合)なので、Accの下位桁は0~3になっているはずである。つまり下位桁同士の加算の結果が16進で0x10~0x13だった事を示している。下位桁から上位桁への桁あふれがあったからACが立っているのである。これをPackedBCDに補正するためにAccに0x06を足す。
ACが立っていない時も、下位桁が0xA~0xF(10進で10~15)なら同様にAccに0x06を足す。
この時にAccが桁あふれしたらCYを立てる。桁あふれが無かったらCYはそのまま変更しない。
下位桁の補正の結果、上位桁が0xA~0xFか、またはCYが立っている場合Accに0x60を足して補正する。
補正をしたらCYを立てる。
※ 例えば0x99+0x61の場合、加算結果は0xFA(CY=0)になるが、下位桁のみ補正した場合Accが0x00になってCYが立つ。その後上位桁補正時はCYが立っているから補正されてAccが0x60でCY=1、つまり0x160になる。
DAA実行前にACが落ちていて、かつ下位桁が10進で10~15の時は6を足す事により下位桁を0~5にして、上位桁に桁上がり(Accの補正時の下位桁→上位桁の桁上がりがあったという事)を伝える。そのためにAccに8ビットの0x06を足すのである。これを下位4ビットに0x6を足すように表現している解説もあるが、ACやCYの変化も考えるとAccに0x06を足すのが正解。
※ DAA実行前にACが立っている時は、下位桁の補正によって上位桁への桁上がりが発生する事はない。ACが立っているという事は直前の加算の結果下位桁は0~3になっているはずだから。
この時の桁上がりをDAA実行後にACに反映するかどうかがNECとインテルの非互換の部分である。
上位桁の補正が必要かどうかは、下位桁の補正の結果で判定する。補正が必要という事は上位桁が10~15か、16~19(つまり0~3でCYが立っているという事)だという意味なので、どちらにしてもキャリーを立てる必要がある。
補正をしなかった場合はキャリーを保存するが、補正の必要が無かったという事はキャリーは立っていなかったという事なので、補正しなかった場合はキャリーをいじる必要は無い。
直前の加算でCYが立っている場合というのは、例えば0x90+0x90で結果0x20+CYなどの場合なので、補正した結果0x80+CY、つまり0x180になる。90+90=180なので、これでPackedBCDとして正しい。
回路
i8080のDAA命令は、実行が4サイクル。最初の3サイクルは命令フェッチとデコードなので、1サイクルで処理しなくてはいけない。という事は途中経過をラッチするタイミングが無い。これを踏まえると以下のような回路になると思われる。
DAA部分の回路
入力はAccとAC、CYの10ビット。出力はAccに書き戻す値とCY補正後のAC。この補正後のACはインテル版は書き戻しているが、NEC版は書き戻していないと思われる。
まごころせいじつ堂「NEC uPD8080AのDAA命令調査 ADD編」
上位桁の補正が必要かどうか、下位桁からの桁上がりも含めて、Accからの入力から求めているので、INC部分の遅延が問題にならないようにしてある。
ADD6
6を加算する回路。一般に定数の加算回路は通常の加算回路よりも規模が小さくなる。入力に加算する/しない信号があり、加算しない場合入力をそのまま出力する。
INC
下位の補正の結果ビット3→ビット4に桁上がりが発生したときに、上位桁にそれを加えるための回路。
上記LogoSimドキュメントはDAA.circから右クリックで保存してください。
