176 #include <type_traits> 204 enum Reg8 :
int {
A,
F,
B,
C,
D,
E,
H,
L,
IXH,
IXL,
IYH,
IYL,
REG_I,
REG_R,
DUMMY };
234 static constexpr
Table initTables()
238 for (
int i = 0; i < 256; ++i) {
239 byte zFlag = (i == 0) ? Z_FLAG : 0;
244 for (
int v = 128; v != 0; v >>= 1) {
245 if (i & v) vFlag ^=
V_FLAG;
247 table.
ZS [i] = zFlag | sFlag;
248 table.
ZSXY [i] = zFlag | sFlag | xFlag | yFlag;
249 table.
ZSP [i] = zFlag | sFlag | vFlag;
250 table.
ZSPXY[i] = zFlag | sFlag | xFlag | yFlag | vFlag;
251 table.
ZSPH [i] = zFlag | sFlag | vFlag |
H_FLAG;
253 assert(table.
ZS [ 0] == ZS0);
254 assert(table.
ZSXY [ 0] == ZSXY0);
255 assert(table.
ZSP [ 0] == ZSP0);
256 assert(table.
ZSPXY[ 0] == ZSPXY0);
257 assert(table.
ZS [255] == ZS255);
258 assert(table.
ZSXY [255] == ZSXY255);
269 static word start_pc;
287 , T(time, motherboard_.getScheduler())
288 , motherboard(motherboard_)
289 , scheduler(motherboard.getScheduler())
291 , traceSetting(traceSetting_)
292 , diHaltCallback(diHaltCallback_)
293 , IRQStatus(motherboard.getDebugger(), name +
".pendingIRQ",
294 "Non-zero if there are pending IRQs (thus CPU would enter " 295 "interrupt routine in EI mode).",
297 , IRQAccept(motherboard.getDebugger(), name +
".acceptIRQ",
298 "This probe is only useful to set a breakpoint on (the value " 299 "return by read is meaningless). The breakpoint gets triggered " 300 "right after the CPU accepted an IRQ.")
302 motherboard.getCommandController(), name +
"_freq_locked",
303 strCat(
"real (locked) or custom (unlocked) ", name,
" frequency"),
306 motherboard.getCommandController(), name +
"_freq",
307 strCat(
"custom ", name,
" frequency (only valid when unlocked)"),
308 T::CLOCK_FREQ, 1000000, 1000000000)
309 , freq(T::CLOCK_FREQ)
313 , tracingEnabled(traceSetting.getBoolean())
314 , isTurboR(motherboard.isTurboR())
316 static_assert(!std::is_polymorphic_v<
CPUCore<T>>,
317 "keep CPUCore non-virtual to keep PC at offset 0");
324 assert(T::getTimeFast() <= time);
357 T::setMemPtr(0xFFFF);
387 assert(NMIStatus == 0);
388 assert(IRQStatus == 0);
427 slowInstructions = 2;
433 assert(IRQStatus >= 0);
434 if (IRQStatus == 0) {
435 setSlowInstructions();
437 IRQStatus = IRQStatus + 1;
442 IRQStatus = IRQStatus - 1;
443 assert(IRQStatus >= 0);
448 assert(NMIStatus >= 0);
449 if (NMIStatus == 0) {
451 setSlowInstructions();
459 assert(NMIStatus >= 0);
475 return address == getPC();
480 assert(time >= getCurrentTime());
481 scheduler.schedule(time);
482 T::advanceTime(time);
488 EmuTime time2 = T::calcTime(time, cycles);
491 scheduler.schedule(time2);
501 static inline char toHex(
byte x)
503 return (x < 10) ? (x +
'0') : (x - 10 +
'A');
505 static void toHex(
byte x,
char* buf)
507 buf[0] = toHex(x / 16);
508 buf[1] = toHex(x & 15);
514 word address = (tokens.size() < 3) ? getPC() : tokens[2].getInt(interp);
516 std::string dasmOutput;
517 unsigned len =
dasm(*interface, address, outBuf, dasmOutput,
520 char tmp[3]; tmp[2] = 0;
521 for (
unsigned i = 0; i < len; ++i) {
522 toHex(outBuf[i], tmp);
529 if (&setting == &freqLocked) {
531 }
else if (&setting == &freqValue) {
533 }
else if (&setting == &traceSetting) {
534 tracingEnabled = traceSetting.getBoolean();
546 if (freqLocked.getBoolean()) {
551 T::setFreq(freqValue.getInt());
558 EmuTime time = T::getTimeFast(cc);
559 scheduler.schedule(time);
560 byte result = interface->readIO(port, time);
567 EmuTime time = T::getTimeFast(cc);
568 scheduler.schedule(time);
569 interface->writeIO(port, value, time);
573 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
579 if (readCacheLine[high] ==
nullptr) {
582 if (
const byte* line = interface->getReadCacheLine(addrBase)) {
584 T::template PRE_MEM<PRE_PB, POST_PB>(address);
585 T::template POST_MEM< POST_PB>(address);
586 readCacheLine[high] = line - addrBase;
587 return readCacheLine[high][address];
591 readCacheLine[high] =
reinterpret_cast<const byte*
>(1);
592 T::template PRE_MEM<PRE_PB, POST_PB>(address);
593 EmuTime time = T::getTimeFast(cc);
594 scheduler.schedule(time);
595 byte result = interface->readMem(address, time);
596 T::template POST_MEM<POST_PB>(address);
599 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
603 if (
likely(uintptr_t(line) > 1)) {
605 T::template PRE_MEM<PRE_PB, POST_PB>(address);
606 T::template POST_MEM< POST_PB>(address);
607 return line[address];
609 return RDMEMslow<PRE_PB, POST_PB>(address, cc);
612 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
617 return RDMEM_impl2<PRE, POST>(address, cc);
630 unsigned address = (getPC() + PC_OFFSET) & 0xFFFF;
631 return RDMEM_impl<false, false>(address, cc);
635 return RDMEM_impl<true, true>(address, cc);
638 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
641 unsigned res = RDMEM_impl<PRE_PB, false>(address, cc);
642 res += RDMEM_impl<false, POST_PB>((address + 1) & 0xFFFF, cc + T::CC_RDMEM) << 8;
645 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
651 T::template PRE_WORD<PRE_PB, POST_PB>(address);
652 T::template POST_WORD< POST_PB>(address);
653 return Endian::read_UA_L16(&line[address]);
656 return RD_WORD_slow<PRE_PB, POST_PB>(address, cc);
659 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
664 return RD_WORD_impl2<PRE, POST>(address, cc);
668 unsigned addr = (getPC() + PC_OFFSET) & 0xFFFF;
669 return RD_WORD_impl<false, false>(addr, cc);
672 unsigned address,
unsigned cc)
674 return RD_WORD_impl<true, true>(address, cc);
677 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
683 if (writeCacheLine[high] ==
nullptr) {
686 if (
byte* line = interface->getWriteCacheLine(addrBase)) {
688 T::template PRE_MEM<PRE_PB, POST_PB>(address);
689 T::template POST_MEM< POST_PB>(address);
690 writeCacheLine[high] = line - addrBase;
691 writeCacheLine[high][address] = value;
696 writeCacheLine[high] =
reinterpret_cast<byte*
>(1);
697 T::template PRE_MEM<PRE_PB, POST_PB>(address);
698 EmuTime time = T::getTimeFast(cc);
699 scheduler.schedule(time);
700 interface->writeMem(address, value, time);
701 T::template POST_MEM<POST_PB>(address);
703 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
705 unsigned address,
byte value,
unsigned cc)
708 if (
likely(uintptr_t(line) > 1)) {
710 T::template PRE_MEM<PRE_PB, POST_PB>(address);
711 T::template POST_MEM< POST_PB>(address);
712 line[address] = value;
714 WRMEMslow<PRE_PB, POST_PB>(address, value, cc);
717 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
719 unsigned address,
byte value,
unsigned cc)
723 WRMEM_impl2<PRE, POST>(address, value, cc);
726 unsigned address,
byte value,
unsigned cc)
728 WRMEM_impl<true, true>(address, value, cc);
732 unsigned address,
unsigned value,
unsigned cc)
734 WRMEM_impl<true, false>( address, value & 255, cc);
735 WRMEM_impl<false, true>((address + 1) & 0xFFFF, value >> 8, cc + T::CC_WRMEM);
738 unsigned address,
unsigned value,
unsigned cc)
743 T::template PRE_WORD<true, true>(address);
744 T::template POST_WORD< true>(address);
745 Endian::write_UA_L16(&line[address], value);
748 WR_WORD_slow(address, value, cc);
753 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
755 unsigned address,
unsigned value,
unsigned cc)
757 WRMEM_impl<PRE_PB, false>((address + 1) & 0xFFFF, value >> 8, cc);
758 WRMEM_impl<false, POST_PB>( address, value & 255, cc + T::CC_WRMEM);
760 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
762 unsigned address,
unsigned value,
unsigned cc)
767 T::template PRE_WORD<PRE_PB, POST_PB>(address);
768 T::template POST_WORD< POST_PB>(address);
769 Endian::write_UA_L16(&line[address], value);
772 WR_WORD_rev_slow<PRE_PB, POST_PB>(address, value, cc);
775 template<
class T>
template<
bool PRE_PB,
bool POST_PB>
777 unsigned address,
unsigned value,
unsigned cc)
781 WR_WORD_rev2<PRE, POST>(address, value, cc);
791 PUSH<T::EE_NMI_1>(getPC());
801 assert(interface->readIRQVector() == 0xFF);
806 PUSH<T::EE_IRQ0_1>(getPC());
808 T::setMemPtr(getPC());
819 PUSH<T::EE_IRQ1_1>(getPC());
821 T::setMemPtr(getPC());
832 PUSH<T::EE_IRQ2_1>(getPC());
833 unsigned x = interface->readIRQVector() | (getI() << 8);
834 setPC(RD_WORD(x, T::CC_IRQ2_2));
835 T::setMemPtr(getPC());
842 checkNoCurrentFlags();
843 #ifdef USE_COMPUTED_GOTO 846 static void* opcodeTable[256] = {
847 &&op00, &&op01, &&op02, &&op03, &&op04, &&op05, &&op06, &&op07,
848 &&op08, &&op09, &&op0A, &&op0B, &&op0C, &&op0D, &&op0E, &&op0F,
849 &&op10, &&op11, &&op12, &&op13, &&op14, &&op15, &&op16, &&op17,
850 &&op18, &&op19, &&op1A, &&op1B, &&op1C, &&op1D, &&op1E, &&op1F,
851 &&op20, &&op21, &&op22, &&op23, &&op24, &&op25, &&op26, &&op27,
852 &&op28, &&op29, &&op2A, &&op2B, &&op2C, &&op2D, &&op2E, &&op2F,
853 &&op30, &&op31, &&op32, &&op33, &&op34, &&op35, &&op36, &&op37,
854 &&op38, &&op39, &&op3A, &&op3B, &&op3C, &&op3D, &&op3E, &&op3F,
855 &&op00, &&op41, &&op42, &&op43, &&op44, &&op45, &&op46, &&op47,
856 &&op48, &&op00, &&op4A, &&op4B, &&op4C, &&op4D, &&op4E, &&op4F,
857 &&op50, &&op51, &&op00, &&op53, &&op54, &&op55, &&op56, &&op57,
858 &&op58, &&op59, &&op5A, &&op00, &&op5C, &&op5D, &&op5E, &&op5F,
859 &&op60, &&op61, &&op62, &&op63, &&op00, &&op65, &&op66, &&op67,
860 &&op68, &&op69, &&op6A, &&op6B, &&op6C, &&op00, &&op6E, &&op6F,
861 &&op70, &&op71, &&op72, &&op73, &&op74, &&op75, &&op76, &&op77,
862 &&op78, &&op79, &&op7A, &&op7B, &&op7C, &&op7D, &&op7E, &&op00,
863 &&op80, &&op81, &&op82, &&op83, &&op84, &&op85, &&op86, &&op87,
864 &&op88, &&op89, &&op8A, &&op8B, &&op8C, &&op8D, &&op8E, &&op8F,
865 &&op90, &&op91, &&op92, &&op93, &&op94, &&op95, &&op96, &&op97,
866 &&op98, &&op99, &&op9A, &&op9B, &&op9C, &&op9D, &&op9E, &&op9F,
867 &&opA0, &&opA1, &&opA2, &&opA3, &&opA4, &&opA5, &&opA6, &&opA7,
868 &&opA8, &&opA9, &&opAA, &&opAB, &&opAC, &&opAD, &&opAE, &&opAF,
869 &&opB0, &&opB1, &&opB2, &&opB3, &&opB4, &&opB5, &&opB6, &&opB7,
870 &&opB8, &&opB9, &&opBA, &&opBB, &&opBC, &&opBD, &&opBE, &&opBF,
871 &&opC0, &&opC1, &&opC2, &&opC3, &&opC4, &&opC5, &&opC6, &&opC7,
872 &&opC8, &&opC9, &&opCA, &&opCB, &&opCC, &&opCD, &&opCE, &&opCF,
873 &&opD0, &&opD1, &&opD2, &&opD3, &&opD4, &&opD5, &&opD6, &&opD7,
874 &&opD8, &&opD9, &&opDA, &&opDB, &&opDC, &&opDD, &&opDE, &&opDF,
875 &&opE0, &&opE1, &&opE2, &&opE3, &&opE4, &&opE5, &&opE6, &&opE7,
876 &&opE8, &&opE9, &&opEA, &&opEB, &&opEC, &&opED, &&opEE, &&opEF,
877 &&opF0, &&opF1, &&opF2, &&opF3, &&opF4, &&opF5, &&opF6, &&opF7,
878 &&opF8, &&opF9, &&opFA, &&opFB, &&opFC, &&opFD, &&opFE, &&opFF,
884 setPC(getPC() + ii.length); \ 886 T::R800Refresh(*this); \ 887 if (likely(!T::limitReached())) { \ 889 unsigned address = getPC(); \ 890 const byte* line = readCacheLine[address >> CacheLine::BITS]; \ 891 if (likely(uintptr_t(line) > 1)) { \ 892 T::template PRE_MEM<false, false>(address); \ 893 T::template POST_MEM< false>(address); \ 894 byte op = line[address]; \ 895 goto *(opcodeTable[op]); \ 904 setPC(getPC() + ii.length); \ 906 T::R800Refresh(*this); \ 907 assert(T::limitReached()); \ 911 setPC(getPC() + ii.length); \ 914 assert(T::limitReached()); \ 918 #define CASE(X) op##X: 920 #else // USE_COMPUTED_GOTO 923 setPC(getPC() + ii.length); \ 925 T::R800Refresh(*this); \ 926 if (likely(!T::limitReached())) { \ 932 setPC(getPC() + ii.length); \ 934 T::R800Refresh(*this); \ 935 assert(T::limitReached()); \ 939 setPC(getPC() + ii.length); \ 942 assert(T::limitReached()); \ 945 #define CASE(X) case 0x##X: 947 #endif // USE_COMPUTED_GOTO 949 #ifndef USE_COMPUTED_GOTO 953 byte opcodeMain = RDMEM_OPCODE<0>(T::CC_MAIN);
955 #ifdef USE_COMPUTED_GOTO 956 goto *(opcodeTable[opcodeMain]);
959 unsigned address = getPC();
960 byte opcodeSlow = RDMEMslow<false, false>(address, T::CC_MAIN);
961 goto *(opcodeTable[opcodeSlow]);
965 #ifndef USE_COMPUTED_GOTO 967 switch (opcodeMain) {
994 CASE(22) {
II ii = ld_xword_SS<HL,0>();
NEXT; }
1008 CASE(09) {
II ii = add_SS_TT<HL,BC,0>();
NEXT; }
1009 CASE(19) {
II ii = add_SS_TT<HL,DE,0>();
NEXT; }
1010 CASE(29) {
II ii = add_SS_SS<HL ,0>();
NEXT; }
1011 CASE(39) {
II ii = add_SS_TT<HL,SP,0>();
NEXT; }
1012 CASE(01) {
II ii = ld_SS_word<BC,0>();
NEXT; }
1013 CASE(11) {
II ii = ld_SS_word<DE,0>();
NEXT; }
1014 CASE(21) {
II ii = ld_SS_word<HL,0>();
NEXT; }
1015 CASE(31) {
II ii = ld_SS_word<SP,0>();
NEXT; }
1167 CASE(E3) {
II ii = ex_xsp_SS<HL,0>();
NEXT; }
1226 byte cb_opcode = RDMEM_OPCODE<0>(T::CC_PREFIX);
1228 switch (cb_opcode) {
1229 case 0x00: {
II ii = rlc_R<B>();
NEXT; }
1230 case 0x01: {
II ii = rlc_R<C>();
NEXT; }
1231 case 0x02: {
II ii = rlc_R<D>();
NEXT; }
1232 case 0x03: {
II ii = rlc_R<E>();
NEXT; }
1233 case 0x04: {
II ii = rlc_R<H>();
NEXT; }
1234 case 0x05: {
II ii = rlc_R<L>();
NEXT; }
1235 case 0x07: {
II ii = rlc_R<A>();
NEXT; }
1236 case 0x06: {
II ii = rlc_xhl();
NEXT; }
1237 case 0x08: {
II ii = rrc_R<B>();
NEXT; }
1238 case 0x09: {
II ii = rrc_R<C>();
NEXT; }
1239 case 0x0a: {
II ii = rrc_R<D>();
NEXT; }
1240 case 0x0b: {
II ii = rrc_R<E>();
NEXT; }
1241 case 0x0c: {
II ii = rrc_R<H>();
NEXT; }
1242 case 0x0d: {
II ii = rrc_R<L>();
NEXT; }
1243 case 0x0f: {
II ii = rrc_R<A>();
NEXT; }
1244 case 0x0e: {
II ii = rrc_xhl();
NEXT; }
1245 case 0x10: {
II ii = rl_R<B>();
NEXT; }
1246 case 0x11: {
II ii = rl_R<C>();
NEXT; }
1247 case 0x12: {
II ii = rl_R<D>();
NEXT; }
1248 case 0x13: {
II ii = rl_R<E>();
NEXT; }
1249 case 0x14: {
II ii = rl_R<H>();
NEXT; }
1250 case 0x15: {
II ii = rl_R<L>();
NEXT; }
1251 case 0x17: {
II ii = rl_R<A>();
NEXT; }
1252 case 0x16: {
II ii = rl_xhl();
NEXT; }
1253 case 0x18: {
II ii = rr_R<B>();
NEXT; }
1254 case 0x19: {
II ii = rr_R<C>();
NEXT; }
1255 case 0x1a: {
II ii = rr_R<D>();
NEXT; }
1256 case 0x1b: {
II ii = rr_R<E>();
NEXT; }
1257 case 0x1c: {
II ii = rr_R<H>();
NEXT; }
1258 case 0x1d: {
II ii = rr_R<L>();
NEXT; }
1259 case 0x1f: {
II ii = rr_R<A>();
NEXT; }
1260 case 0x1e: {
II ii = rr_xhl();
NEXT; }
1261 case 0x20: {
II ii = sla_R<B>();
NEXT; }
1262 case 0x21: {
II ii = sla_R<C>();
NEXT; }
1263 case 0x22: {
II ii = sla_R<D>();
NEXT; }
1264 case 0x23: {
II ii = sla_R<E>();
NEXT; }
1265 case 0x24: {
II ii = sla_R<H>();
NEXT; }
1266 case 0x25: {
II ii = sla_R<L>();
NEXT; }
1267 case 0x27: {
II ii = sla_R<A>();
NEXT; }
1268 case 0x26: {
II ii = sla_xhl();
NEXT; }
1269 case 0x28: {
II ii = sra_R<B>();
NEXT; }
1270 case 0x29: {
II ii = sra_R<C>();
NEXT; }
1271 case 0x2a: {
II ii = sra_R<D>();
NEXT; }
1272 case 0x2b: {
II ii = sra_R<E>();
NEXT; }
1273 case 0x2c: {
II ii = sra_R<H>();
NEXT; }
1274 case 0x2d: {
II ii = sra_R<L>();
NEXT; }
1275 case 0x2f: {
II ii = sra_R<A>();
NEXT; }
1276 case 0x2e: {
II ii = sra_xhl();
NEXT; }
1277 case 0x30: {
II ii = T::isR800() ? sla_R<B>() : sll_R<B>();
NEXT; }
1278 case 0x31: {
II ii = T::isR800() ? sla_R<C>() : sll_R<C>();
NEXT; }
1279 case 0x32: {
II ii = T::isR800() ? sla_R<D>() : sll_R<D>();
NEXT; }
1280 case 0x33: {
II ii = T::isR800() ? sla_R<E>() : sll_R<E>();
NEXT; }
1281 case 0x34: {
II ii = T::isR800() ? sla_R<H>() : sll_R<H>();
NEXT; }
1282 case 0x35: {
II ii = T::isR800() ? sla_R<L>() : sll_R<L>();
NEXT; }
1283 case 0x37: {
II ii = T::isR800() ? sla_R<A>() : sll_R<A>();
NEXT; }
1284 case 0x36: {
II ii = T::isR800() ? sla_xhl() : sll_xhl();
NEXT; }
1285 case 0x38: {
II ii = srl_R<B>();
NEXT; }
1286 case 0x39: {
II ii = srl_R<C>();
NEXT; }
1287 case 0x3a: {
II ii = srl_R<D>();
NEXT; }
1288 case 0x3b: {
II ii = srl_R<E>();
NEXT; }
1289 case 0x3c: {
II ii = srl_R<H>();
NEXT; }
1290 case 0x3d: {
II ii = srl_R<L>();
NEXT; }
1291 case 0x3f: {
II ii = srl_R<A>();
NEXT; }
1292 case 0x3e: {
II ii = srl_xhl();
NEXT; }
1294 case 0x40: {
II ii = bit_N_R<0,B>();
NEXT; }
1295 case 0x41: {
II ii = bit_N_R<0,C>();
NEXT; }
1296 case 0x42: {
II ii = bit_N_R<0,D>();
NEXT; }
1297 case 0x43: {
II ii = bit_N_R<0,E>();
NEXT; }
1298 case 0x44: {
II ii = bit_N_R<0,H>();
NEXT; }
1299 case 0x45: {
II ii = bit_N_R<0,L>();
NEXT; }
1300 case 0x47: {
II ii = bit_N_R<0,A>();
NEXT; }
1301 case 0x48: {
II ii = bit_N_R<1,B>();
NEXT; }
1302 case 0x49: {
II ii = bit_N_R<1,C>();
NEXT; }
1303 case 0x4a: {
II ii = bit_N_R<1,D>();
NEXT; }
1304 case 0x4b: {
II ii = bit_N_R<1,E>();
NEXT; }
1305 case 0x4c: {
II ii = bit_N_R<1,H>();
NEXT; }
1306 case 0x4d: {
II ii = bit_N_R<1,L>();
NEXT; }
1307 case 0x4f: {
II ii = bit_N_R<1,A>();
NEXT; }
1308 case 0x50: {
II ii = bit_N_R<2,B>();
NEXT; }
1309 case 0x51: {
II ii = bit_N_R<2,C>();
NEXT; }
1310 case 0x52: {
II ii = bit_N_R<2,D>();
NEXT; }
1311 case 0x53: {
II ii = bit_N_R<2,E>();
NEXT; }
1312 case 0x54: {
II ii = bit_N_R<2,H>();
NEXT; }
1313 case 0x55: {
II ii = bit_N_R<2,L>();
NEXT; }
1314 case 0x57: {
II ii = bit_N_R<2,A>();
NEXT; }
1315 case 0x58: {
II ii = bit_N_R<3,B>();
NEXT; }
1316 case 0x59: {
II ii = bit_N_R<3,C>();
NEXT; }
1317 case 0x5a: {
II ii = bit_N_R<3,D>();
NEXT; }
1318 case 0x5b: {
II ii = bit_N_R<3,E>();
NEXT; }
1319 case 0x5c: {
II ii = bit_N_R<3,H>();
NEXT; }
1320 case 0x5d: {
II ii = bit_N_R<3,L>();
NEXT; }
1321 case 0x5f: {
II ii = bit_N_R<3,A>();
NEXT; }
1322 case 0x60: {
II ii = bit_N_R<4,B>();
NEXT; }
1323 case 0x61: {
II ii = bit_N_R<4,C>();
NEXT; }
1324 case 0x62: {
II ii = bit_N_R<4,D>();
NEXT; }
1325 case 0x63: {
II ii = bit_N_R<4,E>();
NEXT; }
1326 case 0x64: {
II ii = bit_N_R<4,H>();
NEXT; }
1327 case 0x65: {
II ii = bit_N_R<4,L>();
NEXT; }
1328 case 0x67: {
II ii = bit_N_R<4,A>();
NEXT; }
1329 case 0x68: {
II ii = bit_N_R<5,B>();
NEXT; }
1330 case 0x69: {
II ii = bit_N_R<5,C>();
NEXT; }
1331 case 0x6a: {
II ii = bit_N_R<5,D>();
NEXT; }
1332 case 0x6b: {
II ii = bit_N_R<5,E>();
NEXT; }
1333 case 0x6c: {
II ii = bit_N_R<5,H>();
NEXT; }
1334 case 0x6d: {
II ii = bit_N_R<5,L>();
NEXT; }
1335 case 0x6f: {
II ii = bit_N_R<5,A>();
NEXT; }
1336 case 0x70: {
II ii = bit_N_R<6,B>();
NEXT; }
1337 case 0x71: {
II ii = bit_N_R<6,C>();
NEXT; }
1338 case 0x72: {
II ii = bit_N_R<6,D>();
NEXT; }
1339 case 0x73: {
II ii = bit_N_R<6,E>();
NEXT; }
1340 case 0x74: {
II ii = bit_N_R<6,H>();
NEXT; }
1341 case 0x75: {
II ii = bit_N_R<6,L>();
NEXT; }
1342 case 0x77: {
II ii = bit_N_R<6,A>();
NEXT; }
1343 case 0x78: {
II ii = bit_N_R<7,B>();
NEXT; }
1344 case 0x79: {
II ii = bit_N_R<7,C>();
NEXT; }
1345 case 0x7a: {
II ii = bit_N_R<7,D>();
NEXT; }
1346 case 0x7b: {
II ii = bit_N_R<7,E>();
NEXT; }
1347 case 0x7c: {
II ii = bit_N_R<7,H>();
NEXT; }
1348 case 0x7d: {
II ii = bit_N_R<7,L>();
NEXT; }
1349 case 0x7f: {
II ii = bit_N_R<7,A>();
NEXT; }
1350 case 0x46: {
II ii = bit_N_xhl<0>();
NEXT; }
1351 case 0x4e: {
II ii = bit_N_xhl<1>();
NEXT; }
1352 case 0x56: {
II ii = bit_N_xhl<2>();
NEXT; }
1353 case 0x5e: {
II ii = bit_N_xhl<3>();
NEXT; }
1354 case 0x66: {
II ii = bit_N_xhl<4>();
NEXT; }
1355 case 0x6e: {
II ii = bit_N_xhl<5>();
NEXT; }
1356 case 0x76: {
II ii = bit_N_xhl<6>();
NEXT; }
1357 case 0x7e: {
II ii = bit_N_xhl<7>();
NEXT; }
1359 case 0x80: {
II ii = res_N_R<0,B>();
NEXT; }
1360 case 0x81: {
II ii = res_N_R<0,C>();
NEXT; }
1361 case 0x82: {
II ii = res_N_R<0,D>();
NEXT; }
1362 case 0x83: {
II ii = res_N_R<0,E>();
NEXT; }
1363 case 0x84: {
II ii = res_N_R<0,H>();
NEXT; }
1364 case 0x85: {
II ii = res_N_R<0,L>();
NEXT; }
1365 case 0x87: {
II ii = res_N_R<0,A>();
NEXT; }
1366 case 0x88: {
II ii = res_N_R<1,B>();
NEXT; }
1367 case 0x89: {
II ii = res_N_R<1,C>();
NEXT; }
1368 case 0x8a: {
II ii = res_N_R<1,D>();
NEXT; }
1369 case 0x8b: {
II ii = res_N_R<1,E>();
NEXT; }
1370 case 0x8c: {
II ii = res_N_R<1,H>();
NEXT; }
1371 case 0x8d: {
II ii = res_N_R<1,L>();
NEXT; }
1372 case 0x8f: {
II ii = res_N_R<1,A>();
NEXT; }
1373 case 0x90: {
II ii = res_N_R<2,B>();
NEXT; }
1374 case 0x91: {
II ii = res_N_R<2,C>();
NEXT; }
1375 case 0x92: {
II ii = res_N_R<2,D>();
NEXT; }
1376 case 0x93: {
II ii = res_N_R<2,E>();
NEXT; }
1377 case 0x94: {
II ii = res_N_R<2,H>();
NEXT; }
1378 case 0x95: {
II ii = res_N_R<2,L>();
NEXT; }
1379 case 0x97: {
II ii = res_N_R<2,A>();
NEXT; }
1380 case 0x98: {
II ii = res_N_R<3,B>();
NEXT; }
1381 case 0x99: {
II ii = res_N_R<3,C>();
NEXT; }
1382 case 0x9a: {
II ii = res_N_R<3,D>();
NEXT; }
1383 case 0x9b: {
II ii = res_N_R<3,E>();
NEXT; }
1384 case 0x9c: {
II ii = res_N_R<3,H>();
NEXT; }
1385 case 0x9d: {
II ii = res_N_R<3,L>();
NEXT; }
1386 case 0x9f: {
II ii = res_N_R<3,A>();
NEXT; }
1387 case 0xa0: {
II ii = res_N_R<4,B>();
NEXT; }
1388 case 0xa1: {
II ii = res_N_R<4,C>();
NEXT; }
1389 case 0xa2: {
II ii = res_N_R<4,D>();
NEXT; }
1390 case 0xa3: {
II ii = res_N_R<4,E>();
NEXT; }
1391 case 0xa4: {
II ii = res_N_R<4,H>();
NEXT; }
1392 case 0xa5: {
II ii = res_N_R<4,L>();
NEXT; }
1393 case 0xa7: {
II ii = res_N_R<4,A>();
NEXT; }
1394 case 0xa8: {
II ii = res_N_R<5,B>();
NEXT; }
1395 case 0xa9: {
II ii = res_N_R<5,C>();
NEXT; }
1396 case 0xaa: {
II ii = res_N_R<5,D>();
NEXT; }
1397 case 0xab: {
II ii = res_N_R<5,E>();
NEXT; }
1398 case 0xac: {
II ii = res_N_R<5,H>();
NEXT; }
1399 case 0xad: {
II ii = res_N_R<5,L>();
NEXT; }
1400 case 0xaf: {
II ii = res_N_R<5,A>();
NEXT; }
1401 case 0xb0: {
II ii = res_N_R<6,B>();
NEXT; }
1402 case 0xb1: {
II ii = res_N_R<6,C>();
NEXT; }
1403 case 0xb2: {
II ii = res_N_R<6,D>();
NEXT; }
1404 case 0xb3: {
II ii = res_N_R<6,E>();
NEXT; }
1405 case 0xb4: {
II ii = res_N_R<6,H>();
NEXT; }
1406 case 0xb5: {
II ii = res_N_R<6,L>();
NEXT; }
1407 case 0xb7: {
II ii = res_N_R<6,A>();
NEXT; }
1408 case 0xb8: {
II ii = res_N_R<7,B>();
NEXT; }
1409 case 0xb9: {
II ii = res_N_R<7,C>();
NEXT; }
1410 case 0xba: {
II ii = res_N_R<7,D>();
NEXT; }
1411 case 0xbb: {
II ii = res_N_R<7,E>();
NEXT; }
1412 case 0xbc: {
II ii = res_N_R<7,H>();
NEXT; }
1413 case 0xbd: {
II ii = res_N_R<7,L>();
NEXT; }
1414 case 0xbf: {
II ii = res_N_R<7,A>();
NEXT; }
1415 case 0x86: {
II ii = res_N_xhl<0>();
NEXT; }
1416 case 0x8e: {
II ii = res_N_xhl<1>();
NEXT; }
1417 case 0x96: {
II ii = res_N_xhl<2>();
NEXT; }
1418 case 0x9e: {
II ii = res_N_xhl<3>();
NEXT; }
1419 case 0xa6: {
II ii = res_N_xhl<4>();
NEXT; }
1420 case 0xae: {
II ii = res_N_xhl<5>();
NEXT; }
1421 case 0xb6: {
II ii = res_N_xhl<6>();
NEXT; }
1422 case 0xbe: {
II ii = res_N_xhl<7>();
NEXT; }
1424 case 0xc0: {
II ii = set_N_R<0,B>();
NEXT; }
1425 case 0xc1: {
II ii = set_N_R<0,C>();
NEXT; }
1426 case 0xc2: {
II ii = set_N_R<0,D>();
NEXT; }
1427 case 0xc3: {
II ii = set_N_R<0,E>();
NEXT; }
1428 case 0xc4: {
II ii = set_N_R<0,H>();
NEXT; }
1429 case 0xc5: {
II ii = set_N_R<0,L>();
NEXT; }
1430 case 0xc7: {
II ii = set_N_R<0,A>();
NEXT; }
1431 case 0xc8: {
II ii = set_N_R<1,B>();
NEXT; }
1432 case 0xc9: {
II ii = set_N_R<1,C>();
NEXT; }
1433 case 0xca: {
II ii = set_N_R<1,D>();
NEXT; }
1434 case 0xcb: {
II ii = set_N_R<1,E>();
NEXT; }
1435 case 0xcc: {
II ii = set_N_R<1,H>();
NEXT; }
1436 case 0xcd: {
II ii = set_N_R<1,L>();
NEXT; }
1437 case 0xcf: {
II ii = set_N_R<1,A>();
NEXT; }
1438 case 0xd0: {
II ii = set_N_R<2,B>();
NEXT; }
1439 case 0xd1: {
II ii = set_N_R<2,C>();
NEXT; }
1440 case 0xd2: {
II ii = set_N_R<2,D>();
NEXT; }
1441 case 0xd3: {
II ii = set_N_R<2,E>();
NEXT; }
1442 case 0xd4: {
II ii = set_N_R<2,H>();
NEXT; }
1443 case 0xd5: {
II ii = set_N_R<2,L>();
NEXT; }
1444 case 0xd7: {
II ii = set_N_R<2,A>();
NEXT; }
1445 case 0xd8: {
II ii = set_N_R<3,B>();
NEXT; }
1446 case 0xd9: {
II ii = set_N_R<3,C>();
NEXT; }
1447 case 0xda: {
II ii = set_N_R<3,D>();
NEXT; }
1448 case 0xdb: {
II ii = set_N_R<3,E>();
NEXT; }
1449 case 0xdc: {
II ii = set_N_R<3,H>();
NEXT; }
1450 case 0xdd: {
II ii = set_N_R<3,L>();
NEXT; }
1451 case 0xdf: {
II ii = set_N_R<3,A>();
NEXT; }
1452 case 0xe0: {
II ii = set_N_R<4,B>();
NEXT; }
1453 case 0xe1: {
II ii = set_N_R<4,C>();
NEXT; }
1454 case 0xe2: {
II ii = set_N_R<4,D>();
NEXT; }
1455 case 0xe3: {
II ii = set_N_R<4,E>();
NEXT; }
1456 case 0xe4: {
II ii = set_N_R<4,H>();
NEXT; }
1457 case 0xe5: {
II ii = set_N_R<4,L>();
NEXT; }
1458 case 0xe7: {
II ii = set_N_R<4,A>();
NEXT; }
1459 case 0xe8: {
II ii = set_N_R<5,B>();
NEXT; }
1460 case 0xe9: {
II ii = set_N_R<5,C>();
NEXT; }
1461 case 0xea: {
II ii = set_N_R<5,D>();
NEXT; }
1462 case 0xeb: {
II ii = set_N_R<5,E>();
NEXT; }
1463 case 0xec: {
II ii = set_N_R<5,H>();
NEXT; }
1464 case 0xed: {
II ii = set_N_R<5,L>();
NEXT; }
1465 case 0xef: {
II ii = set_N_R<5,A>();
NEXT; }
1466 case 0xf0: {
II ii = set_N_R<6,B>();
NEXT; }
1467 case 0xf1: {
II ii = set_N_R<6,C>();
NEXT; }
1468 case 0xf2: {
II ii = set_N_R<6,D>();
NEXT; }
1469 case 0xf3: {
II ii = set_N_R<6,E>();
NEXT; }
1470 case 0xf4: {
II ii = set_N_R<6,H>();
NEXT; }
1471 case 0xf5: {
II ii = set_N_R<6,L>();
NEXT; }
1472 case 0xf7: {
II ii = set_N_R<6,A>();
NEXT; }
1473 case 0xf8: {
II ii = set_N_R<7,B>();
NEXT; }
1474 case 0xf9: {
II ii = set_N_R<7,C>();
NEXT; }
1475 case 0xfa: {
II ii = set_N_R<7,D>();
NEXT; }
1476 case 0xfb: {
II ii = set_N_R<7,E>();
NEXT; }
1477 case 0xfc: {
II ii = set_N_R<7,H>();
NEXT; }
1478 case 0xfd: {
II ii = set_N_R<7,L>();
NEXT; }
1479 case 0xff: {
II ii = set_N_R<7,A>();
NEXT; }
1480 case 0xc6: {
II ii = set_N_xhl<0>();
NEXT; }
1481 case 0xce: {
II ii = set_N_xhl<1>();
NEXT; }
1482 case 0xd6: {
II ii = set_N_xhl<2>();
NEXT; }
1483 case 0xde: {
II ii = set_N_xhl<3>();
NEXT; }
1484 case 0xe6: {
II ii = set_N_xhl<4>();
NEXT; }
1485 case 0xee: {
II ii = set_N_xhl<5>();
NEXT; }
1486 case 0xf6: {
II ii = set_N_xhl<6>();
NEXT; }
1487 case 0xfe: {
II ii = set_N_xhl<7>();
NEXT; }
1493 byte ed_opcode = RDMEM_OPCODE<0>(T::CC_PREFIX);
1495 switch (ed_opcode) {
1496 case 0x00:
case 0x01:
case 0x02:
case 0x03:
1497 case 0x04:
case 0x05:
case 0x06:
case 0x07:
1498 case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
1499 case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
1500 case 0x10:
case 0x11:
case 0x12:
case 0x13:
1501 case 0x14:
case 0x15:
case 0x16:
case 0x17:
1502 case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
1503 case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f:
1504 case 0x20:
case 0x21:
case 0x22:
case 0x23:
1505 case 0x24:
case 0x25:
case 0x26:
case 0x27:
1506 case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
1507 case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
1508 case 0x30:
case 0x31:
case 0x32:
case 0x33:
1509 case 0x34:
case 0x35:
case 0x36:
case 0x37:
1510 case 0x38:
case 0x39:
case 0x3a:
case 0x3b:
1511 case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
1513 case 0x77:
case 0x7f:
1515 case 0x80:
case 0x81:
case 0x82:
case 0x83:
1516 case 0x84:
case 0x85:
case 0x86:
case 0x87:
1517 case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
1518 case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
1519 case 0x90:
case 0x91:
case 0x92:
case 0x93:
1520 case 0x94:
case 0x95:
case 0x96:
case 0x97:
1521 case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
1522 case 0x9c:
case 0x9d:
case 0x9e:
case 0x9f:
1523 case 0xa4:
case 0xa5:
case 0xa6:
case 0xa7:
1524 case 0xac:
case 0xad:
case 0xae:
case 0xaf:
1525 case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
1526 case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
1528 case 0xc0:
case 0xc2:
1529 case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
1530 case 0xc8:
case 0xca:
case 0xcb:
1531 case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
1532 case 0xd0:
case 0xd2:
case 0xd3:
1533 case 0xd4:
case 0xd5:
case 0xd6:
case 0xd7:
1534 case 0xd8:
case 0xda:
case 0xdb:
1535 case 0xdc:
case 0xdd:
case 0xde:
case 0xdf:
1536 case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
1537 case 0xe4:
case 0xe5:
case 0xe6:
case 0xe7:
1538 case 0xe8:
case 0xe9:
case 0xea:
case 0xeb:
1539 case 0xec:
case 0xed:
case 0xee:
case 0xef:
1540 case 0xf0:
case 0xf1:
case 0xf2:
1541 case 0xf4:
case 0xf5:
case 0xf6:
case 0xf7:
1542 case 0xf8:
case 0xf9:
case 0xfa:
case 0xfb:
1543 case 0xfc:
case 0xfd:
case 0xfe:
case 0xff:
1546 case 0x40: {
II ii = in_R_c<B>();
NEXT; }
1547 case 0x48: {
II ii = in_R_c<C>();
NEXT; }
1548 case 0x50: {
II ii = in_R_c<D>();
NEXT; }
1549 case 0x58: {
II ii = in_R_c<E>();
NEXT; }
1550 case 0x60: {
II ii = in_R_c<H>();
NEXT; }
1551 case 0x68: {
II ii = in_R_c<L>();
NEXT; }
1552 case 0x70: {
II ii = in_R_c<DUMMY>();
NEXT; }
1553 case 0x78: {
II ii = in_R_c<A>();
NEXT; }
1555 case 0x41: {
II ii = out_c_R<B>();
NEXT; }
1556 case 0x49: {
II ii = out_c_R<C>();
NEXT; }
1557 case 0x51: {
II ii = out_c_R<D>();
NEXT; }
1558 case 0x59: {
II ii = out_c_R<E>();
NEXT; }
1559 case 0x61: {
II ii = out_c_R<H>();
NEXT; }
1560 case 0x69: {
II ii = out_c_R<L>();
NEXT; }
1561 case 0x71: {
II ii = out_c_0();
NEXT; }
1562 case 0x79: {
II ii = out_c_R<A>();
NEXT; }
1564 case 0x42: {
II ii = sbc_hl_SS<BC>();
NEXT; }
1565 case 0x52: {
II ii = sbc_hl_SS<DE>();
NEXT; }
1566 case 0x62: {
II ii = sbc_hl_hl ();
NEXT; }
1567 case 0x72: {
II ii = sbc_hl_SS<SP>();
NEXT; }
1569 case 0x4a: {
II ii = adc_hl_SS<BC>();
NEXT; }
1570 case 0x5a: {
II ii = adc_hl_SS<DE>();
NEXT; }
1571 case 0x6a: {
II ii = adc_hl_hl ();
NEXT; }
1572 case 0x7a: {
II ii = adc_hl_SS<SP>();
NEXT; }
1574 case 0x43: {
II ii = ld_xword_SS_ED<BC>();
NEXT; }
1575 case 0x53: {
II ii = ld_xword_SS_ED<DE>();
NEXT; }
1576 case 0x63: {
II ii = ld_xword_SS_ED<HL>();
NEXT; }
1577 case 0x73: {
II ii = ld_xword_SS_ED<SP>();
NEXT; }
1579 case 0x4b: {
II ii = ld_SS_xword_ED<BC>();
NEXT; }
1580 case 0x5b: {
II ii = ld_SS_xword_ED<DE>();
NEXT; }
1581 case 0x6b: {
II ii = ld_SS_xword_ED<HL>();
NEXT; }
1582 case 0x7b: {
II ii = ld_SS_xword_ED<SP>();
NEXT; }
1584 case 0x47: {
II ii = ld_i_a();
NEXT; }
1585 case 0x4f: {
II ii = ld_r_a();
NEXT; }
1586 case 0x57: {
II ii = ld_a_IR<REG_I>();
if (T::isR800()) {
NEXT; }
else {
NEXT_STOP; }}
1587 case 0x5f: {
II ii = ld_a_IR<REG_R>();
if (T::isR800()) {
NEXT; }
else {
NEXT_STOP; }}
1589 case 0x67: {
II ii = rrd();
NEXT; }
1590 case 0x6f: {
II ii = rld();
NEXT; }
1592 case 0x45:
case 0x4d:
case 0x55:
case 0x5d:
1593 case 0x65:
case 0x6d:
case 0x75:
case 0x7d:
1595 case 0x46:
case 0x4e:
case 0x66:
case 0x6e:
1596 {
II ii = im_N<0>();
NEXT; }
1597 case 0x56:
case 0x76:
1598 {
II ii = im_N<1>();
NEXT; }
1599 case 0x5e:
case 0x7e:
1600 {
II ii = im_N<2>();
NEXT; }
1601 case 0x44:
case 0x4c:
case 0x54:
case 0x5c:
1602 case 0x64:
case 0x6c:
case 0x74:
case 0x7c:
1605 case 0xa0: {
II ii = ldi();
NEXT; }
1606 case 0xa1: {
II ii = cpi();
NEXT; }
1607 case 0xa2: {
II ii = ini();
NEXT; }
1608 case 0xa3: {
II ii = outi();
NEXT; }
1609 case 0xa8: {
II ii = ldd();
NEXT; }
1610 case 0xa9: {
II ii = cpd();
NEXT; }
1611 case 0xaa: {
II ii = ind();
NEXT; }
1612 case 0xab: {
II ii = outd();
NEXT; }
1613 case 0xb0: {
II ii = ldir();
NEXT; }
1614 case 0xb1: {
II ii = cpir();
NEXT; }
1615 case 0xb2: {
II ii = inir();
NEXT; }
1616 case 0xb3: {
II ii = otir();
NEXT; }
1617 case 0xb8: {
II ii = lddr();
NEXT; }
1618 case 0xb9: {
II ii = cpdr();
NEXT; }
1619 case 0xba: {
II ii = indr();
NEXT; }
1620 case 0xbb: {
II ii = otdr();
NEXT; }
1622 case 0xc1: {
II ii = T::isR800() ? mulub_a_R<B>() : nop();
NEXT; }
1623 case 0xc9: {
II ii = T::isR800() ? mulub_a_R<C>() : nop();
NEXT; }
1624 case 0xd1: {
II ii = T::isR800() ? mulub_a_R<D>() : nop();
NEXT; }
1625 case 0xd9: {
II ii = T::isR800() ? mulub_a_R<E>() : nop();
NEXT; }
1626 case 0xc3: {
II ii = T::isR800() ? muluw_hl_SS<BC>() : nop();
NEXT; }
1627 case 0xf3: {
II ii = T::isR800() ? muluw_hl_SS<SP>() : nop();
NEXT; }
1634 byte opcodeDD = RDMEM_OPCODE<0>(T::CC_DD + T::CC_MAIN);
1816 #ifdef USE_COMPUTED_GOTO 1817 goto *(opcodeTable[opcodeDD]);
1819 opcodeMain = opcodeDD;
1824 case 0x09: {
II ii = add_SS_TT<IX,BC,T::CC_DD>();
NEXT; }
1825 case 0x19: {
II ii = add_SS_TT<IX,DE,T::CC_DD>();
NEXT; }
1826 case 0x29: {
II ii = add_SS_SS<IX ,T::CC_DD>();
NEXT; }
1827 case 0x39: {
II ii = add_SS_TT<IX,SP,T::CC_DD>();
NEXT; }
1828 case 0x21: {
II ii = ld_SS_word<IX,T::CC_DD>();
NEXT; }
1829 case 0x22: {
II ii = ld_xword_SS<IX,T::CC_DD>();
NEXT; }
1830 case 0x2a: {
II ii = ld_SS_xword<IX,T::CC_DD>();
NEXT; }
1831 case 0x23: {
II ii = inc_SS<IX,T::CC_DD>();
NEXT; }
1832 case 0x2b: {
II ii = dec_SS<IX,T::CC_DD>();
NEXT; }
1833 case 0x24: {
II ii = inc_R<IXH,T::CC_DD>();
NEXT; }
1834 case 0x2c: {
II ii = inc_R<IXL,T::CC_DD>();
NEXT; }
1835 case 0x25: {
II ii = dec_R<IXH,T::CC_DD>();
NEXT; }
1836 case 0x2d: {
II ii = dec_R<IXL,T::CC_DD>();
NEXT; }
1837 case 0x26: {
II ii = ld_R_byte<IXH,T::CC_DD>();
NEXT; }
1838 case 0x2e: {
II ii = ld_R_byte<IXL,T::CC_DD>();
NEXT; }
1839 case 0x34: {
II ii = inc_xix<IX>();
NEXT; }
1840 case 0x35: {
II ii = dec_xix<IX>();
NEXT; }
1841 case 0x36: {
II ii = ld_xix_byte<IX>();
NEXT; }
1843 case 0x44: {
II ii = ld_R_R<B,IXH,T::CC_DD>();
NEXT; }
1844 case 0x45: {
II ii = ld_R_R<B,IXL,T::CC_DD>();
NEXT; }
1845 case 0x4c: {
II ii = ld_R_R<C,IXH,T::CC_DD>();
NEXT; }
1846 case 0x4d: {
II ii = ld_R_R<C,IXL,T::CC_DD>();
NEXT; }
1847 case 0x54: {
II ii = ld_R_R<D,IXH,T::CC_DD>();
NEXT; }
1848 case 0x55: {
II ii = ld_R_R<D,IXL,T::CC_DD>();
NEXT; }
1849 case 0x5c: {
II ii = ld_R_R<E,IXH,T::CC_DD>();
NEXT; }
1850 case 0x5d: {
II ii = ld_R_R<E,IXL,T::CC_DD>();
NEXT; }
1851 case 0x7c: {
II ii = ld_R_R<A,IXH,T::CC_DD>();
NEXT; }
1852 case 0x7d: {
II ii = ld_R_R<A,IXL,T::CC_DD>();
NEXT; }
1853 case 0x60: {
II ii = ld_R_R<IXH,B,T::CC_DD>();
NEXT; }
1854 case 0x61: {
II ii = ld_R_R<IXH,C,T::CC_DD>();
NEXT; }
1855 case 0x62: {
II ii = ld_R_R<IXH,D,T::CC_DD>();
NEXT; }
1856 case 0x63: {
II ii = ld_R_R<IXH,E,T::CC_DD>();
NEXT; }
1857 case 0x65: {
II ii = ld_R_R<IXH,IXL,T::CC_DD>();
NEXT; }
1858 case 0x67: {
II ii = ld_R_R<IXH,A,T::CC_DD>();
NEXT; }
1859 case 0x68: {
II ii = ld_R_R<IXL,B,T::CC_DD>();
NEXT; }
1860 case 0x69: {
II ii = ld_R_R<IXL,C,T::CC_DD>();
NEXT; }
1861 case 0x6a: {
II ii = ld_R_R<IXL,D,T::CC_DD>();
NEXT; }
1862 case 0x6b: {
II ii = ld_R_R<IXL,E,T::CC_DD>();
NEXT; }
1863 case 0x6c: {
II ii = ld_R_R<IXL,IXH,T::CC_DD>();
NEXT; }
1864 case 0x6f: {
II ii = ld_R_R<IXL,A,T::CC_DD>();
NEXT; }
1865 case 0x70: {
II ii = ld_xix_R<IX,B>();
NEXT; }
1866 case 0x71: {
II ii = ld_xix_R<IX,C>();
NEXT; }
1867 case 0x72: {
II ii = ld_xix_R<IX,D>();
NEXT; }
1868 case 0x73: {
II ii = ld_xix_R<IX,E>();
NEXT; }
1869 case 0x74: {
II ii = ld_xix_R<IX,H>();
NEXT; }
1870 case 0x75: {
II ii = ld_xix_R<IX,L>();
NEXT; }
1871 case 0x77: {
II ii = ld_xix_R<IX,A>();
NEXT; }
1872 case 0x46: {
II ii = ld_R_xix<B,IX>();
NEXT; }
1873 case 0x4e: {
II ii = ld_R_xix<C,IX>();
NEXT; }
1874 case 0x56: {
II ii = ld_R_xix<D,IX>();
NEXT; }
1875 case 0x5e: {
II ii = ld_R_xix<E,IX>();
NEXT; }
1876 case 0x66: {
II ii = ld_R_xix<H,IX>();
NEXT; }
1877 case 0x6e: {
II ii = ld_R_xix<L,IX>();
NEXT; }
1878 case 0x7e: {
II ii = ld_R_xix<A,IX>();
NEXT; }
1880 case 0x84: {
II ii = add_a_R<IXH,T::CC_DD>();
NEXT; }
1881 case 0x85: {
II ii = add_a_R<IXL,T::CC_DD>();
NEXT; }
1882 case 0x86: {
II ii = add_a_xix<IX>();
NEXT; }
1883 case 0x8c: {
II ii = adc_a_R<IXH,T::CC_DD>();
NEXT; }
1884 case 0x8d: {
II ii = adc_a_R<IXL,T::CC_DD>();
NEXT; }
1885 case 0x8e: {
II ii = adc_a_xix<IX>();
NEXT; }
1886 case 0x94: {
II ii = sub_R<IXH,T::CC_DD>();
NEXT; }
1887 case 0x95: {
II ii = sub_R<IXL,T::CC_DD>();
NEXT; }
1888 case 0x96: {
II ii = sub_xix<IX>();
NEXT; }
1889 case 0x9c: {
II ii = sbc_a_R<IXH,T::CC_DD>();
NEXT; }
1890 case 0x9d: {
II ii = sbc_a_R<IXL,T::CC_DD>();
NEXT; }
1891 case 0x9e: {
II ii = sbc_a_xix<IX>();
NEXT; }
1892 case 0xa4: {
II ii = and_R<IXH,T::CC_DD>();
NEXT; }
1893 case 0xa5: {
II ii = and_R<IXL,T::CC_DD>();
NEXT; }
1894 case 0xa6: {
II ii = and_xix<IX>();
NEXT; }
1895 case 0xac: {
II ii = xor_R<IXH,T::CC_DD>();
NEXT; }
1896 case 0xad: {
II ii = xor_R<IXL,T::CC_DD>();
NEXT; }
1897 case 0xae: {
II ii = xor_xix<IX>();
NEXT; }
1898 case 0xb4: {
II ii = or_R<IXH,T::CC_DD>();
NEXT; }
1899 case 0xb5: {
II ii = or_R<IXL,T::CC_DD>();
NEXT; }
1900 case 0xb6: {
II ii = or_xix<IX>();
NEXT; }
1901 case 0xbc: {
II ii = cp_R<IXH,T::CC_DD>();
NEXT; }
1902 case 0xbd: {
II ii = cp_R<IXL,T::CC_DD>();
NEXT; }
1903 case 0xbe: {
II ii = cp_xix<IX>();
NEXT; }
1905 case 0xe1: {
II ii = pop_SS <IX,T::CC_DD>();
NEXT; }
1906 case 0xe5: {
II ii = push_SS<IX,T::CC_DD>();
NEXT; }
1907 case 0xe3: {
II ii = ex_xsp_SS<IX,T::CC_DD>();
NEXT; }
1908 case 0xe9: {
II ii = jp_SS<IX,T::CC_DD>();
NEXT; }
1909 case 0xf9: {
II ii = ld_sp_SS<IX,T::CC_DD>();
NEXT; }
1910 case 0xcb: ixy = getIX();
goto xx_cb;
1911 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
1912 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
1919 byte opcodeFD = RDMEM_OPCODE<0>(T::CC_DD + T::CC_MAIN);
2101 #ifdef USE_COMPUTED_GOTO 2102 goto *(opcodeTable[opcodeFD]);
2104 opcodeMain = opcodeFD;
2109 case 0x09: {
II ii = add_SS_TT<IY,BC,T::CC_DD>();
NEXT; }
2110 case 0x19: {
II ii = add_SS_TT<IY,DE,T::CC_DD>();
NEXT; }
2111 case 0x29: {
II ii = add_SS_SS<IY ,T::CC_DD>();
NEXT; }
2112 case 0x39: {
II ii = add_SS_TT<IY,SP,T::CC_DD>();
NEXT; }
2113 case 0x21: {
II ii = ld_SS_word<IY,T::CC_DD>();
NEXT; }
2114 case 0x22: {
II ii = ld_xword_SS<IY,T::CC_DD>();
NEXT; }
2115 case 0x2a: {
II ii = ld_SS_xword<IY,T::CC_DD>();
NEXT; }
2116 case 0x23: {
II ii = inc_SS<IY,T::CC_DD>();
NEXT; }
2117 case 0x2b: {
II ii = dec_SS<IY,T::CC_DD>();
NEXT; }
2118 case 0x24: {
II ii = inc_R<IYH,T::CC_DD>();
NEXT; }
2119 case 0x2c: {
II ii = inc_R<IYL,T::CC_DD>();
NEXT; }
2120 case 0x25: {
II ii = dec_R<IYH,T::CC_DD>();
NEXT; }
2121 case 0x2d: {
II ii = dec_R<IYL,T::CC_DD>();
NEXT; }
2122 case 0x26: {
II ii = ld_R_byte<IYH,T::CC_DD>();
NEXT; }
2123 case 0x2e: {
II ii = ld_R_byte<IYL,T::CC_DD>();
NEXT; }
2124 case 0x34: {
II ii = inc_xix<IY>();
NEXT; }
2125 case 0x35: {
II ii = dec_xix<IY>();
NEXT; }
2126 case 0x36: {
II ii = ld_xix_byte<IY>();
NEXT; }
2128 case 0x44: {
II ii = ld_R_R<B,IYH,T::CC_DD>();
NEXT; }
2129 case 0x45: {
II ii = ld_R_R<B,IYL,T::CC_DD>();
NEXT; }
2130 case 0x4c: {
II ii = ld_R_R<C,IYH,T::CC_DD>();
NEXT; }
2131 case 0x4d: {
II ii = ld_R_R<C,IYL,T::CC_DD>();
NEXT; }
2132 case 0x54: {
II ii = ld_R_R<D,IYH,T::CC_DD>();
NEXT; }
2133 case 0x55: {
II ii = ld_R_R<D,IYL,T::CC_DD>();
NEXT; }
2134 case 0x5c: {
II ii = ld_R_R<E,IYH,T::CC_DD>();
NEXT; }
2135 case 0x5d: {
II ii = ld_R_R<E,IYL,T::CC_DD>();
NEXT; }
2136 case 0x7c: {
II ii = ld_R_R<A,IYH,T::CC_DD>();
NEXT; }
2137 case 0x7d: {
II ii = ld_R_R<A,IYL,T::CC_DD>();
NEXT; }
2138 case 0x60: {
II ii = ld_R_R<IYH,B,T::CC_DD>();
NEXT; }
2139 case 0x61: {
II ii = ld_R_R<IYH,C,T::CC_DD>();
NEXT; }
2140 case 0x62: {
II ii = ld_R_R<IYH,D,T::CC_DD>();
NEXT; }
2141 case 0x63: {
II ii = ld_R_R<IYH,E,T::CC_DD>();
NEXT; }
2142 case 0x65: {
II ii = ld_R_R<IYH,IYL,T::CC_DD>();
NEXT; }
2143 case 0x67: {
II ii = ld_R_R<IYH,A,T::CC_DD>();
NEXT; }
2144 case 0x68: {
II ii = ld_R_R<IYL,B,T::CC_DD>();
NEXT; }
2145 case 0x69: {
II ii = ld_R_R<IYL,C,T::CC_DD>();
NEXT; }
2146 case 0x6a: {
II ii = ld_R_R<IYL,D,T::CC_DD>();
NEXT; }
2147 case 0x6b: {
II ii = ld_R_R<IYL,E,T::CC_DD>();
NEXT; }
2148 case 0x6c: {
II ii = ld_R_R<IYL,IYH,T::CC_DD>();
NEXT; }
2149 case 0x6f: {
II ii = ld_R_R<IYL,A,T::CC_DD>();
NEXT; }
2150 case 0x70: {
II ii = ld_xix_R<IY,B>();
NEXT; }
2151 case 0x71: {
II ii = ld_xix_R<IY,C>();
NEXT; }
2152 case 0x72: {
II ii = ld_xix_R<IY,D>();
NEXT; }
2153 case 0x73: {
II ii = ld_xix_R<IY,E>();
NEXT; }
2154 case 0x74: {
II ii = ld_xix_R<IY,H>();
NEXT; }
2155 case 0x75: {
II ii = ld_xix_R<IY,L>();
NEXT; }
2156 case 0x77: {
II ii = ld_xix_R<IY,A>();
NEXT; }
2157 case 0x46: {
II ii = ld_R_xix<B,IY>();
NEXT; }
2158 case 0x4e: {
II ii = ld_R_xix<C,IY>();
NEXT; }
2159 case 0x56: {
II ii = ld_R_xix<D,IY>();
NEXT; }
2160 case 0x5e: {
II ii = ld_R_xix<E,IY>();
NEXT; }
2161 case 0x66: {
II ii = ld_R_xix<H,IY>();
NEXT; }
2162 case 0x6e: {
II ii = ld_R_xix<L,IY>();
NEXT; }
2163 case 0x7e: {
II ii = ld_R_xix<A,IY>();
NEXT; }
2165 case 0x84: {
II ii = add_a_R<IYH,T::CC_DD>();
NEXT; }
2166 case 0x85: {
II ii = add_a_R<IYL,T::CC_DD>();
NEXT; }
2167 case 0x86: {
II ii = add_a_xix<IY>();
NEXT; }
2168 case 0x8c: {
II ii = adc_a_R<IYH,T::CC_DD>();
NEXT; }
2169 case 0x8d: {
II ii = adc_a_R<IYL,T::CC_DD>();
NEXT; }
2170 case 0x8e: {
II ii = adc_a_xix<IY>();
NEXT; }
2171 case 0x94: {
II ii = sub_R<IYH,T::CC_DD>();
NEXT; }
2172 case 0x95: {
II ii = sub_R<IYL,T::CC_DD>();
NEXT; }
2173 case 0x96: {
II ii = sub_xix<IY>();
NEXT; }
2174 case 0x9c: {
II ii = sbc_a_R<IYH,T::CC_DD>();
NEXT; }
2175 case 0x9d: {
II ii = sbc_a_R<IYL,T::CC_DD>();
NEXT; }
2176 case 0x9e: {
II ii = sbc_a_xix<IY>();
NEXT; }
2177 case 0xa4: {
II ii = and_R<IYH,T::CC_DD>();
NEXT; }
2178 case 0xa5: {
II ii = and_R<IYL,T::CC_DD>();
NEXT; }
2179 case 0xa6: {
II ii = and_xix<IY>();
NEXT; }
2180 case 0xac: {
II ii = xor_R<IYH,T::CC_DD>();
NEXT; }
2181 case 0xad: {
II ii = xor_R<IYL,T::CC_DD>();
NEXT; }
2182 case 0xae: {
II ii = xor_xix<IY>();
NEXT; }
2183 case 0xb4: {
II ii = or_R<IYH,T::CC_DD>();
NEXT; }
2184 case 0xb5: {
II ii = or_R<IYL,T::CC_DD>();
NEXT; }
2185 case 0xb6: {
II ii = or_xix<IY>();
NEXT; }
2186 case 0xbc: {
II ii = cp_R<IYH,T::CC_DD>();
NEXT; }
2187 case 0xbd: {
II ii = cp_R<IYL,T::CC_DD>();
NEXT; }
2188 case 0xbe: {
II ii = cp_xix<IY>();
NEXT; }
2190 case 0xe1: {
II ii = pop_SS <IY,T::CC_DD>();
NEXT; }
2191 case 0xe5: {
II ii = push_SS<IY,T::CC_DD>();
NEXT; }
2192 case 0xe3: {
II ii = ex_xsp_SS<IY,T::CC_DD>();
NEXT; }
2193 case 0xe9: {
II ii = jp_SS<IY,T::CC_DD>();
NEXT; }
2194 case 0xf9: {
II ii = ld_sp_SS<IY,T::CC_DD>();
NEXT; }
2195 case 0xcb: ixy = getIY();
goto xx_cb;
2196 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
2197 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
2201 #ifndef USE_COMPUTED_GOTO 2207 unsigned tmp = RD_WORD_PC<1>(T::CC_DD + T::CC_DD_CB);
2208 int8_t ofst = tmp & 0xFF;
2209 unsigned addr = (ixy + ofst) & 0xFFFF;
2210 byte xxcb_opcode = tmp >> 8;
2211 switch (xxcb_opcode) {
2212 case 0x00: {
II ii = rlc_xix_R<B>(addr);
NEXT; }
2213 case 0x01: {
II ii = rlc_xix_R<C>(addr);
NEXT; }
2214 case 0x02: {
II ii = rlc_xix_R<D>(addr);
NEXT; }
2215 case 0x03: {
II ii = rlc_xix_R<E>(addr);
NEXT; }
2216 case 0x04: {
II ii = rlc_xix_R<H>(addr);
NEXT; }
2217 case 0x05: {
II ii = rlc_xix_R<L>(addr);
NEXT; }
2218 case 0x06: {
II ii = rlc_xix_R<DUMMY>(addr);
NEXT; }
2219 case 0x07: {
II ii = rlc_xix_R<A>(addr);
NEXT; }
2220 case 0x08: {
II ii = rrc_xix_R<B>(addr);
NEXT; }
2221 case 0x09: {
II ii = rrc_xix_R<C>(addr);
NEXT; }
2222 case 0x0a: {
II ii = rrc_xix_R<D>(addr);
NEXT; }
2223 case 0x0b: {
II ii = rrc_xix_R<E>(addr);
NEXT; }
2224 case 0x0c: {
II ii = rrc_xix_R<H>(addr);
NEXT; }
2225 case 0x0d: {
II ii = rrc_xix_R<L>(addr);
NEXT; }
2226 case 0x0e: {
II ii = rrc_xix_R<DUMMY>(addr);
NEXT; }
2227 case 0x0f: {
II ii = rrc_xix_R<A>(addr);
NEXT; }
2228 case 0x10: {
II ii = rl_xix_R<B>(addr);
NEXT; }
2229 case 0x11: {
II ii = rl_xix_R<C>(addr);
NEXT; }
2230 case 0x12: {
II ii = rl_xix_R<D>(addr);
NEXT; }
2231 case 0x13: {
II ii = rl_xix_R<E>(addr);
NEXT; }
2232 case 0x14: {
II ii = rl_xix_R<H>(addr);
NEXT; }
2233 case 0x15: {
II ii = rl_xix_R<L>(addr);
NEXT; }
2234 case 0x16: {
II ii = rl_xix_R<DUMMY>(addr);
NEXT; }
2235 case 0x17: {
II ii = rl_xix_R<A>(addr);
NEXT; }
2236 case 0x18: {
II ii = rr_xix_R<B>(addr);
NEXT; }
2237 case 0x19: {
II ii = rr_xix_R<C>(addr);
NEXT; }
2238 case 0x1a: {
II ii = rr_xix_R<D>(addr);
NEXT; }
2239 case 0x1b: {
II ii = rr_xix_R<E>(addr);
NEXT; }
2240 case 0x1c: {
II ii = rr_xix_R<H>(addr);
NEXT; }
2241 case 0x1d: {
II ii = rr_xix_R<L>(addr);
NEXT; }
2242 case 0x1e: {
II ii = rr_xix_R<DUMMY>(addr);
NEXT; }
2243 case 0x1f: {
II ii = rr_xix_R<A>(addr);
NEXT; }
2244 case 0x20: {
II ii = sla_xix_R<B>(addr);
NEXT; }
2245 case 0x21: {
II ii = sla_xix_R<C>(addr);
NEXT; }
2246 case 0x22: {
II ii = sla_xix_R<D>(addr);
NEXT; }
2247 case 0x23: {
II ii = sla_xix_R<E>(addr);
NEXT; }
2248 case 0x24: {
II ii = sla_xix_R<H>(addr);
NEXT; }
2249 case 0x25: {
II ii = sla_xix_R<L>(addr);
NEXT; }
2250 case 0x26: {
II ii = sla_xix_R<DUMMY>(addr);
NEXT; }
2251 case 0x27: {
II ii = sla_xix_R<A>(addr);
NEXT; }
2252 case 0x28: {
II ii = sra_xix_R<B>(addr);
NEXT; }
2253 case 0x29: {
II ii = sra_xix_R<C>(addr);
NEXT; }
2254 case 0x2a: {
II ii = sra_xix_R<D>(addr);
NEXT; }
2255 case 0x2b: {
II ii = sra_xix_R<E>(addr);
NEXT; }
2256 case 0x2c: {
II ii = sra_xix_R<H>(addr);
NEXT; }
2257 case 0x2d: {
II ii = sra_xix_R<L>(addr);
NEXT; }
2258 case 0x2e: {
II ii = sra_xix_R<DUMMY>(addr);
NEXT; }
2259 case 0x2f: {
II ii = sra_xix_R<A>(addr);
NEXT; }
2260 case 0x30: {
II ii = T::isR800() ? sll2() : sll_xix_R<B>(addr);
NEXT; }
2261 case 0x31: {
II ii = T::isR800() ? sll2() : sll_xix_R<C>(addr);
NEXT; }
2262 case 0x32: {
II ii = T::isR800() ? sll2() : sll_xix_R<D>(addr);
NEXT; }
2263 case 0x33: {
II ii = T::isR800() ? sll2() : sll_xix_R<E>(addr);
NEXT; }
2264 case 0x34: {
II ii = T::isR800() ? sll2() : sll_xix_R<H>(addr);
NEXT; }
2265 case 0x35: {
II ii = T::isR800() ? sll2() : sll_xix_R<L>(addr);
NEXT; }
2266 case 0x36: {
II ii = T::isR800() ? sll2() : sll_xix_R<DUMMY>(addr);
NEXT; }
2267 case 0x37: {
II ii = T::isR800() ? sll2() : sll_xix_R<A>(addr);
NEXT; }
2268 case 0x38: {
II ii = srl_xix_R<B>(addr);
NEXT; }
2269 case 0x39: {
II ii = srl_xix_R<C>(addr);
NEXT; }
2270 case 0x3a: {
II ii = srl_xix_R<D>(addr);
NEXT; }
2271 case 0x3b: {
II ii = srl_xix_R<E>(addr);
NEXT; }
2272 case 0x3c: {
II ii = srl_xix_R<H>(addr);
NEXT; }
2273 case 0x3d: {
II ii = srl_xix_R<L>(addr);
NEXT; }
2274 case 0x3e: {
II ii = srl_xix_R<DUMMY>(addr);
NEXT; }
2275 case 0x3f: {
II ii = srl_xix_R<A>(addr);
NEXT; }
2277 case 0x40:
case 0x41:
case 0x42:
case 0x43:
2278 case 0x44:
case 0x45:
case 0x46:
case 0x47:
2279 {
II ii = bit_N_xix<0>(addr);
NEXT; }
2280 case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
2281 case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
2282 {
II ii = bit_N_xix<1>(addr);
NEXT; }
2283 case 0x50:
case 0x51:
case 0x52:
case 0x53:
2284 case 0x54:
case 0x55:
case 0x56:
case 0x57:
2285 {
II ii = bit_N_xix<2>(addr);
NEXT; }
2286 case 0x58:
case 0x59:
case 0x5a:
case 0x5b:
2287 case 0x5c:
case 0x5d:
case 0x5e:
case 0x5f:
2288 {
II ii = bit_N_xix<3>(addr);
NEXT; }
2289 case 0x60:
case 0x61:
case 0x62:
case 0x63:
2290 case 0x64:
case 0x65:
case 0x66:
case 0x67:
2291 {
II ii = bit_N_xix<4>(addr);
NEXT; }
2292 case 0x68:
case 0x69:
case 0x6a:
case 0x6b:
2293 case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
2294 {
II ii = bit_N_xix<5>(addr);
NEXT; }
2295 case 0x70:
case 0x71:
case 0x72:
case 0x73:
2296 case 0x74:
case 0x75:
case 0x76:
case 0x77:
2297 {
II ii = bit_N_xix<6>(addr);
NEXT; }
2298 case 0x78:
case 0x79:
case 0x7a:
case 0x7b:
2299 case 0x7c:
case 0x7d:
case 0x7e:
case 0x7f:
2300 {
II ii = bit_N_xix<7>(addr);
NEXT; }
2302 case 0x80: {
II ii = res_N_xix_R<0,B>(addr);
NEXT; }
2303 case 0x81: {
II ii = res_N_xix_R<0,C>(addr);
NEXT; }
2304 case 0x82: {
II ii = res_N_xix_R<0,D>(addr);
NEXT; }
2305 case 0x83: {
II ii = res_N_xix_R<0,E>(addr);
NEXT; }
2306 case 0x84: {
II ii = res_N_xix_R<0,H>(addr);
NEXT; }
2307 case 0x85: {
II ii = res_N_xix_R<0,L>(addr);
NEXT; }
2308 case 0x87: {
II ii = res_N_xix_R<0,A>(addr);
NEXT; }
2309 case 0x88: {
II ii = res_N_xix_R<1,B>(addr);
NEXT; }
2310 case 0x89: {
II ii = res_N_xix_R<1,C>(addr);
NEXT; }
2311 case 0x8a: {
II ii = res_N_xix_R<1,D>(addr);
NEXT; }
2312 case 0x8b: {
II ii = res_N_xix_R<1,E>(addr);
NEXT; }
2313 case 0x8c: {
II ii = res_N_xix_R<1,H>(addr);
NEXT; }
2314 case 0x8d: {
II ii = res_N_xix_R<1,L>(addr);
NEXT; }
2315 case 0x8f: {
II ii = res_N_xix_R<1,A>(addr);
NEXT; }
2316 case 0x90: {
II ii = res_N_xix_R<2,B>(addr);
NEXT; }
2317 case 0x91: {
II ii = res_N_xix_R<2,C>(addr);
NEXT; }
2318 case 0x92: {
II ii = res_N_xix_R<2,D>(addr);
NEXT; }
2319 case 0x93: {
II ii = res_N_xix_R<2,E>(addr);
NEXT; }
2320 case 0x94: {
II ii = res_N_xix_R<2,H>(addr);
NEXT; }
2321 case 0x95: {
II ii = res_N_xix_R<2,L>(addr);
NEXT; }
2322 case 0x97: {
II ii = res_N_xix_R<2,A>(addr);
NEXT; }
2323 case 0x98: {
II ii = res_N_xix_R<3,B>(addr);
NEXT; }
2324 case 0x99: {
II ii = res_N_xix_R<3,C>(addr);
NEXT; }
2325 case 0x9a: {
II ii = res_N_xix_R<3,D>(addr);
NEXT; }
2326 case 0x9b: {
II ii = res_N_xix_R<3,E>(addr);
NEXT; }
2327 case 0x9c: {
II ii = res_N_xix_R<3,H>(addr);
NEXT; }
2328 case 0x9d: {
II ii = res_N_xix_R<3,L>(addr);
NEXT; }
2329 case 0x9f: {
II ii = res_N_xix_R<3,A>(addr);
NEXT; }
2330 case 0xa0: {
II ii = res_N_xix_R<4,B>(addr);
NEXT; }
2331 case 0xa1: {
II ii = res_N_xix_R<4,C>(addr);
NEXT; }
2332 case 0xa2: {
II ii = res_N_xix_R<4,D>(addr);
NEXT; }
2333 case 0xa3: {
II ii = res_N_xix_R<4,E>(addr);
NEXT; }
2334 case 0xa4: {
II ii = res_N_xix_R<4,H>(addr);
NEXT; }
2335 case 0xa5: {
II ii = res_N_xix_R<4,L>(addr);
NEXT; }
2336 case 0xa7: {
II ii = res_N_xix_R<4,A>(addr);
NEXT; }
2337 case 0xa8: {
II ii = res_N_xix_R<5,B>(addr);
NEXT; }
2338 case 0xa9: {
II ii = res_N_xix_R<5,C>(addr);
NEXT; }
2339 case 0xaa: {
II ii = res_N_xix_R<5,D>(addr);
NEXT; }
2340 case 0xab: {
II ii = res_N_xix_R<5,E>(addr);
NEXT; }
2341 case 0xac: {
II ii = res_N_xix_R<5,H>(addr);
NEXT; }
2342 case 0xad: {
II ii = res_N_xix_R<5,L>(addr);
NEXT; }
2343 case 0xaf: {
II ii = res_N_xix_R<5,A>(addr);
NEXT; }
2344 case 0xb0: {
II ii = res_N_xix_R<6,B>(addr);
NEXT; }
2345 case 0xb1: {
II ii = res_N_xix_R<6,C>(addr);
NEXT; }
2346 case 0xb2: {
II ii = res_N_xix_R<6,D>(addr);
NEXT; }
2347 case 0xb3: {
II ii = res_N_xix_R<6,E>(addr);
NEXT; }
2348 case 0xb4: {
II ii = res_N_xix_R<6,H>(addr);
NEXT; }
2349 case 0xb5: {
II ii = res_N_xix_R<6,L>(addr);
NEXT; }
2350 case 0xb7: {
II ii = res_N_xix_R<6,A>(addr);
NEXT; }
2351 case 0xb8: {
II ii = res_N_xix_R<7,B>(addr);
NEXT; }
2352 case 0xb9: {
II ii = res_N_xix_R<7,C>(addr);
NEXT; }
2353 case 0xba: {
II ii = res_N_xix_R<7,D>(addr);
NEXT; }
2354 case 0xbb: {
II ii = res_N_xix_R<7,E>(addr);
NEXT; }
2355 case 0xbc: {
II ii = res_N_xix_R<7,H>(addr);
NEXT; }
2356 case 0xbd: {
II ii = res_N_xix_R<7,L>(addr);
NEXT; }
2357 case 0xbf: {
II ii = res_N_xix_R<7,A>(addr);
NEXT; }
2358 case 0x86: {
II ii = res_N_xix_R<0,DUMMY>(addr);
NEXT; }
2359 case 0x8e: {
II ii = res_N_xix_R<1,DUMMY>(addr);
NEXT; }
2360 case 0x96: {
II ii = res_N_xix_R<2,DUMMY>(addr);
NEXT; }
2361 case 0x9e: {
II ii = res_N_xix_R<3,DUMMY>(addr);
NEXT; }
2362 case 0xa6: {
II ii = res_N_xix_R<4,DUMMY>(addr);
NEXT; }
2363 case 0xae: {
II ii = res_N_xix_R<5,DUMMY>(addr);
NEXT; }
2364 case 0xb6: {
II ii = res_N_xix_R<6,DUMMY>(addr);
NEXT; }
2365 case 0xbe: {
II ii = res_N_xix_R<7,DUMMY>(addr);
NEXT; }
2367 case 0xc0: {
II ii = set_N_xix_R<0,B>(addr);
NEXT; }
2368 case 0xc1: {
II ii = set_N_xix_R<0,C>(addr);
NEXT; }
2369 case 0xc2: {
II ii = set_N_xix_R<0,D>(addr);
NEXT; }
2370 case 0xc3: {
II ii = set_N_xix_R<0,E>(addr);
NEXT; }
2371 case 0xc4: {
II ii = set_N_xix_R<0,H>(addr);
NEXT; }
2372 case 0xc5: {
II ii = set_N_xix_R<0,L>(addr);
NEXT; }
2373 case 0xc7: {
II ii = set_N_xix_R<0,A>(addr);
NEXT; }
2374 case 0xc8: {
II ii = set_N_xix_R<1,B>(addr);
NEXT; }
2375 case 0xc9: {
II ii = set_N_xix_R<1,C>(addr);
NEXT; }
2376 case 0xca: {
II ii = set_N_xix_R<1,D>(addr);
NEXT; }
2377 case 0xcb: {
II ii = set_N_xix_R<1,E>(addr);
NEXT; }
2378 case 0xcc: {
II ii = set_N_xix_R<1,H>(addr);
NEXT; }
2379 case 0xcd: {
II ii = set_N_xix_R<1,L>(addr);
NEXT; }
2380 case 0xcf: {
II ii = set_N_xix_R<1,A>(addr);
NEXT; }
2381 case 0xd0: {
II ii = set_N_xix_R<2,B>(addr);
NEXT; }
2382 case 0xd1: {
II ii = set_N_xix_R<2,C>(addr);
NEXT; }
2383 case 0xd2: {
II ii = set_N_xix_R<2,D>(addr);
NEXT; }
2384 case 0xd3: {
II ii = set_N_xix_R<2,E>(addr);
NEXT; }
2385 case 0xd4: {
II ii = set_N_xix_R<2,H>(addr);
NEXT; }
2386 case 0xd5: {
II ii = set_N_xix_R<2,L>(addr);
NEXT; }
2387 case 0xd7: {
II ii = set_N_xix_R<2,A>(addr);
NEXT; }
2388 case 0xd8: {
II ii = set_N_xix_R<3,B>(addr);
NEXT; }
2389 case 0xd9: {
II ii = set_N_xix_R<3,C>(addr);
NEXT; }
2390 case 0xda: {
II ii = set_N_xix_R<3,D>(addr);
NEXT; }
2391 case 0xdb: {
II ii = set_N_xix_R<3,E>(addr);
NEXT; }
2392 case 0xdc: {
II ii = set_N_xix_R<3,H>(addr);
NEXT; }
2393 case 0xdd: {
II ii = set_N_xix_R<3,L>(addr);
NEXT; }
2394 case 0xdf: {
II ii = set_N_xix_R<3,A>(addr);
NEXT; }
2395 case 0xe0: {
II ii = set_N_xix_R<4,B>(addr);
NEXT; }
2396 case 0xe1: {
II ii = set_N_xix_R<4,C>(addr);
NEXT; }
2397 case 0xe2: {
II ii = set_N_xix_R<4,D>(addr);
NEXT; }
2398 case 0xe3: {
II ii = set_N_xix_R<4,E>(addr);
NEXT; }
2399 case 0xe4: {
II ii = set_N_xix_R<4,H>(addr);
NEXT; }
2400 case 0xe5: {
II ii = set_N_xix_R<4,L>(addr);
NEXT; }
2401 case 0xe7: {
II ii = set_N_xix_R<4,A>(addr);
NEXT; }
2402 case 0xe8: {
II ii = set_N_xix_R<5,B>(addr);
NEXT; }
2403 case 0xe9: {
II ii = set_N_xix_R<5,C>(addr);
NEXT; }
2404 case 0xea: {
II ii = set_N_xix_R<5,D>(addr);
NEXT; }
2405 case 0xeb: {
II ii = set_N_xix_R<5,E>(addr);
NEXT; }
2406 case 0xec: {
II ii = set_N_xix_R<5,H>(addr);
NEXT; }
2407 case 0xed: {
II ii = set_N_xix_R<5,L>(addr);
NEXT; }
2408 case 0xef: {
II ii = set_N_xix_R<5,A>(addr);
NEXT; }
2409 case 0xf0: {
II ii = set_N_xix_R<6,B>(addr);
NEXT; }
2410 case 0xf1: {
II ii = set_N_xix_R<6,C>(addr);
NEXT; }
2411 case 0xf2: {
II ii = set_N_xix_R<6,D>(addr);
NEXT; }
2412 case 0xf3: {
II ii = set_N_xix_R<6,E>(addr);
NEXT; }
2413 case 0xf4: {
II ii = set_N_xix_R<6,H>(addr);
NEXT; }
2414 case 0xf5: {
II ii = set_N_xix_R<6,L>(addr);
NEXT; }
2415 case 0xf7: {
II ii = set_N_xix_R<6,A>(addr);
NEXT; }
2416 case 0xf8: {
II ii = set_N_xix_R<7,B>(addr);
NEXT; }
2417 case 0xf9: {
II ii = set_N_xix_R<7,C>(addr);
NEXT; }
2418 case 0xfa: {
II ii = set_N_xix_R<7,D>(addr);
NEXT; }
2419 case 0xfb: {
II ii = set_N_xix_R<7,E>(addr);
NEXT; }
2420 case 0xfc: {
II ii = set_N_xix_R<7,H>(addr);
NEXT; }
2421 case 0xfd: {
II ii = set_N_xix_R<7,L>(addr);
NEXT; }
2422 case 0xff: {
II ii = set_N_xix_R<7,A>(addr);
NEXT; }
2423 case 0xc6: {
II ii = set_N_xix_R<0,DUMMY>(addr);
NEXT; }
2424 case 0xce: {
II ii = set_N_xix_R<1,DUMMY>(addr);
NEXT; }
2425 case 0xd6: {
II ii = set_N_xix_R<2,DUMMY>(addr);
NEXT; }
2426 case 0xde: {
II ii = set_N_xix_R<3,DUMMY>(addr);
NEXT; }
2427 case 0xe6: {
II ii = set_N_xix_R<4,DUMMY>(addr);
NEXT; }
2428 case 0xee: {
II ii = set_N_xix_R<5,DUMMY>(addr);
NEXT; }
2429 case 0xf6: {
II ii = set_N_xix_R<6,DUMMY>(addr);
NEXT; }
2430 case 0xfe: {
II ii = set_N_xix_R<7,DUMMY>(addr);
NEXT; }
2443 cpuTracePost_slow();
2450 dasm(*interface, start_pc, opbuf, dasmOutput, T::getTimeFast());
2451 std::cout << strCat(hex_string<4>(start_pc),
2453 " AF=", hex_string<4>(getAF()),
2454 " BC=", hex_string<4>(getBC()),
2455 " DE=", hex_string<4>(getDE()),
2456 " HL=", hex_string<4>(getHL()),
2457 " IX=", hex_string<4>(getIX()),
2458 " IY=", hex_string<4>(getIY()),
2459 " SP=", hex_string<4>(getSP()),
2466 if (
unlikely(nmiEdge))
return ExecIRQ::NMI;
2467 if (
unlikely(IRQStatus && getIFF1() && !prevWasEI()))
return ExecIRQ::IRQ;
2468 return ExecIRQ::NONE;
2473 if (
unlikely(execIRQ == ExecIRQ::NMI)) {
2476 }
else if (
unlikely(execIRQ == ExecIRQ::IRQ)) {
2496 assert(getF() & V_FLAG);
2497 setF(getF() & ~V_FLAG);
2512 incR(T::advanceHalt(T::haltStates(), scheduler.getNext()));
2513 setSlowInstructions();
2516 assert(T::limitReached());
2517 executeInstructions();
2543 assert(fastForward || !interface->isBreaked());
2545 interface->setFastForward(
true);
2547 execute2(fastForward);
2548 interface->setFastForward(
false);
2557 scheduler.schedule(T::getTime());
2558 setSlowInstructions();
2564 (!interface->anyBreakPoints() && !tracingEnabled)) {
2567 if (slowInstructions) {
2569 executeSlow(getExecIRQ());
2570 scheduler.schedule(T::getTimeFast());
2572 while (slowInstructions == 0) {
2574 if (
likely(!T::limitReached())) {
2576 executeInstructions();
2581 scheduler.schedule(T::getTimeFast());
2582 if (needExitCPULoop())
return;
2585 }
while (!needExitCPULoop());
2588 if (slowInstructions == 0) {
2590 assert(T::limitReached());
2591 executeInstructions();
2596 executeSlow(getExecIRQ());
2601 scheduler.schedule(T::getTime());
2634 auto execIRQ = getExecIRQ();
2635 if ((execIRQ == ExecIRQ::NONE) &&
2636 interface->checkBreakPoints(getPC(), motherboard)) {
2637 assert(interface->isBreaked());
2640 }
while (!needExitCPULoop());
2645 if (R8 ==
A) {
return getA(); }
2646 else if (R8 ==
F) {
return getF(); }
2647 else if (R8 ==
B) {
return getB(); }
2648 else if (R8 ==
C) {
return getC(); }
2649 else if (R8 ==
D) {
return getD(); }
2650 else if (R8 ==
E) {
return getE(); }
2651 else if (R8 ==
H) {
return getH(); }
2652 else if (R8 ==
L) {
return getL(); }
2653 else if (R8 ==
IXH) {
return getIXh(); }
2654 else if (R8 ==
IXL) {
return getIXl(); }
2655 else if (R8 ==
IYH) {
return getIYh(); }
2656 else if (R8 ==
IYL) {
return getIYl(); }
2657 else if (R8 ==
REG_I) {
return getI(); }
2658 else if (R8 ==
REG_R) {
return getR(); }
2659 else if (R8 == DUMMY) {
return 0; }
2663 if (R16 ==
AF) {
return getAF(); }
2664 else if (R16 ==
BC) {
return getBC(); }
2665 else if (R16 ==
DE) {
return getDE(); }
2666 else if (R16 ==
HL) {
return getHL(); }
2667 else if (R16 ==
IX) {
return getIX(); }
2668 else if (R16 ==
IY) {
return getIY(); }
2669 else if (R16 == SP) {
return getSP(); }
2673 if (R8 ==
A) { setA(x); }
2674 else if (R8 ==
F) { setF(x); }
2675 else if (R8 ==
B) { setB(x); }
2676 else if (R8 ==
C) { setC(x); }
2677 else if (R8 ==
D) { setD(x); }
2678 else if (R8 ==
E) { setE(x); }
2679 else if (R8 ==
H) { setH(x); }
2680 else if (R8 ==
L) { setL(x); }
2681 else if (R8 ==
IXH) { setIXh(x); }
2682 else if (R8 ==
IXL) { setIXl(x); }
2683 else if (R8 ==
IYH) { setIYh(x); }
2684 else if (R8 ==
IYL) { setIYl(x); }
2685 else if (R8 ==
REG_I) { setI(x); }
2686 else if (R8 ==
REG_R) { setR(x); }
2687 else if (R8 == DUMMY) { }
2691 if (R16 ==
AF) { setAF(x); }
2692 else if (R16 ==
BC) { setBC(x); }
2693 else if (R16 ==
DE) { setDE(x); }
2694 else if (R16 ==
HL) { setHL(x); }
2695 else if (R16 ==
IX) { setIX(x); }
2696 else if (R16 ==
IY) { setIY(x); }
2697 else if (R16 == SP) { setSP(x); }
2703 set8<DST>(get8<SRC>());
return {1, T::CC_LD_R_R + EE};
2708 setSP(get16<REG>());
return {1, T::CC_LD_SP_HL + EE};
2713 T::setMemPtr((getA() << 8) | ((get16<REG>() + 1) & 0xFF));
2714 WRMEM(get16<REG>(), getA(), T::CC_LD_SS_A_1);
2715 return {1, T::CC_LD_SS_A};
2720 WRMEM(getHL(), get8<SRC>(), T::CC_LD_HL_R_1);
2721 return {1, T::CC_LD_HL_R};
2726 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_LD_XIX_R_1);
2727 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2729 WRMEM(addr, get8<SRC>(), T::CC_DD + T::CC_LD_XIX_R_2);
2730 return {2, T::CC_DD + T::CC_LD_XIX_R};
2735 byte val = RDMEM_OPCODE<1>(T::CC_LD_HL_N_1);
2736 WRMEM(getHL(), val, T::CC_LD_HL_N_2);
2737 return {2, T::CC_LD_HL_N};
2742 unsigned tmp = RD_WORD_PC<1>(T::CC_DD + T::CC_LD_XIX_N_1);
2743 int8_t ofst = tmp & 0xFF;
2744 byte val = tmp >> 8;
2745 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2747 WRMEM(addr, val, T::CC_DD + T::CC_LD_XIX_N_2);
2748 return {3, T::CC_DD + T::CC_LD_XIX_N};
2753 unsigned x = RD_WORD_PC<1>(T::CC_LD_NN_A_1);
2754 T::setMemPtr((getA() << 8) | ((x + 1) & 0xFF));
2755 WRMEM(x, getA(), T::CC_LD_NN_A_2);
2756 return {3, T::CC_LD_NN_A};
2761 unsigned addr = RD_WORD_PC<1>(T::CC_LD_XX_HL_1 + EE);
2762 T::setMemPtr(addr + 1);
2763 WR_WORD(addr, reg, T::CC_LD_XX_HL_2 + EE);
2764 return {3, T::CC_LD_XX_HL + EE};
2767 return WR_NN_Y<EE >(get16<REG>());
2770 return WR_NN_Y<T::EE_ED>(get16<REG>());
2775 T::setMemPtr(get16<REG>() + 1);
2776 setA(RDMEM(get16<REG>(), T::CC_LD_A_SS_1));
2777 return {1, T::CC_LD_A_SS};
2782 unsigned addr = RD_WORD_PC<1>(T::CC_LD_A_NN_1);
2783 T::setMemPtr(addr + 1);
2784 setA(RDMEM(addr, T::CC_LD_A_NN_2));
2785 return {3, T::CC_LD_A_NN};
2790 set8<DST>(RDMEM_OPCODE<1>(T::CC_LD_R_N_1 + EE));
return {2, T::CC_LD_R_N + EE};
2795 set8<DST>(RDMEM(getHL(), T::CC_LD_R_HL_1));
return {1, T::CC_LD_R_HL};
2800 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_LD_R_XIX_1);
2801 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2803 set8<DST>(RDMEM(addr, T::CC_DD + T::CC_LD_R_XIX_2));
2804 return {2, T::CC_DD + T::CC_LD_R_XIX};
2809 unsigned addr = RD_WORD_PC<1>(T::CC_LD_HL_XX_1 + EE);
2810 T::setMemPtr(addr + 1);
2811 unsigned result = RD_WORD(addr, T::CC_LD_HL_XX_2 + EE);
2815 set16<REG>(RD_P_XX<EE>());
return {3, T::CC_LD_HL_XX + EE};
2818 set16<REG>(RD_P_XX<T::EE_ED>());
return {3, T::CC_LD_HL_XX + T::EE_ED};
2823 set16<REG>(RD_WORD_PC<1>(T::CC_LD_SS_NN_1 + EE));
return {3, T::CC_LD_SS_NN + EE};
2829 unsigned res = getA() + reg + ((getF() &
C_FLAG) ? 1 : 0);
2830 byte f = ((res & 0x100) ? C_FLAG : 0) |
2831 ((getA() ^ res ^ reg) & H_FLAG) |
2832 (((getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2835 f |= table.ZS[res & 0xFF];
2836 f |= getF() & (X_FLAG |
Y_FLAG);
2838 f |= table.ZSXY[res & 0xFF];
2844 unsigned res = 2 * getA() + ((getF() &
C_FLAG) ? 1 : 0);
2845 byte f = ((res & 0x100) ? C_FLAG : 0) |
2847 (((getA() ^ res) & 0x80) >> 5) |
2850 f |= table.ZS[res & 0xFF];
2851 f |= getF() & (X_FLAG |
Y_FLAG);
2853 f |= table.ZSXY[res & 0xFF];
2857 return {1, T::CC_CP_R};
2860 ADC(get8<SRC>());
return {1, T::CC_CP_R + EE};
2863 ADC(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2866 ADC(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2869 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2870 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2872 ADC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2873 return {2, T::CC_DD + T::CC_CP_XIX};
2878 unsigned res = getA() + reg;
2879 byte f = ((res & 0x100) ? C_FLAG : 0) |
2880 ((getA() ^ res ^ reg) & H_FLAG) |
2881 (((getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2884 f |= table.ZS[res & 0xFF];
2885 f |= getF() & (X_FLAG |
Y_FLAG);
2887 f |= table.ZSXY[res & 0xFF];
2893 unsigned res = 2 * getA();
2894 byte f = ((res & 0x100) ? C_FLAG : 0) |
2896 (((getA() ^ res) & 0x80) >> 5) |
2899 f |= table.ZS[res & 0xFF];
2900 f |= getF() & (X_FLAG |
Y_FLAG);
2902 f |= table.ZSXY[res & 0xFF];
2906 return {1, T::CC_CP_R};
2909 ADD(get8<SRC>());
return {1, T::CC_CP_R + EE};
2912 ADD(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2915 ADD(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2918 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2919 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2921 ADD(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2922 return {2, T::CC_DD + T::CC_CP_XIX};
2930 f |= table.ZSPH[getA()];
2931 f |= getF() & (X_FLAG |
Y_FLAG);
2933 f |= table.ZSPXY[getA()] |
H_FLAG;
2940 f |= table.ZSPH[getA()];
2941 f |= getF() & (X_FLAG |
Y_FLAG);
2943 f |= table.ZSPXY[getA()] |
H_FLAG;
2946 return {1, T::CC_CP_R};
2949 AND(get8<SRC>());
return {1, T::CC_CP_R + EE};
2952 AND(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2955 AND(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2958 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2959 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2961 AND(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2962 return {2, T::CC_DD + T::CC_CP_XIX};
2967 unsigned q = getA() - reg;
2968 byte f = table.ZS[q & 0xFF] |
2969 ((q & 0x100) ? C_FLAG : 0) |
2971 ((getA() ^ q ^ reg) & H_FLAG) |
2972 (((reg ^ getA()) & (getA() ^ q) & 0x80) >> 5);
2974 f |= getF() & (X_FLAG |
Y_FLAG);
2976 f |= reg & (X_FLAG |
Y_FLAG);
2983 f |= getF() & (X_FLAG |
Y_FLAG);
2985 f |= getA() & (X_FLAG |
Y_FLAG);
2988 return {1, T::CC_CP_R};
2991 CP(get8<SRC>());
return {1, T::CC_CP_R + EE};
2994 CP(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2997 CP(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3000 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3001 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3003 CP(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3004 return {2, T::CC_DD + T::CC_CP_XIX};
3012 f |= table.ZSP[getA()];
3013 f |= getF() & (X_FLAG |
Y_FLAG);
3015 f |= table.ZSPXY[getA()];
3022 f |= table.ZSP[getA()];
3023 f |= getF() & (X_FLAG |
Y_FLAG);
3025 f |= table.ZSPXY[getA()];
3028 return {1, T::CC_CP_R};
3031 OR(get8<SRC>());
return {1, T::CC_CP_R + EE};
3034 OR(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3037 OR(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3040 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3041 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3043 OR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3044 return {2, T::CC_DD + T::CC_CP_XIX};
3049 unsigned res = getA() - reg - ((getF() &
C_FLAG) ? 1 : 0);
3050 byte f = ((res & 0x100) ? C_FLAG : 0) |
3052 ((getA() ^ res ^ reg) & H_FLAG) |
3053 (((reg ^ getA()) & (getA() ^ res) & 0x80) >> 5);
3055 f |= table.ZS[res & 0xFF];
3056 f |= getF() & (X_FLAG |
Y_FLAG);
3058 f |= table.ZSXY[res & 0xFF];
3066 ? (255 * 256 | ZS255 | C_FLAG | H_FLAG | N_FLAG)
3067 : ( 0 * 256 | ZS0 |
N_FLAG);
3068 setAF(t | (getF() & (X_FLAG | Y_FLAG)));
3070 setAF((getF() & C_FLAG) ?
3071 (255 * 256 | ZSXY255 | C_FLAG | H_FLAG | N_FLAG) :
3072 ( 0 * 256 | ZSXY0 | N_FLAG));
3074 return {1, T::CC_CP_R};
3077 SBC(get8<SRC>());
return {1, T::CC_CP_R + EE};
3080 SBC(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3083 SBC(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3086 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3087 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3089 SBC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3090 return {2, T::CC_DD + T::CC_CP_XIX};
3095 unsigned res = getA() - reg;
3096 byte f = ((res & 0x100) ? C_FLAG : 0) |
3098 ((getA() ^ res ^ reg) & H_FLAG) |
3099 (((reg ^ getA()) & (getA() ^ res) & 0x80) >> 5);
3101 f |= table.ZS[res & 0xFF];
3102 f |= getF() & (X_FLAG |
Y_FLAG);
3104 f |= table.ZSXY[res & 0xFF];
3112 setAF(t | (getF() & (X_FLAG | Y_FLAG)));
3114 setAF(0 * 256 | ZSXY0 | N_FLAG);
3116 return {1, T::CC_CP_R};
3119 SUB(get8<SRC>());
return {1, T::CC_CP_R + EE};
3122 SUB(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3125 SUB(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3128 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3129 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3131 SUB(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3132 return {2, T::CC_DD + T::CC_CP_XIX};
3140 f |= table.ZSP[getA()];
3141 f |= getF() & (X_FLAG |
Y_FLAG);
3143 f |= table.ZSPXY[getA()];
3150 setAF(t | (getF() & (X_FLAG | Y_FLAG)));
3152 setAF(0 * 256 + ZSPXY0);
3154 return {1, T::CC_CP_R};
3157 XOR(get8<SRC>());
return {1, T::CC_CP_R + EE};
3160 XOR(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3163 XOR(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3166 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3167 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3169 XOR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3170 return {2, T::CC_DD + T::CC_CP_XIX};
3177 byte f = ((reg & ~res & 0x80) >> 5) |
3178 (((res & 0x0F) + 1) &
H_FLAG) |
3181 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
3185 f |= table.ZSXY[res];
3191 set8<REG>(DEC(get8<REG>()));
return {1, T::CC_INC_R + EE};
3194 byte val = DEC(RDMEM(x, T::CC_INC_XHL_1 + EE));
3195 WRMEM(x, val, T::CC_INC_XHL_2 + EE);
3199 return {1, T::CC_INC_XHL};
3202 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_INC_XIX_1);
3203 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3205 DEC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3206 return {2, T::CC_INC_XHL + T::CC_DD + T::EE_INC_XIX};
3212 byte f = ((reg & -reg & 0x80) >> 5) |
3213 (((reg & 0x0F) - 1) &
H_FLAG) |
3216 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
3220 f |= table.ZSXY[reg];
3226 set8<REG>(INC(get8<REG>()));
return {1, T::CC_INC_R + EE};
3229 byte val = INC(RDMEM(x, T::CC_INC_XHL_1 + EE));
3230 WRMEM(x, val, T::CC_INC_XHL_2 + EE);
3234 return {1, T::CC_INC_XHL};
3237 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_INC_XIX_1);
3238 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3240 INC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3241 return {2, T::CC_INC_XHL + T::CC_DD + T::EE_INC_XIX};
3247 unsigned reg = get16<REG>();
3248 T::setMemPtr(getHL() + 1);
3249 unsigned res = getHL() + reg + ((getF() &
C_FLAG) ? 1 : 0);
3250 byte f = (res >> 16) |
3253 f |= getF() & (X_FLAG |
Y_FLAG);
3256 f |= ((getHL() ^ res ^ reg) >> 8) &
H_FLAG;
3258 f |= ((getHL() ^ res) & (reg ^ res) & 0x8000) >> 13;
3260 f |= (res >> 8) & S_FLAG;
3262 f |= (res >> 8) & (S_FLAG | X_FLAG | Y_FLAG);
3265 f |= ((getHL() ^ reg) >> 8) &
H_FLAG;
3267 f |= (getHL() & reg & 0x8000) >> 13;
3272 return {1, T::CC_ADC_HL_SS};
3275 T::setMemPtr(getHL() + 1);
3276 unsigned res = 2 * getHL() + ((getF() &
C_FLAG) ? 1 : 0);
3277 byte f = (res >> 16) |
3280 f |= getF() & (X_FLAG |
Y_FLAG);
3284 f |= ((getHL() ^ res) & 0x8000) >> 13;
3286 f |= (res >> 8) & (H_FLAG | S_FLAG);
3288 f |= (res >> 8) & (H_FLAG | S_FLAG | X_FLAG | Y_FLAG);
3292 f |= (getHL() & 0x8000) >> 13;
3297 return {1, T::CC_ADC_HL_SS};
3302 unsigned reg1 = get16<REG1>();
3303 unsigned reg2 = get16<REG2>();
3304 T::setMemPtr(reg1 + 1);
3305 unsigned res = reg1 + reg2;
3306 byte f = (((reg1 ^ res ^ reg2) >> 8) &
H_FLAG) |
3310 f |= getF() & (S_FLAG | Z_FLAG | V_FLAG | X_FLAG |
Y_FLAG);
3312 f |= getF() & (S_FLAG | Z_FLAG |
V_FLAG);
3313 f |= (res >> 8) & (X_FLAG | Y_FLAG);
3316 set16<REG1>(res & 0xFFFF);
3317 return {1, T::CC_ADD_HL_SS + EE};
3320 unsigned reg = get16<REG>();
3321 T::setMemPtr(reg + 1);
3322 unsigned res = 2 * reg;
3323 byte f = (res >> 16) |
3326 f |= getF() & (S_FLAG | Z_FLAG | V_FLAG | X_FLAG |
Y_FLAG);
3327 f |= (res >> 8) & H_FLAG;
3329 f |= getF() & (S_FLAG | Z_FLAG |
V_FLAG);
3330 f |= (res >> 8) & (H_FLAG | X_FLAG | Y_FLAG);
3333 set16<REG>(res & 0xFFFF);
3334 return {1, T::CC_ADD_HL_SS + EE};
3339 unsigned reg = get16<REG>();
3340 T::setMemPtr(getHL() + 1);
3341 unsigned res = getHL() - reg - ((getF() &
C_FLAG) ? 1 : 0);
3342 byte f = ((res & 0x10000) ? C_FLAG : 0) |
3345 f |= getF() & (X_FLAG |
Y_FLAG);
3348 f |= ((getHL() ^ res ^ reg) >> 8) &
H_FLAG;
3350 f |= ((reg ^ getHL()) & (getHL() ^ res) & 0x8000) >> 13;
3352 f |= (res >> 8) & S_FLAG;
3354 f |= (res >> 8) & (S_FLAG | X_FLAG | Y_FLAG);
3357 f |= ((getHL() ^ reg) >> 8) &
H_FLAG;
3359 f |= ((reg ^ getHL()) & getHL() & 0x8000) >> 13;
3364 return {1, T::CC_ADC_HL_SS};
3367 T::setMemPtr(getHL() + 1);
3368 byte f = T::isR800() ? (getF() & (X_FLAG |
Y_FLAG)) : 0;
3370 f |= C_FLAG | H_FLAG | S_FLAG |
N_FLAG;
3380 return {1, T::CC_ADC_HL_SS};
3385 set16<REG>(get16<REG>() - 1);
return {1, T::CC_INC_SS + EE};
3390 set16<REG>(get16<REG>() + 1);
return {1, T::CC_INC_SS + EE};
3396 byte reg = get8<REG>();
3400 f |= getF() & (S_FLAG | V_FLAG | C_FLAG | X_FLAG |
Y_FLAG);
3402 f |= (reg & (1 <<
N)) ? 0 :
Z_FLAG;
3404 f |= table.ZSPH[reg & (1 <<
N)];
3406 f |= reg & (X_FLAG |
Y_FLAG);
3409 return {1, T::CC_BIT_R};
3412 byte m = RDMEM(getHL(), T::CC_BIT_XHL_1) & (1 <<
N);
3415 f |= getF() & (S_FLAG | V_FLAG | C_FLAG | X_FLAG |
Y_FLAG);
3421 f |= (T::getMemPtr() >> 8) & (X_FLAG | Y_FLAG);
3424 return {1, T::CC_BIT_XHL};
3428 byte m = RDMEM(addr, T::CC_DD + T::CC_BIT_XIX_1) & (1 <<
N);
3431 f |= getF() & (S_FLAG | V_FLAG | C_FLAG | X_FLAG |
Y_FLAG);
3437 f |= (addr >> 8) & (X_FLAG | Y_FLAG);
3440 return {3, T::CC_DD + T::CC_BIT_XIX};
3444 static inline byte RES(
unsigned b,
byte reg) {
3445 return reg & ~(1 << b);
3448 set8<REG>(RES(
N, get8<REG>()));
return {1, T::CC_SET_R};
3451 byte res = RES(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3452 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3456 RES_X<0>(
N, getHL());
return {1, T::CC_SET_XHL};
3460 set8<REG>(RES_X<T::CC_DD + T::EE_SET_XIX>(
N, a));
3461 return {3, T::CC_DD + T::CC_SET_XIX};
3465 static inline byte SET(
unsigned b,
byte reg) {
3466 return reg | (1 << b);
3469 set8<REG>(SET(
N, get8<REG>()));
return {1, T::CC_SET_R};
3472 byte res = SET(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3473 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3477 SET_X<0>(
N, getHL());
return {1, T::CC_SET_XHL};
3481 set8<REG>(SET_X<T::CC_DD + T::EE_SET_XIX>(
N, a));
3482 return {3, T::CC_DD + T::CC_SET_XIX};
3488 reg = (reg << 1) | ((getF() & C_FLAG) ? 0x01 : 0);
3491 f |= table.ZSP[reg];
3492 f |= getF() & (X_FLAG |
Y_FLAG);
3494 f |= table.ZSPXY[reg];
3500 byte res = RL(RDMEM(x, T::CC_SET_XHL_1 + EE));
3501 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3505 set8<REG>(RL(get8<REG>()));
return {1, T::CC_SET_R};
3508 RL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3512 set8<REG>(RL_X<T::CC_DD + T::EE_SET_XIX>(a));
3513 return {3, T::CC_DD + T::CC_SET_XIX};
3519 reg = (reg << 1) | c;
3522 f |= table.ZSP[reg];
3523 f |= getF() & (X_FLAG |
Y_FLAG);
3525 f |= table.ZSPXY[reg];
3531 byte res = RLC(RDMEM(x, T::CC_SET_XHL_1 + EE));
3532 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3536 set8<REG>(RLC(get8<REG>()));
return {1, T::CC_SET_R};
3539 RLC_X<0>(getHL());
return {1, T::CC_SET_XHL};
3543 set8<REG>(RLC_X<T::CC_DD + T::EE_SET_XIX>(a));
3544 return {3, T::CC_DD + T::CC_SET_XIX};
3550 reg = (reg >> 1) | ((getF() & C_FLAG) << 7);
3553 f |= table.ZSP[reg];
3554 f |= getF() & (X_FLAG |
Y_FLAG);
3556 f |= table.ZSPXY[reg];
3562 byte res = RR(RDMEM(x, T::CC_SET_XHL_1 + EE));
3563 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3567 set8<REG>(RR(get8<REG>()));
return {1, T::CC_SET_R};
3570 RR_X<0>(getHL());
return {1, T::CC_SET_XHL};
3574 set8<REG>(RR_X<T::CC_DD + T::EE_SET_XIX>(a));
3575 return {3, T::CC_DD + T::CC_SET_XIX};
3581 reg = (reg >> 1) | (c << 7);
3584 f |= table.ZSP[reg];
3585 f |= getF() & (X_FLAG |
Y_FLAG);
3587 f |= table.ZSPXY[reg];
3593 byte res = RRC(RDMEM(x, T::CC_SET_XHL_1 + EE));
3594 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3598 set8<REG>(RRC(get8<REG>()));
return {1, T::CC_SET_R};
3601 RRC_X<0>(getHL());
return {1, T::CC_SET_XHL};
3605 set8<REG>(RRC_X<T::CC_DD + T::EE_SET_XIX>(a));
3606 return {3, T::CC_DD + T::CC_SET_XIX};
3615 f |= table.ZSP[reg];
3616 f |= getF() & (X_FLAG |
Y_FLAG);
3618 f |= table.ZSPXY[reg];
3624 byte res = SLA(RDMEM(x, T::CC_SET_XHL_1 + EE));
3625 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3629 set8<REG>(SLA(get8<REG>()));
return {1, T::CC_SET_R};
3632 SLA_X<0>(getHL());
return {1, T::CC_SET_XHL};
3636 set8<REG>(SLA_X<T::CC_DD + T::EE_SET_XIX>(a));
3637 return {3, T::CC_DD + T::CC_SET_XIX};
3642 assert(!T::isR800());
3644 reg = (reg << 1) | 1;
3646 f |= table.ZSPXY[reg];
3651 byte res = SLL(RDMEM(x, T::CC_SET_XHL_1 + EE));
3652 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3656 set8<REG>(SLL(get8<REG>()));
return {1, T::CC_SET_R};
3659 SLL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3663 set8<REG>(SLL_X<T::CC_DD + T::EE_SET_XIX>(a));
3664 return {3, T::CC_DD + T::CC_SET_XIX};
3667 assert(T::isR800());
3672 return {3, T::CC_DD + T::CC_SET_XIX};
3678 reg = (reg >> 1) | (reg & 0x80);
3681 f |= table.ZSP[reg];
3682 f |= getF() & (X_FLAG |
Y_FLAG);
3684 f |= table.ZSPXY[reg];
3690 byte res = SRA(RDMEM(x, T::CC_SET_XHL_1 + EE));
3691 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3695 set8<REG>(SRA(get8<REG>()));
return {1, T::CC_SET_R};
3698 SRA_X<0>(getHL());
return {1, T::CC_SET_XHL};
3702 set8<REG>(SRA_X<T::CC_DD + T::EE_SET_XIX>(a));
3703 return {3, T::CC_DD + T::CC_SET_XIX};
3712 f |= table.ZSP[reg];
3713 f |= getF() & (X_FLAG |
Y_FLAG);
3715 f |= table.ZSPXY[reg];
3721 byte res = SRL(RDMEM(x, T::CC_SET_XHL_1 + EE));
3722 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3726 set8<REG>(SRL(get8<REG>()));
return {1, T::CC_SET_R};
3729 SRL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3733 set8<REG>(SRL_X<T::CC_DD + T::EE_SET_XIX>(a));
3734 return {3, T::CC_DD + T::CC_SET_XIX};
3740 byte f = (getA() & 0x80) ? C_FLAG : 0;
3742 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG |
Y_FLAG);
3744 f |= getF() & (S_FLAG | Z_FLAG |
P_FLAG);
3746 setA((getA() << 1) | (c ? 1 : 0));
3748 f |= getA() & (X_FLAG |
Y_FLAG);
3751 return {1, T::CC_RLA};
3754 setA((getA() << 1) | (getA() >> 7));
3757 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG |
Y_FLAG);
3760 f |= getF() & (S_FLAG | Z_FLAG |
P_FLAG);
3761 f |= getA() & (Y_FLAG | X_FLAG |
C_FLAG);
3764 return {1, T::CC_RLA};
3768 byte f = (getA() & 0x01) ? C_FLAG : 0;
3770 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG |
Y_FLAG);
3772 f |= getF() & (S_FLAG | Z_FLAG |
P_FLAG);
3774 setA((getA() >> 1) | c);
3776 f |= getA() & (X_FLAG |
Y_FLAG);
3779 return {1, T::CC_RLA};
3784 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG |
Y_FLAG);
3786 f |= getF() & (S_FLAG | Z_FLAG |
P_FLAG);
3788 setA((getA() >> 1) | (getA() << 7));
3790 f |= getA() & (X_FLAG |
Y_FLAG);
3793 return {1, T::CC_RLA};
3799 byte val = RDMEM(getHL(), T::CC_RLD_1);
3800 T::setMemPtr(getHL() + 1);
3801 WRMEM(getHL(), (val << 4) | (getA() & 0x0F), T::CC_RLD_2);
3802 setA((getA() & 0xF0) | (val >> 4));
3805 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
3806 f |= table.ZSP[getA()];
3809 f |= table.ZSPXY[getA()];
3812 return {1, T::CC_RLD};
3817 byte val = RDMEM(getHL(), T::CC_RLD_1);
3818 T::setMemPtr(getHL() + 1);
3819 WRMEM(getHL(), (val >> 4) | (getA() << 4), T::CC_RLD_2);
3820 setA((getA() & 0xF0) | (val & 0x0F));
3823 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
3824 f |= table.ZSP[getA()];
3827 f |= table.ZSPXY[getA()];
3830 return {1, T::CC_RLD};
3835 template<
class T>
template<
int EE>
inline void CPUCore<T>::PUSH(
unsigned reg) {
3837 WR_WORD_rev<true, true>(getSP(), reg, T::CC_PUSH_1 + EE);
3840 PUSH<EE>(get16<REG>());
return {1, T::CC_PUSH + EE};
3844 template<
class T>
template<
int EE>
inline unsigned CPUCore<T>::POP() {
3845 unsigned addr = getSP();
3857 return RD_WORD(addr, T::CC_POP_1 + EE);
3860 set16<REG>(POP<EE>());
return {1, T::CC_POP + EE};
3866 unsigned addr = RD_WORD_PC<1>(T::CC_CALL_1);
3869 PUSH<T::EE_CALL>(getPC() + 3);
3873 setSlowInstructions();
3875 return {0, T::CC_CALL_A};
3877 return {3, T::CC_CALL_B};
3884 PUSH<0>(getPC() + 1);
3889 setSlowInstructions();
3891 return {0, T::CC_RST};
3896 template<
class T>
template<
int EE,
typename COND>
inline II CPUCore<T>::RET(COND cond) {
3898 unsigned addr = POP<EE>();
3901 return {0, T::CC_RET_A + EE};
3903 return {1, T::CC_RET_B + EE};
3907 return RET<T::EE_RET_C>(cond);
3914 setSlowInstructions();
3915 return RET<T::EE_RETN>(
CondTrue());
3921 setPC(get16<REG>()); T::R800ForcePageBreak();
return {0, T::CC_JP_HL + EE};
3926 unsigned addr = RD_WORD_PC<1>(T::CC_JP_1);
3930 T::R800ForcePageBreak();
3931 return {0, T::CC_JP_A};
3933 return {3, T::CC_JP_B};
3939 int8_t ofst = RDMEM_OPCODE<1>(T::CC_JR_1);
3941 if (((getPC() + 2) & 0xFF) == 0) {
3969 T::R800ForcePageBreak();
3971 setPC((getPC() + 2 + ofst) & 0xFFFF);
3972 T::setMemPtr(getPC());
3973 return {0, T::CC_JR_A};
3975 return {2, T::CC_JR_B};
3981 byte b = getB() - 1;
3983 int8_t ofst = RDMEM_OPCODE<1>(T::CC_JR_1 + T::EE_DJNZ);
3985 if (((getPC() + 2) & 0xFF) == 0) {
3987 T::R800ForcePageBreak();
3989 setPC((getPC() + 2 + ofst) & 0xFFFF);
3990 T::setMemPtr(getPC());
3991 return {0, T::CC_JR_A + T::EE_DJNZ};
3993 return {2, T::CC_JR_B + T::EE_DJNZ};
3999 unsigned res = RD_WORD_impl<true, false>(getSP(), T::CC_EX_SP_HL_1 + EE);
4001 WR_WORD_rev<false, true>(getSP(), get16<REG>(), T::CC_EX_SP_HL_2 + EE);
4003 return {1, T::CC_EX_SP_HL + EE};
4008 if (T::isR800()) T::waitForEvenCycle(T::CC_IN_R_C_1);
4009 T::setMemPtr(getBC() + 1);
4010 byte res = READ_PORT(getBC(), T::CC_IN_R_C_1);
4013 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
4014 f |= table.ZSP[res];
4017 f |= table.ZSPXY[res];
4021 return {1, T::CC_IN_R_C};
4026 unsigned y = RDMEM_OPCODE<1>(T::CC_IN_A_N_1) + 256 * getA();
4027 T::setMemPtr(y + 1);
4028 if (T::isR800()) T::waitForEvenCycle(T::CC_IN_A_N_2);
4029 setA(READ_PORT(y, T::CC_IN_A_N_2));
4030 return {2, T::CC_IN_A_N};
4035 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_C_R_1);
4036 T::setMemPtr(getBC() + 1);
4037 WRITE_PORT(getBC(), get8<REG>(), T::CC_OUT_C_R_1);
4038 return {1, T::CC_OUT_C_R};
4042 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_C_R_1);
4043 T::setMemPtr(getBC() + 1);
4044 byte out_c_x = isTurboR ? 255 : 0;
4045 WRITE_PORT(getBC(), out_c_x, T::CC_OUT_C_R_1);
4046 return {1, T::CC_OUT_C_R};
4051 byte port = RDMEM_OPCODE<1>(T::CC_OUT_N_A_1);
4052 unsigned y = (getA() << 8) | port;
4053 T::setMemPtr((getA() << 8) | ((port + 1) & 255));
4054 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_N_A_2);
4055 WRITE_PORT(y, getA(), T::CC_OUT_N_A_2);
4056 return {2, T::CC_OUT_N_A};
4062 T::setMemPtr(T::getMemPtr() + increase);
4063 byte val = RDMEM(getHL(), T::CC_CPI_1);
4064 byte res = getA() - val;
4065 setHL(getHL() + increase);
4067 byte f = ((getA() ^ val ^ res) & H_FLAG) |
4072 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
4075 unsigned k = res - ((f &
H_FLAG) >> 4);
4076 f |= (k << 4) & Y_FLAG;
4080 if (repeat && getBC() && res) {
4082 T::setMemPtr(getPC() + 1);
4083 return {-1, T::CC_CPIR};
4085 return {1, T::CC_CPI};
4096 byte val = RDMEM(getHL(), T::CC_LDI_1);
4097 WRMEM(getDE(), val, T::CC_LDI_2);
4098 setHL(getHL() + increase);
4099 setDE(getDE() + increase);
4103 f |= getF() & (S_FLAG | Z_FLAG | C_FLAG | X_FLAG |
Y_FLAG);
4105 f |= getF() & (S_FLAG | Z_FLAG |
C_FLAG);
4106 f |= ((getA() + val) << 4) &
Y_FLAG;
4107 f |= (getA() + val) & X_FLAG;
4110 if (repeat && getBC()) {
4112 T::setMemPtr(getPC() + 1);
4113 return {-1, T::CC_LDIR};
4115 return {1, T::CC_LDI};
4127 if (T::isR800()) T::waitForEvenCycle(T::CC_INI_1);
4128 T::setMemPtr(getBC() + increase);
4129 setBC(getBC() - 0x100);
4130 byte val = READ_PORT(getBC(), T::CC_INI_1);
4131 WRMEM(getHL(), val, T::CC_INI_2);
4132 setHL(getHL() + increase);
4133 unsigned k = val + ((getC() + increase) & 0xFF);
4135 setF(((val & S_FLAG) >> 6) |
4136 ((k & 0x100) ? (H_FLAG | C_FLAG) : 0) |
4138 (table.ZSPXY[(k & 0x07) ^ b] & P_FLAG));
4141 return {-1, T::CC_INIR};
4143 return {1, T::CC_INI};
4155 byte val = RDMEM(getHL(), T::CC_OUTI_1);
4156 setHL(getHL() + increase);
4157 if (T::isR800()) T::waitForEvenCycle(T::CC_OUTI_2);
4158 WRITE_PORT(getBC(), val, T::CC_OUTI_2);
4159 setBC(getBC() - 0x100);
4160 T::setMemPtr(getBC() + increase);
4161 unsigned k = val + getL();
4163 setF(((val & S_FLAG) >> 6) |
4164 ((k & 0x100) ? (H_FLAG | C_FLAG) : 0) |
4166 (table.ZSPXY[(k & 0x07) ^ b] & P_FLAG));
4169 return {-1, T::CC_OTIR};
4171 return {1, T::CC_OUTI};
4186 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | C_FLAG | X_FLAG | Y_FLAG |
H_FLAG);
4188 f |= (getF() &
C_FLAG) << 4;
4192 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | C_FLAG |
Y_FLAG);
4193 f |= (getF() | getA()) & X_FLAG;
4195 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG |
C_FLAG);
4196 f |= (getF() | getA()) & (X_FLAG | Y_FLAG);
4201 return {1, T::CC_CCF};
4204 setA(getA() ^ 0xFF);
4209 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG |
C_FLAG);
4210 f |= getA() & (X_FLAG |
Y_FLAG);
4213 return {1, T::CC_CPL};
4219 if ((f & H_FLAG) || ((getA() & 0xf) > 9)) adjust += 6;
4220 if ((f & C_FLAG) || (getA() > 0x99)) adjust += 0x60;
4223 f &= C_FLAG | N_FLAG | X_FLAG |
Y_FLAG;
4227 f |= table.ZSPXY[a];
4229 f |= (getA() > 0x99) | ((getA() ^ a) &
H_FLAG);
4232 return {1, T::CC_DAA};
4236 unsigned a = getA();
4237 unsigned res = -signed(a);
4238 byte f = ((res & 0x100) ? C_FLAG : 0) |
4240 ((res ^ a) & H_FLAG) |
4241 ((a & res & 0x80) >> 5);
4243 f |= table.ZS[res & 0xFF];
4244 f |= getF() & (X_FLAG |
Y_FLAG);
4246 f |= table.ZSXY[res & 0xFF];
4250 return {1, T::CC_NEG};
4255 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG |
Y_FLAG);
4260 f |= getF() & (S_FLAG | Z_FLAG | P_FLAG |
Y_FLAG);
4261 f |= (getF() | getA()) & X_FLAG;
4263 f |= getF() & (S_FLAG | Z_FLAG |
P_FLAG);
4264 f |= (getF() | getA()) & (X_FLAG | Y_FLAG);
4268 return {1, T::CC_SCF};
4272 unsigned t = getAF2(); setAF2(getAF()); setAF(t);
4273 return {1, T::CC_EX};
4276 unsigned t = getDE(); setDE(getHL()); setHL(t);
4277 return {1, T::CC_EX};
4280 unsigned t1 = getBC2(); setBC2(getBC()); setBC(t1);
4281 unsigned t2 = getDE2(); setDE2(getDE()); setDE(t2);
4282 unsigned t3 = getHL2(); setHL2(getHL()); setHL(t3);
4283 return {1, T::CC_EX};
4289 return {1, T::CC_DI};
4295 setSlowInstructions();
4296 return {1, T::CC_EI};
4300 setSlowInstructions();
4302 if (!(getIFF1() || getIFF2())) {
4303 diHaltCallback.execute();
4305 return {1, T::CC_HALT};
4308 setIM(
N);
return {1, T::CC_IM};
4316 f |= getF() & (C_FLAG | X_FLAG |
Y_FLAG);
4317 f |= table.ZS[getA()];
4320 f |= table.ZSXY[getA()];
4323 setSlowInstructions();
4326 return {1, T::CC_LD_A_I};
4339 if (T::isR800()) val -= 1;
4341 return {1, T::CC_LD_A_I};
4345 return {1, T::CC_LD_A_I};
4350 assert(T::isR800());
4356 setHL(
unsigned(getA()) * get8<REG>());
4357 setF((getF() & (N_FLAG | H_FLAG | X_FLAG | Y_FLAG)) |
4359 (getHL() ? 0 : Z_FLAG) |
4360 ((getHL() & 0xFF00) ? C_FLAG : 0));
4361 return {1, T::CC_MULUB};
4366 assert(T::isR800());
4372 unsigned res = unsigned(getHL()) * get16<REG>();
4374 setHL(res & 0xffff);
4375 setF((getF() & (N_FLAG | H_FLAG | X_FLAG | Y_FLAG)) |
4377 (res ? 0 : Z_FLAG) |
4378 ((res & 0xFFFF0000) ? C_FLAG : 0));
4379 return {1, T::CC_MULUW};
4389 template<
class T>
template<
typename Archive>
4393 ar.serialize(
"regs", static_cast<CPURegs&>(*
this));
4394 if (ar.versionBelow(version, 2)) {
4396 ar.serialize(
"memptr", mptr);
4400 if (ar.versionBelow(version, 5)) {
4409 ar.serialize(
"nmiEdge", nmiEdge);
4418 if (T::isR800() && ar.versionBelow(version, 4)) {
4419 motherboard.getMSXCliComm().printWarning(
4420 "Loading an old savestate: the timing of the R800 " 4421 "emulation has changed. This may cause synchronization " 4422 "problems in replay.");
uint8_t byte
8 bit unsigned integer
unsigned dasm(const MSXCPUInterface &interf, word pc, byte buf[4], std::string &dest, EmuTime::param time)
Disassemble.
CPUCore(MSXMotherBoard &motherboard, const std::string &name, const BooleanSetting &traceSetting, TclCallback &diHaltCallback, EmuTime::param time)
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte) const
Thanks to enen for testing this on a real cartridge:
bool operator()(byte f) const
uint16_t word
16 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte f) const
constexpr KeyMatrixPosition x
Keyboard bindings.
std::string strCat(Ts &&...ts)
bool operator()(byte f) const
bool operator()(byte f) const
void serialize(Archive &ar, T &t, unsigned version)
bool isMainThread()
Returns true when called from the main thread.
constexpr AdjustTables adjust