|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2022 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // HD64180 演算部分 ! 9: // ! 10: ! 11: #include "hd64180acc.h" ! 12: ! 13: /*static*/ inline uint32 ! 14: hd64180acc::vflag_add(uint32 dst, uint32 src, uint32 res) ! 15: { ! 16: return (src ^ res) & (dst ^ res); ! 17: } ! 18: ! 19: /*static*/ inline uint32 ! 20: hd64180acc::vflag_sub(uint32 dst, uint32 src, uint32 res) ! 21: { ! 22: return (src ^ dst) & (dst ^ res); ! 23: } ! 24: ! 25: /*static*/ inline uint32 ! 26: hd64180acc::hflag_add(uint32 dst, uint32 src) ! 27: { ! 28: return (dst & 0x0f) + (src & 0x0f); ! 29: } ! 30: ! 31: /*static*/ inline uint32 ! 32: hd64180acc::hflag_sub(uint32 dst, uint32 src) ! 33: { ! 34: return (dst & 0x0f) - (src & 0x0f); ! 35: } ! 36: ! 37: // LD A,I、LD A,R 命令のフラグ変化。 ! 38: // S:* Z:* H:0 P/V:IEF2 N:0 C:- ! 39: uint32 ! 40: hd64180acc::ld_ir8(uint32 src) ! 41: { ! 42: // P/V (IEF2) は呼び出し側で行う。 ! 43: ! 44: S = Z = src; ! 45: SetH(false); ! 46: SetN(false); ! 47: return Z; ! 48: } ! 49: ! 50: // save_c が true なら C を変更しない。 ! 51: // S:* Z:* H:* V:* N:0 C:*/- ! 52: uint32 ! 53: hd64180acc::add_8(uint32 dst, uint32 src, bool save_c) ! 54: { ! 55: if (save_c) { ! 56: Z = dst + src; ! 57: } else { ! 58: CZ = dst + src; ! 59: } ! 60: S = Z; ! 61: H = hflag_add(dst, src); ! 62: LetV(vflag_add(dst, src, Z)); ! 63: SetN(false); ! 64: ! 65: return (uint8)Z; ! 66: } ! 67: ! 68: // save_c が true なら C を変更しない。 ! 69: // S:* Z:* H:* V:* N:0 C:*/- ! 70: uint32 ! 71: hd64180acc::sub_8(uint32 dst, uint32 src, bool save_c) ! 72: { ! 73: if (save_c) { ! 74: Z = dst - src; ! 75: } else { ! 76: CZ = dst - src; ! 77: } ! 78: S = Z; ! 79: H = hflag_sub(dst, src); ! 80: LetV(vflag_sub(dst, src, Z)); ! 81: SetN(true); ! 82: ! 83: return (uint8)Z; ! 84: } ! 85: ! 86: // S:* Z:* H:* V:* N:0 C:* ! 87: uint32 ! 88: hd64180acc::adc_8(uint32 dst, uint32 src) ! 89: { ! 90: uint32 cin = IsC() ? 1 : 0; ! 91: uint32 res = dst + src + cin; ! 92: ! 93: CZ = res; ! 94: S = res; ! 95: LetV(vflag_add(dst, src, res)); ! 96: H = hflag_add(dst, src); ! 97: H |= hflag_add(H, cin); ! 98: SetN(false); ! 99: ! 100: return Z; ! 101: } ! 102: ! 103: // S:* Z:* H:* V:* N:0 C:* ! 104: uint32 ! 105: hd64180acc::sbc_8(uint32 dst, uint32 src) ! 106: { ! 107: uint32 cin = IsC() ? 1 : 0; ! 108: uint32 res = dst - src - cin; ! 109: ! 110: CZ = res; ! 111: S = res; ! 112: LetV(vflag_sub(dst, src, res)); ! 113: H = hflag_sub(dst, src); ! 114: H |= hflag_sub(H, cin); ! 115: SetN(true); ! 116: ! 117: return Z; ! 118: } ! 119: ! 120: // S:- Z:- H:X PV:- N:0 C:* ! 121: uint32 ! 122: hd64180acc::add_16(uint32 dst, uint32 src) ! 123: { ! 124: uint32 res = dst + src; ! 125: C = res >> 16; ! 126: SetN(false); ! 127: // XXX H は不定 ! 128: ! 129: return res; ! 130: } ! 131: ! 132: // S:* Z:* H:X V:* N:0 C:* ! 133: uint32 ! 134: hd64180acc::adc_16(uint32 dst, uint32 src) ! 135: { ! 136: // V のために2回に分けて計算しないといけない? ! 137: uint32 res = dst + src; ! 138: uint32 v = vflag_add(dst, src, res); ! 139: ! 140: dst = res; ! 141: src = IsC() ? 1 : 0; ! 142: res = dst + src; ! 143: v |= vflag_add(dst, src, res); ! 144: ! 145: LetV((uint32)(v >> 8)); ! 146: ! 147: // C, S, Z は 16bit が対象でいい? ! 148: C = res >> 16; ! 149: S = res >> 8; ! 150: Z = res | S; ! 151: ! 152: SetN(false); ! 153: ! 154: // XXX H は本当は不定 ! 155: ! 156: return res; ! 157: } ! 158: ! 159: // S:* Z:* H:X V:* N:1 C:* ! 160: uint32 ! 161: hd64180acc::sbc_16(uint32 dst, uint32 src) ! 162: { ! 163: // V のために2回に分けて計算しないといけない? ! 164: uint32 res = dst - src; ! 165: uint32 v = vflag_sub(dst, src, res); ! 166: ! 167: dst = res; ! 168: src = IsC() ? 1 : 0; ! 169: res = dst - src; ! 170: v |= vflag_sub(dst, src, res); ! 171: ! 172: LetV((uint32)(v >> 8)); ! 173: ! 174: // C, S, Z は 16bit が対象でいい? ! 175: C = res >> 16; ! 176: S = res >> 8; ! 177: Z = res | S; ! 178: ! 179: SetN(true); ! 180: ! 181: // XXX H は本当は不定 ! 182: ! 183: return res; ! 184: } ! 185: ! 186: // BIT 命令 ! 187: // S:X Z:* H:1 PV:X N:0 C:- ! 188: void ! 189: hd64180acc::bit_8(uint b, uint32 src) ! 190: { ! 191: Z = src & (1U << b); ! 192: SetH(true); ! 193: SetN(false); ! 194: // XXX S, P(V) は本当は不定 ! 195: } ! 196: ! 197: // IN A,(n) 命令のフラグ変化。他からも色々呼ばれる。 ! 198: // S:* Z:* H:0 P:* N:0 C:- ! 199: uint32 ! 200: hd64180acc::in_8(uint32 src) ! 201: { ! 202: S = Z = src; ! 203: SetN(false); ! 204: SetH(false); ! 205: LetP(Z); ! 206: return Z; ! 207: } ! 208: ! 209: // OTIM/OTDM 命令のフラグ変化。 ! 210: // 戻り値は演算後の B レジスタの値。 ! 211: // HD64180.pdf p.110 ! 212: // S:* Z:* H:* P:* N:* C:* ! 213: uint32 ! 214: hd64180acc::outm_8(uint32 src, uint32 breg) ! 215: { ! 216: CZ = breg - 1; ! 217: S = Z; ! 218: H = hflag_sub(breg, 1); ! 219: LetP(Z); // 減算後の B のパリティ ! 220: N = (src & 0x80); // (HL) の MSB ! 221: ! 222: return Z; ! 223: } ! 224: ! 225: // S:* Z:* H:1 P:* N:0 C:0 ! 226: uint32 ! 227: hd64180acc::and_8(uint32 dst, uint32 src) ! 228: { ! 229: uint32 res; ! 230: SetC(false); ! 231: res = in_8(dst & src); ! 232: SetH(true); // これだけ H はセット ! 233: return res; ! 234: } ! 235: ! 236: // S:* Z:* H:0 P:* N:0 C:0 ! 237: uint32 ! 238: hd64180acc::or_8(uint32 dst, uint32 src) ! 239: { ! 240: SetC(false); ! 241: return in_8(dst | src); ! 242: } ! 243: ! 244: // S:* Z:* H:0 P:* N:0 C:0 ! 245: uint32 ! 246: hd64180acc::xor_8(uint32 dst, uint32 src) ! 247: { ! 248: SetC(false); ! 249: return in_8(dst ^ src); ! 250: } ! 251: ! 252: // S:* Z:* H:1 P:* N:0 C:0 ! 253: void ! 254: hd64180acc::tst_8(uint32 dst, uint32 src) ! 255: { ! 256: in_8(dst & src); ! 257: SetH(true); ! 258: SetC(false); ! 259: } ! 260: ! 261: // S:* Z:* H:0 P:* N:0 C:* ! 262: uint32 ! 263: hd64180acc::sla_8(uint32 src) ! 264: { ! 265: CZ = src << 1; ! 266: return in_8(Z); ! 267: } ! 268: ! 269: // S:* Z:* H:0 P:* N:0 C:* ! 270: uint32 ! 271: hd64180acc::sra_8(uint32 src) ! 272: { ! 273: C = src; ! 274: Z = (src >> 1); ! 275: Z |= src & 0x80; ! 276: return in_8(Z); ! 277: } ! 278: ! 279: // S:* Z:* H:0 P:* N:0 C:* ! 280: uint32 ! 281: hd64180acc::srl_8(uint32 src) ! 282: { ! 283: C = src; ! 284: Z = src >> 1; ! 285: return in_8(Z); ! 286: } ! 287: ! 288: // S Z H P N C ! 289: // RLA - - 0 - 0 * : rl_8() ! 290: // RL r * * 0 P 0 * : in_8(rl_8()) ! 291: // RLD * * 0 P 0 - : in_8() ! 292: ! 293: uint32 ! 294: hd64180acc::rl_8(uint32 src) ! 295: { ! 296: src <<= 1; ! 297: if (IsC()) { ! 298: src |= 0x01; ! 299: } ! 300: C = src >> 8; ! 301: ! 302: SetN(false); ! 303: SetH(false); ! 304: ! 305: return (uint8)src; ! 306: } ! 307: ! 308: uint32 ! 309: hd64180acc::rlc_8(uint32 src) ! 310: { ! 311: src <<= 1; ! 312: if ((src & 0x100)) { ! 313: src |= 0x01; ! 314: } ! 315: C = src >> 8; ! 316: ! 317: SetN(false); ! 318: SetH(false); ! 319: ! 320: return (uint8)src; ! 321: } ! 322: ! 323: uint32 ! 324: hd64180acc::rr_8(uint32 src) ! 325: { ! 326: src = (uint8)src; ! 327: if (IsC()) { ! 328: src |= 0x100; ! 329: } ! 330: C = src; ! 331: src >>= 1; ! 332: ! 333: SetN(false); ! 334: SetH(false); ! 335: ! 336: return (uint8)src; ! 337: } ! 338: ! 339: uint32 ! 340: hd64180acc::rrc_8(uint32 src) ! 341: { ! 342: C = src; ! 343: src = (uint8)src; ! 344: src |= (C << 8); ! 345: src >>= 1; ! 346: ! 347: SetN(false); ! 348: SetH(false); ! 349: ! 350: return (uint8)src; ! 351: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.