--- nono/hd64180/hd64180acc.cpp 2026/04/29 17:05:18 1.1.1.1 +++ nono/hd64180/hd64180acc.cpp 2026/04/29 17:05:21 1.1.1.2 @@ -349,3 +349,84 @@ hd64180acc::rrc_8(uint32 src) return (uint8)src; } + +uint32 +hd64180acc::daa_8(uint32 src) +{ + uint32 ah; + uint32 al; + uint32 b; + uint32 res; + + if (IsN() == false) { + bool tmpC = IsC(); // 入力時の状態 + bool tmpH = IsH(); + + bool resC = IsC(); // 出力用。C は入力と内部演算の和 + bool resH; // 出力用。H は内部演算のみの和 + + // 下位桁 + ah = src >> 4; + al = src & 0xf; + if (al >= 0x0a || IsH()) { + b = 0x06; + } else { + b = 0; + } + src = add_8(src, b); + resC |= IsC(); + resH = IsH(); + + // 上位桁 + ah = src >> 4; + al = src & 0xf; + if (ah >= 0x0a || tmpC) { + b = 0x60; + + // XXX 入力が 9A-9F で H=1 C=0 の時、 + // 下位桁を補正して(6を足して) 上位桁が A になるのに、 + // HD64180 ではこれを補正してないようだ。 + if (0xa0 <= src && src < 0xa6 && tmpH && tmpC == false) { + b = 0; + } + } else { + b = 0; + + // XXX 入力が FA-FF で C=0 の時、 + // 下位桁を補正して(6 を足して) C=1 00-05 に繰り上がるだけの + // はずが、HD64180 では 60 も足してしまうようだ。 + if (IsC() && ah == 0x00 && tmpC == false) { + b = 0x60; + } + } + res = add_8(src, b); + resC |= IsC(); + resH |= IsH(); + + SetH(resH); + SetC(resC); + } else { + // N==1 (減算) 側は跡形なく動作が違う。 + // 意味はさっぱり分からんけどとりあえず実機と同じ動作。 + + bool resC = IsC(); + b = 0; + if (IsH()) { + b += 0x06; + if (src < 0x06) { + resC = true; + } + } + if (IsC()) { + b += 0x60; + } + res = sub_8(src, b); + + SetC(resC); + } + + // P/V フラグは P + LetP(res); + + return res; +}