177 #include <type_traits>
205 enum Reg8 :
int {
A,
F,
B,
C,
D,
E,
H,
L,
IXH,
IXL,
IYH,
IYL,
REG_I,
REG_R,
DUMMY };
235 static constexpr
Table initTables()
239 for (
auto i :
xrange(256)) {
240 byte zFlag = (i == 0) ?
Z_FLAG : 0;
245 for (
int v = 128; v != 0; v >>= 1) {
246 if (i & v) vFlag ^=
V_FLAG;
249 table.
ZSXY [i] = zFlag | sFlag | xFlag | yFlag;
250 table.
ZSP [i] = zFlag | sFlag | vFlag;
251 table.
ZSPXY[i] = zFlag | sFlag | xFlag | yFlag | vFlag;
270 static word start_pc;
288 , T(time, motherboard_.getScheduler())
289 , motherboard(motherboard_)
290 , scheduler(motherboard.getScheduler())
292 , traceSetting(traceSetting_)
293 , diHaltCallback(diHaltCallback_)
294 , IRQStatus(motherboard.getDebugger(), name +
".pendingIRQ",
295 "Non-zero if there are pending IRQs (thus CPU would enter "
296 "interrupt routine in EI mode).",
298 , IRQAccept(motherboard.getDebugger(), name +
".acceptIRQ",
299 "This probe is only useful to set a breakpoint on (the value "
300 "return by read is meaningless). The breakpoint gets triggered "
301 "right after the CPU accepted an IRQ.")
303 motherboard.getCommandController(),
tmpStrCat(name,
"_freq_locked"),
304 "real (locked) or custom (unlocked) CPU frequency",
307 motherboard.getCommandController(),
tmpStrCat(name,
"_freq"),
308 "custom CPU frequency (only valid when unlocked)",
309 T::CLOCK_FREQ, 1000000, 1000000000)
310 , freq(T::CLOCK_FREQ)
314 , tracingEnabled(traceSetting.getBoolean())
315 , isTurboR(motherboard.isTurboR())
317 static_assert(!std::is_polymorphic_v<
CPUCore<T>>,
318 "keep CPUCore non-virtual to keep PC at offset 0");
325 assert(T::getTimeFast() <= time);
358 T::setMemPtr(0xFFFF);
388 assert(NMIStatus == 0);
389 assert(IRQStatus == 0);
426 template<
typename T>
void CPUCore<T>::setSlowInstructions()
428 slowInstructions = 2;
434 assert(IRQStatus >= 0);
435 if (IRQStatus == 0) {
436 setSlowInstructions();
438 IRQStatus = IRQStatus + 1;
443 IRQStatus = IRQStatus - 1;
444 assert(IRQStatus >= 0);
449 assert(NMIStatus >= 0);
450 if (NMIStatus == 0) {
452 setSlowInstructions();
460 assert(NMIStatus >= 0);
476 return address == getPC();
481 assert(time >= getCurrentTime());
482 scheduler.schedule(time);
483 T::advanceTime(time);
489 EmuTime time2 = T::calcTime(time, cycles);
492 scheduler.schedule(time2);
502 static inline char toHex(
byte x)
504 return (
x < 10) ? (
x +
'0') : (
x - 10 +
'A');
506 static void toHex(
byte x,
char* buf)
508 buf[0] = toHex(
x / 16);
509 buf[1] = toHex(
x & 15);
515 word address = (tokens.
size() < 3) ? getPC() : tokens[2].getInt(interp);
517 std::string dasmOutput;
518 unsigned len =
dasm(*interface, address, outBuf, dasmOutput,
521 char tmp[3]; tmp[2] = 0;
522 for (
auto i :
xrange(len)) {
523 toHex(outBuf[i], tmp);
530 if (&setting == &freqLocked) {
532 }
else if (&setting == &freqValue) {
534 }
else if (&setting == &traceSetting) {
535 tracingEnabled = traceSetting.getBoolean();
547 if (freqLocked.getBoolean()) {
552 T::setFreq(freqValue.getInt());
557 template<
typename T>
inline byte CPUCore<T>::READ_PORT(
unsigned port,
unsigned cc)
559 EmuTime time = T::getTimeFast(cc);
560 scheduler.schedule(time);
561 byte result = interface->readIO(port, time);
566 template<
typename T>
inline void CPUCore<T>::WRITE_PORT(
unsigned port,
byte value,
unsigned cc)
568 EmuTime time = T::getTimeFast(cc);
569 scheduler.schedule(time);
570 interface->writeIO(port, value, time);
574 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
580 if (readCacheLine[high] ==
nullptr) {
583 if (
const byte* line = interface->getReadCacheLine(addrBase)) {
585 T::template PRE_MEM<PRE_PB, POST_PB>(address);
586 T::template POST_MEM< POST_PB>(address);
587 readCacheLine[high] = line - addrBase;
588 return readCacheLine[high][address];
592 readCacheLine[high] =
reinterpret_cast<const byte*
>(1);
593 T::template PRE_MEM<PRE_PB, POST_PB>(address);
594 EmuTime time = T::getTimeFast(cc);
595 scheduler.schedule(time);
596 byte result = interface->readMem(address, time);
597 T::template POST_MEM<POST_PB>(address);
600 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
604 if (
likely(uintptr_t(line) > 1)) {
606 T::template PRE_MEM<PRE_PB, POST_PB>(address);
607 T::template POST_MEM< POST_PB>(address);
608 return line[address];
610 return RDMEMslow<PRE_PB, POST_PB>(address, cc);
613 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
618 return RDMEM_impl2<PRE, POST>(address, cc);
631 unsigned address = (getPC() + PC_OFFSET) & 0xFFFF;
632 return RDMEM_impl<false, false>(address, cc);
636 return RDMEM_impl<true, true>(address, cc);
639 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
642 unsigned res = RDMEM_impl<PRE_PB, false>(address, cc);
643 res += RDMEM_impl<false, POST_PB>((address + 1) & 0xFFFF, cc + T::CC_RDMEM) << 8;
646 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
652 T::template PRE_WORD<PRE_PB, POST_PB>(address);
653 T::template POST_WORD< POST_PB>(address);
657 return RD_WORD_slow<PRE_PB, POST_PB>(address, cc);
660 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
665 return RD_WORD_impl2<PRE, POST>(address, cc);
669 unsigned addr = (getPC() + PC_OFFSET) & 0xFFFF;
670 return RD_WORD_impl<false, false>(addr, cc);
673 unsigned address,
unsigned cc)
675 return RD_WORD_impl<true, true>(address, cc);
678 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
684 if (writeCacheLine[high] ==
nullptr) {
687 if (
byte* line = interface->getWriteCacheLine(addrBase)) {
689 T::template PRE_MEM<PRE_PB, POST_PB>(address);
690 T::template POST_MEM< POST_PB>(address);
691 writeCacheLine[high] = line - addrBase;
692 writeCacheLine[high][address] = value;
697 writeCacheLine[high] =
reinterpret_cast<byte*
>(1);
698 T::template PRE_MEM<PRE_PB, POST_PB>(address);
699 EmuTime time = T::getTimeFast(cc);
700 scheduler.schedule(time);
701 interface->writeMem(address, value, time);
702 T::template POST_MEM<POST_PB>(address);
704 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
706 unsigned address,
byte value,
unsigned cc)
709 if (
likely(uintptr_t(line) > 1)) {
711 T::template PRE_MEM<PRE_PB, POST_PB>(address);
712 T::template POST_MEM< POST_PB>(address);
713 line[address] = value;
715 WRMEMslow<PRE_PB, POST_PB>(address, value, cc);
718 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
720 unsigned address,
byte value,
unsigned cc)
724 WRMEM_impl2<PRE, POST>(address, value, cc);
727 unsigned address,
byte value,
unsigned cc)
729 WRMEM_impl<true, true>(address, value, cc);
732 template<
typename T>
NEVER_INLINE void CPUCore<T>::WR_WORD_slow(
733 unsigned address,
unsigned value,
unsigned cc)
735 WRMEM_impl<true, false>( address, value & 255, cc);
736 WRMEM_impl<false, true>((address + 1) & 0xFFFF, value >> 8, cc + T::CC_WRMEM);
739 unsigned address,
unsigned value,
unsigned cc)
744 T::template PRE_WORD<true, true>(address);
745 T::template POST_WORD< true>(address);
749 WR_WORD_slow(address, value, cc);
754 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
756 unsigned address,
unsigned value,
unsigned cc)
758 WRMEM_impl<PRE_PB, false>((address + 1) & 0xFFFF, value >> 8, cc);
759 WRMEM_impl<false, POST_PB>( address, value & 255, cc + T::CC_WRMEM);
761 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
763 unsigned address,
unsigned value,
unsigned cc)
768 T::template PRE_WORD<PRE_PB, POST_PB>(address);
769 T::template POST_WORD< POST_PB>(address);
773 WR_WORD_rev_slow<PRE_PB, POST_PB>(address, value, cc);
776 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
778 unsigned address,
unsigned value,
unsigned cc)
782 WR_WORD_rev2<PRE, POST>(address, value, cc);
792 PUSH<T::EE_NMI_1>(getPC());
798 template<
typename T>
inline void CPUCore<T>::irq0()
802 assert(interface->readIRQVector() == 0xFF);
807 PUSH<T::EE_IRQ0_1>(getPC());
809 T::setMemPtr(getPC());
814 template<
typename T>
inline void CPUCore<T>::irq1()
820 PUSH<T::EE_IRQ1_1>(getPC());
822 T::setMemPtr(getPC());
827 template<
typename T>
inline void CPUCore<T>::irq2()
833 PUSH<T::EE_IRQ2_1>(getPC());
834 unsigned x = interface->readIRQVector() | (getI() << 8);
835 setPC(RD_WORD(
x, T::CC_IRQ2_2));
836 T::setMemPtr(getPC());
841 void CPUCore<T>::executeInstructions()
843 checkNoCurrentFlags();
844 #ifdef USE_COMPUTED_GOTO
847 static void* opcodeTable[256] = {
848 &&op00, &&op01, &&op02, &&op03, &&op04, &&op05, &&op06, &&op07,
849 &&op08, &&op09, &&op0A, &&op0B, &&op0C, &&op0D, &&op0E, &&op0F,
850 &&op10, &&op11, &&op12, &&op13, &&op14, &&op15, &&op16, &&op17,
851 &&op18, &&op19, &&op1A, &&op1B, &&op1C, &&op1D, &&op1E, &&op1F,
852 &&op20, &&op21, &&op22, &&op23, &&op24, &&op25, &&op26, &&op27,
853 &&op28, &&op29, &&op2A, &&op2B, &&op2C, &&op2D, &&op2E, &&op2F,
854 &&op30, &&op31, &&op32, &&op33, &&op34, &&op35, &&op36, &&op37,
855 &&op38, &&op39, &&op3A, &&op3B, &&op3C, &&op3D, &&op3E, &&op3F,
856 &&op00, &&op41, &&op42, &&op43, &&op44, &&op45, &&op46, &&op47,
857 &&op48, &&op00, &&op4A, &&op4B, &&op4C, &&op4D, &&op4E, &&op4F,
858 &&op50, &&op51, &&op00, &&op53, &&op54, &&op55, &&op56, &&op57,
859 &&op58, &&op59, &&op5A, &&op00, &&op5C, &&op5D, &&op5E, &&op5F,
860 &&op60, &&op61, &&op62, &&op63, &&op00, &&op65, &&op66, &&op67,
861 &&op68, &&op69, &&op6A, &&op6B, &&op6C, &&op00, &&op6E, &&op6F,
862 &&op70, &&op71, &&op72, &&op73, &&op74, &&op75, &&op76, &&op77,
863 &&op78, &&op79, &&op7A, &&op7B, &&op7C, &&op7D, &&op7E, &&op00,
864 &&op80, &&op81, &&op82, &&op83, &&op84, &&op85, &&op86, &&op87,
865 &&op88, &&op89, &&op8A, &&op8B, &&op8C, &&op8D, &&op8E, &&op8F,
866 &&op90, &&op91, &&op92, &&op93, &&op94, &&op95, &&op96, &&op97,
867 &&op98, &&op99, &&op9A, &&op9B, &&op9C, &&op9D, &&op9E, &&op9F,
868 &&opA0, &&opA1, &&opA2, &&opA3, &&opA4, &&opA5, &&opA6, &&opA7,
869 &&opA8, &&opA9, &&opAA, &&opAB, &&opAC, &&opAD, &&opAE, &&opAF,
870 &&opB0, &&opB1, &&opB2, &&opB3, &&opB4, &&opB5, &&opB6, &&opB7,
871 &&opB8, &&opB9, &&opBA, &&opBB, &&opBC, &&opBD, &&opBE, &&opBF,
872 &&opC0, &&opC1, &&opC2, &&opC3, &&opC4, &&opC5, &&opC6, &&opC7,
873 &&opC8, &&opC9, &&opCA, &&opCB, &&opCC, &&opCD, &&opCE, &&opCF,
874 &&opD0, &&opD1, &&opD2, &&opD3, &&opD4, &&opD5, &&opD6, &&opD7,
875 &&opD8, &&opD9, &&opDA, &&opDB, &&opDC, &&opDD, &&opDE, &&opDF,
876 &&opE0, &&opE1, &&opE2, &&opE3, &&opE4, &&opE5, &&opE6, &&opE7,
877 &&opE8, &&opE9, &&opEA, &&opEB, &&opEC, &&opED, &&opEE, &&opEF,
878 &&opF0, &&opF1, &&opF2, &&opF3, &&opF4, &&opF5, &&opF6, &&opF7,
879 &&opF8, &&opF9, &&opFA, &&opFB, &&opFC, &&opFD, &&opFE, &&opFF,
885 setPC(getPC() + ii.length); \
887 T::R800Refresh(*this); \
888 if (likely(!T::limitReached())) { \
890 unsigned address = getPC(); \
891 const byte* line = readCacheLine[address >> CacheLine::BITS]; \
892 if (likely(uintptr_t(line) > 1)) { \
893 T::template PRE_MEM<false, false>(address); \
894 T::template POST_MEM< false>(address); \
895 byte op = line[address]; \
896 goto *(opcodeTable[op]); \
905 setPC(getPC() + ii.length); \
907 T::R800Refresh(*this); \
908 assert(T::limitReached()); \
912 setPC(getPC() + ii.length); \
915 assert(T::limitReached()); \
919 #define CASE(X) op##X:
921 #else // USE_COMPUTED_GOTO
924 setPC(getPC() + ii.length); \
926 T::R800Refresh(*this); \
927 if (likely(!T::limitReached())) { \
933 setPC(getPC() + ii.length); \
935 T::R800Refresh(*this); \
936 assert(T::limitReached()); \
940 setPC(getPC() + ii.length); \
943 assert(T::limitReached()); \
946 #define CASE(X) case 0x##X:
948 #endif // USE_COMPUTED_GOTO
950 #ifndef USE_COMPUTED_GOTO
954 byte opcodeMain = RDMEM_OPCODE<0>(T::CC_MAIN);
956 #ifdef USE_COMPUTED_GOTO
957 goto *(opcodeTable[opcodeMain]);
960 unsigned address = getPC();
961 byte opcodeSlow = RDMEMslow<false, false>(address, T::CC_MAIN);
962 goto *(opcodeTable[opcodeSlow]);
966 #ifndef USE_COMPUTED_GOTO
968 switch (opcodeMain) {
982 CASE(08) { II ii = ex_af_af();
NEXT; }
987 CASE(20) { II ii = jr(CondNZ());
NEXT; }
988 CASE(28) { II ii = jr(CondZ ());
NEXT; }
989 CASE(30) { II ii = jr(CondNC());
NEXT; }
990 CASE(38) { II ii = jr(CondC ());
NEXT; }
991 CASE(18) { II ii = jr(CondTrue());
NEXT; }
993 CASE(32) { II ii = ld_xbyte_a();
NEXT; }
995 CASE(22) { II ii = ld_xword_SS<HL,0>();
NEXT; }
996 CASE(2
A) { II ii = ld_SS_xword<HL,0>();
NEXT; }
997 CASE(02) { II ii = ld_SS_a<BC>();
NEXT; }
998 CASE(12) { II ii = ld_SS_a<DE>();
NEXT; }
999 CASE(1
A) { II ii = ld_a_SS<DE>();
NEXT; }
1000 CASE(0
A) { II ii = ld_a_SS<BC>();
NEXT; }
1001 CASE(03) { II ii = inc_SS<BC,0>();
NEXT; }
1002 CASE(13) { II ii = inc_SS<DE,0>();
NEXT; }
1003 CASE(23) { II ii = inc_SS<HL,0>();
NEXT; }
1004 CASE(33) { II ii = inc_SS<SP,0>();
NEXT; }
1005 CASE(0
B) { II ii = dec_SS<BC,0>();
NEXT; }
1006 CASE(1
B) { II ii = dec_SS<DE,0>();
NEXT; }
1007 CASE(2
B) { II ii = dec_SS<HL,0>();
NEXT; }
1008 CASE(3
B) { II ii = dec_SS<SP,0>();
NEXT; }
1009 CASE(09) { II ii = add_SS_TT<HL,BC,0>();
NEXT; }
1010 CASE(19) { II ii = add_SS_TT<HL,DE,0>();
NEXT; }
1011 CASE(29) { II ii = add_SS_SS<HL ,0>();
NEXT; }
1012 CASE(39) { II ii = add_SS_TT<HL,SP,0>();
NEXT; }
1013 CASE(01) { II ii = ld_SS_word<BC,0>();
NEXT; }
1014 CASE(11) { II ii = ld_SS_word<DE,0>();
NEXT; }
1015 CASE(21) { II ii = ld_SS_word<HL,0>();
NEXT; }
1016 CASE(31) { II ii = ld_SS_word<SP,0>();
NEXT; }
1017 CASE(04) { II ii = inc_R<B,0>();
NEXT; }
1018 CASE(0
C) { II ii = inc_R<C,0>();
NEXT; }
1019 CASE(14) { II ii = inc_R<D,0>();
NEXT; }
1020 CASE(1
C) { II ii = inc_R<E,0>();
NEXT; }
1021 CASE(24) { II ii = inc_R<H,0>();
NEXT; }
1022 CASE(2
C) { II ii = inc_R<L,0>();
NEXT; }
1023 CASE(3
C) { II ii = inc_R<A,0>();
NEXT; }
1024 CASE(34) { II ii = inc_xhl();
NEXT; }
1025 CASE(05) { II ii = dec_R<B,0>();
NEXT; }
1026 CASE(0
D) { II ii = dec_R<C,0>();
NEXT; }
1027 CASE(15) { II ii = dec_R<D,0>();
NEXT; }
1028 CASE(1
D) { II ii = dec_R<E,0>();
NEXT; }
1029 CASE(25) { II ii = dec_R<H,0>();
NEXT; }
1030 CASE(2
D) { II ii = dec_R<L,0>();
NEXT; }
1031 CASE(3
D) { II ii = dec_R<A,0>();
NEXT; }
1032 CASE(35) { II ii = dec_xhl();
NEXT; }
1033 CASE(06) { II ii = ld_R_byte<B,0>();
NEXT; }
1034 CASE(0
E) { II ii = ld_R_byte<C,0>();
NEXT; }
1035 CASE(16) { II ii = ld_R_byte<D,0>();
NEXT; }
1036 CASE(1
E) { II ii = ld_R_byte<E,0>();
NEXT; }
1037 CASE(26) { II ii = ld_R_byte<H,0>();
NEXT; }
1038 CASE(2
E) { II ii = ld_R_byte<L,0>();
NEXT; }
1039 CASE(3
E) { II ii = ld_R_byte<A,0>();
NEXT; }
1040 CASE(36) { II ii = ld_xhl_byte();
NEXT; }
1042 CASE(41) { II ii = ld_R_R<B,C,0>();
NEXT; }
1043 CASE(42) { II ii = ld_R_R<B,D,0>();
NEXT; }
1044 CASE(43) { II ii = ld_R_R<B,E,0>();
NEXT; }
1045 CASE(44) { II ii = ld_R_R<B,H,0>();
NEXT; }
1046 CASE(45) { II ii = ld_R_R<B,L,0>();
NEXT; }
1047 CASE(47) { II ii = ld_R_R<B,A,0>();
NEXT; }
1048 CASE(48) { II ii = ld_R_R<C,B,0>();
NEXT; }
1049 CASE(4
A) { II ii = ld_R_R<C,D,0>();
NEXT; }
1050 CASE(4
B) { II ii = ld_R_R<C,E,0>();
NEXT; }
1051 CASE(4
C) { II ii = ld_R_R<C,H,0>();
NEXT; }
1052 CASE(4
D) { II ii = ld_R_R<C,L,0>();
NEXT; }
1053 CASE(4
F) { II ii = ld_R_R<C,A,0>();
NEXT; }
1054 CASE(50) { II ii = ld_R_R<D,B,0>();
NEXT; }
1055 CASE(51) { II ii = ld_R_R<D,C,0>();
NEXT; }
1056 CASE(53) { II ii = ld_R_R<D,E,0>();
NEXT; }
1057 CASE(54) { II ii = ld_R_R<D,H,0>();
NEXT; }
1058 CASE(55) { II ii = ld_R_R<D,L,0>();
NEXT; }
1059 CASE(57) { II ii = ld_R_R<D,A,0>();
NEXT; }
1060 CASE(58) { II ii = ld_R_R<E,B,0>();
NEXT; }
1061 CASE(59) { II ii = ld_R_R<E,C,0>();
NEXT; }
1062 CASE(5
A) { II ii = ld_R_R<E,D,0>();
NEXT; }
1063 CASE(5
C) { II ii = ld_R_R<E,H,0>();
NEXT; }
1064 CASE(5
D) { II ii = ld_R_R<E,L,0>();
NEXT; }
1065 CASE(5
F) { II ii = ld_R_R<E,A,0>();
NEXT; }
1066 CASE(60) { II ii = ld_R_R<H,B,0>();
NEXT; }
1067 CASE(61) { II ii = ld_R_R<H,C,0>();
NEXT; }
1068 CASE(62) { II ii = ld_R_R<H,D,0>();
NEXT; }
1069 CASE(63) { II ii = ld_R_R<H,E,0>();
NEXT; }
1070 CASE(65) { II ii = ld_R_R<H,L,0>();
NEXT; }
1071 CASE(67) { II ii = ld_R_R<H,A,0>();
NEXT; }
1072 CASE(68) { II ii = ld_R_R<L,B,0>();
NEXT; }
1073 CASE(69) { II ii = ld_R_R<L,C,0>();
NEXT; }
1074 CASE(6
A) { II ii = ld_R_R<L,D,0>();
NEXT; }
1075 CASE(6
B) { II ii = ld_R_R<L,E,0>();
NEXT; }
1076 CASE(6
C) { II ii = ld_R_R<L,H,0>();
NEXT; }
1077 CASE(6
F) { II ii = ld_R_R<L,A,0>();
NEXT; }
1078 CASE(78) { II ii = ld_R_R<A,B,0>();
NEXT; }
1079 CASE(79) { II ii = ld_R_R<A,C,0>();
NEXT; }
1080 CASE(7
A) { II ii = ld_R_R<A,D,0>();
NEXT; }
1081 CASE(7
B) { II ii = ld_R_R<A,E,0>();
NEXT; }
1082 CASE(7
C) { II ii = ld_R_R<A,H,0>();
NEXT; }
1083 CASE(7
D) { II ii = ld_R_R<A,L,0>();
NEXT; }
1084 CASE(70) { II ii = ld_xhl_R<B>();
NEXT; }
1085 CASE(71) { II ii = ld_xhl_R<C>();
NEXT; }
1086 CASE(72) { II ii = ld_xhl_R<D>();
NEXT; }
1087 CASE(73) { II ii = ld_xhl_R<E>();
NEXT; }
1088 CASE(74) { II ii = ld_xhl_R<H>();
NEXT; }
1089 CASE(75) { II ii = ld_xhl_R<L>();
NEXT; }
1090 CASE(77) { II ii = ld_xhl_R<A>();
NEXT; }
1091 CASE(46) { II ii = ld_R_xhl<B>();
NEXT; }
1092 CASE(4
E) { II ii = ld_R_xhl<C>();
NEXT; }
1093 CASE(56) { II ii = ld_R_xhl<D>();
NEXT; }
1094 CASE(5
E) { II ii = ld_R_xhl<E>();
NEXT; }
1095 CASE(66) { II ii = ld_R_xhl<H>();
NEXT; }
1096 CASE(6
E) { II ii = ld_R_xhl<L>();
NEXT; }
1097 CASE(7
E) { II ii = ld_R_xhl<A>();
NEXT; }
1100 CASE(80) { II ii = add_a_R<B,0>();
NEXT; }
1101 CASE(81) { II ii = add_a_R<C,0>();
NEXT; }
1102 CASE(82) { II ii = add_a_R<D,0>();
NEXT; }
1103 CASE(83) { II ii = add_a_R<E,0>();
NEXT; }
1104 CASE(84) { II ii = add_a_R<H,0>();
NEXT; }
1105 CASE(85) { II ii = add_a_R<L,0>();
NEXT; }
1106 CASE(86) { II ii = add_a_xhl();
NEXT; }
1107 CASE(87) { II ii = add_a_a();
NEXT; }
1108 CASE(88) { II ii = adc_a_R<B,0>();
NEXT; }
1109 CASE(89) { II ii = adc_a_R<C,0>();
NEXT; }
1110 CASE(8
A) { II ii = adc_a_R<D,0>();
NEXT; }
1111 CASE(8
B) { II ii = adc_a_R<E,0>();
NEXT; }
1112 CASE(8
C) { II ii = adc_a_R<H,0>();
NEXT; }
1113 CASE(8
D) { II ii = adc_a_R<L,0>();
NEXT; }
1116 CASE(90) { II ii = sub_R<B,0>();
NEXT; }
1117 CASE(91) { II ii = sub_R<C,0>();
NEXT; }
1118 CASE(92) { II ii = sub_R<D,0>();
NEXT; }
1119 CASE(93) { II ii = sub_R<E,0>();
NEXT; }
1120 CASE(94) { II ii = sub_R<H,0>();
NEXT; }
1121 CASE(95) { II ii = sub_R<L,0>();
NEXT; }
1122 CASE(96) { II ii = sub_xhl();
NEXT; }
1123 CASE(97) { II ii = sub_a();
NEXT; }
1124 CASE(98) { II ii = sbc_a_R<B,0>();
NEXT; }
1125 CASE(99) { II ii = sbc_a_R<C,0>();
NEXT; }
1126 CASE(9
A) { II ii = sbc_a_R<D,0>();
NEXT; }
1127 CASE(9
B) { II ii = sbc_a_R<E,0>();
NEXT; }
1128 CASE(9
C) { II ii = sbc_a_R<H,0>();
NEXT; }
1129 CASE(9
D) { II ii = sbc_a_R<L,0>();
NEXT; }
1132 CASE(A0) { II ii = and_R<B,0>();
NEXT; }
1133 CASE(A1) { II ii = and_R<C,0>();
NEXT; }
1134 CASE(A2) { II ii = and_R<D,0>();
NEXT; }
1135 CASE(A3) { II ii = and_R<E,0>();
NEXT; }
1136 CASE(A4) { II ii = and_R<H,0>();
NEXT; }
1137 CASE(A5) { II ii = and_R<L,0>();
NEXT; }
1138 CASE(A6) { II ii = and_xhl();
NEXT; }
1139 CASE(A7) { II ii = and_a();
NEXT; }
1140 CASE(A8) { II ii = xor_R<B,0>();
NEXT; }
1141 CASE(A9) { II ii = xor_R<C,0>();
NEXT; }
1142 CASE(AA) { II ii = xor_R<D,0>();
NEXT; }
1143 CASE(AB) { II ii = xor_R<E,0>();
NEXT; }
1144 CASE(AC) { II ii = xor_R<H,0>();
NEXT; }
1145 CASE(AD) { II ii = xor_R<L,0>();
NEXT; }
1146 CASE(AE) { II ii = xor_xhl();
NEXT; }
1156 CASE(B8) { II ii = cp_R<B,0>();
NEXT; }
1157 CASE(B9) { II ii = cp_R<C,0>();
NEXT; }
1158 CASE(BA) { II ii = cp_R<D,0>();
NEXT; }
1159 CASE(BB) { II ii = cp_R<E,0>();
NEXT; }
1161 CASE(BD) { II ii = cp_R<L,0>();
NEXT; }
1162 CASE(BE) { II ii = cp_xhl();
NEXT; }
1165 CASE(D3) { II ii = out_byte_a();
NEXT; }
1166 CASE(DB) { II ii = in_a_byte();
NEXT; }
1168 CASE(E3) { II ii = ex_xsp_SS<HL,0>();
NEXT; }
1169 CASE(EB) { II ii = ex_de_hl();
NEXT; }
1170 CASE(E9) { II ii = jp_SS<HL,0>();
NEXT; }
1171 CASE(F9) { II ii = ld_sp_SS<HL,0>();
NEXT; }
1174 CASE(C6) { II ii = add_a_byte();
NEXT; }
1175 CASE(CE) { II ii = adc_a_byte();
NEXT; }
1176 CASE(D6) { II ii = sub_byte();
NEXT; }
1178 CASE(E6) { II ii = and_byte();
NEXT; }
1179 CASE(EE) { II ii = xor_byte();
NEXT; }
1180 CASE(F6) { II ii = or_byte();
NEXT; }
1181 CASE(FE) { II ii = cp_byte();
NEXT; }
1182 CASE(C0) { II ii = ret(CondNZ());
NEXT; }
1183 CASE(C8) { II ii = ret(CondZ ());
NEXT; }
1184 CASE(D0) { II ii = ret(CondNC());
NEXT; }
1185 CASE(D8) { II ii = ret(CondC ());
NEXT; }
1186 CASE(E0) { II ii = ret(CondPO());
NEXT; }
1187 CASE(E8) { II ii = ret(CondPE());
NEXT; }
1188 CASE(F0) { II ii = ret(CondP ());
NEXT; }
1189 CASE(F8) { II ii = ret(CondM ());
NEXT; }
1191 CASE(C2) { II ii = jp(CondNZ());
NEXT; }
1192 CASE(CA) { II ii = jp(CondZ ());
NEXT; }
1193 CASE(D2) { II ii = jp(CondNC());
NEXT; }
1194 CASE(DA) { II ii = jp(CondC ());
NEXT; }
1195 CASE(E2) { II ii = jp(CondPO());
NEXT; }
1196 CASE(EA) { II ii = jp(CondPE());
NEXT; }
1197 CASE(F2) { II ii = jp(CondP ());
NEXT; }
1198 CASE(FA) { II ii = jp(CondM ());
NEXT; }
1199 CASE(C3) { II ii = jp(CondTrue());
NEXT; }
1200 CASE(C4) { II ii = call(CondNZ());
NEXT; }
1201 CASE(CC) { II ii = call(CondZ ());
NEXT; }
1202 CASE(D4) { II ii = call(CondNC());
NEXT; }
1203 CASE(DC) { II ii = call(CondC ());
NEXT; }
1204 CASE(E4) { II ii = call(CondPO());
NEXT; }
1205 CASE(EC) { II ii = call(CondPE());
NEXT; }
1206 CASE(F4) { II ii = call(CondP ());
NEXT; }
1207 CASE(FC) { II ii = call(CondM ());
NEXT; }
1208 CASE(CD) { II ii = call(CondTrue());
NEXT; }
1209 CASE(C1) { II ii = pop_SS <BC,0>();
NEXT; }
1210 CASE(D1) { II ii = pop_SS <DE,0>();
NEXT; }
1211 CASE(E1) { II ii = pop_SS <HL,0>();
NEXT; }
1212 CASE(F1) { II ii = pop_SS <AF,0>();
NEXT; }
1213 CASE(C5) { II ii = push_SS<BC,0>();
NEXT; }
1214 CASE(D5) { II ii = push_SS<DE,0>();
NEXT; }
1215 CASE(E5) { II ii = push_SS<HL,0>();
NEXT; }
1216 CASE(F5) { II ii = push_SS<AF,0>();
NEXT; }
1217 CASE(C7) { II ii = rst<0x00>();
NEXT; }
1218 CASE(CF) { II ii = rst<0x08>();
NEXT; }
1219 CASE(D7) { II ii = rst<0x10>();
NEXT; }
1220 CASE(DF) { II ii = rst<0x18>();
NEXT; }
1221 CASE(E7) { II ii = rst<0x20>();
NEXT; }
1222 CASE(EF) { II ii = rst<0x28>();
NEXT; }
1223 CASE(F7) { II ii = rst<0x30>();
NEXT; }
1224 CASE(FF) { II ii = rst<0x38>();
NEXT; }
1227 byte cb_opcode = RDMEM_OPCODE<0>(T::CC_PREFIX);
1229 switch (cb_opcode) {
1230 case 0x00: { II ii = rlc_R<B>();
NEXT; }
1231 case 0x01: { II ii = rlc_R<C>();
NEXT; }
1232 case 0x02: { II ii = rlc_R<D>();
NEXT; }
1233 case 0x03: { II ii = rlc_R<E>();
NEXT; }
1234 case 0x04: { II ii = rlc_R<H>();
NEXT; }
1235 case 0x05: { II ii = rlc_R<L>();
NEXT; }
1236 case 0x07: { II ii = rlc_R<A>();
NEXT; }
1237 case 0x06: { II ii = rlc_xhl();
NEXT; }
1238 case 0x08: { II ii = rrc_R<B>();
NEXT; }
1239 case 0x09: { II ii = rrc_R<C>();
NEXT; }
1240 case 0x0a: { II ii = rrc_R<D>();
NEXT; }
1241 case 0x0b: { II ii = rrc_R<E>();
NEXT; }
1242 case 0x0c: { II ii = rrc_R<H>();
NEXT; }
1243 case 0x0d: { II ii = rrc_R<L>();
NEXT; }
1244 case 0x0f: { II ii = rrc_R<A>();
NEXT; }
1245 case 0x0e: { II ii = rrc_xhl();
NEXT; }
1246 case 0x10: { II ii = rl_R<B>();
NEXT; }
1247 case 0x11: { II ii = rl_R<C>();
NEXT; }
1248 case 0x12: { II ii = rl_R<D>();
NEXT; }
1249 case 0x13: { II ii = rl_R<E>();
NEXT; }
1250 case 0x14: { II ii = rl_R<H>();
NEXT; }
1251 case 0x15: { II ii = rl_R<L>();
NEXT; }
1252 case 0x17: { II ii = rl_R<A>();
NEXT; }
1253 case 0x16: { II ii = rl_xhl();
NEXT; }
1254 case 0x18: { II ii = rr_R<B>();
NEXT; }
1255 case 0x19: { II ii = rr_R<C>();
NEXT; }
1256 case 0x1a: { II ii = rr_R<D>();
NEXT; }
1257 case 0x1b: { II ii = rr_R<E>();
NEXT; }
1258 case 0x1c: { II ii = rr_R<H>();
NEXT; }
1259 case 0x1d: { II ii = rr_R<L>();
NEXT; }
1260 case 0x1f: { II ii = rr_R<A>();
NEXT; }
1261 case 0x1e: { II ii = rr_xhl();
NEXT; }
1262 case 0x20: { II ii = sla_R<B>();
NEXT; }
1263 case 0x21: { II ii = sla_R<C>();
NEXT; }
1264 case 0x22: { II ii = sla_R<D>();
NEXT; }
1265 case 0x23: { II ii = sla_R<E>();
NEXT; }
1266 case 0x24: { II ii = sla_R<H>();
NEXT; }
1267 case 0x25: { II ii = sla_R<L>();
NEXT; }
1268 case 0x27: { II ii = sla_R<A>();
NEXT; }
1269 case 0x26: { II ii = sla_xhl();
NEXT; }
1270 case 0x28: { II ii = sra_R<B>();
NEXT; }
1271 case 0x29: { II ii = sra_R<C>();
NEXT; }
1272 case 0x2a: { II ii = sra_R<D>();
NEXT; }
1273 case 0x2b: { II ii = sra_R<E>();
NEXT; }
1274 case 0x2c: { II ii = sra_R<H>();
NEXT; }
1275 case 0x2d: { II ii = sra_R<L>();
NEXT; }
1276 case 0x2f: { II ii = sra_R<A>();
NEXT; }
1277 case 0x2e: { II ii = sra_xhl();
NEXT; }
1278 case 0x30: { II ii = T::isR800() ? sla_R<B>() : sll_R<
B>();
NEXT; }
1279 case 0x31: { II ii = T::isR800() ? sla_R<C>() : sll_R<
C>();
NEXT; }
1280 case 0x32: { II ii = T::isR800() ? sla_R<D>() : sll_R<
D>();
NEXT; }
1281 case 0x33: { II ii = T::isR800() ? sla_R<E>() : sll_R<
E>();
NEXT; }
1282 case 0x34: { II ii = T::isR800() ? sla_R<H>() : sll_R<
H>();
NEXT; }
1283 case 0x35: { II ii = T::isR800() ? sla_R<L>() : sll_R<
L>();
NEXT; }
1284 case 0x37: { II ii = T::isR800() ? sla_R<A>() : sll_R<
A>();
NEXT; }
1285 case 0x36: { II ii = T::isR800() ? sla_xhl() : sll_xhl();
NEXT; }
1286 case 0x38: { II ii = srl_R<B>();
NEXT; }
1287 case 0x39: { II ii = srl_R<C>();
NEXT; }
1288 case 0x3a: { II ii = srl_R<D>();
NEXT; }
1289 case 0x3b: { II ii = srl_R<E>();
NEXT; }
1290 case 0x3c: { II ii = srl_R<H>();
NEXT; }
1291 case 0x3d: { II ii = srl_R<L>();
NEXT; }
1292 case 0x3f: { II ii = srl_R<A>();
NEXT; }
1293 case 0x3e: { II ii = srl_xhl();
NEXT; }
1295 case 0x40: { II ii = bit_N_R<0,B>();
NEXT; }
1296 case 0x41: { II ii = bit_N_R<0,C>();
NEXT; }
1297 case 0x42: { II ii = bit_N_R<0,D>();
NEXT; }
1298 case 0x43: { II ii = bit_N_R<0,E>();
NEXT; }
1299 case 0x44: { II ii = bit_N_R<0,H>();
NEXT; }
1300 case 0x45: { II ii = bit_N_R<0,L>();
NEXT; }
1301 case 0x47: { II ii = bit_N_R<0,A>();
NEXT; }
1302 case 0x48: { II ii = bit_N_R<1,B>();
NEXT; }
1303 case 0x49: { II ii = bit_N_R<1,C>();
NEXT; }
1304 case 0x4a: { II ii = bit_N_R<1,D>();
NEXT; }
1305 case 0x4b: { II ii = bit_N_R<1,E>();
NEXT; }
1306 case 0x4c: { II ii = bit_N_R<1,H>();
NEXT; }
1307 case 0x4d: { II ii = bit_N_R<1,L>();
NEXT; }
1308 case 0x4f: { II ii = bit_N_R<1,A>();
NEXT; }
1309 case 0x50: { II ii = bit_N_R<2,B>();
NEXT; }
1310 case 0x51: { II ii = bit_N_R<2,C>();
NEXT; }
1311 case 0x52: { II ii = bit_N_R<2,D>();
NEXT; }
1312 case 0x53: { II ii = bit_N_R<2,E>();
NEXT; }
1313 case 0x54: { II ii = bit_N_R<2,H>();
NEXT; }
1314 case 0x55: { II ii = bit_N_R<2,L>();
NEXT; }
1315 case 0x57: { II ii = bit_N_R<2,A>();
NEXT; }
1316 case 0x58: { II ii = bit_N_R<3,B>();
NEXT; }
1317 case 0x59: { II ii = bit_N_R<3,C>();
NEXT; }
1318 case 0x5a: { II ii = bit_N_R<3,D>();
NEXT; }
1319 case 0x5b: { II ii = bit_N_R<3,E>();
NEXT; }
1320 case 0x5c: { II ii = bit_N_R<3,H>();
NEXT; }
1321 case 0x5d: { II ii = bit_N_R<3,L>();
NEXT; }
1322 case 0x5f: { II ii = bit_N_R<3,A>();
NEXT; }
1323 case 0x60: { II ii = bit_N_R<4,B>();
NEXT; }
1324 case 0x61: { II ii = bit_N_R<4,C>();
NEXT; }
1325 case 0x62: { II ii = bit_N_R<4,D>();
NEXT; }
1326 case 0x63: { II ii = bit_N_R<4,E>();
NEXT; }
1327 case 0x64: { II ii = bit_N_R<4,H>();
NEXT; }
1328 case 0x65: { II ii = bit_N_R<4,L>();
NEXT; }
1329 case 0x67: { II ii = bit_N_R<4,A>();
NEXT; }
1330 case 0x68: { II ii = bit_N_R<5,B>();
NEXT; }
1331 case 0x69: { II ii = bit_N_R<5,C>();
NEXT; }
1332 case 0x6a: { II ii = bit_N_R<5,D>();
NEXT; }
1333 case 0x6b: { II ii = bit_N_R<5,E>();
NEXT; }
1334 case 0x6c: { II ii = bit_N_R<5,H>();
NEXT; }
1335 case 0x6d: { II ii = bit_N_R<5,L>();
NEXT; }
1336 case 0x6f: { II ii = bit_N_R<5,A>();
NEXT; }
1337 case 0x70: { II ii = bit_N_R<6,B>();
NEXT; }
1338 case 0x71: { II ii = bit_N_R<6,C>();
NEXT; }
1339 case 0x72: { II ii = bit_N_R<6,D>();
NEXT; }
1340 case 0x73: { II ii = bit_N_R<6,E>();
NEXT; }
1341 case 0x74: { II ii = bit_N_R<6,H>();
NEXT; }
1342 case 0x75: { II ii = bit_N_R<6,L>();
NEXT; }
1343 case 0x77: { II ii = bit_N_R<6,A>();
NEXT; }
1344 case 0x78: { II ii = bit_N_R<7,B>();
NEXT; }
1345 case 0x79: { II ii = bit_N_R<7,C>();
NEXT; }
1346 case 0x7a: { II ii = bit_N_R<7,D>();
NEXT; }
1347 case 0x7b: { II ii = bit_N_R<7,E>();
NEXT; }
1348 case 0x7c: { II ii = bit_N_R<7,H>();
NEXT; }
1349 case 0x7d: { II ii = bit_N_R<7,L>();
NEXT; }
1350 case 0x7f: { II ii = bit_N_R<7,A>();
NEXT; }
1351 case 0x46: { II ii = bit_N_xhl<0>();
NEXT; }
1352 case 0x4e: { II ii = bit_N_xhl<1>();
NEXT; }
1353 case 0x56: { II ii = bit_N_xhl<2>();
NEXT; }
1354 case 0x5e: { II ii = bit_N_xhl<3>();
NEXT; }
1355 case 0x66: { II ii = bit_N_xhl<4>();
NEXT; }
1356 case 0x6e: { II ii = bit_N_xhl<5>();
NEXT; }
1357 case 0x76: { II ii = bit_N_xhl<6>();
NEXT; }
1358 case 0x7e: { II ii = bit_N_xhl<7>();
NEXT; }
1360 case 0x80: { II ii = res_N_R<0,B>();
NEXT; }
1361 case 0x81: { II ii = res_N_R<0,C>();
NEXT; }
1362 case 0x82: { II ii = res_N_R<0,D>();
NEXT; }
1363 case 0x83: { II ii = res_N_R<0,E>();
NEXT; }
1364 case 0x84: { II ii = res_N_R<0,H>();
NEXT; }
1365 case 0x85: { II ii = res_N_R<0,L>();
NEXT; }
1366 case 0x87: { II ii = res_N_R<0,A>();
NEXT; }
1367 case 0x88: { II ii = res_N_R<1,B>();
NEXT; }
1368 case 0x89: { II ii = res_N_R<1,C>();
NEXT; }
1369 case 0x8a: { II ii = res_N_R<1,D>();
NEXT; }
1370 case 0x8b: { II ii = res_N_R<1,E>();
NEXT; }
1371 case 0x8c: { II ii = res_N_R<1,H>();
NEXT; }
1372 case 0x8d: { II ii = res_N_R<1,L>();
NEXT; }
1373 case 0x8f: { II ii = res_N_R<1,A>();
NEXT; }
1374 case 0x90: { II ii = res_N_R<2,B>();
NEXT; }
1375 case 0x91: { II ii = res_N_R<2,C>();
NEXT; }
1376 case 0x92: { II ii = res_N_R<2,D>();
NEXT; }
1377 case 0x93: { II ii = res_N_R<2,E>();
NEXT; }
1378 case 0x94: { II ii = res_N_R<2,H>();
NEXT; }
1379 case 0x95: { II ii = res_N_R<2,L>();
NEXT; }
1380 case 0x97: { II ii = res_N_R<2,A>();
NEXT; }
1381 case 0x98: { II ii = res_N_R<3,B>();
NEXT; }
1382 case 0x99: { II ii = res_N_R<3,C>();
NEXT; }
1383 case 0x9a: { II ii = res_N_R<3,D>();
NEXT; }
1384 case 0x9b: { II ii = res_N_R<3,E>();
NEXT; }
1385 case 0x9c: { II ii = res_N_R<3,H>();
NEXT; }
1386 case 0x9d: { II ii = res_N_R<3,L>();
NEXT; }
1387 case 0x9f: { II ii = res_N_R<3,A>();
NEXT; }
1388 case 0xa0: { II ii = res_N_R<4,B>();
NEXT; }
1389 case 0xa1: { II ii = res_N_R<4,C>();
NEXT; }
1390 case 0xa2: { II ii = res_N_R<4,D>();
NEXT; }
1391 case 0xa3: { II ii = res_N_R<4,E>();
NEXT; }
1392 case 0xa4: { II ii = res_N_R<4,H>();
NEXT; }
1393 case 0xa5: { II ii = res_N_R<4,L>();
NEXT; }
1394 case 0xa7: { II ii = res_N_R<4,A>();
NEXT; }
1395 case 0xa8: { II ii = res_N_R<5,B>();
NEXT; }
1396 case 0xa9: { II ii = res_N_R<5,C>();
NEXT; }
1397 case 0xaa: { II ii = res_N_R<5,D>();
NEXT; }
1398 case 0xab: { II ii = res_N_R<5,E>();
NEXT; }
1399 case 0xac: { II ii = res_N_R<5,H>();
NEXT; }
1400 case 0xad: { II ii = res_N_R<5,L>();
NEXT; }
1401 case 0xaf: { II ii = res_N_R<5,A>();
NEXT; }
1402 case 0xb0: { II ii = res_N_R<6,B>();
NEXT; }
1403 case 0xb1: { II ii = res_N_R<6,C>();
NEXT; }
1404 case 0xb2: { II ii = res_N_R<6,D>();
NEXT; }
1405 case 0xb3: { II ii = res_N_R<6,E>();
NEXT; }
1406 case 0xb4: { II ii = res_N_R<6,H>();
NEXT; }
1407 case 0xb5: { II ii = res_N_R<6,L>();
NEXT; }
1408 case 0xb7: { II ii = res_N_R<6,A>();
NEXT; }
1409 case 0xb8: { II ii = res_N_R<7,B>();
NEXT; }
1410 case 0xb9: { II ii = res_N_R<7,C>();
NEXT; }
1411 case 0xba: { II ii = res_N_R<7,D>();
NEXT; }
1412 case 0xbb: { II ii = res_N_R<7,E>();
NEXT; }
1413 case 0xbc: { II ii = res_N_R<7,H>();
NEXT; }
1414 case 0xbd: { II ii = res_N_R<7,L>();
NEXT; }
1415 case 0xbf: { II ii = res_N_R<7,A>();
NEXT; }
1416 case 0x86: { II ii = res_N_xhl<0>();
NEXT; }
1417 case 0x8e: { II ii = res_N_xhl<1>();
NEXT; }
1418 case 0x96: { II ii = res_N_xhl<2>();
NEXT; }
1419 case 0x9e: { II ii = res_N_xhl<3>();
NEXT; }
1420 case 0xa6: { II ii = res_N_xhl<4>();
NEXT; }
1421 case 0xae: { II ii = res_N_xhl<5>();
NEXT; }
1422 case 0xb6: { II ii = res_N_xhl<6>();
NEXT; }
1423 case 0xbe: { II ii = res_N_xhl<7>();
NEXT; }
1425 case 0xc0: { II ii = set_N_R<0,B>();
NEXT; }
1426 case 0xc1: { II ii = set_N_R<0,C>();
NEXT; }
1427 case 0xc2: { II ii = set_N_R<0,D>();
NEXT; }
1428 case 0xc3: { II ii = set_N_R<0,E>();
NEXT; }
1429 case 0xc4: { II ii = set_N_R<0,H>();
NEXT; }
1430 case 0xc5: { II ii = set_N_R<0,L>();
NEXT; }
1431 case 0xc7: { II ii = set_N_R<0,A>();
NEXT; }
1432 case 0xc8: { II ii = set_N_R<1,B>();
NEXT; }
1433 case 0xc9: { II ii = set_N_R<1,C>();
NEXT; }
1434 case 0xca: { II ii = set_N_R<1,D>();
NEXT; }
1435 case 0xcb: { II ii = set_N_R<1,E>();
NEXT; }
1436 case 0xcc: { II ii = set_N_R<1,H>();
NEXT; }
1437 case 0xcd: { II ii = set_N_R<1,L>();
NEXT; }
1438 case 0xcf: { II ii = set_N_R<1,A>();
NEXT; }
1439 case 0xd0: { II ii = set_N_R<2,B>();
NEXT; }
1440 case 0xd1: { II ii = set_N_R<2,C>();
NEXT; }
1441 case 0xd2: { II ii = set_N_R<2,D>();
NEXT; }
1442 case 0xd3: { II ii = set_N_R<2,E>();
NEXT; }
1443 case 0xd4: { II ii = set_N_R<2,H>();
NEXT; }
1444 case 0xd5: { II ii = set_N_R<2,L>();
NEXT; }
1445 case 0xd7: { II ii = set_N_R<2,A>();
NEXT; }
1446 case 0xd8: { II ii = set_N_R<3,B>();
NEXT; }
1447 case 0xd9: { II ii = set_N_R<3,C>();
NEXT; }
1448 case 0xda: { II ii = set_N_R<3,D>();
NEXT; }
1449 case 0xdb: { II ii = set_N_R<3,E>();
NEXT; }
1450 case 0xdc: { II ii = set_N_R<3,H>();
NEXT; }
1451 case 0xdd: { II ii = set_N_R<3,L>();
NEXT; }
1452 case 0xdf: { II ii = set_N_R<3,A>();
NEXT; }
1453 case 0xe0: { II ii = set_N_R<4,B>();
NEXT; }
1454 case 0xe1: { II ii = set_N_R<4,C>();
NEXT; }
1455 case 0xe2: { II ii = set_N_R<4,D>();
NEXT; }
1456 case 0xe3: { II ii = set_N_R<4,E>();
NEXT; }
1457 case 0xe4: { II ii = set_N_R<4,H>();
NEXT; }
1458 case 0xe5: { II ii = set_N_R<4,L>();
NEXT; }
1459 case 0xe7: { II ii = set_N_R<4,A>();
NEXT; }
1460 case 0xe8: { II ii = set_N_R<5,B>();
NEXT; }
1461 case 0xe9: { II ii = set_N_R<5,C>();
NEXT; }
1462 case 0xea: { II ii = set_N_R<5,D>();
NEXT; }
1463 case 0xeb: { II ii = set_N_R<5,E>();
NEXT; }
1464 case 0xec: { II ii = set_N_R<5,H>();
NEXT; }
1465 case 0xed: { II ii = set_N_R<5,L>();
NEXT; }
1466 case 0xef: { II ii = set_N_R<5,A>();
NEXT; }
1467 case 0xf0: { II ii = set_N_R<6,B>();
NEXT; }
1468 case 0xf1: { II ii = set_N_R<6,C>();
NEXT; }
1469 case 0xf2: { II ii = set_N_R<6,D>();
NEXT; }
1470 case 0xf3: { II ii = set_N_R<6,E>();
NEXT; }
1471 case 0xf4: { II ii = set_N_R<6,H>();
NEXT; }
1472 case 0xf5: { II ii = set_N_R<6,L>();
NEXT; }
1473 case 0xf7: { II ii = set_N_R<6,A>();
NEXT; }
1474 case 0xf8: { II ii = set_N_R<7,B>();
NEXT; }
1475 case 0xf9: { II ii = set_N_R<7,C>();
NEXT; }
1476 case 0xfa: { II ii = set_N_R<7,D>();
NEXT; }
1477 case 0xfb: { II ii = set_N_R<7,E>();
NEXT; }
1478 case 0xfc: { II ii = set_N_R<7,H>();
NEXT; }
1479 case 0xfd: { II ii = set_N_R<7,L>();
NEXT; }
1480 case 0xff: { II ii = set_N_R<7,A>();
NEXT; }
1481 case 0xc6: { II ii = set_N_xhl<0>();
NEXT; }
1482 case 0xce: { II ii = set_N_xhl<1>();
NEXT; }
1483 case 0xd6: { II ii = set_N_xhl<2>();
NEXT; }
1484 case 0xde: { II ii = set_N_xhl<3>();
NEXT; }
1485 case 0xe6: { II ii = set_N_xhl<4>();
NEXT; }
1486 case 0xee: { II ii = set_N_xhl<5>();
NEXT; }
1487 case 0xf6: { II ii = set_N_xhl<6>();
NEXT; }
1488 case 0xfe: { II ii = set_N_xhl<7>();
NEXT; }
1494 byte ed_opcode = RDMEM_OPCODE<0>(T::CC_PREFIX);
1496 switch (ed_opcode) {
1497 case 0x00:
case 0x01:
case 0x02:
case 0x03:
1498 case 0x04:
case 0x05:
case 0x06:
case 0x07:
1499 case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
1500 case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
1501 case 0x10:
case 0x11:
case 0x12:
case 0x13:
1502 case 0x14:
case 0x15:
case 0x16:
case 0x17:
1503 case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
1504 case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f:
1505 case 0x20:
case 0x21:
case 0x22:
case 0x23:
1506 case 0x24:
case 0x25:
case 0x26:
case 0x27:
1507 case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
1508 case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
1509 case 0x30:
case 0x31:
case 0x32:
case 0x33:
1510 case 0x34:
case 0x35:
case 0x36:
case 0x37:
1511 case 0x38:
case 0x39:
case 0x3a:
case 0x3b:
1512 case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
1514 case 0x77:
case 0x7f:
1516 case 0x80:
case 0x81:
case 0x82:
case 0x83:
1517 case 0x84:
case 0x85:
case 0x86:
case 0x87:
1518 case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
1519 case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
1520 case 0x90:
case 0x91:
case 0x92:
case 0x93:
1521 case 0x94:
case 0x95:
case 0x96:
case 0x97:
1522 case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
1523 case 0x9c:
case 0x9d:
case 0x9e:
case 0x9f:
1524 case 0xa4:
case 0xa5:
case 0xa6:
case 0xa7:
1525 case 0xac:
case 0xad:
case 0xae:
case 0xaf:
1526 case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
1527 case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
1529 case 0xc0:
case 0xc2:
1530 case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
1531 case 0xc8:
case 0xca:
case 0xcb:
1532 case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
1533 case 0xd0:
case 0xd2:
case 0xd3:
1534 case 0xd4:
case 0xd5:
case 0xd6:
case 0xd7:
1535 case 0xd8:
case 0xda:
case 0xdb:
1536 case 0xdc:
case 0xdd:
case 0xde:
case 0xdf:
1537 case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
1538 case 0xe4:
case 0xe5:
case 0xe6:
case 0xe7:
1539 case 0xe8:
case 0xe9:
case 0xea:
case 0xeb:
1540 case 0xec:
case 0xed:
case 0xee:
case 0xef:
1541 case 0xf0:
case 0xf1:
case 0xf2:
1542 case 0xf4:
case 0xf5:
case 0xf6:
case 0xf7:
1543 case 0xf8:
case 0xf9:
case 0xfa:
case 0xfb:
1544 case 0xfc:
case 0xfd:
case 0xfe:
case 0xff:
1545 { II ii = nop();
NEXT; }
1547 case 0x40: { II ii = in_R_c<B>();
NEXT; }
1548 case 0x48: { II ii = in_R_c<C>();
NEXT; }
1549 case 0x50: { II ii = in_R_c<D>();
NEXT; }
1550 case 0x58: { II ii = in_R_c<E>();
NEXT; }
1551 case 0x60: { II ii = in_R_c<H>();
NEXT; }
1552 case 0x68: { II ii = in_R_c<L>();
NEXT; }
1553 case 0x70: { II ii = in_R_c<DUMMY>();
NEXT; }
1554 case 0x78: { II ii = in_R_c<A>();
NEXT; }
1556 case 0x41: { II ii = out_c_R<B>();
NEXT; }
1557 case 0x49: { II ii = out_c_R<C>();
NEXT; }
1558 case 0x51: { II ii = out_c_R<D>();
NEXT; }
1559 case 0x59: { II ii = out_c_R<E>();
NEXT; }
1560 case 0x61: { II ii = out_c_R<H>();
NEXT; }
1561 case 0x69: { II ii = out_c_R<L>();
NEXT; }
1562 case 0x71: { II ii = out_c_0();
NEXT; }
1563 case 0x79: { II ii = out_c_R<A>();
NEXT; }
1565 case 0x42: { II ii = sbc_hl_SS<BC>();
NEXT; }
1566 case 0x52: { II ii = sbc_hl_SS<DE>();
NEXT; }
1567 case 0x62: { II ii = sbc_hl_hl ();
NEXT; }
1568 case 0x72: { II ii = sbc_hl_SS<SP>();
NEXT; }
1570 case 0x4a: { II ii = adc_hl_SS<BC>();
NEXT; }
1571 case 0x5a: { II ii = adc_hl_SS<DE>();
NEXT; }
1572 case 0x6a: { II ii = adc_hl_hl ();
NEXT; }
1573 case 0x7a: { II ii = adc_hl_SS<SP>();
NEXT; }
1575 case 0x43: { II ii = ld_xword_SS_ED<BC>();
NEXT; }
1576 case 0x53: { II ii = ld_xword_SS_ED<DE>();
NEXT; }
1577 case 0x63: { II ii = ld_xword_SS_ED<HL>();
NEXT; }
1578 case 0x73: { II ii = ld_xword_SS_ED<SP>();
NEXT; }
1580 case 0x4b: { II ii = ld_SS_xword_ED<BC>();
NEXT; }
1581 case 0x5b: { II ii = ld_SS_xword_ED<DE>();
NEXT; }
1582 case 0x6b: { II ii = ld_SS_xword_ED<HL>();
NEXT; }
1583 case 0x7b: { II ii = ld_SS_xword_ED<SP>();
NEXT; }
1585 case 0x47: { II ii = ld_i_a();
NEXT; }
1586 case 0x4f: { II ii = ld_r_a();
NEXT; }
1587 case 0x57: { II ii = ld_a_IR<REG_I>();
if (T::isR800()) {
NEXT; }
else {
NEXT_STOP; }}
1588 case 0x5f: { II ii = ld_a_IR<REG_R>();
if (T::isR800()) {
NEXT; }
else {
NEXT_STOP; }}
1590 case 0x67: { II ii = rrd();
NEXT; }
1591 case 0x6f: { II ii = rld();
NEXT; }
1593 case 0x45:
case 0x4d:
case 0x55:
case 0x5d:
1594 case 0x65:
case 0x6d:
case 0x75:
case 0x7d:
1596 case 0x46:
case 0x4e:
case 0x66:
case 0x6e:
1597 { II ii = im_N<0>();
NEXT; }
1598 case 0x56:
case 0x76:
1599 { II ii = im_N<1>();
NEXT; }
1600 case 0x5e:
case 0x7e:
1601 { II ii = im_N<2>();
NEXT; }
1602 case 0x44:
case 0x4c:
case 0x54:
case 0x5c:
1603 case 0x64:
case 0x6c:
case 0x74:
case 0x7c:
1604 { II ii = neg();
NEXT; }
1606 case 0xa0: { II ii = ldi();
NEXT; }
1607 case 0xa1: { II ii = cpi();
NEXT; }
1608 case 0xa2: { II ii = ini();
NEXT; }
1609 case 0xa3: { II ii = outi();
NEXT; }
1610 case 0xa8: { II ii = ldd();
NEXT; }
1611 case 0xa9: { II ii = cpd();
NEXT; }
1612 case 0xaa: { II ii = ind();
NEXT; }
1613 case 0xab: { II ii = outd();
NEXT; }
1614 case 0xb0: { II ii = ldir();
NEXT; }
1615 case 0xb1: { II ii = cpir();
NEXT; }
1616 case 0xb2: { II ii = inir();
NEXT; }
1617 case 0xb3: { II ii = otir();
NEXT; }
1618 case 0xb8: { II ii = lddr();
NEXT; }
1619 case 0xb9: { II ii = cpdr();
NEXT; }
1620 case 0xba: { II ii = indr();
NEXT; }
1621 case 0xbb: { II ii = otdr();
NEXT; }
1623 case 0xc1: { II ii = T::isR800() ? mulub_a_R<B>() : nop();
NEXT; }
1624 case 0xc9: { II ii = T::isR800() ? mulub_a_R<C>() : nop();
NEXT; }
1625 case 0xd1: { II ii = T::isR800() ? mulub_a_R<D>() : nop();
NEXT; }
1626 case 0xd9: { II ii = T::isR800() ? mulub_a_R<E>() : nop();
NEXT; }
1627 case 0xc3: { II ii = T::isR800() ? muluw_hl_SS<BC>() : nop();
NEXT; }
1628 case 0xf3: { II ii = T::isR800() ? muluw_hl_SS<SP>() : nop();
NEXT; }
1635 byte opcodeDD = RDMEM_OPCODE<0>(T::CC_DD + T::CC_MAIN);
1813 ii.cycles += T::CC_DD;
1817 #ifdef USE_COMPUTED_GOTO
1818 goto *(opcodeTable[opcodeDD]);
1820 opcodeMain = opcodeDD;
1825 case 0x09: { II ii = add_SS_TT<IX,BC,T::CC_DD>();
NEXT; }
1826 case 0x19: { II ii = add_SS_TT<IX,DE,T::CC_DD>();
NEXT; }
1827 case 0x29: { II ii = add_SS_SS<IX ,T::CC_DD>();
NEXT; }
1828 case 0x39: { II ii = add_SS_TT<IX,SP,T::CC_DD>();
NEXT; }
1829 case 0x21: { II ii = ld_SS_word<IX,T::CC_DD>();
NEXT; }
1830 case 0x22: { II ii = ld_xword_SS<IX,T::CC_DD>();
NEXT; }
1831 case 0x2a: { II ii = ld_SS_xword<IX,T::CC_DD>();
NEXT; }
1832 case 0x23: { II ii = inc_SS<IX,T::CC_DD>();
NEXT; }
1833 case 0x2b: { II ii = dec_SS<IX,T::CC_DD>();
NEXT; }
1834 case 0x24: { II ii = inc_R<IXH,T::CC_DD>();
NEXT; }
1835 case 0x2c: { II ii = inc_R<IXL,T::CC_DD>();
NEXT; }
1836 case 0x25: { II ii = dec_R<IXH,T::CC_DD>();
NEXT; }
1837 case 0x2d: { II ii = dec_R<IXL,T::CC_DD>();
NEXT; }
1838 case 0x26: { II ii = ld_R_byte<IXH,T::CC_DD>();
NEXT; }
1839 case 0x2e: { II ii = ld_R_byte<IXL,T::CC_DD>();
NEXT; }
1840 case 0x34: { II ii = inc_xix<IX>();
NEXT; }
1841 case 0x35: { II ii = dec_xix<IX>();
NEXT; }
1842 case 0x36: { II ii = ld_xix_byte<IX>();
NEXT; }
1844 case 0x44: { II ii = ld_R_R<B,IXH,T::CC_DD>();
NEXT; }
1845 case 0x45: { II ii = ld_R_R<B,IXL,T::CC_DD>();
NEXT; }
1846 case 0x4c: { II ii = ld_R_R<C,IXH,T::CC_DD>();
NEXT; }
1847 case 0x4d: { II ii = ld_R_R<C,IXL,T::CC_DD>();
NEXT; }
1848 case 0x54: { II ii = ld_R_R<D,IXH,T::CC_DD>();
NEXT; }
1849 case 0x55: { II ii = ld_R_R<D,IXL,T::CC_DD>();
NEXT; }
1850 case 0x5c: { II ii = ld_R_R<E,IXH,T::CC_DD>();
NEXT; }
1851 case 0x5d: { II ii = ld_R_R<E,IXL,T::CC_DD>();
NEXT; }
1852 case 0x7c: { II ii = ld_R_R<A,IXH,T::CC_DD>();
NEXT; }
1853 case 0x7d: { II ii = ld_R_R<A,IXL,T::CC_DD>();
NEXT; }
1854 case 0x60: { II ii = ld_R_R<IXH,B,T::CC_DD>();
NEXT; }
1855 case 0x61: { II ii = ld_R_R<IXH,C,T::CC_DD>();
NEXT; }
1856 case 0x62: { II ii = ld_R_R<IXH,D,T::CC_DD>();
NEXT; }
1857 case 0x63: { II ii = ld_R_R<IXH,E,T::CC_DD>();
NEXT; }
1858 case 0x65: { II ii = ld_R_R<IXH,IXL,T::CC_DD>();
NEXT; }
1859 case 0x67: { II ii = ld_R_R<IXH,A,T::CC_DD>();
NEXT; }
1860 case 0x68: { II ii = ld_R_R<IXL,B,T::CC_DD>();
NEXT; }
1861 case 0x69: { II ii = ld_R_R<IXL,C,T::CC_DD>();
NEXT; }
1862 case 0x6a: { II ii = ld_R_R<IXL,D,T::CC_DD>();
NEXT; }
1863 case 0x6b: { II ii = ld_R_R<IXL,E,T::CC_DD>();
NEXT; }
1864 case 0x6c: { II ii = ld_R_R<IXL,IXH,T::CC_DD>();
NEXT; }
1865 case 0x6f: { II ii = ld_R_R<IXL,A,T::CC_DD>();
NEXT; }
1866 case 0x70: { II ii = ld_xix_R<IX,B>();
NEXT; }
1867 case 0x71: { II ii = ld_xix_R<IX,C>();
NEXT; }
1868 case 0x72: { II ii = ld_xix_R<IX,D>();
NEXT; }
1869 case 0x73: { II ii = ld_xix_R<IX,E>();
NEXT; }
1870 case 0x74: { II ii = ld_xix_R<IX,H>();
NEXT; }
1871 case 0x75: { II ii = ld_xix_R<IX,L>();
NEXT; }
1872 case 0x77: { II ii = ld_xix_R<IX,A>();
NEXT; }
1873 case 0x46: { II ii = ld_R_xix<B,IX>();
NEXT; }
1874 case 0x4e: { II ii = ld_R_xix<C,IX>();
NEXT; }
1875 case 0x56: { II ii = ld_R_xix<D,IX>();
NEXT; }
1876 case 0x5e: { II ii = ld_R_xix<E,IX>();
NEXT; }
1877 case 0x66: { II ii = ld_R_xix<H,IX>();
NEXT; }
1878 case 0x6e: { II ii = ld_R_xix<L,IX>();
NEXT; }
1879 case 0x7e: { II ii = ld_R_xix<A,IX>();
NEXT; }
1881 case 0x84: { II ii = add_a_R<IXH,T::CC_DD>();
NEXT; }
1882 case 0x85: { II ii = add_a_R<IXL,T::CC_DD>();
NEXT; }
1883 case 0x86: { II ii = add_a_xix<IX>();
NEXT; }
1884 case 0x8c: { II ii = adc_a_R<IXH,T::CC_DD>();
NEXT; }
1885 case 0x8d: { II ii = adc_a_R<IXL,T::CC_DD>();
NEXT; }
1886 case 0x8e: { II ii = adc_a_xix<IX>();
NEXT; }
1887 case 0x94: { II ii = sub_R<IXH,T::CC_DD>();
NEXT; }
1888 case 0x95: { II ii = sub_R<IXL,T::CC_DD>();
NEXT; }
1889 case 0x96: { II ii = sub_xix<IX>();
NEXT; }
1890 case 0x9c: { II ii = sbc_a_R<IXH,T::CC_DD>();
NEXT; }
1891 case 0x9d: { II ii = sbc_a_R<IXL,T::CC_DD>();
NEXT; }
1892 case 0x9e: { II ii = sbc_a_xix<IX>();
NEXT; }
1893 case 0xa4: { II ii = and_R<IXH,T::CC_DD>();
NEXT; }
1894 case 0xa5: { II ii = and_R<IXL,T::CC_DD>();
NEXT; }
1895 case 0xa6: { II ii = and_xix<IX>();
NEXT; }
1896 case 0xac: { II ii = xor_R<IXH,T::CC_DD>();
NEXT; }
1897 case 0xad: { II ii = xor_R<IXL,T::CC_DD>();
NEXT; }
1898 case 0xae: { II ii = xor_xix<IX>();
NEXT; }
1899 case 0xb4: { II ii = or_R<IXH,T::CC_DD>();
NEXT; }
1900 case 0xb5: { II ii = or_R<IXL,T::CC_DD>();
NEXT; }
1901 case 0xb6: { II ii = or_xix<IX>();
NEXT; }
1902 case 0xbc: { II ii = cp_R<IXH,T::CC_DD>();
NEXT; }
1903 case 0xbd: { II ii = cp_R<IXL,T::CC_DD>();
NEXT; }
1904 case 0xbe: { II ii = cp_xix<IX>();
NEXT; }
1906 case 0xe1: { II ii = pop_SS <IX,T::CC_DD>();
NEXT; }
1907 case 0xe5: { II ii = push_SS<IX,T::CC_DD>();
NEXT; }
1908 case 0xe3: { II ii = ex_xsp_SS<IX,T::CC_DD>();
NEXT; }
1909 case 0xe9: { II ii = jp_SS<IX,T::CC_DD>();
NEXT; }
1910 case 0xf9: { II ii = ld_sp_SS<IX,T::CC_DD>();
NEXT; }
1911 case 0xcb: ixy = getIX();
goto xx_cb;
1912 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
1913 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
1920 byte opcodeFD = RDMEM_OPCODE<0>(T::CC_DD + T::CC_MAIN);
2098 ii.cycles += T::CC_DD;
2102 #ifdef USE_COMPUTED_GOTO
2103 goto *(opcodeTable[opcodeFD]);
2105 opcodeMain = opcodeFD;
2110 case 0x09: { II ii = add_SS_TT<IY,BC,T::CC_DD>();
NEXT; }
2111 case 0x19: { II ii = add_SS_TT<IY,DE,T::CC_DD>();
NEXT; }
2112 case 0x29: { II ii = add_SS_SS<IY ,T::CC_DD>();
NEXT; }
2113 case 0x39: { II ii = add_SS_TT<IY,SP,T::CC_DD>();
NEXT; }
2114 case 0x21: { II ii = ld_SS_word<IY,T::CC_DD>();
NEXT; }
2115 case 0x22: { II ii = ld_xword_SS<IY,T::CC_DD>();
NEXT; }
2116 case 0x2a: { II ii = ld_SS_xword<IY,T::CC_DD>();
NEXT; }
2117 case 0x23: { II ii = inc_SS<IY,T::CC_DD>();
NEXT; }
2118 case 0x2b: { II ii = dec_SS<IY,T::CC_DD>();
NEXT; }
2119 case 0x24: { II ii = inc_R<IYH,T::CC_DD>();
NEXT; }
2120 case 0x2c: { II ii = inc_R<IYL,T::CC_DD>();
NEXT; }
2121 case 0x25: { II ii = dec_R<IYH,T::CC_DD>();
NEXT; }
2122 case 0x2d: { II ii = dec_R<IYL,T::CC_DD>();
NEXT; }
2123 case 0x26: { II ii = ld_R_byte<IYH,T::CC_DD>();
NEXT; }
2124 case 0x2e: { II ii = ld_R_byte<IYL,T::CC_DD>();
NEXT; }
2125 case 0x34: { II ii = inc_xix<IY>();
NEXT; }
2126 case 0x35: { II ii = dec_xix<IY>();
NEXT; }
2127 case 0x36: { II ii = ld_xix_byte<IY>();
NEXT; }
2129 case 0x44: { II ii = ld_R_R<B,IYH,T::CC_DD>();
NEXT; }
2130 case 0x45: { II ii = ld_R_R<B,IYL,T::CC_DD>();
NEXT; }
2131 case 0x4c: { II ii = ld_R_R<C,IYH,T::CC_DD>();
NEXT; }
2132 case 0x4d: { II ii = ld_R_R<C,IYL,T::CC_DD>();
NEXT; }
2133 case 0x54: { II ii = ld_R_R<D,IYH,T::CC_DD>();
NEXT; }
2134 case 0x55: { II ii = ld_R_R<D,IYL,T::CC_DD>();
NEXT; }
2135 case 0x5c: { II ii = ld_R_R<E,IYH,T::CC_DD>();
NEXT; }
2136 case 0x5d: { II ii = ld_R_R<E,IYL,T::CC_DD>();
NEXT; }
2137 case 0x7c: { II ii = ld_R_R<A,IYH,T::CC_DD>();
NEXT; }
2138 case 0x7d: { II ii = ld_R_R<A,IYL,T::CC_DD>();
NEXT; }
2139 case 0x60: { II ii = ld_R_R<IYH,B,T::CC_DD>();
NEXT; }
2140 case 0x61: { II ii = ld_R_R<IYH,C,T::CC_DD>();
NEXT; }
2141 case 0x62: { II ii = ld_R_R<IYH,D,T::CC_DD>();
NEXT; }
2142 case 0x63: { II ii = ld_R_R<IYH,E,T::CC_DD>();
NEXT; }
2143 case 0x65: { II ii = ld_R_R<IYH,IYL,T::CC_DD>();
NEXT; }
2144 case 0x67: { II ii = ld_R_R<IYH,A,T::CC_DD>();
NEXT; }
2145 case 0x68: { II ii = ld_R_R<IYL,B,T::CC_DD>();
NEXT; }
2146 case 0x69: { II ii = ld_R_R<IYL,C,T::CC_DD>();
NEXT; }
2147 case 0x6a: { II ii = ld_R_R<IYL,D,T::CC_DD>();
NEXT; }
2148 case 0x6b: { II ii = ld_R_R<IYL,E,T::CC_DD>();
NEXT; }
2149 case 0x6c: { II ii = ld_R_R<IYL,IYH,T::CC_DD>();
NEXT; }
2150 case 0x6f: { II ii = ld_R_R<IYL,A,T::CC_DD>();
NEXT; }
2151 case 0x70: { II ii = ld_xix_R<IY,B>();
NEXT; }
2152 case 0x71: { II ii = ld_xix_R<IY,C>();
NEXT; }
2153 case 0x72: { II ii = ld_xix_R<IY,D>();
NEXT; }
2154 case 0x73: { II ii = ld_xix_R<IY,E>();
NEXT; }
2155 case 0x74: { II ii = ld_xix_R<IY,H>();
NEXT; }
2156 case 0x75: { II ii = ld_xix_R<IY,L>();
NEXT; }
2157 case 0x77: { II ii = ld_xix_R<IY,A>();
NEXT; }
2158 case 0x46: { II ii = ld_R_xix<B,IY>();
NEXT; }
2159 case 0x4e: { II ii = ld_R_xix<C,IY>();
NEXT; }
2160 case 0x56: { II ii = ld_R_xix<D,IY>();
NEXT; }
2161 case 0x5e: { II ii = ld_R_xix<E,IY>();
NEXT; }
2162 case 0x66: { II ii = ld_R_xix<H,IY>();
NEXT; }
2163 case 0x6e: { II ii = ld_R_xix<L,IY>();
NEXT; }
2164 case 0x7e: { II ii = ld_R_xix<A,IY>();
NEXT; }
2166 case 0x84: { II ii = add_a_R<IYH,T::CC_DD>();
NEXT; }
2167 case 0x85: { II ii = add_a_R<IYL,T::CC_DD>();
NEXT; }
2168 case 0x86: { II ii = add_a_xix<IY>();
NEXT; }
2169 case 0x8c: { II ii = adc_a_R<IYH,T::CC_DD>();
NEXT; }
2170 case 0x8d: { II ii = adc_a_R<IYL,T::CC_DD>();
NEXT; }
2171 case 0x8e: { II ii = adc_a_xix<IY>();
NEXT; }
2172 case 0x94: { II ii = sub_R<IYH,T::CC_DD>();
NEXT; }
2173 case 0x95: { II ii = sub_R<IYL,T::CC_DD>();
NEXT; }
2174 case 0x96: { II ii = sub_xix<IY>();
NEXT; }
2175 case 0x9c: { II ii = sbc_a_R<IYH,T::CC_DD>();
NEXT; }
2176 case 0x9d: { II ii = sbc_a_R<IYL,T::CC_DD>();
NEXT; }
2177 case 0x9e: { II ii = sbc_a_xix<IY>();
NEXT; }
2178 case 0xa4: { II ii = and_R<IYH,T::CC_DD>();
NEXT; }
2179 case 0xa5: { II ii = and_R<IYL,T::CC_DD>();
NEXT; }
2180 case 0xa6: { II ii = and_xix<IY>();
NEXT; }
2181 case 0xac: { II ii = xor_R<IYH,T::CC_DD>();
NEXT; }
2182 case 0xad: { II ii = xor_R<IYL,T::CC_DD>();
NEXT; }
2183 case 0xae: { II ii = xor_xix<IY>();
NEXT; }
2184 case 0xb4: { II ii = or_R<IYH,T::CC_DD>();
NEXT; }
2185 case 0xb5: { II ii = or_R<IYL,T::CC_DD>();
NEXT; }
2186 case 0xb6: { II ii = or_xix<IY>();
NEXT; }
2187 case 0xbc: { II ii = cp_R<IYH,T::CC_DD>();
NEXT; }
2188 case 0xbd: { II ii = cp_R<IYL,T::CC_DD>();
NEXT; }
2189 case 0xbe: { II ii = cp_xix<IY>();
NEXT; }
2191 case 0xe1: { II ii = pop_SS <IY,T::CC_DD>();
NEXT; }
2192 case 0xe5: { II ii = push_SS<IY,T::CC_DD>();
NEXT; }
2193 case 0xe3: { II ii = ex_xsp_SS<IY,T::CC_DD>();
NEXT; }
2194 case 0xe9: { II ii = jp_SS<IY,T::CC_DD>();
NEXT; }
2195 case 0xf9: { II ii = ld_sp_SS<IY,T::CC_DD>();
NEXT; }
2196 case 0xcb: ixy = getIY();
goto xx_cb;
2197 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
2198 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
2202 #ifndef USE_COMPUTED_GOTO
2208 unsigned tmp = RD_WORD_PC<1>(T::CC_DD + T::CC_DD_CB);
2209 int8_t ofst = tmp & 0xFF;
2210 unsigned addr = (ixy + ofst) & 0xFFFF;
2211 byte xxcb_opcode = tmp >> 8;
2212 switch (xxcb_opcode) {
2213 case 0x00: { II ii = rlc_xix_R<B>(addr);
NEXT; }
2214 case 0x01: { II ii = rlc_xix_R<C>(addr);
NEXT; }
2215 case 0x02: { II ii = rlc_xix_R<D>(addr);
NEXT; }
2216 case 0x03: { II ii = rlc_xix_R<E>(addr);
NEXT; }
2217 case 0x04: { II ii = rlc_xix_R<H>(addr);
NEXT; }
2218 case 0x05: { II ii = rlc_xix_R<L>(addr);
NEXT; }
2219 case 0x06: { II ii = rlc_xix_R<DUMMY>(addr);
NEXT; }
2220 case 0x07: { II ii = rlc_xix_R<A>(addr);
NEXT; }
2221 case 0x08: { II ii = rrc_xix_R<B>(addr);
NEXT; }
2222 case 0x09: { II ii = rrc_xix_R<C>(addr);
NEXT; }
2223 case 0x0a: { II ii = rrc_xix_R<D>(addr);
NEXT; }
2224 case 0x0b: { II ii = rrc_xix_R<E>(addr);
NEXT; }
2225 case 0x0c: { II ii = rrc_xix_R<H>(addr);
NEXT; }
2226 case 0x0d: { II ii = rrc_xix_R<L>(addr);
NEXT; }
2227 case 0x0e: { II ii = rrc_xix_R<DUMMY>(addr);
NEXT; }
2228 case 0x0f: { II ii = rrc_xix_R<A>(addr);
NEXT; }
2229 case 0x10: { II ii = rl_xix_R<B>(addr);
NEXT; }
2230 case 0x11: { II ii = rl_xix_R<C>(addr);
NEXT; }
2231 case 0x12: { II ii = rl_xix_R<D>(addr);
NEXT; }
2232 case 0x13: { II ii = rl_xix_R<E>(addr);
NEXT; }
2233 case 0x14: { II ii = rl_xix_R<H>(addr);
NEXT; }
2234 case 0x15: { II ii = rl_xix_R<L>(addr);
NEXT; }
2235 case 0x16: { II ii = rl_xix_R<DUMMY>(addr);
NEXT; }
2236 case 0x17: { II ii = rl_xix_R<A>(addr);
NEXT; }
2237 case 0x18: { II ii = rr_xix_R<B>(addr);
NEXT; }
2238 case 0x19: { II ii = rr_xix_R<C>(addr);
NEXT; }
2239 case 0x1a: { II ii = rr_xix_R<D>(addr);
NEXT; }
2240 case 0x1b: { II ii = rr_xix_R<E>(addr);
NEXT; }
2241 case 0x1c: { II ii = rr_xix_R<H>(addr);
NEXT; }
2242 case 0x1d: { II ii = rr_xix_R<L>(addr);
NEXT; }
2243 case 0x1e: { II ii = rr_xix_R<DUMMY>(addr);
NEXT; }
2244 case 0x1f: { II ii = rr_xix_R<A>(addr);
NEXT; }
2245 case 0x20: { II ii = sla_xix_R<B>(addr);
NEXT; }
2246 case 0x21: { II ii = sla_xix_R<C>(addr);
NEXT; }
2247 case 0x22: { II ii = sla_xix_R<D>(addr);
NEXT; }
2248 case 0x23: { II ii = sla_xix_R<E>(addr);
NEXT; }
2249 case 0x24: { II ii = sla_xix_R<H>(addr);
NEXT; }
2250 case 0x25: { II ii = sla_xix_R<L>(addr);
NEXT; }
2251 case 0x26: { II ii = sla_xix_R<DUMMY>(addr);
NEXT; }
2252 case 0x27: { II ii = sla_xix_R<A>(addr);
NEXT; }
2253 case 0x28: { II ii = sra_xix_R<B>(addr);
NEXT; }
2254 case 0x29: { II ii = sra_xix_R<C>(addr);
NEXT; }
2255 case 0x2a: { II ii = sra_xix_R<D>(addr);
NEXT; }
2256 case 0x2b: { II ii = sra_xix_R<E>(addr);
NEXT; }
2257 case 0x2c: { II ii = sra_xix_R<H>(addr);
NEXT; }
2258 case 0x2d: { II ii = sra_xix_R<L>(addr);
NEXT; }
2259 case 0x2e: { II ii = sra_xix_R<DUMMY>(addr);
NEXT; }
2260 case 0x2f: { II ii = sra_xix_R<A>(addr);
NEXT; }
2261 case 0x30: { II ii = T::isR800() ? sll2() : sll_xix_R<
B>(addr);
NEXT; }
2262 case 0x31: { II ii = T::isR800() ? sll2() : sll_xix_R<
C>(addr);
NEXT; }
2263 case 0x32: { II ii = T::isR800() ? sll2() : sll_xix_R<
D>(addr);
NEXT; }
2264 case 0x33: { II ii = T::isR800() ? sll2() : sll_xix_R<
E>(addr);
NEXT; }
2265 case 0x34: { II ii = T::isR800() ? sll2() : sll_xix_R<
H>(addr);
NEXT; }
2266 case 0x35: { II ii = T::isR800() ? sll2() : sll_xix_R<
L>(addr);
NEXT; }
2267 case 0x36: { II ii = T::isR800() ? sll2() : sll_xix_R<
DUMMY>(addr);
NEXT; }
2268 case 0x37: { II ii = T::isR800() ? sll2() : sll_xix_R<
A>(addr);
NEXT; }
2269 case 0x38: { II ii = srl_xix_R<B>(addr);
NEXT; }
2270 case 0x39: { II ii = srl_xix_R<C>(addr);
NEXT; }
2271 case 0x3a: { II ii = srl_xix_R<D>(addr);
NEXT; }
2272 case 0x3b: { II ii = srl_xix_R<E>(addr);
NEXT; }
2273 case 0x3c: { II ii = srl_xix_R<H>(addr);
NEXT; }
2274 case 0x3d: { II ii = srl_xix_R<L>(addr);
NEXT; }
2275 case 0x3e: { II ii = srl_xix_R<DUMMY>(addr);
NEXT; }
2276 case 0x3f: { II ii = srl_xix_R<A>(addr);
NEXT; }
2278 case 0x40:
case 0x41:
case 0x42:
case 0x43:
2279 case 0x44:
case 0x45:
case 0x46:
case 0x47:
2280 { II ii = bit_N_xix<0>(addr);
NEXT; }
2281 case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
2282 case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
2283 { II ii = bit_N_xix<1>(addr);
NEXT; }
2284 case 0x50:
case 0x51:
case 0x52:
case 0x53:
2285 case 0x54:
case 0x55:
case 0x56:
case 0x57:
2286 { II ii = bit_N_xix<2>(addr);
NEXT; }
2287 case 0x58:
case 0x59:
case 0x5a:
case 0x5b:
2288 case 0x5c:
case 0x5d:
case 0x5e:
case 0x5f:
2289 { II ii = bit_N_xix<3>(addr);
NEXT; }
2290 case 0x60:
case 0x61:
case 0x62:
case 0x63:
2291 case 0x64:
case 0x65:
case 0x66:
case 0x67:
2292 { II ii = bit_N_xix<4>(addr);
NEXT; }
2293 case 0x68:
case 0x69:
case 0x6a:
case 0x6b:
2294 case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
2295 { II ii = bit_N_xix<5>(addr);
NEXT; }
2296 case 0x70:
case 0x71:
case 0x72:
case 0x73:
2297 case 0x74:
case 0x75:
case 0x76:
case 0x77:
2298 { II ii = bit_N_xix<6>(addr);
NEXT; }
2299 case 0x78:
case 0x79:
case 0x7a:
case 0x7b:
2300 case 0x7c:
case 0x7d:
case 0x7e:
case 0x7f:
2301 { II ii = bit_N_xix<7>(addr);
NEXT; }
2303 case 0x80: { II ii = res_N_xix_R<0,B>(addr);
NEXT; }
2304 case 0x81: { II ii = res_N_xix_R<0,C>(addr);
NEXT; }
2305 case 0x82: { II ii = res_N_xix_R<0,D>(addr);
NEXT; }
2306 case 0x83: { II ii = res_N_xix_R<0,E>(addr);
NEXT; }
2307 case 0x84: { II ii = res_N_xix_R<0,H>(addr);
NEXT; }
2308 case 0x85: { II ii = res_N_xix_R<0,L>(addr);
NEXT; }
2309 case 0x87: { II ii = res_N_xix_R<0,A>(addr);
NEXT; }
2310 case 0x88: { II ii = res_N_xix_R<1,B>(addr);
NEXT; }
2311 case 0x89: { II ii = res_N_xix_R<1,C>(addr);
NEXT; }
2312 case 0x8a: { II ii = res_N_xix_R<1,D>(addr);
NEXT; }
2313 case 0x8b: { II ii = res_N_xix_R<1,E>(addr);
NEXT; }
2314 case 0x8c: { II ii = res_N_xix_R<1,H>(addr);
NEXT; }
2315 case 0x8d: { II ii = res_N_xix_R<1,L>(addr);
NEXT; }
2316 case 0x8f: { II ii = res_N_xix_R<1,A>(addr);
NEXT; }
2317 case 0x90: { II ii = res_N_xix_R<2,B>(addr);
NEXT; }
2318 case 0x91: { II ii = res_N_xix_R<2,C>(addr);
NEXT; }
2319 case 0x92: { II ii = res_N_xix_R<2,D>(addr);
NEXT; }
2320 case 0x93: { II ii = res_N_xix_R<2,E>(addr);
NEXT; }
2321 case 0x94: { II ii = res_N_xix_R<2,H>(addr);
NEXT; }
2322 case 0x95: { II ii = res_N_xix_R<2,L>(addr);
NEXT; }
2323 case 0x97: { II ii = res_N_xix_R<2,A>(addr);
NEXT; }
2324 case 0x98: { II ii = res_N_xix_R<3,B>(addr);
NEXT; }
2325 case 0x99: { II ii = res_N_xix_R<3,C>(addr);
NEXT; }
2326 case 0x9a: { II ii = res_N_xix_R<3,D>(addr);
NEXT; }
2327 case 0x9b: { II ii = res_N_xix_R<3,E>(addr);
NEXT; }
2328 case 0x9c: { II ii = res_N_xix_R<3,H>(addr);
NEXT; }
2329 case 0x9d: { II ii = res_N_xix_R<3,L>(addr);
NEXT; }
2330 case 0x9f: { II ii = res_N_xix_R<3,A>(addr);
NEXT; }
2331 case 0xa0: { II ii = res_N_xix_R<4,B>(addr);
NEXT; }
2332 case 0xa1: { II ii = res_N_xix_R<4,C>(addr);
NEXT; }
2333 case 0xa2: { II ii = res_N_xix_R<4,D>(addr);
NEXT; }
2334 case 0xa3: { II ii = res_N_xix_R<4,E>(addr);
NEXT; }
2335 case 0xa4: { II ii = res_N_xix_R<4,H>(addr);
NEXT; }
2336 case 0xa5: { II ii = res_N_xix_R<4,L>(addr);
NEXT; }
2337 case 0xa7: { II ii = res_N_xix_R<4,A>(addr);
NEXT; }
2338 case 0xa8: { II ii = res_N_xix_R<5,B>(addr);
NEXT; }
2339 case 0xa9: { II ii = res_N_xix_R<5,C>(addr);
NEXT; }
2340 case 0xaa: { II ii = res_N_xix_R<5,D>(addr);
NEXT; }
2341 case 0xab: { II ii = res_N_xix_R<5,E>(addr);
NEXT; }
2342 case 0xac: { II ii = res_N_xix_R<5,H>(addr);
NEXT; }
2343 case 0xad: { II ii = res_N_xix_R<5,L>(addr);
NEXT; }
2344 case 0xaf: { II ii = res_N_xix_R<5,A>(addr);
NEXT; }
2345 case 0xb0: { II ii = res_N_xix_R<6,B>(addr);
NEXT; }
2346 case 0xb1: { II ii = res_N_xix_R<6,C>(addr);
NEXT; }
2347 case 0xb2: { II ii = res_N_xix_R<6,D>(addr);
NEXT; }
2348 case 0xb3: { II ii = res_N_xix_R<6,E>(addr);
NEXT; }
2349 case 0xb4: { II ii = res_N_xix_R<6,H>(addr);
NEXT; }
2350 case 0xb5: { II ii = res_N_xix_R<6,L>(addr);
NEXT; }
2351 case 0xb7: { II ii = res_N_xix_R<6,A>(addr);
NEXT; }
2352 case 0xb8: { II ii = res_N_xix_R<7,B>(addr);
NEXT; }
2353 case 0xb9: { II ii = res_N_xix_R<7,C>(addr);
NEXT; }
2354 case 0xba: { II ii = res_N_xix_R<7,D>(addr);
NEXT; }
2355 case 0xbb: { II ii = res_N_xix_R<7,E>(addr);
NEXT; }
2356 case 0xbc: { II ii = res_N_xix_R<7,H>(addr);
NEXT; }
2357 case 0xbd: { II ii = res_N_xix_R<7,L>(addr);
NEXT; }
2358 case 0xbf: { II ii = res_N_xix_R<7,A>(addr);
NEXT; }
2359 case 0x86: { II ii = res_N_xix_R<0,DUMMY>(addr);
NEXT; }
2360 case 0x8e: { II ii = res_N_xix_R<1,DUMMY>(addr);
NEXT; }
2361 case 0x96: { II ii = res_N_xix_R<2,DUMMY>(addr);
NEXT; }
2362 case 0x9e: { II ii = res_N_xix_R<3,DUMMY>(addr);
NEXT; }
2363 case 0xa6: { II ii = res_N_xix_R<4,DUMMY>(addr);
NEXT; }
2364 case 0xae: { II ii = res_N_xix_R<5,DUMMY>(addr);
NEXT; }
2365 case 0xb6: { II ii = res_N_xix_R<6,DUMMY>(addr);
NEXT; }
2366 case 0xbe: { II ii = res_N_xix_R<7,DUMMY>(addr);
NEXT; }
2368 case 0xc0: { II ii = set_N_xix_R<0,B>(addr);
NEXT; }
2369 case 0xc1: { II ii = set_N_xix_R<0,C>(addr);
NEXT; }
2370 case 0xc2: { II ii = set_N_xix_R<0,D>(addr);
NEXT; }
2371 case 0xc3: { II ii = set_N_xix_R<0,E>(addr);
NEXT; }
2372 case 0xc4: { II ii = set_N_xix_R<0,H>(addr);
NEXT; }
2373 case 0xc5: { II ii = set_N_xix_R<0,L>(addr);
NEXT; }
2374 case 0xc7: { II ii = set_N_xix_R<0,A>(addr);
NEXT; }
2375 case 0xc8: { II ii = set_N_xix_R<1,B>(addr);
NEXT; }
2376 case 0xc9: { II ii = set_N_xix_R<1,C>(addr);
NEXT; }
2377 case 0xca: { II ii = set_N_xix_R<1,D>(addr);
NEXT; }
2378 case 0xcb: { II ii = set_N_xix_R<1,E>(addr);
NEXT; }
2379 case 0xcc: { II ii = set_N_xix_R<1,H>(addr);
NEXT; }
2380 case 0xcd: { II ii = set_N_xix_R<1,L>(addr);
NEXT; }
2381 case 0xcf: { II ii = set_N_xix_R<1,A>(addr);
NEXT; }
2382 case 0xd0: { II ii = set_N_xix_R<2,B>(addr);
NEXT; }
2383 case 0xd1: { II ii = set_N_xix_R<2,C>(addr);
NEXT; }
2384 case 0xd2: { II ii = set_N_xix_R<2,D>(addr);
NEXT; }
2385 case 0xd3: { II ii = set_N_xix_R<2,E>(addr);
NEXT; }
2386 case 0xd4: { II ii = set_N_xix_R<2,H>(addr);
NEXT; }
2387 case 0xd5: { II ii = set_N_xix_R<2,L>(addr);
NEXT; }
2388 case 0xd7: { II ii = set_N_xix_R<2,A>(addr);
NEXT; }
2389 case 0xd8: { II ii = set_N_xix_R<3,B>(addr);
NEXT; }
2390 case 0xd9: { II ii = set_N_xix_R<3,C>(addr);
NEXT; }
2391 case 0xda: { II ii = set_N_xix_R<3,D>(addr);
NEXT; }
2392 case 0xdb: { II ii = set_N_xix_R<3,E>(addr);
NEXT; }
2393 case 0xdc: { II ii = set_N_xix_R<3,H>(addr);
NEXT; }
2394 case 0xdd: { II ii = set_N_xix_R<3,L>(addr);
NEXT; }
2395 case 0xdf: { II ii = set_N_xix_R<3,A>(addr);
NEXT; }
2396 case 0xe0: { II ii = set_N_xix_R<4,B>(addr);
NEXT; }
2397 case 0xe1: { II ii = set_N_xix_R<4,C>(addr);
NEXT; }
2398 case 0xe2: { II ii = set_N_xix_R<4,D>(addr);
NEXT; }
2399 case 0xe3: { II ii = set_N_xix_R<4,E>(addr);
NEXT; }
2400 case 0xe4: { II ii = set_N_xix_R<4,H>(addr);
NEXT; }
2401 case 0xe5: { II ii = set_N_xix_R<4,L>(addr);
NEXT; }
2402 case 0xe7: { II ii = set_N_xix_R<4,A>(addr);
NEXT; }
2403 case 0xe8: { II ii = set_N_xix_R<5,B>(addr);
NEXT; }
2404 case 0xe9: { II ii = set_N_xix_R<5,C>(addr);
NEXT; }
2405 case 0xea: { II ii = set_N_xix_R<5,D>(addr);
NEXT; }
2406 case 0xeb: { II ii = set_N_xix_R<5,E>(addr);
NEXT; }
2407 case 0xec: { II ii = set_N_xix_R<5,H>(addr);
NEXT; }
2408 case 0xed: { II ii = set_N_xix_R<5,L>(addr);
NEXT; }
2409 case 0xef: { II ii = set_N_xix_R<5,A>(addr);
NEXT; }
2410 case 0xf0: { II ii = set_N_xix_R<6,B>(addr);
NEXT; }
2411 case 0xf1: { II ii = set_N_xix_R<6,C>(addr);
NEXT; }
2412 case 0xf2: { II ii = set_N_xix_R<6,D>(addr);
NEXT; }
2413 case 0xf3: { II ii = set_N_xix_R<6,E>(addr);
NEXT; }
2414 case 0xf4: { II ii = set_N_xix_R<6,H>(addr);
NEXT; }
2415 case 0xf5: { II ii = set_N_xix_R<6,L>(addr);
NEXT; }
2416 case 0xf7: { II ii = set_N_xix_R<6,A>(addr);
NEXT; }
2417 case 0xf8: { II ii = set_N_xix_R<7,B>(addr);
NEXT; }
2418 case 0xf9: { II ii = set_N_xix_R<7,C>(addr);
NEXT; }
2419 case 0xfa: { II ii = set_N_xix_R<7,D>(addr);
NEXT; }
2420 case 0xfb: { II ii = set_N_xix_R<7,E>(addr);
NEXT; }
2421 case 0xfc: { II ii = set_N_xix_R<7,H>(addr);
NEXT; }
2422 case 0xfd: { II ii = set_N_xix_R<7,L>(addr);
NEXT; }
2423 case 0xff: { II ii = set_N_xix_R<7,A>(addr);
NEXT; }
2424 case 0xc6: { II ii = set_N_xix_R<0,DUMMY>(addr);
NEXT; }
2425 case 0xce: { II ii = set_N_xix_R<1,DUMMY>(addr);
NEXT; }
2426 case 0xd6: { II ii = set_N_xix_R<2,DUMMY>(addr);
NEXT; }
2427 case 0xde: { II ii = set_N_xix_R<3,DUMMY>(addr);
NEXT; }
2428 case 0xe6: { II ii = set_N_xix_R<4,DUMMY>(addr);
NEXT; }
2429 case 0xee: { II ii = set_N_xix_R<5,DUMMY>(addr);
NEXT; }
2430 case 0xf6: { II ii = set_N_xix_R<6,DUMMY>(addr);
NEXT; }
2431 case 0xfe: { II ii = set_N_xix_R<7,DUMMY>(addr);
NEXT; }
2437 template<
typename T>
inline void CPUCore<T>::cpuTracePre()
2441 template<
typename T>
inline void CPUCore<T>::cpuTracePost()
2444 cpuTracePost_slow();
2447 template<
typename T>
void CPUCore<T>::cpuTracePost_slow()
2451 dasm(*interface, start_pc, opBuf, dasmOutput, T::getTimeFast());
2452 std::cout << strCat(hex_string<4>(start_pc),
2454 " AF=", hex_string<4>(getAF()),
2455 " BC=", hex_string<4>(getBC()),
2456 " DE=", hex_string<4>(getDE()),
2457 " HL=", hex_string<4>(getHL()),
2458 " IX=", hex_string<4>(getIX()),
2459 " IY=", hex_string<4>(getIY()),
2460 " SP=", hex_string<4>(getSP()),
2465 template<
typename T>
ExecIRQ CPUCore<T>::getExecIRQ()
const
2467 if (
unlikely(nmiEdge))
return ExecIRQ::NMI;
2468 if (
unlikely(IRQStatus && getIFF1() && !prevWasEI()))
return ExecIRQ::IRQ;
2472 template<
typename T>
void CPUCore<T>::executeSlow(
ExecIRQ execIRQ)
2474 if (
unlikely(execIRQ == ExecIRQ::NMI)) {
2477 }
else if (
unlikely(execIRQ == ExecIRQ::IRQ)) {
2513 incR(T::advanceHalt(T::haltStates(), scheduler.getNext()));
2514 setSlowInstructions();
2517 assert(T::limitReached());
2518 executeInstructions();
2544 assert(fastForward || !interface->isBreaked());
2546 interface->setFastForward(
true);
2548 execute2(fastForward);
2549 interface->setFastForward(
false);
2558 scheduler.schedule(T::getTime());
2559 setSlowInstructions();
2565 (!interface->anyBreakPoints() && !tracingEnabled)) {
2568 if (slowInstructions) {
2570 executeSlow(getExecIRQ());
2571 scheduler.schedule(T::getTimeFast());
2573 while (slowInstructions == 0) {
2575 if (
likely(!T::limitReached())) {
2577 executeInstructions();
2582 scheduler.schedule(T::getTimeFast());
2583 if (needExitCPULoop())
return;
2586 }
while (!needExitCPULoop());
2589 if (slowInstructions == 0) {
2591 assert(T::limitReached());
2592 executeInstructions();
2597 executeSlow(getExecIRQ());
2602 scheduler.schedule(T::getTime());
2635 auto execIRQ = getExecIRQ();
2637 interface->checkBreakPoints(getPC(), motherboard)) {
2638 assert(interface->isBreaked());
2641 }
while (!needExitCPULoop());
2646 if (R8 ==
A) {
return getA(); }
2647 else if (R8 ==
F) {
return getF(); }
2648 else if (R8 ==
B) {
return getB(); }
2649 else if (R8 ==
C) {
return getC(); }
2650 else if (R8 ==
D) {
return getD(); }
2651 else if (R8 ==
E) {
return getE(); }
2652 else if (R8 ==
H) {
return getH(); }
2653 else if (R8 ==
L) {
return getL(); }
2654 else if (R8 ==
IXH) {
return getIXh(); }
2655 else if (R8 ==
IXL) {
return getIXl(); }
2656 else if (R8 ==
IYH) {
return getIYh(); }
2657 else if (R8 ==
IYL) {
return getIYl(); }
2658 else if (R8 ==
REG_I) {
return getI(); }
2659 else if (R8 ==
REG_R) {
return getR(); }
2660 else if (R8 ==
DUMMY) {
return 0; }
2664 if (R16 ==
AF) {
return getAF(); }
2665 else if (R16 ==
BC) {
return getBC(); }
2666 else if (R16 ==
DE) {
return getDE(); }
2667 else if (R16 ==
HL) {
return getHL(); }
2668 else if (R16 ==
IX) {
return getIX(); }
2669 else if (R16 ==
IY) {
return getIY(); }
2670 else if (R16 ==
SP) {
return getSP(); }
2674 if (R8 ==
A) { setA(
x); }
2675 else if (R8 ==
F) { setF(
x); }
2676 else if (R8 ==
B) { setB(
x); }
2677 else if (R8 ==
C) { setC(
x); }
2678 else if (R8 ==
D) { setD(
x); }
2679 else if (R8 ==
E) { setE(
x); }
2680 else if (R8 ==
H) { setH(
x); }
2681 else if (R8 ==
L) { setL(
x); }
2682 else if (R8 ==
IXH) { setIXh(
x); }
2683 else if (R8 ==
IXL) { setIXl(
x); }
2684 else if (R8 ==
IYH) { setIYh(
x); }
2685 else if (R8 ==
IYL) { setIYl(
x); }
2686 else if (R8 ==
REG_I) { setI(
x); }
2687 else if (R8 ==
REG_R) { setR(
x); }
2688 else if (R8 ==
DUMMY) { }
2692 if (R16 ==
AF) { setAF(
x); }
2693 else if (R16 ==
BC) { setBC(
x); }
2694 else if (R16 ==
DE) { setDE(
x); }
2695 else if (R16 ==
HL) { setHL(
x); }
2696 else if (R16 ==
IX) { setIX(
x); }
2697 else if (R16 ==
IY) { setIY(
x); }
2698 else if (R16 ==
SP) { setSP(
x); }
2704 set8<DST>(get8<SRC>());
return {1, T::CC_LD_R_R + EE};
2708 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_sp_SS() {
2709 setSP(get16<REG>());
return {1, T::CC_LD_SP_HL + EE};
2713 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_SS_a() {
2714 T::setMemPtr((getA() << 8) | ((get16<REG>() + 1) & 0xFF));
2715 WRMEM(get16<REG>(), getA(), T::CC_LD_SS_A_1);
2716 return {1, T::CC_LD_SS_A};
2720 template<
typename T>
template<Reg8 SRC> II CPUCore<T>::ld_xhl_R() {
2721 WRMEM(getHL(), get8<SRC>(), T::CC_LD_HL_R_1);
2722 return {1, T::CC_LD_HL_R};
2726 template<
typename T>
template<Reg16 IXY, Reg8 SRC> II CPUCore<T>::ld_xix_R() {
2727 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_LD_XIX_R_1);
2728 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2730 WRMEM(addr, get8<SRC>(), T::CC_DD + T::CC_LD_XIX_R_2);
2731 return {2, T::CC_DD + T::CC_LD_XIX_R};
2735 template<
typename T> II CPUCore<T>::ld_xhl_byte() {
2736 byte val = RDMEM_OPCODE<1>(T::CC_LD_HL_N_1);
2737 WRMEM(getHL(), val, T::CC_LD_HL_N_2);
2738 return {2, T::CC_LD_HL_N};
2742 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::ld_xix_byte() {
2743 unsigned tmp = RD_WORD_PC<1>(T::CC_DD + T::CC_LD_XIX_N_1);
2744 int8_t ofst = tmp & 0xFF;
2745 byte val = tmp >> 8;
2746 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2748 WRMEM(addr, val, T::CC_DD + T::CC_LD_XIX_N_2);
2749 return {3, T::CC_DD + T::CC_LD_XIX_N};
2753 template<
typename T> II CPUCore<T>::ld_xbyte_a() {
2754 unsigned x = RD_WORD_PC<1>(T::CC_LD_NN_A_1);
2755 T::setMemPtr((getA() << 8) | ((
x + 1) & 0xFF));
2756 WRMEM(
x, getA(), T::CC_LD_NN_A_2);
2757 return {3, T::CC_LD_NN_A};
2761 template<
typename T>
template<
int EE>
inline II CPUCore<T>::WR_NN_Y(
unsigned reg) {
2762 unsigned addr = RD_WORD_PC<1>(T::CC_LD_XX_HL_1 + EE);
2763 T::setMemPtr(addr + 1);
2764 WR_WORD(addr, reg, T::CC_LD_XX_HL_2 + EE);
2765 return {3, T::CC_LD_XX_HL + EE};
2767 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_xword_SS() {
2768 return WR_NN_Y<EE >(get16<REG>());
2770 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_xword_SS_ED() {
2771 return WR_NN_Y<T::EE_ED>(get16<REG>());
2775 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_a_SS() {
2776 T::setMemPtr(get16<REG>() + 1);
2777 setA(RDMEM(get16<REG>(), T::CC_LD_A_SS_1));
2778 return {1, T::CC_LD_A_SS};
2782 template<
typename T> II CPUCore<T>::ld_a_xbyte() {
2783 unsigned addr = RD_WORD_PC<1>(T::CC_LD_A_NN_1);
2784 T::setMemPtr(addr + 1);
2785 setA(RDMEM(addr, T::CC_LD_A_NN_2));
2786 return {3, T::CC_LD_A_NN};
2790 template<
typename T>
template<Reg8 DST,
int EE> II CPUCore<T>::ld_R_byte() {
2791 set8<DST>(RDMEM_OPCODE<1>(T::CC_LD_R_N_1 + EE));
return {2, T::CC_LD_R_N + EE};
2795 template<
typename T>
template<Reg8 DST> II CPUCore<T>::ld_R_xhl() {
2796 set8<DST>(RDMEM(getHL(), T::CC_LD_R_HL_1));
return {1, T::CC_LD_R_HL};
2800 template<
typename T>
template<Reg8 DST, Reg16 IXY> II CPUCore<T>::ld_R_xix() {
2801 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_LD_R_XIX_1);
2802 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2804 set8<DST>(RDMEM(addr, T::CC_DD + T::CC_LD_R_XIX_2));
2805 return {2, T::CC_DD + T::CC_LD_R_XIX};
2809 template<
typename T>
template<
int EE>
inline unsigned CPUCore<T>::RD_P_XX() {
2810 unsigned addr = RD_WORD_PC<1>(T::CC_LD_HL_XX_1 + EE);
2811 T::setMemPtr(addr + 1);
2812 unsigned result = RD_WORD(addr, T::CC_LD_HL_XX_2 + EE);
2815 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_SS_xword() {
2816 set16<REG>(RD_P_XX<EE>());
return {3, T::CC_LD_HL_XX + EE};
2818 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_SS_xword_ED() {
2819 set16<REG>(RD_P_XX<T::EE_ED>());
return {3, T::CC_LD_HL_XX + T::EE_ED};
2823 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_SS_word() {
2824 set16<REG>(RD_WORD_PC<1>(T::CC_LD_SS_NN_1 + EE));
return {3, T::CC_LD_SS_NN + EE};
2829 template<
typename T>
inline void CPUCore<T>::ADC(
byte reg) {
2830 unsigned res = getA() + reg + ((getF() &
C_FLAG) ? 1 : 0);
2831 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2832 ((getA() ^ res ^ reg) &
H_FLAG) |
2833 (((getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2844 template<
typename T>
inline II CPUCore<T>::adc_a_a() {
2845 unsigned res = 2 * getA() + ((getF() &
C_FLAG) ? 1 : 0);
2846 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2848 (((getA() ^ res) & 0x80) >> 5) |
2858 return {1, T::CC_CP_R};
2860 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::adc_a_R() {
2861 ADC(get8<SRC>());
return {1, T::CC_CP_R + EE};
2863 template<
typename T> II CPUCore<T>::adc_a_byte() {
2864 ADC(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2866 template<
typename T> II CPUCore<T>::adc_a_xhl() {
2867 ADC(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2869 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::adc_a_xix() {
2870 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2871 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2873 ADC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2874 return {2, T::CC_DD + T::CC_CP_XIX};
2878 template<
typename T>
inline void CPUCore<T>::ADD(
byte reg) {
2879 unsigned res = getA() + reg;
2880 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2881 ((getA() ^ res ^ reg) &
H_FLAG) |
2882 (((getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2893 template<
typename T>
inline II CPUCore<T>::add_a_a() {
2894 unsigned res = 2 * getA();
2895 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2897 (((getA() ^ res) & 0x80) >> 5) |
2907 return {1, T::CC_CP_R};
2909 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::add_a_R() {
2910 ADD(get8<SRC>());
return {1, T::CC_CP_R + EE};
2912 template<
typename T> II CPUCore<T>::add_a_byte() {
2913 ADD(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2915 template<
typename T> II CPUCore<T>::add_a_xhl() {
2916 ADD(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2918 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::add_a_xix() {
2919 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2920 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2922 ADD(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2923 return {2, T::CC_DD + T::CC_CP_XIX};
2927 template<
typename T>
inline void CPUCore<T>::AND(
byte reg) {
2938 template<
typename T> II CPUCore<T>::and_a() {
2947 return {1, T::CC_CP_R};
2949 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::and_R() {
2950 AND(get8<SRC>());
return {1, T::CC_CP_R + EE};
2952 template<
typename T> II CPUCore<T>::and_byte() {
2953 AND(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2955 template<
typename T> II CPUCore<T>::and_xhl() {
2956 AND(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2958 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::and_xix() {
2959 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2960 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2962 AND(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2963 return {2, T::CC_DD + T::CC_CP_XIX};
2967 template<
typename T>
inline void CPUCore<T>::CP(
byte reg) {
2968 unsigned q = getA() - reg;
2970 ((q & 0x100) ?
C_FLAG : 0) |
2972 ((getA() ^ q ^ reg) &
H_FLAG) |
2973 (((reg ^ getA()) & (getA() ^ q) & 0x80) >> 5);
2981 template<
typename T> II CPUCore<T>::cp_a() {
2989 return {1, T::CC_CP_R};
2991 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::cp_R() {
2992 CP(get8<SRC>());
return {1, T::CC_CP_R + EE};
2994 template<
typename T> II CPUCore<T>::cp_byte() {
2995 CP(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2997 template<
typename T> II CPUCore<T>::cp_xhl() {
2998 CP(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3000 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::cp_xix() {
3001 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3002 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3004 CP(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3005 return {2, T::CC_DD + T::CC_CP_XIX};
3009 template<
typename T>
inline void CPUCore<T>::OR(
byte reg) {
3020 template<
typename T> II CPUCore<T>::or_a() {
3029 return {1, T::CC_CP_R};
3031 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::or_R() {
3032 OR(get8<SRC>());
return {1, T::CC_CP_R + EE};
3034 template<
typename T> II CPUCore<T>::or_byte() {
3035 OR(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3037 template<
typename T> II CPUCore<T>::or_xhl() {
3038 OR(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3040 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::or_xix() {
3041 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3042 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3044 OR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3045 return {2, T::CC_DD + T::CC_CP_XIX};
3049 template<
typename T>
inline void CPUCore<T>::SBC(
byte reg) {
3050 unsigned res = getA() - reg - ((getF() &
C_FLAG) ? 1 : 0);
3051 byte f = ((res & 0x100) ?
C_FLAG : 0) |
3053 ((getA() ^ res ^ reg) &
H_FLAG) |
3054 (((reg ^ getA()) & (getA() ^ res) & 0x80) >> 5);
3064 template<
typename T> II CPUCore<T>::sbc_a_a() {
3071 setAF((getF() &
C_FLAG) ?
3075 return {1, T::CC_CP_R};
3077 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::sbc_a_R() {
3078 SBC(get8<SRC>());
return {1, T::CC_CP_R + EE};
3080 template<
typename T> II CPUCore<T>::sbc_a_byte() {
3081 SBC(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3083 template<
typename T> II CPUCore<T>::sbc_a_xhl() {
3084 SBC(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3086 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::sbc_a_xix() {
3087 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3088 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3090 SBC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3091 return {2, T::CC_DD + T::CC_CP_XIX};
3095 template<
typename T>
inline void CPUCore<T>::SUB(
byte reg) {
3096 unsigned res = getA() - reg;
3097 byte f = ((res & 0x100) ?
C_FLAG : 0) |
3099 ((getA() ^ res ^ reg) &
H_FLAG) |
3100 (((reg ^ getA()) & (getA() ^ res) & 0x80) >> 5);
3110 template<
typename T> II CPUCore<T>::sub_a() {
3117 return {1, T::CC_CP_R};
3119 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::sub_R() {
3120 SUB(get8<SRC>());
return {1, T::CC_CP_R + EE};
3122 template<
typename T> II CPUCore<T>::sub_byte() {
3123 SUB(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3125 template<
typename T> II CPUCore<T>::sub_xhl() {
3126 SUB(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3128 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::sub_xix() {
3129 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3130 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3132 SUB(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3133 return {2, T::CC_DD + T::CC_CP_XIX};
3137 template<
typename T>
inline void CPUCore<T>::XOR(
byte reg) {
3148 template<
typename T> II CPUCore<T>::xor_a() {
3155 return {1, T::CC_CP_R};
3157 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::xor_R() {
3158 XOR(get8<SRC>());
return {1, T::CC_CP_R + EE};
3160 template<
typename T> II CPUCore<T>::xor_byte() {
3161 XOR(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3163 template<
typename T> II CPUCore<T>::xor_xhl() {
3164 XOR(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3166 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::xor_xix() {
3167 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3168 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3170 XOR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3171 return {2, T::CC_DD + T::CC_CP_XIX};
3176 template<
typename T>
inline byte CPUCore<T>::DEC(
byte reg) {
3178 byte f = ((reg & ~res & 0x80) >> 5) |
3179 (((res & 0x0F) + 1) &
H_FLAG) |
3191 template<
typename T>
template<Reg8 REG,
int EE> II CPUCore<T>::dec_R() {
3192 set8<REG>(DEC(get8<REG>()));
return {1, T::CC_INC_R + EE};
3194 template<
typename T>
template<
int EE>
inline void CPUCore<T>::DEC_X(
unsigned x) {
3195 byte val = DEC(RDMEM(
x, T::CC_INC_XHL_1 + EE));
3196 WRMEM(
x, val, T::CC_INC_XHL_2 + EE);
3198 template<
typename T> II CPUCore<T>::dec_xhl() {
3200 return {1, T::CC_INC_XHL};
3202 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::dec_xix() {
3203 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_INC_XIX_1);
3204 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3206 DEC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3207 return {2, T::CC_INC_XHL + T::CC_DD + T::EE_INC_XIX};
3211 template<
typename T>
inline byte CPUCore<T>::INC(
byte reg) {
3213 byte f = ((reg & -reg & 0x80) >> 5) |
3214 (((reg & 0x0F) - 1) &
H_FLAG) |
3226 template<
typename T>
template<Reg8 REG,
int EE> II CPUCore<T>::inc_R() {
3227 set8<REG>(INC(get8<REG>()));
return {1, T::CC_INC_R + EE};
3229 template<
typename T>
template<
int EE>
inline void CPUCore<T>::INC_X(
unsigned x) {
3230 byte val = INC(RDMEM(
x, T::CC_INC_XHL_1 + EE));
3231 WRMEM(
x, val, T::CC_INC_XHL_2 + EE);
3233 template<
typename T> II CPUCore<T>::inc_xhl() {
3235 return {1, T::CC_INC_XHL};
3237 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::inc_xix() {
3238 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_INC_XIX_1);
3239 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3241 INC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3242 return {2, T::CC_INC_XHL + T::CC_DD + T::EE_INC_XIX};
3247 template<
typename T>
template<Reg16 REG>
inline II CPUCore<T>::adc_hl_SS() {
3248 unsigned reg = get16<REG>();
3249 T::setMemPtr(getHL() + 1);
3250 unsigned res = getHL() + reg + ((getF() &
C_FLAG) ? 1 : 0);
3251 byte f = (res >> 16) |
3257 f |= ((getHL() ^ res ^ reg) >> 8) &
H_FLAG;
3259 f |= ((getHL() ^ res) & (reg ^ res) & 0x8000) >> 13;
3261 f |= (res >> 8) &
S_FLAG;
3266 f |= ((getHL() ^ reg) >> 8) &
H_FLAG;
3268 f |= (getHL() & reg & 0x8000) >> 13;
3273 return {1, T::CC_ADC_HL_SS};
3275 template<
typename T> II CPUCore<T>::adc_hl_hl() {
3276 T::setMemPtr(getHL() + 1);
3277 unsigned res = 2 * getHL() + ((getF() &
C_FLAG) ? 1 : 0);
3278 byte f = (res >> 16) |
3285 f |= ((getHL() ^ res) & 0x8000) >> 13;
3293 f |= (getHL() & 0x8000) >> 13;
3298 return {1, T::CC_ADC_HL_SS};
3302 template<
typename T>
template<Reg16 REG1, Reg16 REG2,
int EE> II CPUCore<T>::add_SS_TT() {
3303 unsigned reg1 = get16<REG1>();
3304 unsigned reg2 = get16<REG2>();
3305 T::setMemPtr(reg1 + 1);
3306 unsigned res = reg1 + reg2;
3307 byte f = (((reg1 ^ res ^ reg2) >> 8) &
H_FLAG) |
3317 set16<REG1>(res & 0xFFFF);
3318 return {1, T::CC_ADD_HL_SS + EE};
3320 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::add_SS_SS() {
3321 unsigned reg = get16<REG>();
3322 T::setMemPtr(reg + 1);
3323 unsigned res = 2 * reg;
3324 byte f = (res >> 16) |
3328 f |= (res >> 8) &
H_FLAG;
3334 set16<REG>(res & 0xFFFF);
3335 return {1, T::CC_ADD_HL_SS + EE};
3339 template<
typename T>
template<Reg16 REG>
inline II CPUCore<T>::sbc_hl_SS() {
3340 unsigned reg = get16<REG>();
3341 T::setMemPtr(getHL() + 1);
3342 unsigned res = getHL() - reg - ((getF() &
C_FLAG) ? 1 : 0);
3343 byte f = ((res & 0x10000) ?
C_FLAG : 0) |
3349 f |= ((getHL() ^ res ^ reg) >> 8) &
H_FLAG;
3351 f |= ((reg ^ getHL()) & (getHL() ^ res) & 0x8000) >> 13;
3353 f |= (res >> 8) &
S_FLAG;
3358 f |= ((getHL() ^ reg) >> 8) &
H_FLAG;
3360 f |= ((reg ^ getHL()) & getHL() & 0x8000) >> 13;
3365 return {1, T::CC_ADC_HL_SS};
3367 template<
typename T> II CPUCore<T>::sbc_hl_hl() {
3368 T::setMemPtr(getHL() + 1);
3369 byte f = T::isR800() ? (getF() & (
X_FLAG |
Y_FLAG)) : 0;
3381 return {1, T::CC_ADC_HL_SS};
3385 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::dec_SS() {
3386 set16<REG>(get16<REG>() - 1);
return {1, T::CC_INC_SS + EE};
3390 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::inc_SS() {
3391 set16<REG>(get16<REG>() + 1);
return {1, T::CC_INC_SS + EE};
3396 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::bit_N_R() {
3397 byte reg = get8<REG>();
3403 f |= (reg & (1 <<
N)) ? 0 :
Z_FLAG;
3410 return {1, T::CC_BIT_R};
3412 template<
typename T>
template<
unsigned N>
inline II CPUCore<T>::bit_N_xhl() {
3413 byte m = RDMEM(getHL(), T::CC_BIT_XHL_1) & (1 <<
N);
3425 return {1, T::CC_BIT_XHL};
3427 template<
typename T>
template<
unsigned N>
inline II CPUCore<T>::bit_N_xix(
unsigned addr) {
3429 byte m = RDMEM(addr, T::CC_DD + T::CC_BIT_XIX_1) & (1 <<
N);
3441 return {3, T::CC_DD + T::CC_BIT_XIX};
3445 static inline byte RES(
unsigned b,
byte reg) {
3446 return reg & ~(1 << b);
3448 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::res_N_R() {
3449 set8<REG>(RES(
N, get8<REG>()));
return {1, T::CC_SET_R};
3451 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RES_X(
unsigned bit,
unsigned addr) {
3452 byte res = RES(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3453 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3456 template<
typename T>
template<
unsigned N> II CPUCore<T>::res_N_xhl() {
3457 RES_X<0>(
N, getHL());
return {1, T::CC_SET_XHL};
3459 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::res_N_xix_R(
unsigned a) {
3461 set8<REG>(RES_X<T::CC_DD + T::EE_SET_XIX>(
N, a));
3462 return {3, T::CC_DD + T::CC_SET_XIX};
3466 static inline byte SET(
unsigned b,
byte reg) {
3467 return reg | (1 << b);
3469 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::set_N_R() {
3470 set8<REG>(SET(
N, get8<REG>()));
return {1, T::CC_SET_R};
3472 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SET_X(
unsigned bit,
unsigned addr) {
3473 byte res = SET(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3474 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3477 template<
typename T>
template<
unsigned N> II CPUCore<T>::set_N_xhl() {
3478 SET_X<0>(
N, getHL());
return {1, T::CC_SET_XHL};
3480 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::set_N_xix_R(
unsigned a) {
3482 set8<REG>(SET_X<T::CC_DD + T::EE_SET_XIX>(
N, a));
3483 return {3, T::CC_DD + T::CC_SET_XIX};
3487 template<
typename T>
inline byte CPUCore<T>::RL(
byte reg) {
3489 reg = (reg << 1) | ((getF() &
C_FLAG) ? 0x01 : 0);
3500 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RL_X(
unsigned x) {
3501 byte res = RL(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3502 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3505 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rl_R() {
3506 set8<REG>(RL(get8<REG>()));
return {1, T::CC_SET_R};
3508 template<
typename T> II CPUCore<T>::rl_xhl() {
3509 RL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3511 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rl_xix_R(
unsigned a) {
3513 set8<REG>(RL_X<T::CC_DD + T::EE_SET_XIX>(a));
3514 return {3, T::CC_DD + T::CC_SET_XIX};
3518 template<
typename T>
inline byte CPUCore<T>::RLC(
byte reg) {
3520 reg = (reg << 1) | c;
3531 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RLC_X(
unsigned x) {
3532 byte res = RLC(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3533 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3536 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rlc_R() {
3537 set8<REG>(RLC(get8<REG>()));
return {1, T::CC_SET_R};
3539 template<
typename T> II CPUCore<T>::rlc_xhl() {
3540 RLC_X<0>(getHL());
return {1, T::CC_SET_XHL};
3542 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rlc_xix_R(
unsigned a) {
3544 set8<REG>(RLC_X<T::CC_DD + T::EE_SET_XIX>(a));
3545 return {3, T::CC_DD + T::CC_SET_XIX};
3549 template<
typename T>
inline byte CPUCore<T>::RR(
byte reg) {
3551 reg = (reg >> 1) | ((getF() &
C_FLAG) << 7);
3562 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RR_X(
unsigned x) {
3563 byte res = RR(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3564 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3567 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rr_R() {
3568 set8<REG>(RR(get8<REG>()));
return {1, T::CC_SET_R};
3570 template<
typename T> II CPUCore<T>::rr_xhl() {
3571 RR_X<0>(getHL());
return {1, T::CC_SET_XHL};
3573 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rr_xix_R(
unsigned a) {
3575 set8<REG>(RR_X<T::CC_DD + T::EE_SET_XIX>(a));
3576 return {3, T::CC_DD + T::CC_SET_XIX};
3580 template<
typename T>
inline byte CPUCore<T>::RRC(
byte reg) {
3582 reg = (reg >> 1) | (c << 7);
3593 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RRC_X(
unsigned x) {
3594 byte res = RRC(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3595 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3598 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rrc_R() {
3599 set8<REG>(RRC(get8<REG>()));
return {1, T::CC_SET_R};
3601 template<
typename T> II CPUCore<T>::rrc_xhl() {
3602 RRC_X<0>(getHL());
return {1, T::CC_SET_XHL};
3604 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rrc_xix_R(
unsigned a) {
3606 set8<REG>(RRC_X<T::CC_DD + T::EE_SET_XIX>(a));
3607 return {3, T::CC_DD + T::CC_SET_XIX};
3611 template<
typename T>
inline byte CPUCore<T>::SLA(
byte reg) {
3624 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SLA_X(
unsigned x) {
3625 byte res = SLA(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3626 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3629 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sla_R() {
3630 set8<REG>(SLA(get8<REG>()));
return {1, T::CC_SET_R};
3632 template<
typename T> II CPUCore<T>::sla_xhl() {
3633 SLA_X<0>(getHL());
return {1, T::CC_SET_XHL};
3635 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sla_xix_R(
unsigned a) {
3637 set8<REG>(SLA_X<T::CC_DD + T::EE_SET_XIX>(a));
3638 return {3, T::CC_DD + T::CC_SET_XIX};
3642 template<
typename T>
inline byte CPUCore<T>::SLL(
byte reg) {
3643 assert(!T::isR800());
3645 reg = (reg << 1) | 1;
3651 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SLL_X(
unsigned x) {
3652 byte res = SLL(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3653 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3656 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sll_R() {
3657 set8<REG>(SLL(get8<REG>()));
return {1, T::CC_SET_R};
3659 template<
typename T> II CPUCore<T>::sll_xhl() {
3660 SLL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3662 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sll_xix_R(
unsigned a) {
3664 set8<REG>(SLL_X<T::CC_DD + T::EE_SET_XIX>(a));
3665 return {3, T::CC_DD + T::CC_SET_XIX};
3667 template<
typename T> II CPUCore<T>::sll2() {
3668 assert(T::isR800());
3673 return {3, T::CC_DD + T::CC_SET_XIX};
3677 template<
typename T>
inline byte CPUCore<T>::SRA(
byte reg) {
3679 reg = (reg >> 1) | (reg & 0x80);
3690 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SRA_X(
unsigned x) {
3691 byte res = SRA(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3692 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3695 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sra_R() {
3696 set8<REG>(SRA(get8<REG>()));
return {1, T::CC_SET_R};
3698 template<
typename T> II CPUCore<T>::sra_xhl() {
3699 SRA_X<0>(getHL());
return {1, T::CC_SET_XHL};
3701 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sra_xix_R(
unsigned a) {
3703 set8<REG>(SRA_X<T::CC_DD + T::EE_SET_XIX>(a));
3704 return {3, T::CC_DD + T::CC_SET_XIX};
3708 template<
typename T>
inline byte CPUCore<T>::SRL(
byte reg) {
3721 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SRL_X(
unsigned x) {
3722 byte res = SRL(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3723 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3726 template<
typename T>
template<Reg8 REG> II CPUCore<T>::srl_R() {
3727 set8<REG>(SRL(get8<REG>()));
return {1, T::CC_SET_R};
3729 template<
typename T> II CPUCore<T>::srl_xhl() {
3730 SRL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3732 template<
typename T>
template<Reg8 REG> II CPUCore<T>::srl_xix_R(
unsigned a) {
3734 set8<REG>(SRL_X<T::CC_DD + T::EE_SET_XIX>(a));
3735 return {3, T::CC_DD + T::CC_SET_XIX};
3739 template<
typename T> II CPUCore<T>::rla() {
3740 byte c = getF() &
C_FLAG;
3741 byte f = (getA() & 0x80) ?
C_FLAG : 0;
3747 setA((getA() << 1) | (c ? 1 : 0));
3752 return {1, T::CC_RLA};
3754 template<
typename T> II CPUCore<T>::rlca() {
3755 setA((getA() << 1) | (getA() >> 7));
3765 return {1, T::CC_RLA};
3767 template<
typename T> II CPUCore<T>::rra() {
3768 byte c = (getF() &
C_FLAG) << 7;
3769 byte f = (getA() & 0x01) ?
C_FLAG : 0;
3775 setA((getA() >> 1) | c);
3780 return {1, T::CC_RLA};
3782 template<
typename T> II CPUCore<T>::rrca() {
3783 byte f = getA() &
C_FLAG;
3789 setA((getA() >> 1) | (getA() << 7));
3794 return {1, T::CC_RLA};
3799 template<
typename T> II CPUCore<T>::rld() {
3800 byte val = RDMEM(getHL(), T::CC_RLD_1);
3801 T::setMemPtr(getHL() + 1);
3802 WRMEM(getHL(), (val << 4) | (getA() & 0x0F), T::CC_RLD_2);
3803 setA((getA() & 0xF0) | (val >> 4));
3813 return {1, T::CC_RLD};
3817 template<
typename T> II CPUCore<T>::rrd() {
3818 byte val = RDMEM(getHL(), T::CC_RLD_1);
3819 T::setMemPtr(getHL() + 1);
3820 WRMEM(getHL(), (val >> 4) | (getA() << 4), T::CC_RLD_2);
3821 setA((getA() & 0xF0) | (val & 0x0F));
3831 return {1, T::CC_RLD};
3836 template<
typename T>
template<
int EE>
inline void CPUCore<T>::PUSH(
unsigned reg) {
3838 WR_WORD_rev<true, true>(getSP(), reg, T::CC_PUSH_1 + EE);
3840 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::push_SS() {
3841 PUSH<EE>(get16<REG>());
return {1, T::CC_PUSH + EE};
3845 template<
typename T>
template<
int EE>
inline unsigned CPUCore<T>::POP() {
3846 unsigned addr = getSP();
3858 return RD_WORD(addr, T::CC_POP_1 + EE);
3860 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::pop_SS() {
3861 set16<REG>(POP<EE>());
return {1, T::CC_POP + EE};
3866 template<
typename T>
template<
typename COND> II CPUCore<T>::call(COND cond) {
3867 unsigned addr = RD_WORD_PC<1>(T::CC_CALL_1);
3870 PUSH<T::EE_CALL>(getPC() + 3);
3874 setSlowInstructions();
3876 return {0, T::CC_CALL_A};
3878 return {3, T::CC_CALL_B};
3884 template<
typename T>
template<
unsigned ADDR> II CPUCore<T>::rst() {
3885 PUSH<0>(getPC() + 1);
3890 setSlowInstructions();
3892 return {0, T::CC_RST};
3897 template<
typename T>
template<
int EE,
typename COND>
inline II CPUCore<T>::RET(COND cond) {
3899 unsigned addr = POP<EE>();
3902 return {0, T::CC_RET_A + EE};
3904 return {1, T::CC_RET_B + EE};
3907 template<
typename T>
template<
typename COND> II CPUCore<T>::ret(COND cond) {
3908 return RET<T::EE_RET_C>(cond);
3910 template<
typename T> II CPUCore<T>::ret() {
3911 return RET<0>(CondTrue());
3913 template<
typename T> II CPUCore<T>::retn() {
3915 setSlowInstructions();
3916 return RET<T::EE_RETN>(CondTrue());
3921 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::jp_SS() {
3922 setPC(get16<REG>()); T::R800ForcePageBreak();
return {0, T::CC_JP_HL + EE};
3926 template<
typename T>
template<
typename COND> II CPUCore<T>::jp(COND cond) {
3927 unsigned addr = RD_WORD_PC<1>(T::CC_JP_1);
3931 T::R800ForcePageBreak();
3932 return {0, T::CC_JP_A};
3934 return {3, T::CC_JP_B};
3939 template<
typename T>
template<
typename COND> II CPUCore<T>::jr(COND cond) {
3940 int8_t ofst = RDMEM_OPCODE<1>(T::CC_JR_1);
3942 if (((getPC() + 2) & 0xFF) == 0) {
3970 T::R800ForcePageBreak();
3972 setPC((getPC() + 2 + ofst) & 0xFFFF);
3973 T::setMemPtr(getPC());
3974 return {0, T::CC_JR_A};
3976 return {2, T::CC_JR_B};
3981 template<
typename T> II CPUCore<T>::djnz() {
3982 byte b = getB() - 1;
3984 int8_t ofst = RDMEM_OPCODE<1>(T::CC_JR_1 + T::EE_DJNZ);
3986 if (((getPC() + 2) & 0xFF) == 0) {
3988 T::R800ForcePageBreak();
3990 setPC((getPC() + 2 + ofst) & 0xFFFF);
3991 T::setMemPtr(getPC());
3992 return {0, T::CC_JR_A + T::EE_DJNZ};
3994 return {2, T::CC_JR_B + T::EE_DJNZ};
3999 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ex_xsp_SS() {
4000 unsigned res = RD_WORD_impl<true, false>(getSP(), T::CC_EX_SP_HL_1 + EE);
4002 WR_WORD_rev<false, true>(getSP(), get16<REG>(), T::CC_EX_SP_HL_2 + EE);
4004 return {1, T::CC_EX_SP_HL + EE};
4008 template<
typename T>
template<Reg8 REG> II CPUCore<T>::in_R_c() {
4009 if (T::isR800()) T::waitForEvenCycle(T::CC_IN_R_C_1);
4010 T::setMemPtr(getBC() + 1);
4011 byte res = READ_PORT(getBC(), T::CC_IN_R_C_1);
4022 return {1, T::CC_IN_R_C};
4026 template<
typename T> II CPUCore<T>::in_a_byte() {
4027 unsigned y = RDMEM_OPCODE<1>(T::CC_IN_A_N_1) + 256 * getA();
4028 T::setMemPtr(y + 1);
4029 if (T::isR800()) T::waitForEvenCycle(T::CC_IN_A_N_2);
4030 setA(READ_PORT(y, T::CC_IN_A_N_2));
4031 return {2, T::CC_IN_A_N};
4035 template<
typename T>
template<Reg8 REG> II CPUCore<T>::out_c_R() {
4036 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_C_R_1);
4037 T::setMemPtr(getBC() + 1);
4038 WRITE_PORT(getBC(), get8<REG>(), T::CC_OUT_C_R_1);
4039 return {1, T::CC_OUT_C_R};
4041 template<
typename T> II CPUCore<T>::out_c_0() {
4043 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_C_R_1);
4044 T::setMemPtr(getBC() + 1);
4045 byte out_c_x = isTurboR ? 255 : 0;
4046 WRITE_PORT(getBC(), out_c_x, T::CC_OUT_C_R_1);
4047 return {1, T::CC_OUT_C_R};
4051 template<
typename T> II CPUCore<T>::out_byte_a() {
4052 byte port = RDMEM_OPCODE<1>(T::CC_OUT_N_A_1);
4053 unsigned y = (getA() << 8) | port;
4054 T::setMemPtr((getA() << 8) | ((port + 1) & 255));
4055 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_N_A_2);
4056 WRITE_PORT(y, getA(), T::CC_OUT_N_A_2);
4057 return {2, T::CC_OUT_N_A};
4062 template<
typename T>
inline II CPUCore<T>::BLOCK_CP(
int increase,
bool repeat) {
4063 T::setMemPtr(T::getMemPtr() + increase);
4064 byte val = RDMEM(getHL(), T::CC_CPI_1);
4065 byte res = getA() - val;
4066 setHL(getHL() + increase);
4068 byte f = ((getA() ^ val ^ res) &
H_FLAG) |
4076 unsigned k = res - ((f &
H_FLAG) >> 4);
4081 if (
repeat && getBC() && res) {
4083 T::setMemPtr(getPC() + 1);
4084 return {-1, T::CC_CPIR};
4086 return {1, T::CC_CPI};
4089 template<
typename T> II CPUCore<T>::cpd() {
return BLOCK_CP(-1,
false); }
4090 template<
typename T> II CPUCore<T>::cpi() {
return BLOCK_CP( 1,
false); }
4091 template<
typename T> II CPUCore<T>::cpdr() {
return BLOCK_CP(-1,
true ); }
4092 template<
typename T> II CPUCore<T>::cpir() {
return BLOCK_CP( 1,
true ); }
4096 template<
typename T>
inline II CPUCore<T>::BLOCK_LD(
int increase,
bool repeat) {
4097 byte val = RDMEM(getHL(), T::CC_LDI_1);
4098 WRMEM(getDE(), val, T::CC_LDI_2);
4099 setHL(getHL() + increase);
4100 setDE(getDE() + increase);
4102 byte f = getBC() ?
V_FLAG : 0;
4107 f |= ((getA() + val) << 4) &
Y_FLAG;
4108 f |= (getA() + val) &
X_FLAG;
4113 T::setMemPtr(getPC() + 1);
4114 return {-1, T::CC_LDIR};
4116 return {1, T::CC_LDI};
4119 template<
typename T> II CPUCore<T>::ldd() {
return BLOCK_LD(-1,
false); }
4120 template<
typename T> II CPUCore<T>::ldi() {
return BLOCK_LD( 1,
false); }
4121 template<
typename T> II CPUCore<T>::lddr() {
return BLOCK_LD(-1,
true ); }
4122 template<
typename T> II CPUCore<T>::ldir() {
return BLOCK_LD( 1,
true ); }
4126 template<
typename T>
inline II CPUCore<T>::BLOCK_IN(
int increase,
bool repeat) {
4128 if (T::isR800()) T::waitForEvenCycle(T::CC_INI_1);
4129 T::setMemPtr(getBC() + increase);
4130 setBC(getBC() - 0x100);
4131 byte val = READ_PORT(getBC(), T::CC_INI_1);
4132 WRMEM(getHL(), val, T::CC_INI_2);
4133 setHL(getHL() + increase);
4134 unsigned k = val + ((getC() + increase) & 0xFF);
4136 setF(((val &
S_FLAG) >> 6) |
4142 return {-1, T::CC_INIR};
4144 return {1, T::CC_INI};
4147 template<
typename T> II CPUCore<T>::ind() {
return BLOCK_IN(-1,
false); }
4148 template<
typename T> II CPUCore<T>::ini() {
return BLOCK_IN( 1,
false); }
4149 template<
typename T> II CPUCore<T>::indr() {
return BLOCK_IN(-1,
true ); }
4150 template<
typename T> II CPUCore<T>::inir() {
return BLOCK_IN( 1,
true ); }
4154 template<
typename T>
inline II CPUCore<T>::BLOCK_OUT(
int increase,
bool repeat) {
4156 byte val = RDMEM(getHL(), T::CC_OUTI_1);
4157 setHL(getHL() + increase);
4158 if (T::isR800()) T::waitForEvenCycle(T::CC_OUTI_2);
4159 WRITE_PORT(getBC(), val, T::CC_OUTI_2);
4160 setBC(getBC() - 0x100);
4161 T::setMemPtr(getBC() + increase);
4162 unsigned k = val + getL();
4164 setF(((val &
S_FLAG) >> 6) |
4170 return {-1, T::CC_OTIR};
4172 return {1, T::CC_OUTI};
4175 template<
typename T> II CPUCore<T>::outd() {
return BLOCK_OUT(-1,
false); }
4176 template<
typename T> II CPUCore<T>::outi() {
return BLOCK_OUT( 1,
false); }
4177 template<
typename T> II CPUCore<T>::otdr() {
return BLOCK_OUT(-1,
true ); }
4178 template<
typename T> II CPUCore<T>::otir() {
return BLOCK_OUT( 1,
true ); }
4182 template<
typename T> II CPUCore<T>::nop() {
return {1, T::CC_NOP}; }
4183 template<
typename T> II CPUCore<T>::ccf() {
4189 f |= (getF() &
C_FLAG) << 4;
4194 f |= (getF() | getA()) &
X_FLAG;
4202 return {1, T::CC_CCF};
4204 template<
typename T> II CPUCore<T>::cpl() {
4205 setA(getA() ^ 0xFF);
4214 return {1, T::CC_CPL};
4216 template<
typename T> II CPUCore<T>::daa() {
4220 if ((f &
H_FLAG) || ((getA() & 0xf) > 9)) adjust += 6;
4221 if ((f &
C_FLAG) || (getA() > 0x99)) adjust += 0x60;
4222 if (f &
N_FLAG) a -= adjust;
else a += adjust;
4230 f |= (getA() > 0x99) | ((getA() ^ a) &
H_FLAG);
4233 return {1, T::CC_DAA};
4235 template<
typename T> II CPUCore<T>::neg() {
4237 unsigned a = getA();
4238 unsigned res = -signed(a);
4239 byte f = ((res & 0x100) ?
C_FLAG : 0) |
4242 ((a & res & 0x80) >> 5);
4251 return {1, T::CC_NEG};
4253 template<
typename T> II CPUCore<T>::scf() {
4262 f |= (getF() | getA()) &
X_FLAG;
4269 return {1, T::CC_SCF};
4272 template<
typename T> II CPUCore<T>::ex_af_af() {
4273 unsigned t = getAF2(); setAF2(getAF()); setAF(
t);
4274 return {1, T::CC_EX};
4276 template<
typename T> II CPUCore<T>::ex_de_hl() {
4277 unsigned t = getDE(); setDE(getHL()); setHL(
t);
4278 return {1, T::CC_EX};
4280 template<
typename T> II CPUCore<T>::exx() {
4281 unsigned t1 = getBC2(); setBC2(getBC()); setBC(t1);
4282 unsigned t2 = getDE2(); setDE2(getDE()); setDE(t2);
4283 unsigned t3 = getHL2(); setHL2(getHL()); setHL(t3);
4284 return {1, T::CC_EX};
4287 template<
typename T> II CPUCore<T>::di() {
4290 return {1, T::CC_DI};
4292 template<
typename T> II CPUCore<T>::ei() {
4296 setSlowInstructions();
4297 return {1, T::CC_EI};
4299 template<
typename T> II CPUCore<T>::halt() {
4301 setSlowInstructions();
4303 if (!(getIFF1() || getIFF2())) {
4304 diHaltCallback.execute();
4306 return {1, T::CC_HALT};
4308 template<
typename T>
template<
unsigned N> II CPUCore<T>::im_N() {
4309 setIM(
N);
return {1, T::CC_IM};
4313 template<
typename T>
template<Reg8 REG> II CPUCore<T>::ld_a_IR() {
4315 byte f = getIFF2() ?
V_FLAG : 0;
4324 setSlowInstructions();
4327 return {1, T::CC_LD_A_I};
4331 template<
typename T> II CPUCore<T>::ld_r_a() {
4340 if (T::isR800()) val -= 1;
4342 return {1, T::CC_LD_A_I};
4344 template<
typename T> II CPUCore<T>::ld_i_a() {
4346 return {1, T::CC_LD_A_I};
4350 template<
typename T>
template<Reg8 REG> II CPUCore<T>::mulub_a_R() {
4351 assert(T::isR800());
4357 setHL(
unsigned(getA()) * get8<REG>());
4361 ((getHL() & 0xFF00) ?
C_FLAG : 0));
4362 return {1, T::CC_MULUB};
4366 template<
typename T>
template<Reg16 REG> II CPUCore<T>::muluw_hl_SS() {
4367 assert(T::isR800());
4373 unsigned res = unsigned(getHL()) * get16<REG>();
4375 setHL(res & 0xffff);
4379 ((res & 0xFFFF0000) ?
C_FLAG : 0));
4380 return {1, T::CC_MULUW};
4390 template<
typename T>
template<
typename Archive>
4394 ar.serialize(
"regs",
static_cast<CPURegs&
>(*
this));
4395 if (ar.versionBelow(version, 2)) {
4397 ar.serialize(
"memptr", mPtr);
4401 if (ar.versionBelow(version, 5)) {
4410 ar.serialize(
"nmiEdge", nmiEdge);
4419 if (T::isR800() && ar.versionBelow(version, 4)) {
4420 motherboard.getMSXCliComm().printWarning(
4421 "Loading an old savestate: the timing of the R800 "
4422 "emulation has changed. This may cause synchronization "
4423 "problems in replay.");