アカウント名:
パスワード:
0~99の数値Aの10での余りは、Aを8での商と余りの二つにわけて、各々の10での余りを加算すればいい A =(A/8)*8 + (A%8) A%10=((A/8)*8)%10 + (A%8)%10 (この加算で10を越えたらもう一度余りを…)
と
DAAでは(ざっくり)0~15の連続数が0~9、16~21に分断される、これを使って割る10をうまいこと振り分けて・・・?
を組み合わせて 余りを求めているのではないか? までわかった、つもり。
で、
(A/8)を足してはDAA、足してはDAAで8回足し、最後に(A%8)を足してDAAすれば、Aに二進化10進で商と余りがペアで入る、(56→0x56になる)ような気がする、けど極端に短くはなりませんでした。 (商と余りの分割もクロック喰うし)
というところで勘弁してください。
p.s. INC A ... は二つ前の日記で触れてありましたね。
p.s. 足してはDAA足してはDAA…は一つ前の日記に書いてありましたね。 (他の考察も)
-*-*-
DAA は鬼門なんですよ…。
以下、私が今をさること25年ぐらい前に書いたZ80シミュレータの DAA の部分です。(たぶん間違っている)int ans, half_ans, dst;u_char data;
case 0x27:#ifdef DEBUG fprintf(stdout, "DAA ");#endif /* DEBUG */ data = 0x00; if(((reg.sing.A & 0xf) > 9) || (reg.flag.H==1)) { data = 0x06; } if((reg.sing.A > 0x90) || (reg.flag.C==1)) { data |= 0x60; } if(reg.flag.N==0) { half_ans = (reg.sing.A & 0x0f) + (data & 0x0f); reg.sing.A = ans = reg.sing.A + data; } else { half_ans = (reg.sing.A & 0x0f) - (data & 0x0f); reg.sing.A = ans = reg.sing.A - data; } reg.flag.H = half_ans >> 4; reg.flag.C |= ans >> 8; /* is it true ??? */ reg.flag.S = reg.sing.A >> 7; reg.flag.Z = (reg.sing.A==0); reg.flag.P = parity(reg.sing.A); return(D_OK);
本や解説書には「二進化10進の補正をします」ぐらいしか書いてなくて、想像と実機でちょろっと確認したぐらいで、書いたものです。加算を一度しかやっていないので、0x89 + 0x11 → DAA が0x00 にならないからたぶん間違っているんじゃないかなぁ…。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
犯人は巨人ファンでA型で眼鏡をかけている -- あるハッカー
後半の前半 (スコア:1)
0~99の数値Aの10での余りは、Aを8での商と余りの
二つにわけて、各々の10での余りを加算すればいい
A =(A/8)*8 + (A%8)
A%10=((A/8)*8)%10 + (A%8)%10
(この加算で10を越えたらもう一度余りを…)
と
DAAでは(ざっくり)0~15の連続数が0~9、16~21に
分断される、これを使って割る10をうまいこと振り分けて・・・?
を
組み合わせて 余りを求めているのではないか? までわかった、つもり。
で、
(A/8)を足してはDAA、足してはDAAで8回足し、
最後に(A%8)を足してDAAすれば、
Aに二進化10進で商と余りがペアで入る、
(56→0x56になる)ような気がする、
けど極端に短くはなりませんでした。
(商と余りの分割もクロック喰うし)
というところで勘弁してください。
p.s.
INC A ... は二つ前の日記で触れてありましたね。
Re:後半の前半 (スコア:1)
p.s.
足してはDAA足してはDAA…は一つ前の日記に書いてありましたね。
(他の考察も)
-*-*-
DAA は鬼門なんですよ…。
以下、私が今をさること25年ぐらい前に書いた
Z80シミュレータの DAA の部分です。(たぶん間違っている)
int ans, half_ans, dst;
u_char data;
case 0x27:
#ifdef DEBUG
fprintf(stdout, "DAA ");
#endif /* DEBUG */
data = 0x00;
if(((reg.sing.A & 0xf) > 9) || (reg.flag.H==1)) {
data = 0x06;
}
if((reg.sing.A > 0x90) || (reg.flag.C==1)) {
data |= 0x60;
}
if(reg.flag.N==0) {
half_ans = (reg.sing.A & 0x0f) + (data & 0x0f);
reg.sing.A = ans = reg.sing.A + data;
} else {
half_ans = (reg.sing.A & 0x0f) - (data & 0x0f);
reg.sing.A = ans = reg.sing.A - data;
}
reg.flag.H = half_ans >> 4;
reg.flag.C |= ans >> 8; /* is it true ??? */
reg.flag.S = reg.sing.A >> 7;
reg.flag.Z = (reg.sing.A==0);
reg.flag.P = parity(reg.sing.A);
return(D_OK);
本や解説書には「二進化10進の補正をします」ぐらいしか書いてなくて、
想像と実機でちょろっと確認したぐらいで、書いたものです。
加算を一度しかやっていないので、0x89 + 0x11 → DAA が
0x00 にならないからたぶん間違っているんじゃないかなぁ…。