177 #include <type_traits>
201 enum Reg8 :
int {
A,
F,
B,
C,
D,
E,
H,
L,
IXH,
IXL,
IYH,
IYL,
REG_I,
REG_R,
DUMMY };
231 static constexpr
Table initTables()
235 for (
auto i :
xrange(256)) {
236 byte zFlag = (i == 0) ?
Z_FLAG : 0;
241 for (
int v = 128; v != 0; v >>= 1) {
242 if (i & v) vFlag ^=
V_FLAG;
245 table.
ZSXY [i] = zFlag | sFlag | xFlag | yFlag;
246 table.
ZSP [i] = zFlag | sFlag | vFlag;
247 table.
ZSPXY[i] = zFlag | sFlag | xFlag | yFlag | vFlag;
266 static word start_pc;
284 , T(time, motherboard_.getScheduler())
285 , motherboard(motherboard_)
286 , scheduler(motherboard.getScheduler())
288 , traceSetting(traceSetting_)
289 , diHaltCallback(diHaltCallback_)
290 , IRQStatus(motherboard.getDebugger(), name +
".pendingIRQ",
291 "Non-zero if there are pending IRQs (thus CPU would enter "
292 "interrupt routine in EI mode).",
294 , IRQAccept(motherboard.getDebugger(), name +
".acceptIRQ",
295 "This probe is only useful to set a breakpoint on (the value "
296 "return by read is meaningless). The breakpoint gets triggered "
297 "right after the CPU accepted an IRQ.")
299 motherboard.getCommandController(),
tmpStrCat(name,
"_freq_locked"),
300 "real (locked) or custom (unlocked) CPU frequency",
303 motherboard.getCommandController(),
tmpStrCat(name,
"_freq"),
304 "custom CPU frequency (only valid when unlocked)",
305 T::CLOCK_FREQ, 1000000, 1000000000)
306 , freq(T::CLOCK_FREQ)
310 , tracingEnabled(traceSetting.getBoolean())
311 , isCMOS(motherboard.hasToshibaEngine())
313 static_assert(!std::is_polymorphic_v<
CPUCore<T>>,
314 "keep CPUCore non-virtual to keep PC at offset 0");
321 assert(T::getTimeFast() <= time);
354 T::setMemPtr(0xFFFF);
384 assert(NMIStatus == 0);
385 assert(IRQStatus == 0);
422 template<
typename T>
void CPUCore<T>::setSlowInstructions()
424 slowInstructions = 2;
430 assert(IRQStatus >= 0);
431 if (IRQStatus == 0) {
432 setSlowInstructions();
434 IRQStatus = IRQStatus + 1;
439 IRQStatus = IRQStatus - 1;
440 assert(IRQStatus >= 0);
445 assert(NMIStatus >= 0);
446 if (NMIStatus == 0) {
448 setSlowInstructions();
456 assert(NMIStatus >= 0);
472 return address == getPC();
477 assert(time >= getCurrentTime());
478 scheduler.schedule(time);
479 T::advanceTime(time);
485 EmuTime time2 = T::calcTime(time, cycles);
488 scheduler.schedule(time2);
498 static constexpr
char toHex(
byte x)
500 return (
x < 10) ? (
x +
'0') : (
x - 10 +
'A');
502 static constexpr
void toHex(
byte x,
char* buf)
504 buf[0] = toHex(
x / 16);
505 buf[1] = toHex(
x & 15);
511 word address = (tokens.
size() < 3) ? getPC() : tokens[2].getInt(interp);
513 std::string dasmOutput;
514 unsigned len =
dasm(*interface, address, outBuf, dasmOutput,
517 char tmp[3]; tmp[2] = 0;
518 for (
auto i :
xrange(len)) {
519 toHex(outBuf[i], tmp);
528 }
else if (&
setting == &freqValue) {
530 }
else if (&
setting == &traceSetting) {
531 tracingEnabled = traceSetting.getBoolean();
543 if (freqLocked.getBoolean()) {
548 T::setFreq(freqValue.getInt());
553 template<
typename T>
inline byte CPUCore<T>::READ_PORT(
unsigned port,
unsigned cc)
555 EmuTime time = T::getTimeFast(cc);
556 scheduler.schedule(time);
557 byte result = interface->readIO(port, time);
562 template<
typename T>
inline void CPUCore<T>::WRITE_PORT(
unsigned port,
byte value,
unsigned cc)
564 EmuTime time = T::getTimeFast(cc);
565 scheduler.schedule(time);
566 interface->writeIO(port, value, time);
570 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
576 if (readCacheLine[high] ==
nullptr) {
579 if (
const byte* line = interface->getReadCacheLine(addrBase)) {
581 T::template PRE_MEM<PRE_PB, POST_PB>(address);
582 T::template POST_MEM< POST_PB>(address);
583 readCacheLine[high] = line - addrBase;
584 return readCacheLine[high][address];
588 readCacheLine[high] =
reinterpret_cast<const byte*
>(1);
589 T::template PRE_MEM<PRE_PB, POST_PB>(address);
590 EmuTime time = T::getTimeFast(cc);
591 scheduler.schedule(time);
592 byte result = interface->readMem(address, time);
593 T::template POST_MEM<POST_PB>(address);
596 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
600 if (
likely(uintptr_t(line) > 1)) {
602 T::template PRE_MEM<PRE_PB, POST_PB>(address);
603 T::template POST_MEM< POST_PB>(address);
604 return line[address];
606 return RDMEMslow<PRE_PB, POST_PB>(address, cc);
609 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
612 constexpr
bool PRE = T::template Normalize<PRE_PB >::value;
613 constexpr
bool POST = T::template Normalize<POST_PB>::value;
614 return RDMEM_impl2<PRE, POST>(address, cc);
627 unsigned address = (getPC() + PC_OFFSET) & 0xFFFF;
628 return RDMEM_impl<false, false>(address, cc);
632 return RDMEM_impl<true, true>(address, cc);
635 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
638 unsigned res = RDMEM_impl<PRE_PB, false>(address, cc);
639 res += RDMEM_impl<false, POST_PB>((address + 1) & 0xFFFF, cc + T::CC_RDMEM) << 8;
642 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
648 T::template PRE_WORD<PRE_PB, POST_PB>(address);
649 T::template POST_WORD< POST_PB>(address);
653 return RD_WORD_slow<PRE_PB, POST_PB>(address, cc);
656 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
659 constexpr
bool PRE = T::template Normalize<PRE_PB >::value;
660 constexpr
bool POST = T::template Normalize<POST_PB>::value;
661 return RD_WORD_impl2<PRE, POST>(address, cc);
665 unsigned addr = (getPC() + PC_OFFSET) & 0xFFFF;
666 return RD_WORD_impl<false, false>(addr, cc);
669 unsigned address,
unsigned cc)
671 return RD_WORD_impl<true, true>(address, cc);
674 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
680 if (writeCacheLine[high] ==
nullptr) {
683 if (
byte* line = interface->getWriteCacheLine(addrBase)) {
685 T::template PRE_MEM<PRE_PB, POST_PB>(address);
686 T::template POST_MEM< POST_PB>(address);
687 writeCacheLine[high] = line - addrBase;
688 writeCacheLine[high][address] = value;
693 writeCacheLine[high] =
reinterpret_cast<byte*
>(1);
694 T::template PRE_MEM<PRE_PB, POST_PB>(address);
695 EmuTime time = T::getTimeFast(cc);
696 scheduler.schedule(time);
697 interface->writeMem(address, value, time);
698 T::template POST_MEM<POST_PB>(address);
700 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
702 unsigned address,
byte value,
unsigned cc)
705 if (
likely(uintptr_t(line) > 1)) {
707 T::template PRE_MEM<PRE_PB, POST_PB>(address);
708 T::template POST_MEM< POST_PB>(address);
709 line[address] = value;
711 WRMEMslow<PRE_PB, POST_PB>(address, value, cc);
714 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
716 unsigned address,
byte value,
unsigned cc)
718 constexpr
bool PRE = T::template Normalize<PRE_PB >::value;
719 constexpr
bool POST = T::template Normalize<POST_PB>::value;
720 WRMEM_impl2<PRE, POST>(address, value, cc);
723 unsigned address,
byte value,
unsigned cc)
725 WRMEM_impl<true, true>(address, value, cc);
728 template<
typename T>
NEVER_INLINE void CPUCore<T>::WR_WORD_slow(
729 unsigned address,
unsigned value,
unsigned cc)
731 WRMEM_impl<true, false>( address, value & 255, cc);
732 WRMEM_impl<false, true>((address + 1) & 0xFFFF, value >> 8, cc + T::CC_WRMEM);
735 unsigned address,
unsigned value,
unsigned cc)
740 T::template PRE_WORD<true, true>(address);
741 T::template POST_WORD< true>(address);
745 WR_WORD_slow(address, value, cc);
750 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
752 unsigned address,
unsigned value,
unsigned cc)
754 WRMEM_impl<PRE_PB, false>((address + 1) & 0xFFFF, value >> 8, cc);
755 WRMEM_impl<false, POST_PB>( address, value & 255, cc + T::CC_WRMEM);
757 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
759 unsigned address,
unsigned value,
unsigned cc)
764 T::template PRE_WORD<PRE_PB, POST_PB>(address);
765 T::template POST_WORD< POST_PB>(address);
769 WR_WORD_rev_slow<PRE_PB, POST_PB>(address, value, cc);
772 template<
typename T>
template<
bool PRE_PB,
bool POST_PB>
774 unsigned address,
unsigned value,
unsigned cc)
776 constexpr
bool PRE = T::template Normalize<PRE_PB >::value;
777 constexpr
bool POST = T::template Normalize<POST_PB>::value;
778 WR_WORD_rev2<PRE, POST>(address, value, cc);
788 PUSH<T::EE_NMI_1>(getPC());
794 template<
typename T>
inline void CPUCore<T>::irq0()
798 assert(interface->readIRQVector() == 0xFF);
803 PUSH<T::EE_IRQ0_1>(getPC());
805 T::setMemPtr(getPC());
810 template<
typename T>
inline void CPUCore<T>::irq1()
816 PUSH<T::EE_IRQ1_1>(getPC());
818 T::setMemPtr(getPC());
823 template<
typename T>
inline void CPUCore<T>::irq2()
829 PUSH<T::EE_IRQ2_1>(getPC());
830 unsigned x = interface->readIRQVector() | (getI() << 8);
831 setPC(RD_WORD(
x, T::CC_IRQ2_2));
832 T::setMemPtr(getPC());
837 void CPUCore<T>::executeInstructions()
839 checkNoCurrentFlags();
840 #ifdef USE_COMPUTED_GOTO
843 static void* opcodeTable[256] = {
844 &&op00, &&op01, &&op02, &&op03, &&op04, &&op05, &&op06, &&op07,
845 &&op08, &&op09, &&op0A, &&op0B, &&op0C, &&op0D, &&op0E, &&op0F,
846 &&op10, &&op11, &&op12, &&op13, &&op14, &&op15, &&op16, &&op17,
847 &&op18, &&op19, &&op1A, &&op1B, &&op1C, &&op1D, &&op1E, &&op1F,
848 &&op20, &&op21, &&op22, &&op23, &&op24, &&op25, &&op26, &&op27,
849 &&op28, &&op29, &&op2A, &&op2B, &&op2C, &&op2D, &&op2E, &&op2F,
850 &&op30, &&op31, &&op32, &&op33, &&op34, &&op35, &&op36, &&op37,
851 &&op38, &&op39, &&op3A, &&op3B, &&op3C, &&op3D, &&op3E, &&op3F,
852 &&op00, &&op41, &&op42, &&op43, &&op44, &&op45, &&op46, &&op47,
853 &&op48, &&op00, &&op4A, &&op4B, &&op4C, &&op4D, &&op4E, &&op4F,
854 &&op50, &&op51, &&op00, &&op53, &&op54, &&op55, &&op56, &&op57,
855 &&op58, &&op59, &&op5A, &&op00, &&op5C, &&op5D, &&op5E, &&op5F,
856 &&op60, &&op61, &&op62, &&op63, &&op00, &&op65, &&op66, &&op67,
857 &&op68, &&op69, &&op6A, &&op6B, &&op6C, &&op00, &&op6E, &&op6F,
858 &&op70, &&op71, &&op72, &&op73, &&op74, &&op75, &&op76, &&op77,
859 &&op78, &&op79, &&op7A, &&op7B, &&op7C, &&op7D, &&op7E, &&op00,
860 &&op80, &&op81, &&op82, &&op83, &&op84, &&op85, &&op86, &&op87,
861 &&op88, &&op89, &&op8A, &&op8B, &&op8C, &&op8D, &&op8E, &&op8F,
862 &&op90, &&op91, &&op92, &&op93, &&op94, &&op95, &&op96, &&op97,
863 &&op98, &&op99, &&op9A, &&op9B, &&op9C, &&op9D, &&op9E, &&op9F,
864 &&opA0, &&opA1, &&opA2, &&opA3, &&opA4, &&opA5, &&opA6, &&opA7,
865 &&opA8, &&opA9, &&opAA, &&opAB, &&opAC, &&opAD, &&opAE, &&opAF,
866 &&opB0, &&opB1, &&opB2, &&opB3, &&opB4, &&opB5, &&opB6, &&opB7,
867 &&opB8, &&opB9, &&opBA, &&opBB, &&opBC, &&opBD, &&opBE, &&opBF,
868 &&opC0, &&opC1, &&opC2, &&opC3, &&opC4, &&opC5, &&opC6, &&opC7,
869 &&opC8, &&opC9, &&opCA, &&opCB, &&opCC, &&opCD, &&opCE, &&opCF,
870 &&opD0, &&opD1, &&opD2, &&opD3, &&opD4, &&opD5, &&opD6, &&opD7,
871 &&opD8, &&opD9, &&opDA, &&opDB, &&opDC, &&opDD, &&opDE, &&opDF,
872 &&opE0, &&opE1, &&opE2, &&opE3, &&opE4, &&opE5, &&opE6, &&opE7,
873 &&opE8, &&opE9, &&opEA, &&opEB, &&opEC, &&opED, &&opEE, &&opEF,
874 &&opF0, &&opF1, &&opF2, &&opF3, &&opF4, &&opF5, &&opF6, &&opF7,
875 &&opF8, &&opF9, &&opFA, &&opFB, &&opFC, &&opFD, &&opFE, &&opFF,
881 setPC(getPC() + ii.length); \
883 T::R800Refresh(*this); \
884 if (likely(!T::limitReached())) { \
886 unsigned address = getPC(); \
887 const byte* line = readCacheLine[address >> CacheLine::BITS]; \
888 if (likely(uintptr_t(line) > 1)) { \
889 T::template PRE_MEM<false, false>(address); \
890 T::template POST_MEM< false>(address); \
891 byte op = line[address]; \
892 goto *(opcodeTable[op]); \
901 setPC(getPC() + ii.length); \
903 T::R800Refresh(*this); \
904 assert(T::limitReached()); \
908 setPC(getPC() + ii.length); \
911 assert(T::limitReached()); \
915 #define CASE(X) op##X:
920 setPC(getPC() + ii.length); \
922 T::R800Refresh(*this); \
923 if (likely(!T::limitReached())) { \
929 setPC(getPC() + ii.length); \
931 T::R800Refresh(*this); \
932 assert(T::limitReached()); \
936 setPC(getPC() + ii.length); \
939 assert(T::limitReached()); \
942 #define CASE(X) case 0x##X:
946 #ifndef USE_COMPUTED_GOTO
950 byte opcodeMain = RDMEM_OPCODE<0>(T::CC_MAIN);
952 #ifdef USE_COMPUTED_GOTO
953 goto *(opcodeTable[opcodeMain]);
956 unsigned address = getPC();
957 byte opcodeSlow = RDMEMslow<false, false>(address, T::CC_MAIN);
958 goto *(opcodeTable[opcodeSlow]);
962 #ifndef USE_COMPUTED_GOTO
964 switch (opcodeMain) {
978 CASE(08) { II ii = ex_af_af();
NEXT; }
983 CASE(20) { II ii = jr(CondNZ());
NEXT; }
984 CASE(28) { II ii = jr(CondZ ());
NEXT; }
985 CASE(30) { II ii = jr(CondNC());
NEXT; }
986 CASE(38) { II ii = jr(CondC ());
NEXT; }
987 CASE(18) { II ii = jr(CondTrue());
NEXT; }
989 CASE(32) { II ii = ld_xbyte_a();
NEXT; }
991 CASE(22) { II ii = ld_xword_SS<HL,0>();
NEXT; }
992 CASE(2
A) { II ii = ld_SS_xword<HL,0>();
NEXT; }
993 CASE(02) { II ii = ld_SS_a<BC>();
NEXT; }
994 CASE(12) { II ii = ld_SS_a<DE>();
NEXT; }
995 CASE(1
A) { II ii = ld_a_SS<DE>();
NEXT; }
996 CASE(0
A) { II ii = ld_a_SS<BC>();
NEXT; }
997 CASE(03) { II ii = inc_SS<BC,0>();
NEXT; }
998 CASE(13) { II ii = inc_SS<DE,0>();
NEXT; }
999 CASE(23) { II ii = inc_SS<HL,0>();
NEXT; }
1000 CASE(33) { II ii = inc_SS<SP,0>();
NEXT; }
1001 CASE(0
B) { II ii = dec_SS<BC,0>();
NEXT; }
1002 CASE(1
B) { II ii = dec_SS<DE,0>();
NEXT; }
1003 CASE(2
B) { II ii = dec_SS<HL,0>();
NEXT; }
1004 CASE(3
B) { II ii = dec_SS<SP,0>();
NEXT; }
1005 CASE(09) { II ii = add_SS_TT<HL,BC,0>();
NEXT; }
1006 CASE(19) { II ii = add_SS_TT<HL,DE,0>();
NEXT; }
1007 CASE(29) { II ii = add_SS_SS<HL ,0>();
NEXT; }
1008 CASE(39) { II ii = add_SS_TT<HL,SP,0>();
NEXT; }
1009 CASE(01) { II ii = ld_SS_word<BC,0>();
NEXT; }
1010 CASE(11) { II ii = ld_SS_word<DE,0>();
NEXT; }
1011 CASE(21) { II ii = ld_SS_word<HL,0>();
NEXT; }
1012 CASE(31) { II ii = ld_SS_word<SP,0>();
NEXT; }
1013 CASE(04) { II ii = inc_R<B,0>();
NEXT; }
1014 CASE(0
C) { II ii = inc_R<C,0>();
NEXT; }
1015 CASE(14) { II ii = inc_R<D,0>();
NEXT; }
1016 CASE(1
C) { II ii = inc_R<E,0>();
NEXT; }
1017 CASE(24) { II ii = inc_R<H,0>();
NEXT; }
1018 CASE(2
C) { II ii = inc_R<L,0>();
NEXT; }
1019 CASE(3
C) { II ii = inc_R<A,0>();
NEXT; }
1020 CASE(34) { II ii = inc_xhl();
NEXT; }
1021 CASE(05) { II ii = dec_R<B,0>();
NEXT; }
1022 CASE(0
D) { II ii = dec_R<C,0>();
NEXT; }
1023 CASE(15) { II ii = dec_R<D,0>();
NEXT; }
1024 CASE(1
D) { II ii = dec_R<E,0>();
NEXT; }
1025 CASE(25) { II ii = dec_R<H,0>();
NEXT; }
1026 CASE(2
D) { II ii = dec_R<L,0>();
NEXT; }
1027 CASE(3
D) { II ii = dec_R<A,0>();
NEXT; }
1028 CASE(35) { II ii = dec_xhl();
NEXT; }
1029 CASE(06) { II ii = ld_R_byte<B,0>();
NEXT; }
1030 CASE(0
E) { II ii = ld_R_byte<C,0>();
NEXT; }
1031 CASE(16) { II ii = ld_R_byte<D,0>();
NEXT; }
1032 CASE(1
E) { II ii = ld_R_byte<E,0>();
NEXT; }
1033 CASE(26) { II ii = ld_R_byte<H,0>();
NEXT; }
1034 CASE(2
E) { II ii = ld_R_byte<L,0>();
NEXT; }
1035 CASE(3
E) { II ii = ld_R_byte<A,0>();
NEXT; }
1036 CASE(36) { II ii = ld_xhl_byte();
NEXT; }
1038 CASE(41) { II ii = ld_R_R<B,C,0>();
NEXT; }
1039 CASE(42) { II ii = ld_R_R<B,D,0>();
NEXT; }
1040 CASE(43) { II ii = ld_R_R<B,E,0>();
NEXT; }
1041 CASE(44) { II ii = ld_R_R<B,H,0>();
NEXT; }
1042 CASE(45) { II ii = ld_R_R<B,L,0>();
NEXT; }
1043 CASE(47) { II ii = ld_R_R<B,A,0>();
NEXT; }
1044 CASE(48) { II ii = ld_R_R<C,B,0>();
NEXT; }
1045 CASE(4
A) { II ii = ld_R_R<C,D,0>();
NEXT; }
1046 CASE(4
B) { II ii = ld_R_R<C,E,0>();
NEXT; }
1047 CASE(4
C) { II ii = ld_R_R<C,H,0>();
NEXT; }
1048 CASE(4
D) { II ii = ld_R_R<C,L,0>();
NEXT; }
1049 CASE(4
F) { II ii = ld_R_R<C,A,0>();
NEXT; }
1050 CASE(50) { II ii = ld_R_R<D,B,0>();
NEXT; }
1051 CASE(51) { II ii = ld_R_R<D,C,0>();
NEXT; }
1052 CASE(53) { II ii = ld_R_R<D,E,0>();
NEXT; }
1053 CASE(54) { II ii = ld_R_R<D,H,0>();
NEXT; }
1054 CASE(55) { II ii = ld_R_R<D,L,0>();
NEXT; }
1055 CASE(57) { II ii = ld_R_R<D,A,0>();
NEXT; }
1056 CASE(58) { II ii = ld_R_R<E,B,0>();
NEXT; }
1057 CASE(59) { II ii = ld_R_R<E,C,0>();
NEXT; }
1058 CASE(5
A) { II ii = ld_R_R<E,D,0>();
NEXT; }
1059 CASE(5
C) { II ii = ld_R_R<E,H,0>();
NEXT; }
1060 CASE(5
D) { II ii = ld_R_R<E,L,0>();
NEXT; }
1061 CASE(5
F) { II ii = ld_R_R<E,A,0>();
NEXT; }
1062 CASE(60) { II ii = ld_R_R<H,B,0>();
NEXT; }
1063 CASE(61) { II ii = ld_R_R<H,C,0>();
NEXT; }
1064 CASE(62) { II ii = ld_R_R<H,D,0>();
NEXT; }
1065 CASE(63) { II ii = ld_R_R<H,E,0>();
NEXT; }
1066 CASE(65) { II ii = ld_R_R<H,L,0>();
NEXT; }
1067 CASE(67) { II ii = ld_R_R<H,A,0>();
NEXT; }
1068 CASE(68) { II ii = ld_R_R<L,B,0>();
NEXT; }
1069 CASE(69) { II ii = ld_R_R<L,C,0>();
NEXT; }
1070 CASE(6
A) { II ii = ld_R_R<L,D,0>();
NEXT; }
1071 CASE(6
B) { II ii = ld_R_R<L,E,0>();
NEXT; }
1072 CASE(6
C) { II ii = ld_R_R<L,H,0>();
NEXT; }
1073 CASE(6
F) { II ii = ld_R_R<L,A,0>();
NEXT; }
1074 CASE(78) { II ii = ld_R_R<A,B,0>();
NEXT; }
1075 CASE(79) { II ii = ld_R_R<A,C,0>();
NEXT; }
1076 CASE(7
A) { II ii = ld_R_R<A,D,0>();
NEXT; }
1077 CASE(7
B) { II ii = ld_R_R<A,E,0>();
NEXT; }
1078 CASE(7
C) { II ii = ld_R_R<A,H,0>();
NEXT; }
1079 CASE(7
D) { II ii = ld_R_R<A,L,0>();
NEXT; }
1080 CASE(70) { II ii = ld_xhl_R<B>();
NEXT; }
1081 CASE(71) { II ii = ld_xhl_R<C>();
NEXT; }
1082 CASE(72) { II ii = ld_xhl_R<D>();
NEXT; }
1083 CASE(73) { II ii = ld_xhl_R<E>();
NEXT; }
1084 CASE(74) { II ii = ld_xhl_R<H>();
NEXT; }
1085 CASE(75) { II ii = ld_xhl_R<L>();
NEXT; }
1086 CASE(77) { II ii = ld_xhl_R<A>();
NEXT; }
1087 CASE(46) { II ii = ld_R_xhl<B>();
NEXT; }
1088 CASE(4
E) { II ii = ld_R_xhl<C>();
NEXT; }
1089 CASE(56) { II ii = ld_R_xhl<D>();
NEXT; }
1090 CASE(5
E) { II ii = ld_R_xhl<E>();
NEXT; }
1091 CASE(66) { II ii = ld_R_xhl<H>();
NEXT; }
1092 CASE(6
E) { II ii = ld_R_xhl<L>();
NEXT; }
1093 CASE(7
E) { II ii = ld_R_xhl<A>();
NEXT; }
1096 CASE(80) { II ii = add_a_R<B,0>();
NEXT; }
1097 CASE(81) { II ii = add_a_R<C,0>();
NEXT; }
1098 CASE(82) { II ii = add_a_R<D,0>();
NEXT; }
1099 CASE(83) { II ii = add_a_R<E,0>();
NEXT; }
1100 CASE(84) { II ii = add_a_R<H,0>();
NEXT; }
1101 CASE(85) { II ii = add_a_R<L,0>();
NEXT; }
1102 CASE(86) { II ii = add_a_xhl();
NEXT; }
1103 CASE(87) { II ii = add_a_a();
NEXT; }
1104 CASE(88) { II ii = adc_a_R<B,0>();
NEXT; }
1105 CASE(89) { II ii = adc_a_R<C,0>();
NEXT; }
1106 CASE(8
A) { II ii = adc_a_R<D,0>();
NEXT; }
1107 CASE(8
B) { II ii = adc_a_R<E,0>();
NEXT; }
1108 CASE(8
C) { II ii = adc_a_R<H,0>();
NEXT; }
1109 CASE(8
D) { II ii = adc_a_R<L,0>();
NEXT; }
1112 CASE(90) { II ii = sub_R<B,0>();
NEXT; }
1113 CASE(91) { II ii = sub_R<C,0>();
NEXT; }
1114 CASE(92) { II ii = sub_R<D,0>();
NEXT; }
1115 CASE(93) { II ii = sub_R<E,0>();
NEXT; }
1116 CASE(94) { II ii = sub_R<H,0>();
NEXT; }
1117 CASE(95) { II ii = sub_R<L,0>();
NEXT; }
1118 CASE(96) { II ii = sub_xhl();
NEXT; }
1119 CASE(97) { II ii = sub_a();
NEXT; }
1120 CASE(98) { II ii = sbc_a_R<B,0>();
NEXT; }
1121 CASE(99) { II ii = sbc_a_R<C,0>();
NEXT; }
1122 CASE(9
A) { II ii = sbc_a_R<D,0>();
NEXT; }
1123 CASE(9
B) { II ii = sbc_a_R<E,0>();
NEXT; }
1124 CASE(9
C) { II ii = sbc_a_R<H,0>();
NEXT; }
1125 CASE(9
D) { II ii = sbc_a_R<L,0>();
NEXT; }
1128 CASE(A0) { II ii = and_R<B,0>();
NEXT; }
1129 CASE(A1) { II ii = and_R<C,0>();
NEXT; }
1130 CASE(A2) { II ii = and_R<D,0>();
NEXT; }
1131 CASE(A3) { II ii = and_R<E,0>();
NEXT; }
1132 CASE(A4) { II ii = and_R<H,0>();
NEXT; }
1133 CASE(A5) { II ii = and_R<L,0>();
NEXT; }
1134 CASE(A6) { II ii = and_xhl();
NEXT; }
1135 CASE(A7) { II ii = and_a();
NEXT; }
1136 CASE(A8) { II ii = xor_R<B,0>();
NEXT; }
1137 CASE(A9) { II ii = xor_R<C,0>();
NEXT; }
1138 CASE(AA) { II ii = xor_R<D,0>();
NEXT; }
1139 CASE(AB) { II ii = xor_R<E,0>();
NEXT; }
1140 CASE(AC) { II ii = xor_R<H,0>();
NEXT; }
1141 CASE(AD) { II ii = xor_R<L,0>();
NEXT; }
1142 CASE(AE) { II ii = xor_xhl();
NEXT; }
1152 CASE(B8) { II ii = cp_R<B,0>();
NEXT; }
1153 CASE(B9) { II ii = cp_R<C,0>();
NEXT; }
1154 CASE(BA) { II ii = cp_R<D,0>();
NEXT; }
1155 CASE(BB) { II ii = cp_R<E,0>();
NEXT; }
1157 CASE(BD) { II ii = cp_R<L,0>();
NEXT; }
1158 CASE(BE) { II ii = cp_xhl();
NEXT; }
1161 CASE(D3) { II ii = out_byte_a();
NEXT; }
1162 CASE(DB) { II ii = in_a_byte();
NEXT; }
1164 CASE(E3) { II ii = ex_xsp_SS<HL,0>();
NEXT; }
1165 CASE(EB) { II ii = ex_de_hl();
NEXT; }
1166 CASE(E9) { II ii = jp_SS<HL,0>();
NEXT; }
1167 CASE(F9) { II ii = ld_sp_SS<HL,0>();
NEXT; }
1170 CASE(C6) { II ii = add_a_byte();
NEXT; }
1171 CASE(CE) { II ii = adc_a_byte();
NEXT; }
1172 CASE(D6) { II ii = sub_byte();
NEXT; }
1174 CASE(E6) { II ii = and_byte();
NEXT; }
1175 CASE(EE) { II ii = xor_byte();
NEXT; }
1176 CASE(F6) { II ii = or_byte();
NEXT; }
1177 CASE(FE) { II ii = cp_byte();
NEXT; }
1178 CASE(C0) { II ii = ret(CondNZ());
NEXT; }
1179 CASE(C8) { II ii = ret(CondZ ());
NEXT; }
1180 CASE(D0) { II ii = ret(CondNC());
NEXT; }
1181 CASE(D8) { II ii = ret(CondC ());
NEXT; }
1182 CASE(E0) { II ii = ret(CondPO());
NEXT; }
1183 CASE(E8) { II ii = ret(CondPE());
NEXT; }
1184 CASE(F0) { II ii = ret(CondP ());
NEXT; }
1185 CASE(F8) { II ii = ret(CondM ());
NEXT; }
1187 CASE(C2) { II ii = jp(CondNZ());
NEXT; }
1188 CASE(CA) { II ii = jp(CondZ ());
NEXT; }
1189 CASE(D2) { II ii = jp(CondNC());
NEXT; }
1190 CASE(DA) { II ii = jp(CondC ());
NEXT; }
1191 CASE(E2) { II ii = jp(CondPO());
NEXT; }
1192 CASE(EA) { II ii = jp(CondPE());
NEXT; }
1193 CASE(F2) { II ii = jp(CondP ());
NEXT; }
1194 CASE(FA) { II ii = jp(CondM ());
NEXT; }
1195 CASE(C3) { II ii = jp(CondTrue());
NEXT; }
1196 CASE(C4) { II ii = call(CondNZ());
NEXT; }
1197 CASE(CC) { II ii = call(CondZ ());
NEXT; }
1198 CASE(D4) { II ii = call(CondNC());
NEXT; }
1199 CASE(DC) { II ii = call(CondC ());
NEXT; }
1200 CASE(E4) { II ii = call(CondPO());
NEXT; }
1201 CASE(EC) { II ii = call(CondPE());
NEXT; }
1202 CASE(F4) { II ii = call(CondP ());
NEXT; }
1203 CASE(FC) { II ii = call(CondM ());
NEXT; }
1204 CASE(CD) { II ii = call(CondTrue());
NEXT; }
1205 CASE(C1) { II ii = pop_SS <BC,0>();
NEXT; }
1206 CASE(D1) { II ii = pop_SS <DE,0>();
NEXT; }
1207 CASE(E1) { II ii = pop_SS <HL,0>();
NEXT; }
1208 CASE(F1) { II ii = pop_SS <AF,0>();
NEXT; }
1209 CASE(C5) { II ii = push_SS<BC,0>();
NEXT; }
1210 CASE(D5) { II ii = push_SS<DE,0>();
NEXT; }
1211 CASE(E5) { II ii = push_SS<HL,0>();
NEXT; }
1212 CASE(F5) { II ii = push_SS<AF,0>();
NEXT; }
1213 CASE(C7) { II ii = rst<0x00>();
NEXT; }
1214 CASE(CF) { II ii = rst<0x08>();
NEXT; }
1215 CASE(D7) { II ii = rst<0x10>();
NEXT; }
1216 CASE(DF) { II ii = rst<0x18>();
NEXT; }
1217 CASE(E7) { II ii = rst<0x20>();
NEXT; }
1218 CASE(EF) { II ii = rst<0x28>();
NEXT; }
1219 CASE(F7) { II ii = rst<0x30>();
NEXT; }
1220 CASE(FF) { II ii = rst<0x38>();
NEXT; }
1223 byte cb_opcode = RDMEM_OPCODE<0>(T::CC_PREFIX);
1225 switch (cb_opcode) {
1226 case 0x00: { II ii = rlc_R<B>();
NEXT; }
1227 case 0x01: { II ii = rlc_R<C>();
NEXT; }
1228 case 0x02: { II ii = rlc_R<D>();
NEXT; }
1229 case 0x03: { II ii = rlc_R<E>();
NEXT; }
1230 case 0x04: { II ii = rlc_R<H>();
NEXT; }
1231 case 0x05: { II ii = rlc_R<L>();
NEXT; }
1232 case 0x07: { II ii = rlc_R<A>();
NEXT; }
1233 case 0x06: { II ii = rlc_xhl();
NEXT; }
1234 case 0x08: { II ii = rrc_R<B>();
NEXT; }
1235 case 0x09: { II ii = rrc_R<C>();
NEXT; }
1236 case 0x0a: { II ii = rrc_R<D>();
NEXT; }
1237 case 0x0b: { II ii = rrc_R<E>();
NEXT; }
1238 case 0x0c: { II ii = rrc_R<H>();
NEXT; }
1239 case 0x0d: { II ii = rrc_R<L>();
NEXT; }
1240 case 0x0f: { II ii = rrc_R<A>();
NEXT; }
1241 case 0x0e: { II ii = rrc_xhl();
NEXT; }
1242 case 0x10: { II ii = rl_R<B>();
NEXT; }
1243 case 0x11: { II ii = rl_R<C>();
NEXT; }
1244 case 0x12: { II ii = rl_R<D>();
NEXT; }
1245 case 0x13: { II ii = rl_R<E>();
NEXT; }
1246 case 0x14: { II ii = rl_R<H>();
NEXT; }
1247 case 0x15: { II ii = rl_R<L>();
NEXT; }
1248 case 0x17: { II ii = rl_R<A>();
NEXT; }
1249 case 0x16: { II ii = rl_xhl();
NEXT; }
1250 case 0x18: { II ii = rr_R<B>();
NEXT; }
1251 case 0x19: { II ii = rr_R<C>();
NEXT; }
1252 case 0x1a: { II ii = rr_R<D>();
NEXT; }
1253 case 0x1b: { II ii = rr_R<E>();
NEXT; }
1254 case 0x1c: { II ii = rr_R<H>();
NEXT; }
1255 case 0x1d: { II ii = rr_R<L>();
NEXT; }
1256 case 0x1f: { II ii = rr_R<A>();
NEXT; }
1257 case 0x1e: { II ii = rr_xhl();
NEXT; }
1258 case 0x20: { II ii = sla_R<B>();
NEXT; }
1259 case 0x21: { II ii = sla_R<C>();
NEXT; }
1260 case 0x22: { II ii = sla_R<D>();
NEXT; }
1261 case 0x23: { II ii = sla_R<E>();
NEXT; }
1262 case 0x24: { II ii = sla_R<H>();
NEXT; }
1263 case 0x25: { II ii = sla_R<L>();
NEXT; }
1264 case 0x27: { II ii = sla_R<A>();
NEXT; }
1265 case 0x26: { II ii = sla_xhl();
NEXT; }
1266 case 0x28: { II ii = sra_R<B>();
NEXT; }
1267 case 0x29: { II ii = sra_R<C>();
NEXT; }
1268 case 0x2a: { II ii = sra_R<D>();
NEXT; }
1269 case 0x2b: { II ii = sra_R<E>();
NEXT; }
1270 case 0x2c: { II ii = sra_R<H>();
NEXT; }
1271 case 0x2d: { II ii = sra_R<L>();
NEXT; }
1272 case 0x2f: { II ii = sra_R<A>();
NEXT; }
1273 case 0x2e: { II ii = sra_xhl();
NEXT; }
1274 case 0x30: { II ii = T::IS_R800 ? sla_R<B>() : sll_R<
B>();
NEXT; }
1275 case 0x31: { II ii = T::IS_R800 ? sla_R<C>() : sll_R<
C>();
NEXT; }
1276 case 0x32: { II ii = T::IS_R800 ? sla_R<D>() : sll_R<
D>();
NEXT; }
1277 case 0x33: { II ii = T::IS_R800 ? sla_R<E>() : sll_R<
E>();
NEXT; }
1278 case 0x34: { II ii = T::IS_R800 ? sla_R<H>() : sll_R<
H>();
NEXT; }
1279 case 0x35: { II ii = T::IS_R800 ? sla_R<L>() : sll_R<
L>();
NEXT; }
1280 case 0x37: { II ii = T::IS_R800 ? sla_R<A>() : sll_R<
A>();
NEXT; }
1281 case 0x36: { II ii = T::IS_R800 ? sla_xhl() : sll_xhl();
NEXT; }
1282 case 0x38: { II ii = srl_R<B>();
NEXT; }
1283 case 0x39: { II ii = srl_R<C>();
NEXT; }
1284 case 0x3a: { II ii = srl_R<D>();
NEXT; }
1285 case 0x3b: { II ii = srl_R<E>();
NEXT; }
1286 case 0x3c: { II ii = srl_R<H>();
NEXT; }
1287 case 0x3d: { II ii = srl_R<L>();
NEXT; }
1288 case 0x3f: { II ii = srl_R<A>();
NEXT; }
1289 case 0x3e: { II ii = srl_xhl();
NEXT; }
1291 case 0x40: { II ii = bit_N_R<0,B>();
NEXT; }
1292 case 0x41: { II ii = bit_N_R<0,C>();
NEXT; }
1293 case 0x42: { II ii = bit_N_R<0,D>();
NEXT; }
1294 case 0x43: { II ii = bit_N_R<0,E>();
NEXT; }
1295 case 0x44: { II ii = bit_N_R<0,H>();
NEXT; }
1296 case 0x45: { II ii = bit_N_R<0,L>();
NEXT; }
1297 case 0x47: { II ii = bit_N_R<0,A>();
NEXT; }
1298 case 0x48: { II ii = bit_N_R<1,B>();
NEXT; }
1299 case 0x49: { II ii = bit_N_R<1,C>();
NEXT; }
1300 case 0x4a: { II ii = bit_N_R<1,D>();
NEXT; }
1301 case 0x4b: { II ii = bit_N_R<1,E>();
NEXT; }
1302 case 0x4c: { II ii = bit_N_R<1,H>();
NEXT; }
1303 case 0x4d: { II ii = bit_N_R<1,L>();
NEXT; }
1304 case 0x4f: { II ii = bit_N_R<1,A>();
NEXT; }
1305 case 0x50: { II ii = bit_N_R<2,B>();
NEXT; }
1306 case 0x51: { II ii = bit_N_R<2,C>();
NEXT; }
1307 case 0x52: { II ii = bit_N_R<2,D>();
NEXT; }
1308 case 0x53: { II ii = bit_N_R<2,E>();
NEXT; }
1309 case 0x54: { II ii = bit_N_R<2,H>();
NEXT; }
1310 case 0x55: { II ii = bit_N_R<2,L>();
NEXT; }
1311 case 0x57: { II ii = bit_N_R<2,A>();
NEXT; }
1312 case 0x58: { II ii = bit_N_R<3,B>();
NEXT; }
1313 case 0x59: { II ii = bit_N_R<3,C>();
NEXT; }
1314 case 0x5a: { II ii = bit_N_R<3,D>();
NEXT; }
1315 case 0x5b: { II ii = bit_N_R<3,E>();
NEXT; }
1316 case 0x5c: { II ii = bit_N_R<3,H>();
NEXT; }
1317 case 0x5d: { II ii = bit_N_R<3,L>();
NEXT; }
1318 case 0x5f: { II ii = bit_N_R<3,A>();
NEXT; }
1319 case 0x60: { II ii = bit_N_R<4,B>();
NEXT; }
1320 case 0x61: { II ii = bit_N_R<4,C>();
NEXT; }
1321 case 0x62: { II ii = bit_N_R<4,D>();
NEXT; }
1322 case 0x63: { II ii = bit_N_R<4,E>();
NEXT; }
1323 case 0x64: { II ii = bit_N_R<4,H>();
NEXT; }
1324 case 0x65: { II ii = bit_N_R<4,L>();
NEXT; }
1325 case 0x67: { II ii = bit_N_R<4,A>();
NEXT; }
1326 case 0x68: { II ii = bit_N_R<5,B>();
NEXT; }
1327 case 0x69: { II ii = bit_N_R<5,C>();
NEXT; }
1328 case 0x6a: { II ii = bit_N_R<5,D>();
NEXT; }
1329 case 0x6b: { II ii = bit_N_R<5,E>();
NEXT; }
1330 case 0x6c: { II ii = bit_N_R<5,H>();
NEXT; }
1331 case 0x6d: { II ii = bit_N_R<5,L>();
NEXT; }
1332 case 0x6f: { II ii = bit_N_R<5,A>();
NEXT; }
1333 case 0x70: { II ii = bit_N_R<6,B>();
NEXT; }
1334 case 0x71: { II ii = bit_N_R<6,C>();
NEXT; }
1335 case 0x72: { II ii = bit_N_R<6,D>();
NEXT; }
1336 case 0x73: { II ii = bit_N_R<6,E>();
NEXT; }
1337 case 0x74: { II ii = bit_N_R<6,H>();
NEXT; }
1338 case 0x75: { II ii = bit_N_R<6,L>();
NEXT; }
1339 case 0x77: { II ii = bit_N_R<6,A>();
NEXT; }
1340 case 0x78: { II ii = bit_N_R<7,B>();
NEXT; }
1341 case 0x79: { II ii = bit_N_R<7,C>();
NEXT; }
1342 case 0x7a: { II ii = bit_N_R<7,D>();
NEXT; }
1343 case 0x7b: { II ii = bit_N_R<7,E>();
NEXT; }
1344 case 0x7c: { II ii = bit_N_R<7,H>();
NEXT; }
1345 case 0x7d: { II ii = bit_N_R<7,L>();
NEXT; }
1346 case 0x7f: { II ii = bit_N_R<7,A>();
NEXT; }
1347 case 0x46: { II ii = bit_N_xhl<0>();
NEXT; }
1348 case 0x4e: { II ii = bit_N_xhl<1>();
NEXT; }
1349 case 0x56: { II ii = bit_N_xhl<2>();
NEXT; }
1350 case 0x5e: { II ii = bit_N_xhl<3>();
NEXT; }
1351 case 0x66: { II ii = bit_N_xhl<4>();
NEXT; }
1352 case 0x6e: { II ii = bit_N_xhl<5>();
NEXT; }
1353 case 0x76: { II ii = bit_N_xhl<6>();
NEXT; }
1354 case 0x7e: { II ii = bit_N_xhl<7>();
NEXT; }
1356 case 0x80: { II ii = res_N_R<0,B>();
NEXT; }
1357 case 0x81: { II ii = res_N_R<0,C>();
NEXT; }
1358 case 0x82: { II ii = res_N_R<0,D>();
NEXT; }
1359 case 0x83: { II ii = res_N_R<0,E>();
NEXT; }
1360 case 0x84: { II ii = res_N_R<0,H>();
NEXT; }
1361 case 0x85: { II ii = res_N_R<0,L>();
NEXT; }
1362 case 0x87: { II ii = res_N_R<0,A>();
NEXT; }
1363 case 0x88: { II ii = res_N_R<1,B>();
NEXT; }
1364 case 0x89: { II ii = res_N_R<1,C>();
NEXT; }
1365 case 0x8a: { II ii = res_N_R<1,D>();
NEXT; }
1366 case 0x8b: { II ii = res_N_R<1,E>();
NEXT; }
1367 case 0x8c: { II ii = res_N_R<1,H>();
NEXT; }
1368 case 0x8d: { II ii = res_N_R<1,L>();
NEXT; }
1369 case 0x8f: { II ii = res_N_R<1,A>();
NEXT; }
1370 case 0x90: { II ii = res_N_R<2,B>();
NEXT; }
1371 case 0x91: { II ii = res_N_R<2,C>();
NEXT; }
1372 case 0x92: { II ii = res_N_R<2,D>();
NEXT; }
1373 case 0x93: { II ii = res_N_R<2,E>();
NEXT; }
1374 case 0x94: { II ii = res_N_R<2,H>();
NEXT; }
1375 case 0x95: { II ii = res_N_R<2,L>();
NEXT; }
1376 case 0x97: { II ii = res_N_R<2,A>();
NEXT; }
1377 case 0x98: { II ii = res_N_R<3,B>();
NEXT; }
1378 case 0x99: { II ii = res_N_R<3,C>();
NEXT; }
1379 case 0x9a: { II ii = res_N_R<3,D>();
NEXT; }
1380 case 0x9b: { II ii = res_N_R<3,E>();
NEXT; }
1381 case 0x9c: { II ii = res_N_R<3,H>();
NEXT; }
1382 case 0x9d: { II ii = res_N_R<3,L>();
NEXT; }
1383 case 0x9f: { II ii = res_N_R<3,A>();
NEXT; }
1384 case 0xa0: { II ii = res_N_R<4,B>();
NEXT; }
1385 case 0xa1: { II ii = res_N_R<4,C>();
NEXT; }
1386 case 0xa2: { II ii = res_N_R<4,D>();
NEXT; }
1387 case 0xa3: { II ii = res_N_R<4,E>();
NEXT; }
1388 case 0xa4: { II ii = res_N_R<4,H>();
NEXT; }
1389 case 0xa5: { II ii = res_N_R<4,L>();
NEXT; }
1390 case 0xa7: { II ii = res_N_R<4,A>();
NEXT; }
1391 case 0xa8: { II ii = res_N_R<5,B>();
NEXT; }
1392 case 0xa9: { II ii = res_N_R<5,C>();
NEXT; }
1393 case 0xaa: { II ii = res_N_R<5,D>();
NEXT; }
1394 case 0xab: { II ii = res_N_R<5,E>();
NEXT; }
1395 case 0xac: { II ii = res_N_R<5,H>();
NEXT; }
1396 case 0xad: { II ii = res_N_R<5,L>();
NEXT; }
1397 case 0xaf: { II ii = res_N_R<5,A>();
NEXT; }
1398 case 0xb0: { II ii = res_N_R<6,B>();
NEXT; }
1399 case 0xb1: { II ii = res_N_R<6,C>();
NEXT; }
1400 case 0xb2: { II ii = res_N_R<6,D>();
NEXT; }
1401 case 0xb3: { II ii = res_N_R<6,E>();
NEXT; }
1402 case 0xb4: { II ii = res_N_R<6,H>();
NEXT; }
1403 case 0xb5: { II ii = res_N_R<6,L>();
NEXT; }
1404 case 0xb7: { II ii = res_N_R<6,A>();
NEXT; }
1405 case 0xb8: { II ii = res_N_R<7,B>();
NEXT; }
1406 case 0xb9: { II ii = res_N_R<7,C>();
NEXT; }
1407 case 0xba: { II ii = res_N_R<7,D>();
NEXT; }
1408 case 0xbb: { II ii = res_N_R<7,E>();
NEXT; }
1409 case 0xbc: { II ii = res_N_R<7,H>();
NEXT; }
1410 case 0xbd: { II ii = res_N_R<7,L>();
NEXT; }
1411 case 0xbf: { II ii = res_N_R<7,A>();
NEXT; }
1412 case 0x86: { II ii = res_N_xhl<0>();
NEXT; }
1413 case 0x8e: { II ii = res_N_xhl<1>();
NEXT; }
1414 case 0x96: { II ii = res_N_xhl<2>();
NEXT; }
1415 case 0x9e: { II ii = res_N_xhl<3>();
NEXT; }
1416 case 0xa6: { II ii = res_N_xhl<4>();
NEXT; }
1417 case 0xae: { II ii = res_N_xhl<5>();
NEXT; }
1418 case 0xb6: { II ii = res_N_xhl<6>();
NEXT; }
1419 case 0xbe: { II ii = res_N_xhl<7>();
NEXT; }
1421 case 0xc0: { II ii = set_N_R<0,B>();
NEXT; }
1422 case 0xc1: { II ii = set_N_R<0,C>();
NEXT; }
1423 case 0xc2: { II ii = set_N_R<0,D>();
NEXT; }
1424 case 0xc3: { II ii = set_N_R<0,E>();
NEXT; }
1425 case 0xc4: { II ii = set_N_R<0,H>();
NEXT; }
1426 case 0xc5: { II ii = set_N_R<0,L>();
NEXT; }
1427 case 0xc7: { II ii = set_N_R<0,A>();
NEXT; }
1428 case 0xc8: { II ii = set_N_R<1,B>();
NEXT; }
1429 case 0xc9: { II ii = set_N_R<1,C>();
NEXT; }
1430 case 0xca: { II ii = set_N_R<1,D>();
NEXT; }
1431 case 0xcb: { II ii = set_N_R<1,E>();
NEXT; }
1432 case 0xcc: { II ii = set_N_R<1,H>();
NEXT; }
1433 case 0xcd: { II ii = set_N_R<1,L>();
NEXT; }
1434 case 0xcf: { II ii = set_N_R<1,A>();
NEXT; }
1435 case 0xd0: { II ii = set_N_R<2,B>();
NEXT; }
1436 case 0xd1: { II ii = set_N_R<2,C>();
NEXT; }
1437 case 0xd2: { II ii = set_N_R<2,D>();
NEXT; }
1438 case 0xd3: { II ii = set_N_R<2,E>();
NEXT; }
1439 case 0xd4: { II ii = set_N_R<2,H>();
NEXT; }
1440 case 0xd5: { II ii = set_N_R<2,L>();
NEXT; }
1441 case 0xd7: { II ii = set_N_R<2,A>();
NEXT; }
1442 case 0xd8: { II ii = set_N_R<3,B>();
NEXT; }
1443 case 0xd9: { II ii = set_N_R<3,C>();
NEXT; }
1444 case 0xda: { II ii = set_N_R<3,D>();
NEXT; }
1445 case 0xdb: { II ii = set_N_R<3,E>();
NEXT; }
1446 case 0xdc: { II ii = set_N_R<3,H>();
NEXT; }
1447 case 0xdd: { II ii = set_N_R<3,L>();
NEXT; }
1448 case 0xdf: { II ii = set_N_R<3,A>();
NEXT; }
1449 case 0xe0: { II ii = set_N_R<4,B>();
NEXT; }
1450 case 0xe1: { II ii = set_N_R<4,C>();
NEXT; }
1451 case 0xe2: { II ii = set_N_R<4,D>();
NEXT; }
1452 case 0xe3: { II ii = set_N_R<4,E>();
NEXT; }
1453 case 0xe4: { II ii = set_N_R<4,H>();
NEXT; }
1454 case 0xe5: { II ii = set_N_R<4,L>();
NEXT; }
1455 case 0xe7: { II ii = set_N_R<4,A>();
NEXT; }
1456 case 0xe8: { II ii = set_N_R<5,B>();
NEXT; }
1457 case 0xe9: { II ii = set_N_R<5,C>();
NEXT; }
1458 case 0xea: { II ii = set_N_R<5,D>();
NEXT; }
1459 case 0xeb: { II ii = set_N_R<5,E>();
NEXT; }
1460 case 0xec: { II ii = set_N_R<5,H>();
NEXT; }
1461 case 0xed: { II ii = set_N_R<5,L>();
NEXT; }
1462 case 0xef: { II ii = set_N_R<5,A>();
NEXT; }
1463 case 0xf0: { II ii = set_N_R<6,B>();
NEXT; }
1464 case 0xf1: { II ii = set_N_R<6,C>();
NEXT; }
1465 case 0xf2: { II ii = set_N_R<6,D>();
NEXT; }
1466 case 0xf3: { II ii = set_N_R<6,E>();
NEXT; }
1467 case 0xf4: { II ii = set_N_R<6,H>();
NEXT; }
1468 case 0xf5: { II ii = set_N_R<6,L>();
NEXT; }
1469 case 0xf7: { II ii = set_N_R<6,A>();
NEXT; }
1470 case 0xf8: { II ii = set_N_R<7,B>();
NEXT; }
1471 case 0xf9: { II ii = set_N_R<7,C>();
NEXT; }
1472 case 0xfa: { II ii = set_N_R<7,D>();
NEXT; }
1473 case 0xfb: { II ii = set_N_R<7,E>();
NEXT; }
1474 case 0xfc: { II ii = set_N_R<7,H>();
NEXT; }
1475 case 0xfd: { II ii = set_N_R<7,L>();
NEXT; }
1476 case 0xff: { II ii = set_N_R<7,A>();
NEXT; }
1477 case 0xc6: { II ii = set_N_xhl<0>();
NEXT; }
1478 case 0xce: { II ii = set_N_xhl<1>();
NEXT; }
1479 case 0xd6: { II ii = set_N_xhl<2>();
NEXT; }
1480 case 0xde: { II ii = set_N_xhl<3>();
NEXT; }
1481 case 0xe6: { II ii = set_N_xhl<4>();
NEXT; }
1482 case 0xee: { II ii = set_N_xhl<5>();
NEXT; }
1483 case 0xf6: { II ii = set_N_xhl<6>();
NEXT; }
1484 case 0xfe: { II ii = set_N_xhl<7>();
NEXT; }
1490 byte ed_opcode = RDMEM_OPCODE<0>(T::CC_PREFIX);
1492 switch (ed_opcode) {
1493 case 0x00:
case 0x01:
case 0x02:
case 0x03:
1494 case 0x04:
case 0x05:
case 0x06:
case 0x07:
1495 case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
1496 case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
1497 case 0x10:
case 0x11:
case 0x12:
case 0x13:
1498 case 0x14:
case 0x15:
case 0x16:
case 0x17:
1499 case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
1500 case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f:
1501 case 0x20:
case 0x21:
case 0x22:
case 0x23:
1502 case 0x24:
case 0x25:
case 0x26:
case 0x27:
1503 case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
1504 case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
1505 case 0x30:
case 0x31:
case 0x32:
case 0x33:
1506 case 0x34:
case 0x35:
case 0x36:
case 0x37:
1507 case 0x38:
case 0x39:
case 0x3a:
case 0x3b:
1508 case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
1510 case 0x77:
case 0x7f:
1512 case 0x80:
case 0x81:
case 0x82:
case 0x83:
1513 case 0x84:
case 0x85:
case 0x86:
case 0x87:
1514 case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
1515 case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
1516 case 0x90:
case 0x91:
case 0x92:
case 0x93:
1517 case 0x94:
case 0x95:
case 0x96:
case 0x97:
1518 case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
1519 case 0x9c:
case 0x9d:
case 0x9e:
case 0x9f:
1520 case 0xa4:
case 0xa5:
case 0xa6:
case 0xa7:
1521 case 0xac:
case 0xad:
case 0xae:
case 0xaf:
1522 case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
1523 case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
1525 case 0xc0:
case 0xc2:
1526 case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
1527 case 0xc8:
case 0xca:
case 0xcb:
1528 case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
1529 case 0xd0:
case 0xd2:
case 0xd3:
1530 case 0xd4:
case 0xd5:
case 0xd6:
case 0xd7:
1531 case 0xd8:
case 0xda:
case 0xdb:
1532 case 0xdc:
case 0xdd:
case 0xde:
case 0xdf:
1533 case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
1534 case 0xe4:
case 0xe5:
case 0xe6:
case 0xe7:
1535 case 0xe8:
case 0xe9:
case 0xea:
case 0xeb:
1536 case 0xec:
case 0xed:
case 0xee:
case 0xef:
1537 case 0xf0:
case 0xf1:
case 0xf2:
1538 case 0xf4:
case 0xf5:
case 0xf6:
case 0xf7:
1539 case 0xf8:
case 0xf9:
case 0xfa:
case 0xfb:
1540 case 0xfc:
case 0xfd:
case 0xfe:
case 0xff:
1541 { II ii = nop();
NEXT; }
1543 case 0x40: { II ii = in_R_c<B>();
NEXT; }
1544 case 0x48: { II ii = in_R_c<C>();
NEXT; }
1545 case 0x50: { II ii = in_R_c<D>();
NEXT; }
1546 case 0x58: { II ii = in_R_c<E>();
NEXT; }
1547 case 0x60: { II ii = in_R_c<H>();
NEXT; }
1548 case 0x68: { II ii = in_R_c<L>();
NEXT; }
1549 case 0x70: { II ii = in_R_c<DUMMY>();
NEXT; }
1550 case 0x78: { II ii = in_R_c<A>();
NEXT; }
1552 case 0x41: { II ii = out_c_R<B>();
NEXT; }
1553 case 0x49: { II ii = out_c_R<C>();
NEXT; }
1554 case 0x51: { II ii = out_c_R<D>();
NEXT; }
1555 case 0x59: { II ii = out_c_R<E>();
NEXT; }
1556 case 0x61: { II ii = out_c_R<H>();
NEXT; }
1557 case 0x69: { II ii = out_c_R<L>();
NEXT; }
1558 case 0x71: { II ii = out_c_0();
NEXT; }
1559 case 0x79: { II ii = out_c_R<A>();
NEXT; }
1561 case 0x42: { II ii = sbc_hl_SS<BC>();
NEXT; }
1562 case 0x52: { II ii = sbc_hl_SS<DE>();
NEXT; }
1563 case 0x62: { II ii = sbc_hl_hl ();
NEXT; }
1564 case 0x72: { II ii = sbc_hl_SS<SP>();
NEXT; }
1566 case 0x4a: { II ii = adc_hl_SS<BC>();
NEXT; }
1567 case 0x5a: { II ii = adc_hl_SS<DE>();
NEXT; }
1568 case 0x6a: { II ii = adc_hl_hl ();
NEXT; }
1569 case 0x7a: { II ii = adc_hl_SS<SP>();
NEXT; }
1571 case 0x43: { II ii = ld_xword_SS_ED<BC>();
NEXT; }
1572 case 0x53: { II ii = ld_xword_SS_ED<DE>();
NEXT; }
1573 case 0x63: { II ii = ld_xword_SS_ED<HL>();
NEXT; }
1574 case 0x73: { II ii = ld_xword_SS_ED<SP>();
NEXT; }
1576 case 0x4b: { II ii = ld_SS_xword_ED<BC>();
NEXT; }
1577 case 0x5b: { II ii = ld_SS_xword_ED<DE>();
NEXT; }
1578 case 0x6b: { II ii = ld_SS_xword_ED<HL>();
NEXT; }
1579 case 0x7b: { II ii = ld_SS_xword_ED<SP>();
NEXT; }
1581 case 0x47: { II ii = ld_i_a();
NEXT; }
1582 case 0x4f: { II ii = ld_r_a();
NEXT; }
1583 case 0x57: { II ii = ld_a_IR<REG_I>();
if (T::IS_R800) {
NEXT; }
else {
NEXT_STOP; }}
1584 case 0x5f: { II ii = ld_a_IR<REG_R>();
if (T::IS_R800) {
NEXT; }
else {
NEXT_STOP; }}
1586 case 0x67: { II ii = rrd();
NEXT; }
1587 case 0x6f: { II ii = rld();
NEXT; }
1589 case 0x45:
case 0x4d:
case 0x55:
case 0x5d:
1590 case 0x65:
case 0x6d:
case 0x75:
case 0x7d:
1592 case 0x46:
case 0x4e:
case 0x66:
case 0x6e:
1593 { II ii = im_N<0>();
NEXT; }
1594 case 0x56:
case 0x76:
1595 { II ii = im_N<1>();
NEXT; }
1596 case 0x5e:
case 0x7e:
1597 { II ii = im_N<2>();
NEXT; }
1598 case 0x44:
case 0x4c:
case 0x54:
case 0x5c:
1599 case 0x64:
case 0x6c:
case 0x74:
case 0x7c:
1600 { II ii = neg();
NEXT; }
1602 case 0xa0: { II ii = ldi();
NEXT; }
1603 case 0xa1: { II ii = cpi();
NEXT; }
1604 case 0xa2: { II ii = ini();
NEXT; }
1605 case 0xa3: { II ii = outi();
NEXT; }
1606 case 0xa8: { II ii = ldd();
NEXT; }
1607 case 0xa9: { II ii = cpd();
NEXT; }
1608 case 0xaa: { II ii = ind();
NEXT; }
1609 case 0xab: { II ii = outd();
NEXT; }
1610 case 0xb0: { II ii = ldir();
NEXT; }
1611 case 0xb1: { II ii = cpir();
NEXT; }
1612 case 0xb2: { II ii = inir();
NEXT; }
1613 case 0xb3: { II ii = otir();
NEXT; }
1614 case 0xb8: { II ii = lddr();
NEXT; }
1615 case 0xb9: { II ii = cpdr();
NEXT; }
1616 case 0xba: { II ii = indr();
NEXT; }
1617 case 0xbb: { II ii = otdr();
NEXT; }
1619 case 0xc1: { II ii = T::IS_R800 ? mulub_a_R<B>() : nop();
NEXT; }
1620 case 0xc9: { II ii = T::IS_R800 ? mulub_a_R<C>() : nop();
NEXT; }
1621 case 0xd1: { II ii = T::IS_R800 ? mulub_a_R<D>() : nop();
NEXT; }
1622 case 0xd9: { II ii = T::IS_R800 ? mulub_a_R<E>() : nop();
NEXT; }
1623 case 0xc3: { II ii = T::IS_R800 ? muluw_hl_SS<BC>() : nop();
NEXT; }
1624 case 0xf3: { II ii = T::IS_R800 ? muluw_hl_SS<SP>() : nop();
NEXT; }
1631 byte opcodeDD = RDMEM_OPCODE<0>(T::CC_DD + T::CC_MAIN);
1809 ii.cycles += T::CC_DD;
1813 #ifdef USE_COMPUTED_GOTO
1814 goto *(opcodeTable[opcodeDD]);
1816 opcodeMain = opcodeDD;
1821 case 0x09: { II ii = add_SS_TT<IX,BC,T::CC_DD>();
NEXT; }
1822 case 0x19: { II ii = add_SS_TT<IX,DE,T::CC_DD>();
NEXT; }
1823 case 0x29: { II ii = add_SS_SS<IX ,T::CC_DD>();
NEXT; }
1824 case 0x39: { II ii = add_SS_TT<IX,SP,T::CC_DD>();
NEXT; }
1825 case 0x21: { II ii = ld_SS_word<IX,T::CC_DD>();
NEXT; }
1826 case 0x22: { II ii = ld_xword_SS<IX,T::CC_DD>();
NEXT; }
1827 case 0x2a: { II ii = ld_SS_xword<IX,T::CC_DD>();
NEXT; }
1828 case 0x23: { II ii = inc_SS<IX,T::CC_DD>();
NEXT; }
1829 case 0x2b: { II ii = dec_SS<IX,T::CC_DD>();
NEXT; }
1830 case 0x24: { II ii = inc_R<IXH,T::CC_DD>();
NEXT; }
1831 case 0x2c: { II ii = inc_R<IXL,T::CC_DD>();
NEXT; }
1832 case 0x25: { II ii = dec_R<IXH,T::CC_DD>();
NEXT; }
1833 case 0x2d: { II ii = dec_R<IXL,T::CC_DD>();
NEXT; }
1834 case 0x26: { II ii = ld_R_byte<IXH,T::CC_DD>();
NEXT; }
1835 case 0x2e: { II ii = ld_R_byte<IXL,T::CC_DD>();
NEXT; }
1836 case 0x34: { II ii = inc_xix<IX>();
NEXT; }
1837 case 0x35: { II ii = dec_xix<IX>();
NEXT; }
1838 case 0x36: { II ii = ld_xix_byte<IX>();
NEXT; }
1840 case 0x44: { II ii = ld_R_R<B,IXH,T::CC_DD>();
NEXT; }
1841 case 0x45: { II ii = ld_R_R<B,IXL,T::CC_DD>();
NEXT; }
1842 case 0x4c: { II ii = ld_R_R<C,IXH,T::CC_DD>();
NEXT; }
1843 case 0x4d: { II ii = ld_R_R<C,IXL,T::CC_DD>();
NEXT; }
1844 case 0x54: { II ii = ld_R_R<D,IXH,T::CC_DD>();
NEXT; }
1845 case 0x55: { II ii = ld_R_R<D,IXL,T::CC_DD>();
NEXT; }
1846 case 0x5c: { II ii = ld_R_R<E,IXH,T::CC_DD>();
NEXT; }
1847 case 0x5d: { II ii = ld_R_R<E,IXL,T::CC_DD>();
NEXT; }
1848 case 0x7c: { II ii = ld_R_R<A,IXH,T::CC_DD>();
NEXT; }
1849 case 0x7d: { II ii = ld_R_R<A,IXL,T::CC_DD>();
NEXT; }
1850 case 0x60: { II ii = ld_R_R<IXH,B,T::CC_DD>();
NEXT; }
1851 case 0x61: { II ii = ld_R_R<IXH,C,T::CC_DD>();
NEXT; }
1852 case 0x62: { II ii = ld_R_R<IXH,D,T::CC_DD>();
NEXT; }
1853 case 0x63: { II ii = ld_R_R<IXH,E,T::CC_DD>();
NEXT; }
1854 case 0x65: { II ii = ld_R_R<IXH,IXL,T::CC_DD>();
NEXT; }
1855 case 0x67: { II ii = ld_R_R<IXH,A,T::CC_DD>();
NEXT; }
1856 case 0x68: { II ii = ld_R_R<IXL,B,T::CC_DD>();
NEXT; }
1857 case 0x69: { II ii = ld_R_R<IXL,C,T::CC_DD>();
NEXT; }
1858 case 0x6a: { II ii = ld_R_R<IXL,D,T::CC_DD>();
NEXT; }
1859 case 0x6b: { II ii = ld_R_R<IXL,E,T::CC_DD>();
NEXT; }
1860 case 0x6c: { II ii = ld_R_R<IXL,IXH,T::CC_DD>();
NEXT; }
1861 case 0x6f: { II ii = ld_R_R<IXL,A,T::CC_DD>();
NEXT; }
1862 case 0x70: { II ii = ld_xix_R<IX,B>();
NEXT; }
1863 case 0x71: { II ii = ld_xix_R<IX,C>();
NEXT; }
1864 case 0x72: { II ii = ld_xix_R<IX,D>();
NEXT; }
1865 case 0x73: { II ii = ld_xix_R<IX,E>();
NEXT; }
1866 case 0x74: { II ii = ld_xix_R<IX,H>();
NEXT; }
1867 case 0x75: { II ii = ld_xix_R<IX,L>();
NEXT; }
1868 case 0x77: { II ii = ld_xix_R<IX,A>();
NEXT; }
1869 case 0x46: { II ii = ld_R_xix<B,IX>();
NEXT; }
1870 case 0x4e: { II ii = ld_R_xix<C,IX>();
NEXT; }
1871 case 0x56: { II ii = ld_R_xix<D,IX>();
NEXT; }
1872 case 0x5e: { II ii = ld_R_xix<E,IX>();
NEXT; }
1873 case 0x66: { II ii = ld_R_xix<H,IX>();
NEXT; }
1874 case 0x6e: { II ii = ld_R_xix<L,IX>();
NEXT; }
1875 case 0x7e: { II ii = ld_R_xix<A,IX>();
NEXT; }
1877 case 0x84: { II ii = add_a_R<IXH,T::CC_DD>();
NEXT; }
1878 case 0x85: { II ii = add_a_R<IXL,T::CC_DD>();
NEXT; }
1879 case 0x86: { II ii = add_a_xix<IX>();
NEXT; }
1880 case 0x8c: { II ii = adc_a_R<IXH,T::CC_DD>();
NEXT; }
1881 case 0x8d: { II ii = adc_a_R<IXL,T::CC_DD>();
NEXT; }
1882 case 0x8e: { II ii = adc_a_xix<IX>();
NEXT; }
1883 case 0x94: { II ii = sub_R<IXH,T::CC_DD>();
NEXT; }
1884 case 0x95: { II ii = sub_R<IXL,T::CC_DD>();
NEXT; }
1885 case 0x96: { II ii = sub_xix<IX>();
NEXT; }
1886 case 0x9c: { II ii = sbc_a_R<IXH,T::CC_DD>();
NEXT; }
1887 case 0x9d: { II ii = sbc_a_R<IXL,T::CC_DD>();
NEXT; }
1888 case 0x9e: { II ii = sbc_a_xix<IX>();
NEXT; }
1889 case 0xa4: { II ii = and_R<IXH,T::CC_DD>();
NEXT; }
1890 case 0xa5: { II ii = and_R<IXL,T::CC_DD>();
NEXT; }
1891 case 0xa6: { II ii = and_xix<IX>();
NEXT; }
1892 case 0xac: { II ii = xor_R<IXH,T::CC_DD>();
NEXT; }
1893 case 0xad: { II ii = xor_R<IXL,T::CC_DD>();
NEXT; }
1894 case 0xae: { II ii = xor_xix<IX>();
NEXT; }
1895 case 0xb4: { II ii = or_R<IXH,T::CC_DD>();
NEXT; }
1896 case 0xb5: { II ii = or_R<IXL,T::CC_DD>();
NEXT; }
1897 case 0xb6: { II ii = or_xix<IX>();
NEXT; }
1898 case 0xbc: { II ii = cp_R<IXH,T::CC_DD>();
NEXT; }
1899 case 0xbd: { II ii = cp_R<IXL,T::CC_DD>();
NEXT; }
1900 case 0xbe: { II ii = cp_xix<IX>();
NEXT; }
1902 case 0xe1: { II ii = pop_SS <IX,T::CC_DD>();
NEXT; }
1903 case 0xe5: { II ii = push_SS<IX,T::CC_DD>();
NEXT; }
1904 case 0xe3: { II ii = ex_xsp_SS<IX,T::CC_DD>();
NEXT; }
1905 case 0xe9: { II ii = jp_SS<IX,T::CC_DD>();
NEXT; }
1906 case 0xf9: { II ii = ld_sp_SS<IX,T::CC_DD>();
NEXT; }
1907 case 0xcb: ixy = getIX();
goto xx_cb;
1908 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
1909 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
1916 byte opcodeFD = RDMEM_OPCODE<0>(T::CC_DD + T::CC_MAIN);
2092 if constexpr (T::IS_R800) {
2094 ii.cycles += T::CC_DD;
2098 #ifdef USE_COMPUTED_GOTO
2099 goto *(opcodeTable[opcodeFD]);
2101 opcodeMain = opcodeFD;
2106 case 0x09: { II ii = add_SS_TT<IY,BC,T::CC_DD>();
NEXT; }
2107 case 0x19: { II ii = add_SS_TT<IY,DE,T::CC_DD>();
NEXT; }
2108 case 0x29: { II ii = add_SS_SS<IY ,T::CC_DD>();
NEXT; }
2109 case 0x39: { II ii = add_SS_TT<IY,SP,T::CC_DD>();
NEXT; }
2110 case 0x21: { II ii = ld_SS_word<IY,T::CC_DD>();
NEXT; }
2111 case 0x22: { II ii = ld_xword_SS<IY,T::CC_DD>();
NEXT; }
2112 case 0x2a: { II ii = ld_SS_xword<IY,T::CC_DD>();
NEXT; }
2113 case 0x23: { II ii = inc_SS<IY,T::CC_DD>();
NEXT; }
2114 case 0x2b: { II ii = dec_SS<IY,T::CC_DD>();
NEXT; }
2115 case 0x24: { II ii = inc_R<IYH,T::CC_DD>();
NEXT; }
2116 case 0x2c: { II ii = inc_R<IYL,T::CC_DD>();
NEXT; }
2117 case 0x25: { II ii = dec_R<IYH,T::CC_DD>();
NEXT; }
2118 case 0x2d: { II ii = dec_R<IYL,T::CC_DD>();
NEXT; }
2119 case 0x26: { II ii = ld_R_byte<IYH,T::CC_DD>();
NEXT; }
2120 case 0x2e: { II ii = ld_R_byte<IYL,T::CC_DD>();
NEXT; }
2121 case 0x34: { II ii = inc_xix<IY>();
NEXT; }
2122 case 0x35: { II ii = dec_xix<IY>();
NEXT; }
2123 case 0x36: { II ii = ld_xix_byte<IY>();
NEXT; }
2125 case 0x44: { II ii = ld_R_R<B,IYH,T::CC_DD>();
NEXT; }
2126 case 0x45: { II ii = ld_R_R<B,IYL,T::CC_DD>();
NEXT; }
2127 case 0x4c: { II ii = ld_R_R<C,IYH,T::CC_DD>();
NEXT; }
2128 case 0x4d: { II ii = ld_R_R<C,IYL,T::CC_DD>();
NEXT; }
2129 case 0x54: { II ii = ld_R_R<D,IYH,T::CC_DD>();
NEXT; }
2130 case 0x55: { II ii = ld_R_R<D,IYL,T::CC_DD>();
NEXT; }
2131 case 0x5c: { II ii = ld_R_R<E,IYH,T::CC_DD>();
NEXT; }
2132 case 0x5d: { II ii = ld_R_R<E,IYL,T::CC_DD>();
NEXT; }
2133 case 0x7c: { II ii = ld_R_R<A,IYH,T::CC_DD>();
NEXT; }
2134 case 0x7d: { II ii = ld_R_R<A,IYL,T::CC_DD>();
NEXT; }
2135 case 0x60: { II ii = ld_R_R<IYH,B,T::CC_DD>();
NEXT; }
2136 case 0x61: { II ii = ld_R_R<IYH,C,T::CC_DD>();
NEXT; }
2137 case 0x62: { II ii = ld_R_R<IYH,D,T::CC_DD>();
NEXT; }
2138 case 0x63: { II ii = ld_R_R<IYH,E,T::CC_DD>();
NEXT; }
2139 case 0x65: { II ii = ld_R_R<IYH,IYL,T::CC_DD>();
NEXT; }
2140 case 0x67: { II ii = ld_R_R<IYH,A,T::CC_DD>();
NEXT; }
2141 case 0x68: { II ii = ld_R_R<IYL,B,T::CC_DD>();
NEXT; }
2142 case 0x69: { II ii = ld_R_R<IYL,C,T::CC_DD>();
NEXT; }
2143 case 0x6a: { II ii = ld_R_R<IYL,D,T::CC_DD>();
NEXT; }
2144 case 0x6b: { II ii = ld_R_R<IYL,E,T::CC_DD>();
NEXT; }
2145 case 0x6c: { II ii = ld_R_R<IYL,IYH,T::CC_DD>();
NEXT; }
2146 case 0x6f: { II ii = ld_R_R<IYL,A,T::CC_DD>();
NEXT; }
2147 case 0x70: { II ii = ld_xix_R<IY,B>();
NEXT; }
2148 case 0x71: { II ii = ld_xix_R<IY,C>();
NEXT; }
2149 case 0x72: { II ii = ld_xix_R<IY,D>();
NEXT; }
2150 case 0x73: { II ii = ld_xix_R<IY,E>();
NEXT; }
2151 case 0x74: { II ii = ld_xix_R<IY,H>();
NEXT; }
2152 case 0x75: { II ii = ld_xix_R<IY,L>();
NEXT; }
2153 case 0x77: { II ii = ld_xix_R<IY,A>();
NEXT; }
2154 case 0x46: { II ii = ld_R_xix<B,IY>();
NEXT; }
2155 case 0x4e: { II ii = ld_R_xix<C,IY>();
NEXT; }
2156 case 0x56: { II ii = ld_R_xix<D,IY>();
NEXT; }
2157 case 0x5e: { II ii = ld_R_xix<E,IY>();
NEXT; }
2158 case 0x66: { II ii = ld_R_xix<H,IY>();
NEXT; }
2159 case 0x6e: { II ii = ld_R_xix<L,IY>();
NEXT; }
2160 case 0x7e: { II ii = ld_R_xix<A,IY>();
NEXT; }
2162 case 0x84: { II ii = add_a_R<IYH,T::CC_DD>();
NEXT; }
2163 case 0x85: { II ii = add_a_R<IYL,T::CC_DD>();
NEXT; }
2164 case 0x86: { II ii = add_a_xix<IY>();
NEXT; }
2165 case 0x8c: { II ii = adc_a_R<IYH,T::CC_DD>();
NEXT; }
2166 case 0x8d: { II ii = adc_a_R<IYL,T::CC_DD>();
NEXT; }
2167 case 0x8e: { II ii = adc_a_xix<IY>();
NEXT; }
2168 case 0x94: { II ii = sub_R<IYH,T::CC_DD>();
NEXT; }
2169 case 0x95: { II ii = sub_R<IYL,T::CC_DD>();
NEXT; }
2170 case 0x96: { II ii = sub_xix<IY>();
NEXT; }
2171 case 0x9c: { II ii = sbc_a_R<IYH,T::CC_DD>();
NEXT; }
2172 case 0x9d: { II ii = sbc_a_R<IYL,T::CC_DD>();
NEXT; }
2173 case 0x9e: { II ii = sbc_a_xix<IY>();
NEXT; }
2174 case 0xa4: { II ii = and_R<IYH,T::CC_DD>();
NEXT; }
2175 case 0xa5: { II ii = and_R<IYL,T::CC_DD>();
NEXT; }
2176 case 0xa6: { II ii = and_xix<IY>();
NEXT; }
2177 case 0xac: { II ii = xor_R<IYH,T::CC_DD>();
NEXT; }
2178 case 0xad: { II ii = xor_R<IYL,T::CC_DD>();
NEXT; }
2179 case 0xae: { II ii = xor_xix<IY>();
NEXT; }
2180 case 0xb4: { II ii = or_R<IYH,T::CC_DD>();
NEXT; }
2181 case 0xb5: { II ii = or_R<IYL,T::CC_DD>();
NEXT; }
2182 case 0xb6: { II ii = or_xix<IY>();
NEXT; }
2183 case 0xbc: { II ii = cp_R<IYH,T::CC_DD>();
NEXT; }
2184 case 0xbd: { II ii = cp_R<IYL,T::CC_DD>();
NEXT; }
2185 case 0xbe: { II ii = cp_xix<IY>();
NEXT; }
2187 case 0xe1: { II ii = pop_SS <IY,T::CC_DD>();
NEXT; }
2188 case 0xe5: { II ii = push_SS<IY,T::CC_DD>();
NEXT; }
2189 case 0xe3: { II ii = ex_xsp_SS<IY,T::CC_DD>();
NEXT; }
2190 case 0xe9: { II ii = jp_SS<IY,T::CC_DD>();
NEXT; }
2191 case 0xf9: { II ii = ld_sp_SS<IY,T::CC_DD>();
NEXT; }
2192 case 0xcb: ixy = getIY();
goto xx_cb;
2193 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
2194 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
2198 #ifndef USE_COMPUTED_GOTO
2204 unsigned tmp = RD_WORD_PC<1>(T::CC_DD + T::CC_DD_CB);
2205 int8_t ofst = tmp & 0xFF;
2206 unsigned addr = (ixy + ofst) & 0xFFFF;
2207 byte xxcb_opcode = tmp >> 8;
2208 switch (xxcb_opcode) {
2209 case 0x00: { II ii = rlc_xix_R<B>(addr);
NEXT; }
2210 case 0x01: { II ii = rlc_xix_R<C>(addr);
NEXT; }
2211 case 0x02: { II ii = rlc_xix_R<D>(addr);
NEXT; }
2212 case 0x03: { II ii = rlc_xix_R<E>(addr);
NEXT; }
2213 case 0x04: { II ii = rlc_xix_R<H>(addr);
NEXT; }
2214 case 0x05: { II ii = rlc_xix_R<L>(addr);
NEXT; }
2215 case 0x06: { II ii = rlc_xix_R<DUMMY>(addr);
NEXT; }
2216 case 0x07: { II ii = rlc_xix_R<A>(addr);
NEXT; }
2217 case 0x08: { II ii = rrc_xix_R<B>(addr);
NEXT; }
2218 case 0x09: { II ii = rrc_xix_R<C>(addr);
NEXT; }
2219 case 0x0a: { II ii = rrc_xix_R<D>(addr);
NEXT; }
2220 case 0x0b: { II ii = rrc_xix_R<E>(addr);
NEXT; }
2221 case 0x0c: { II ii = rrc_xix_R<H>(addr);
NEXT; }
2222 case 0x0d: { II ii = rrc_xix_R<L>(addr);
NEXT; }
2223 case 0x0e: { II ii = rrc_xix_R<DUMMY>(addr);
NEXT; }
2224 case 0x0f: { II ii = rrc_xix_R<A>(addr);
NEXT; }
2225 case 0x10: { II ii = rl_xix_R<B>(addr);
NEXT; }
2226 case 0x11: { II ii = rl_xix_R<C>(addr);
NEXT; }
2227 case 0x12: { II ii = rl_xix_R<D>(addr);
NEXT; }
2228 case 0x13: { II ii = rl_xix_R<E>(addr);
NEXT; }
2229 case 0x14: { II ii = rl_xix_R<H>(addr);
NEXT; }
2230 case 0x15: { II ii = rl_xix_R<L>(addr);
NEXT; }
2231 case 0x16: { II ii = rl_xix_R<DUMMY>(addr);
NEXT; }
2232 case 0x17: { II ii = rl_xix_R<A>(addr);
NEXT; }
2233 case 0x18: { II ii = rr_xix_R<B>(addr);
NEXT; }
2234 case 0x19: { II ii = rr_xix_R<C>(addr);
NEXT; }
2235 case 0x1a: { II ii = rr_xix_R<D>(addr);
NEXT; }
2236 case 0x1b: { II ii = rr_xix_R<E>(addr);
NEXT; }
2237 case 0x1c: { II ii = rr_xix_R<H>(addr);
NEXT; }
2238 case 0x1d: { II ii = rr_xix_R<L>(addr);
NEXT; }
2239 case 0x1e: { II ii = rr_xix_R<DUMMY>(addr);
NEXT; }
2240 case 0x1f: { II ii = rr_xix_R<A>(addr);
NEXT; }
2241 case 0x20: { II ii = sla_xix_R<B>(addr);
NEXT; }
2242 case 0x21: { II ii = sla_xix_R<C>(addr);
NEXT; }
2243 case 0x22: { II ii = sla_xix_R<D>(addr);
NEXT; }
2244 case 0x23: { II ii = sla_xix_R<E>(addr);
NEXT; }
2245 case 0x24: { II ii = sla_xix_R<H>(addr);
NEXT; }
2246 case 0x25: { II ii = sla_xix_R<L>(addr);
NEXT; }
2247 case 0x26: { II ii = sla_xix_R<DUMMY>(addr);
NEXT; }
2248 case 0x27: { II ii = sla_xix_R<A>(addr);
NEXT; }
2249 case 0x28: { II ii = sra_xix_R<B>(addr);
NEXT; }
2250 case 0x29: { II ii = sra_xix_R<C>(addr);
NEXT; }
2251 case 0x2a: { II ii = sra_xix_R<D>(addr);
NEXT; }
2252 case 0x2b: { II ii = sra_xix_R<E>(addr);
NEXT; }
2253 case 0x2c: { II ii = sra_xix_R<H>(addr);
NEXT; }
2254 case 0x2d: { II ii = sra_xix_R<L>(addr);
NEXT; }
2255 case 0x2e: { II ii = sra_xix_R<DUMMY>(addr);
NEXT; }
2256 case 0x2f: { II ii = sra_xix_R<A>(addr);
NEXT; }
2257 case 0x30: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
B>(addr);
NEXT; }
2258 case 0x31: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
C>(addr);
NEXT; }
2259 case 0x32: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
D>(addr);
NEXT; }
2260 case 0x33: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
E>(addr);
NEXT; }
2261 case 0x34: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
H>(addr);
NEXT; }
2262 case 0x35: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
L>(addr);
NEXT; }
2263 case 0x36: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
DUMMY>(addr);
NEXT; }
2264 case 0x37: { II ii = T::IS_R800 ? sll2() : sll_xix_R<
A>(addr);
NEXT; }
2265 case 0x38: { II ii = srl_xix_R<B>(addr);
NEXT; }
2266 case 0x39: { II ii = srl_xix_R<C>(addr);
NEXT; }
2267 case 0x3a: { II ii = srl_xix_R<D>(addr);
NEXT; }
2268 case 0x3b: { II ii = srl_xix_R<E>(addr);
NEXT; }
2269 case 0x3c: { II ii = srl_xix_R<H>(addr);
NEXT; }
2270 case 0x3d: { II ii = srl_xix_R<L>(addr);
NEXT; }
2271 case 0x3e: { II ii = srl_xix_R<DUMMY>(addr);
NEXT; }
2272 case 0x3f: { II ii = srl_xix_R<A>(addr);
NEXT; }
2274 case 0x40:
case 0x41:
case 0x42:
case 0x43:
2275 case 0x44:
case 0x45:
case 0x46:
case 0x47:
2276 { II ii = bit_N_xix<0>(addr);
NEXT; }
2277 case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
2278 case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
2279 { II ii = bit_N_xix<1>(addr);
NEXT; }
2280 case 0x50:
case 0x51:
case 0x52:
case 0x53:
2281 case 0x54:
case 0x55:
case 0x56:
case 0x57:
2282 { II ii = bit_N_xix<2>(addr);
NEXT; }
2283 case 0x58:
case 0x59:
case 0x5a:
case 0x5b:
2284 case 0x5c:
case 0x5d:
case 0x5e:
case 0x5f:
2285 { II ii = bit_N_xix<3>(addr);
NEXT; }
2286 case 0x60:
case 0x61:
case 0x62:
case 0x63:
2287 case 0x64:
case 0x65:
case 0x66:
case 0x67:
2288 { II ii = bit_N_xix<4>(addr);
NEXT; }
2289 case 0x68:
case 0x69:
case 0x6a:
case 0x6b:
2290 case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
2291 { II ii = bit_N_xix<5>(addr);
NEXT; }
2292 case 0x70:
case 0x71:
case 0x72:
case 0x73:
2293 case 0x74:
case 0x75:
case 0x76:
case 0x77:
2294 { II ii = bit_N_xix<6>(addr);
NEXT; }
2295 case 0x78:
case 0x79:
case 0x7a:
case 0x7b:
2296 case 0x7c:
case 0x7d:
case 0x7e:
case 0x7f:
2297 { II ii = bit_N_xix<7>(addr);
NEXT; }
2299 case 0x80: { II ii = res_N_xix_R<0,B>(addr);
NEXT; }
2300 case 0x81: { II ii = res_N_xix_R<0,C>(addr);
NEXT; }
2301 case 0x82: { II ii = res_N_xix_R<0,D>(addr);
NEXT; }
2302 case 0x83: { II ii = res_N_xix_R<0,E>(addr);
NEXT; }
2303 case 0x84: { II ii = res_N_xix_R<0,H>(addr);
NEXT; }
2304 case 0x85: { II ii = res_N_xix_R<0,L>(addr);
NEXT; }
2305 case 0x87: { II ii = res_N_xix_R<0,A>(addr);
NEXT; }
2306 case 0x88: { II ii = res_N_xix_R<1,B>(addr);
NEXT; }
2307 case 0x89: { II ii = res_N_xix_R<1,C>(addr);
NEXT; }
2308 case 0x8a: { II ii = res_N_xix_R<1,D>(addr);
NEXT; }
2309 case 0x8b: { II ii = res_N_xix_R<1,E>(addr);
NEXT; }
2310 case 0x8c: { II ii = res_N_xix_R<1,H>(addr);
NEXT; }
2311 case 0x8d: { II ii = res_N_xix_R<1,L>(addr);
NEXT; }
2312 case 0x8f: { II ii = res_N_xix_R<1,A>(addr);
NEXT; }
2313 case 0x90: { II ii = res_N_xix_R<2,B>(addr);
NEXT; }
2314 case 0x91: { II ii = res_N_xix_R<2,C>(addr);
NEXT; }
2315 case 0x92: { II ii = res_N_xix_R<2,D>(addr);
NEXT; }
2316 case 0x93: { II ii = res_N_xix_R<2,E>(addr);
NEXT; }
2317 case 0x94: { II ii = res_N_xix_R<2,H>(addr);
NEXT; }
2318 case 0x95: { II ii = res_N_xix_R<2,L>(addr);
NEXT; }
2319 case 0x97: { II ii = res_N_xix_R<2,A>(addr);
NEXT; }
2320 case 0x98: { II ii = res_N_xix_R<3,B>(addr);
NEXT; }
2321 case 0x99: { II ii = res_N_xix_R<3,C>(addr);
NEXT; }
2322 case 0x9a: { II ii = res_N_xix_R<3,D>(addr);
NEXT; }
2323 case 0x9b: { II ii = res_N_xix_R<3,E>(addr);
NEXT; }
2324 case 0x9c: { II ii = res_N_xix_R<3,H>(addr);
NEXT; }
2325 case 0x9d: { II ii = res_N_xix_R<3,L>(addr);
NEXT; }
2326 case 0x9f: { II ii = res_N_xix_R<3,A>(addr);
NEXT; }
2327 case 0xa0: { II ii = res_N_xix_R<4,B>(addr);
NEXT; }
2328 case 0xa1: { II ii = res_N_xix_R<4,C>(addr);
NEXT; }
2329 case 0xa2: { II ii = res_N_xix_R<4,D>(addr);
NEXT; }
2330 case 0xa3: { II ii = res_N_xix_R<4,E>(addr);
NEXT; }
2331 case 0xa4: { II ii = res_N_xix_R<4,H>(addr);
NEXT; }
2332 case 0xa5: { II ii = res_N_xix_R<4,L>(addr);
NEXT; }
2333 case 0xa7: { II ii = res_N_xix_R<4,A>(addr);
NEXT; }
2334 case 0xa8: { II ii = res_N_xix_R<5,B>(addr);
NEXT; }
2335 case 0xa9: { II ii = res_N_xix_R<5,C>(addr);
NEXT; }
2336 case 0xaa: { II ii = res_N_xix_R<5,D>(addr);
NEXT; }
2337 case 0xab: { II ii = res_N_xix_R<5,E>(addr);
NEXT; }
2338 case 0xac: { II ii = res_N_xix_R<5,H>(addr);
NEXT; }
2339 case 0xad: { II ii = res_N_xix_R<5,L>(addr);
NEXT; }
2340 case 0xaf: { II ii = res_N_xix_R<5,A>(addr);
NEXT; }
2341 case 0xb0: { II ii = res_N_xix_R<6,B>(addr);
NEXT; }
2342 case 0xb1: { II ii = res_N_xix_R<6,C>(addr);
NEXT; }
2343 case 0xb2: { II ii = res_N_xix_R<6,D>(addr);
NEXT; }
2344 case 0xb3: { II ii = res_N_xix_R<6,E>(addr);
NEXT; }
2345 case 0xb4: { II ii = res_N_xix_R<6,H>(addr);
NEXT; }
2346 case 0xb5: { II ii = res_N_xix_R<6,L>(addr);
NEXT; }
2347 case 0xb7: { II ii = res_N_xix_R<6,A>(addr);
NEXT; }
2348 case 0xb8: { II ii = res_N_xix_R<7,B>(addr);
NEXT; }
2349 case 0xb9: { II ii = res_N_xix_R<7,C>(addr);
NEXT; }
2350 case 0xba: { II ii = res_N_xix_R<7,D>(addr);
NEXT; }
2351 case 0xbb: { II ii = res_N_xix_R<7,E>(addr);
NEXT; }
2352 case 0xbc: { II ii = res_N_xix_R<7,H>(addr);
NEXT; }
2353 case 0xbd: { II ii = res_N_xix_R<7,L>(addr);
NEXT; }
2354 case 0xbf: { II ii = res_N_xix_R<7,A>(addr);
NEXT; }
2355 case 0x86: { II ii = res_N_xix_R<0,DUMMY>(addr);
NEXT; }
2356 case 0x8e: { II ii = res_N_xix_R<1,DUMMY>(addr);
NEXT; }
2357 case 0x96: { II ii = res_N_xix_R<2,DUMMY>(addr);
NEXT; }
2358 case 0x9e: { II ii = res_N_xix_R<3,DUMMY>(addr);
NEXT; }
2359 case 0xa6: { II ii = res_N_xix_R<4,DUMMY>(addr);
NEXT; }
2360 case 0xae: { II ii = res_N_xix_R<5,DUMMY>(addr);
NEXT; }
2361 case 0xb6: { II ii = res_N_xix_R<6,DUMMY>(addr);
NEXT; }
2362 case 0xbe: { II ii = res_N_xix_R<7,DUMMY>(addr);
NEXT; }
2364 case 0xc0: { II ii = set_N_xix_R<0,B>(addr);
NEXT; }
2365 case 0xc1: { II ii = set_N_xix_R<0,C>(addr);
NEXT; }
2366 case 0xc2: { II ii = set_N_xix_R<0,D>(addr);
NEXT; }
2367 case 0xc3: { II ii = set_N_xix_R<0,E>(addr);
NEXT; }
2368 case 0xc4: { II ii = set_N_xix_R<0,H>(addr);
NEXT; }
2369 case 0xc5: { II ii = set_N_xix_R<0,L>(addr);
NEXT; }
2370 case 0xc7: { II ii = set_N_xix_R<0,A>(addr);
NEXT; }
2371 case 0xc8: { II ii = set_N_xix_R<1,B>(addr);
NEXT; }
2372 case 0xc9: { II ii = set_N_xix_R<1,C>(addr);
NEXT; }
2373 case 0xca: { II ii = set_N_xix_R<1,D>(addr);
NEXT; }
2374 case 0xcb: { II ii = set_N_xix_R<1,E>(addr);
NEXT; }
2375 case 0xcc: { II ii = set_N_xix_R<1,H>(addr);
NEXT; }
2376 case 0xcd: { II ii = set_N_xix_R<1,L>(addr);
NEXT; }
2377 case 0xcf: { II ii = set_N_xix_R<1,A>(addr);
NEXT; }
2378 case 0xd0: { II ii = set_N_xix_R<2,B>(addr);
NEXT; }
2379 case 0xd1: { II ii = set_N_xix_R<2,C>(addr);
NEXT; }
2380 case 0xd2: { II ii = set_N_xix_R<2,D>(addr);
NEXT; }
2381 case 0xd3: { II ii = set_N_xix_R<2,E>(addr);
NEXT; }
2382 case 0xd4: { II ii = set_N_xix_R<2,H>(addr);
NEXT; }
2383 case 0xd5: { II ii = set_N_xix_R<2,L>(addr);
NEXT; }
2384 case 0xd7: { II ii = set_N_xix_R<2,A>(addr);
NEXT; }
2385 case 0xd8: { II ii = set_N_xix_R<3,B>(addr);
NEXT; }
2386 case 0xd9: { II ii = set_N_xix_R<3,C>(addr);
NEXT; }
2387 case 0xda: { II ii = set_N_xix_R<3,D>(addr);
NEXT; }
2388 case 0xdb: { II ii = set_N_xix_R<3,E>(addr);
NEXT; }
2389 case 0xdc: { II ii = set_N_xix_R<3,H>(addr);
NEXT; }
2390 case 0xdd: { II ii = set_N_xix_R<3,L>(addr);
NEXT; }
2391 case 0xdf: { II ii = set_N_xix_R<3,A>(addr);
NEXT; }
2392 case 0xe0: { II ii = set_N_xix_R<4,B>(addr);
NEXT; }
2393 case 0xe1: { II ii = set_N_xix_R<4,C>(addr);
NEXT; }
2394 case 0xe2: { II ii = set_N_xix_R<4,D>(addr);
NEXT; }
2395 case 0xe3: { II ii = set_N_xix_R<4,E>(addr);
NEXT; }
2396 case 0xe4: { II ii = set_N_xix_R<4,H>(addr);
NEXT; }
2397 case 0xe5: { II ii = set_N_xix_R<4,L>(addr);
NEXT; }
2398 case 0xe7: { II ii = set_N_xix_R<4,A>(addr);
NEXT; }
2399 case 0xe8: { II ii = set_N_xix_R<5,B>(addr);
NEXT; }
2400 case 0xe9: { II ii = set_N_xix_R<5,C>(addr);
NEXT; }
2401 case 0xea: { II ii = set_N_xix_R<5,D>(addr);
NEXT; }
2402 case 0xeb: { II ii = set_N_xix_R<5,E>(addr);
NEXT; }
2403 case 0xec: { II ii = set_N_xix_R<5,H>(addr);
NEXT; }
2404 case 0xed: { II ii = set_N_xix_R<5,L>(addr);
NEXT; }
2405 case 0xef: { II ii = set_N_xix_R<5,A>(addr);
NEXT; }
2406 case 0xf0: { II ii = set_N_xix_R<6,B>(addr);
NEXT; }
2407 case 0xf1: { II ii = set_N_xix_R<6,C>(addr);
NEXT; }
2408 case 0xf2: { II ii = set_N_xix_R<6,D>(addr);
NEXT; }
2409 case 0xf3: { II ii = set_N_xix_R<6,E>(addr);
NEXT; }
2410 case 0xf4: { II ii = set_N_xix_R<6,H>(addr);
NEXT; }
2411 case 0xf5: { II ii = set_N_xix_R<6,L>(addr);
NEXT; }
2412 case 0xf7: { II ii = set_N_xix_R<6,A>(addr);
NEXT; }
2413 case 0xf8: { II ii = set_N_xix_R<7,B>(addr);
NEXT; }
2414 case 0xf9: { II ii = set_N_xix_R<7,C>(addr);
NEXT; }
2415 case 0xfa: { II ii = set_N_xix_R<7,D>(addr);
NEXT; }
2416 case 0xfb: { II ii = set_N_xix_R<7,E>(addr);
NEXT; }
2417 case 0xfc: { II ii = set_N_xix_R<7,H>(addr);
NEXT; }
2418 case 0xfd: { II ii = set_N_xix_R<7,L>(addr);
NEXT; }
2419 case 0xff: { II ii = set_N_xix_R<7,A>(addr);
NEXT; }
2420 case 0xc6: { II ii = set_N_xix_R<0,DUMMY>(addr);
NEXT; }
2421 case 0xce: { II ii = set_N_xix_R<1,DUMMY>(addr);
NEXT; }
2422 case 0xd6: { II ii = set_N_xix_R<2,DUMMY>(addr);
NEXT; }
2423 case 0xde: { II ii = set_N_xix_R<3,DUMMY>(addr);
NEXT; }
2424 case 0xe6: { II ii = set_N_xix_R<4,DUMMY>(addr);
NEXT; }
2425 case 0xee: { II ii = set_N_xix_R<5,DUMMY>(addr);
NEXT; }
2426 case 0xf6: { II ii = set_N_xix_R<6,DUMMY>(addr);
NEXT; }
2427 case 0xfe: { II ii = set_N_xix_R<7,DUMMY>(addr);
NEXT; }
2433 template<
typename T>
inline void CPUCore<T>::cpuTracePre()
2437 template<
typename T>
inline void CPUCore<T>::cpuTracePost()
2440 cpuTracePost_slow();
2443 template<
typename T>
void CPUCore<T>::cpuTracePost_slow()
2446 std::string dasmOutput;
2447 dasm(*interface, start_pc, opBuf, dasmOutput, T::getTimeFast());
2448 std::cout << strCat(hex_string<4>(start_pc),
2450 " AF=", hex_string<4>(getAF()),
2451 " BC=", hex_string<4>(getBC()),
2452 " DE=", hex_string<4>(getDE()),
2453 " HL=", hex_string<4>(getHL()),
2454 " IX=", hex_string<4>(getIX()),
2455 " IY=", hex_string<4>(getIY()),
2456 " SP=", hex_string<4>(getSP()),
2461 template<
typename T>
ExecIRQ CPUCore<T>::getExecIRQ()
const
2468 template<
typename T>
void CPUCore<T>::executeSlow(
ExecIRQ execIRQ)
2509 incR(T::advanceHalt(T::HALT_STATES, scheduler.getNext()));
2510 setSlowInstructions();
2513 assert(T::limitReached());
2514 executeInstructions();
2517 if constexpr (T::IS_R800) {
2540 assert(fastForward || !interface->isBreaked());
2542 interface->setFastForward(
true);
2544 execute2(fastForward);
2545 interface->setFastForward(
false);
2554 scheduler.schedule(T::getTime());
2555 setSlowInstructions();
2561 (!interface->anyBreakPoints() && !tracingEnabled)) {
2564 if (slowInstructions) {
2566 executeSlow(getExecIRQ());
2567 scheduler.schedule(T::getTimeFast());
2569 while (slowInstructions == 0) {
2571 if (
likely(!T::limitReached())) {
2573 executeInstructions();
2578 scheduler.schedule(T::getTimeFast());
2579 if (needExitCPULoop())
return;
2582 }
while (!needExitCPULoop());
2585 if (slowInstructions == 0) {
2587 assert(T::limitReached());
2588 executeInstructions();
2593 executeSlow(getExecIRQ());
2598 scheduler.schedule(T::getTime());
2631 auto execIRQ = getExecIRQ();
2633 interface->checkBreakPoints(getPC())) {
2634 assert(interface->isBreaked());
2637 }
while (!needExitCPULoop());
2642 if constexpr (R8 ==
A) {
return getA(); }
2643 else if constexpr (R8 ==
F) {
return getF(); }
2644 else if constexpr (R8 ==
B) {
return getB(); }
2645 else if constexpr (R8 ==
C) {
return getC(); }
2646 else if constexpr (R8 ==
D) {
return getD(); }
2647 else if constexpr (R8 ==
E) {
return getE(); }
2648 else if constexpr (R8 ==
H) {
return getH(); }
2649 else if constexpr (R8 ==
L) {
return getL(); }
2650 else if constexpr (R8 ==
IXH) {
return getIXh(); }
2651 else if constexpr (R8 ==
IXL) {
return getIXl(); }
2652 else if constexpr (R8 ==
IYH) {
return getIYh(); }
2653 else if constexpr (R8 ==
IYL) {
return getIYl(); }
2654 else if constexpr (R8 ==
REG_I) {
return getI(); }
2655 else if constexpr (R8 ==
REG_R) {
return getR(); }
2656 else if constexpr (R8 ==
DUMMY) {
return 0; }
2660 if constexpr (R16 ==
AF) {
return getAF(); }
2661 else if constexpr (R16 ==
BC) {
return getBC(); }
2662 else if constexpr (R16 ==
DE) {
return getDE(); }
2663 else if constexpr (R16 ==
HL) {
return getHL(); }
2664 else if constexpr (R16 ==
IX) {
return getIX(); }
2665 else if constexpr (R16 ==
IY) {
return getIY(); }
2666 else if constexpr (R16 ==
SP) {
return getSP(); }
2670 if constexpr (R8 ==
A) { setA(
x); }
2671 else if constexpr (R8 ==
F) { setF(
x); }
2672 else if constexpr (R8 ==
B) { setB(
x); }
2673 else if constexpr (R8 ==
C) { setC(
x); }
2674 else if constexpr (R8 ==
D) { setD(
x); }
2675 else if constexpr (R8 ==
E) { setE(
x); }
2676 else if constexpr (R8 ==
H) { setH(
x); }
2677 else if constexpr (R8 ==
L) { setL(
x); }
2678 else if constexpr (R8 ==
IXH) { setIXh(
x); }
2679 else if constexpr (R8 ==
IXL) { setIXl(
x); }
2680 else if constexpr (R8 ==
IYH) { setIYh(
x); }
2681 else if constexpr (R8 ==
IYL) { setIYl(
x); }
2682 else if constexpr (R8 ==
REG_I) { setI(
x); }
2683 else if constexpr (R8 ==
REG_R) { setR(
x); }
2684 else if constexpr (R8 ==
DUMMY) { }
2688 if constexpr (R16 ==
AF) { setAF(
x); }
2689 else if constexpr (R16 ==
BC) { setBC(
x); }
2690 else if constexpr (R16 ==
DE) { setDE(
x); }
2691 else if constexpr (R16 ==
HL) { setHL(
x); }
2692 else if constexpr (R16 ==
IX) { setIX(
x); }
2693 else if constexpr (R16 ==
IY) { setIY(
x); }
2694 else if constexpr (R16 ==
SP) { setSP(
x); }
2700 set8<DST>(get8<SRC>());
return {1, T::CC_LD_R_R + EE};
2704 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_sp_SS() {
2705 setSP(get16<REG>());
return {1, T::CC_LD_SP_HL + EE};
2709 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_SS_a() {
2710 T::setMemPtr((getA() << 8) | ((get16<REG>() + 1) & 0xFF));
2711 WRMEM(get16<REG>(), getA(), T::CC_LD_SS_A_1);
2712 return {1, T::CC_LD_SS_A};
2716 template<
typename T>
template<Reg8 SRC> II CPUCore<T>::ld_xhl_R() {
2717 WRMEM(getHL(), get8<SRC>(), T::CC_LD_HL_R_1);
2718 return {1, T::CC_LD_HL_R};
2722 template<
typename T>
template<Reg16 IXY, Reg8 SRC> II CPUCore<T>::ld_xix_R() {
2723 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_LD_XIX_R_1);
2724 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2726 WRMEM(addr, get8<SRC>(), T::CC_DD + T::CC_LD_XIX_R_2);
2727 return {2, T::CC_DD + T::CC_LD_XIX_R};
2731 template<
typename T> II CPUCore<T>::ld_xhl_byte() {
2732 byte val = RDMEM_OPCODE<1>(T::CC_LD_HL_N_1);
2733 WRMEM(getHL(), val, T::CC_LD_HL_N_2);
2734 return {2, T::CC_LD_HL_N};
2738 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::ld_xix_byte() {
2739 unsigned tmp = RD_WORD_PC<1>(T::CC_DD + T::CC_LD_XIX_N_1);
2740 int8_t ofst = tmp & 0xFF;
2741 byte val = tmp >> 8;
2742 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2744 WRMEM(addr, val, T::CC_DD + T::CC_LD_XIX_N_2);
2745 return {3, T::CC_DD + T::CC_LD_XIX_N};
2749 template<
typename T> II CPUCore<T>::ld_xbyte_a() {
2750 unsigned x = RD_WORD_PC<1>(T::CC_LD_NN_A_1);
2751 T::setMemPtr((getA() << 8) | ((
x + 1) & 0xFF));
2752 WRMEM(
x, getA(), T::CC_LD_NN_A_2);
2753 return {3, T::CC_LD_NN_A};
2757 template<
typename T>
template<
int EE>
inline II CPUCore<T>::WR_NN_Y(
unsigned reg) {
2758 unsigned addr = RD_WORD_PC<1>(T::CC_LD_XX_HL_1 + EE);
2759 T::setMemPtr(addr + 1);
2760 WR_WORD(addr, reg, T::CC_LD_XX_HL_2 + EE);
2761 return {3, T::CC_LD_XX_HL + EE};
2763 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_xword_SS() {
2764 return WR_NN_Y<EE >(get16<REG>());
2766 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_xword_SS_ED() {
2767 return WR_NN_Y<T::EE_ED>(get16<REG>());
2771 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_a_SS() {
2772 T::setMemPtr(get16<REG>() + 1);
2773 setA(RDMEM(get16<REG>(), T::CC_LD_A_SS_1));
2774 return {1, T::CC_LD_A_SS};
2778 template<
typename T> II CPUCore<T>::ld_a_xbyte() {
2779 unsigned addr = RD_WORD_PC<1>(T::CC_LD_A_NN_1);
2780 T::setMemPtr(addr + 1);
2781 setA(RDMEM(addr, T::CC_LD_A_NN_2));
2782 return {3, T::CC_LD_A_NN};
2786 template<
typename T>
template<Reg8 DST,
int EE> II CPUCore<T>::ld_R_byte() {
2787 set8<DST>(RDMEM_OPCODE<1>(T::CC_LD_R_N_1 + EE));
return {2, T::CC_LD_R_N + EE};
2791 template<
typename T>
template<Reg8 DST> II CPUCore<T>::ld_R_xhl() {
2792 set8<DST>(RDMEM(getHL(), T::CC_LD_R_HL_1));
return {1, T::CC_LD_R_HL};
2796 template<
typename T>
template<Reg8 DST, Reg16 IXY> II CPUCore<T>::ld_R_xix() {
2797 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_LD_R_XIX_1);
2798 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2800 set8<DST>(RDMEM(addr, T::CC_DD + T::CC_LD_R_XIX_2));
2801 return {2, T::CC_DD + T::CC_LD_R_XIX};
2805 template<
typename T>
template<
int EE>
inline unsigned CPUCore<T>::RD_P_XX() {
2806 unsigned addr = RD_WORD_PC<1>(T::CC_LD_HL_XX_1 + EE);
2807 T::setMemPtr(addr + 1);
2808 unsigned result = RD_WORD(addr, T::CC_LD_HL_XX_2 + EE);
2811 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_SS_xword() {
2812 set16<REG>(RD_P_XX<EE>());
return {3, T::CC_LD_HL_XX + EE};
2814 template<
typename T>
template<Reg16 REG> II CPUCore<T>::ld_SS_xword_ED() {
2815 set16<REG>(RD_P_XX<T::EE_ED>());
return {3, T::CC_LD_HL_XX + T::EE_ED};
2819 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ld_SS_word() {
2820 set16<REG>(RD_WORD_PC<1>(T::CC_LD_SS_NN_1 + EE));
return {3, T::CC_LD_SS_NN + EE};
2825 template<
typename T>
inline void CPUCore<T>::ADC(
byte reg) {
2826 unsigned res = getA() + reg + ((getF() &
C_FLAG) ? 1 : 0);
2827 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2828 ((getA() ^ res ^ reg) &
H_FLAG) |
2829 (((getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2831 if constexpr (T::IS_R800) {
2840 template<
typename T>
inline II CPUCore<T>::adc_a_a() {
2841 unsigned res = 2 * getA() + ((getF() &
C_FLAG) ? 1 : 0);
2842 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2844 (((getA() ^ res) & 0x80) >> 5) |
2846 if constexpr (T::IS_R800) {
2854 return {1, T::CC_CP_R};
2856 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::adc_a_R() {
2857 ADC(get8<SRC>());
return {1, T::CC_CP_R + EE};
2859 template<
typename T> II CPUCore<T>::adc_a_byte() {
2860 ADC(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2862 template<
typename T> II CPUCore<T>::adc_a_xhl() {
2863 ADC(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2865 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::adc_a_xix() {
2866 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2867 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2869 ADC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2870 return {2, T::CC_DD + T::CC_CP_XIX};
2874 template<
typename T>
inline void CPUCore<T>::ADD(
byte reg) {
2875 unsigned res = getA() + reg;
2876 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2877 ((getA() ^ res ^ reg) &
H_FLAG) |
2878 (((getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2880 if constexpr (T::IS_R800) {
2889 template<
typename T>
inline II CPUCore<T>::add_a_a() {
2890 unsigned res = 2 * getA();
2891 byte f = ((res & 0x100) ?
C_FLAG : 0) |
2893 (((getA() ^ res) & 0x80) >> 5) |
2895 if constexpr (T::IS_R800) {
2903 return {1, T::CC_CP_R};
2905 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::add_a_R() {
2906 ADD(get8<SRC>());
return {1, T::CC_CP_R + EE};
2908 template<
typename T> II CPUCore<T>::add_a_byte() {
2909 ADD(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2911 template<
typename T> II CPUCore<T>::add_a_xhl() {
2912 ADD(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2914 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::add_a_xix() {
2915 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2916 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2918 ADD(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2919 return {2, T::CC_DD + T::CC_CP_XIX};
2923 template<
typename T>
inline void CPUCore<T>::AND(
byte reg) {
2926 if constexpr (T::IS_R800) {
2934 template<
typename T> II CPUCore<T>::and_a() {
2936 if constexpr (T::IS_R800) {
2943 return {1, T::CC_CP_R};
2945 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::and_R() {
2946 AND(get8<SRC>());
return {1, T::CC_CP_R + EE};
2948 template<
typename T> II CPUCore<T>::and_byte() {
2949 AND(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2951 template<
typename T> II CPUCore<T>::and_xhl() {
2952 AND(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2954 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::and_xix() {
2955 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2956 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
2958 AND(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2959 return {2, T::CC_DD + T::CC_CP_XIX};
2963 template<
typename T>
inline void CPUCore<T>::CP(
byte reg) {
2964 unsigned q = getA() - reg;
2966 ((q & 0x100) ?
C_FLAG : 0) |
2968 ((getA() ^ q ^ reg) &
H_FLAG) |
2969 (((reg ^ getA()) & (getA() ^ q) & 0x80) >> 5);
2970 if constexpr (T::IS_R800) {
2977 template<
typename T> II CPUCore<T>::cp_a() {
2979 if constexpr (T::IS_R800) {
2985 return {1, T::CC_CP_R};
2987 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::cp_R() {
2988 CP(get8<SRC>());
return {1, T::CC_CP_R + EE};
2990 template<
typename T> II CPUCore<T>::cp_byte() {
2991 CP(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
2993 template<
typename T> II CPUCore<T>::cp_xhl() {
2994 CP(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
2996 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::cp_xix() {
2997 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
2998 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3000 CP(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3001 return {2, T::CC_DD + T::CC_CP_XIX};
3005 template<
typename T>
inline void CPUCore<T>::OR(
byte reg) {
3008 if constexpr (T::IS_R800) {
3016 template<
typename T> II CPUCore<T>::or_a() {
3018 if constexpr (T::IS_R800) {
3025 return {1, T::CC_CP_R};
3027 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::or_R() {
3028 OR(get8<SRC>());
return {1, T::CC_CP_R + EE};
3030 template<
typename T> II CPUCore<T>::or_byte() {
3031 OR(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3033 template<
typename T> II CPUCore<T>::or_xhl() {
3034 OR(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3036 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::or_xix() {
3037 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3038 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3040 OR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3041 return {2, T::CC_DD + T::CC_CP_XIX};
3045 template<
typename T>
inline void CPUCore<T>::SBC(
byte reg) {
3046 unsigned res = getA() - reg - ((getF() &
C_FLAG) ? 1 : 0);
3047 byte f = ((res & 0x100) ?
C_FLAG : 0) |
3049 ((getA() ^ res ^ reg) &
H_FLAG) |
3050 (((reg ^ getA()) & (getA() ^ res) & 0x80) >> 5);
3051 if constexpr (T::IS_R800) {
3060 template<
typename T> II CPUCore<T>::sbc_a_a() {
3061 if constexpr (T::IS_R800) {
3067 setAF((getF() &
C_FLAG) ?
3071 return {1, T::CC_CP_R};
3073 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::sbc_a_R() {
3074 SBC(get8<SRC>());
return {1, T::CC_CP_R + EE};
3076 template<
typename T> II CPUCore<T>::sbc_a_byte() {
3077 SBC(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3079 template<
typename T> II CPUCore<T>::sbc_a_xhl() {
3080 SBC(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3082 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::sbc_a_xix() {
3083 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3084 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3086 SBC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3087 return {2, T::CC_DD + T::CC_CP_XIX};
3091 template<
typename T>
inline void CPUCore<T>::SUB(
byte reg) {
3092 unsigned res = getA() - reg;
3093 byte f = ((res & 0x100) ?
C_FLAG : 0) |
3095 ((getA() ^ res ^ reg) &
H_FLAG) |
3096 (((reg ^ getA()) & (getA() ^ res) & 0x80) >> 5);
3097 if constexpr (T::IS_R800) {
3106 template<
typename T> II CPUCore<T>::sub_a() {
3107 if constexpr (T::IS_R800) {
3113 return {1, T::CC_CP_R};
3115 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::sub_R() {
3116 SUB(get8<SRC>());
return {1, T::CC_CP_R + EE};
3118 template<
typename T> II CPUCore<T>::sub_byte() {
3119 SUB(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3121 template<
typename T> II CPUCore<T>::sub_xhl() {
3122 SUB(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3124 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::sub_xix() {
3125 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3126 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3128 SUB(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3129 return {2, T::CC_DD + T::CC_CP_XIX};
3133 template<
typename T>
inline void CPUCore<T>::XOR(
byte reg) {
3136 if constexpr (T::IS_R800) {
3144 template<
typename T> II CPUCore<T>::xor_a() {
3145 if constexpr (T::IS_R800) {
3151 return {1, T::CC_CP_R};
3153 template<
typename T>
template<Reg8 SRC,
int EE> II CPUCore<T>::xor_R() {
3154 XOR(get8<SRC>());
return {1, T::CC_CP_R + EE};
3156 template<
typename T> II CPUCore<T>::xor_byte() {
3157 XOR(RDMEM_OPCODE<1>(T::CC_CP_N_1));
return {2, T::CC_CP_N};
3159 template<
typename T> II CPUCore<T>::xor_xhl() {
3160 XOR(RDMEM(getHL(), T::CC_CP_XHL_1));
return {1, T::CC_CP_XHL};
3162 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::xor_xix() {
3163 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_CP_XIX_1);
3164 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3166 XOR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3167 return {2, T::CC_DD + T::CC_CP_XIX};
3172 template<
typename T>
inline byte CPUCore<T>::DEC(
byte reg) {
3174 byte f = ((reg & ~res & 0x80) >> 5) |
3175 (((res & 0x0F) + 1) &
H_FLAG) |
3177 if constexpr (T::IS_R800) {
3187 template<
typename T>
template<Reg8 REG,
int EE> II CPUCore<T>::dec_R() {
3188 set8<REG>(DEC(get8<REG>()));
return {1, T::CC_INC_R + EE};
3190 template<
typename T>
template<
int EE>
inline void CPUCore<T>::DEC_X(
unsigned x) {
3191 byte val = DEC(RDMEM(
x, T::CC_INC_XHL_1 + EE));
3192 WRMEM(
x, val, T::CC_INC_XHL_2 + EE);
3194 template<
typename T> II CPUCore<T>::dec_xhl() {
3196 return {1, T::CC_INC_XHL};
3198 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::dec_xix() {
3199 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_INC_XIX_1);
3200 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3202 DEC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3203 return {2, T::CC_INC_XHL + T::CC_DD + T::EE_INC_XIX};
3207 template<
typename T>
inline byte CPUCore<T>::INC(
byte reg) {
3209 byte f = ((reg & -reg & 0x80) >> 5) |
3210 (((reg & 0x0F) - 1) &
H_FLAG) |
3212 if constexpr (T::IS_R800) {
3222 template<
typename T>
template<Reg8 REG,
int EE> II CPUCore<T>::inc_R() {
3223 set8<REG>(INC(get8<REG>()));
return {1, T::CC_INC_R + EE};
3225 template<
typename T>
template<
int EE>
inline void CPUCore<T>::INC_X(
unsigned x) {
3226 byte val = INC(RDMEM(
x, T::CC_INC_XHL_1 + EE));
3227 WRMEM(
x, val, T::CC_INC_XHL_2 + EE);
3229 template<
typename T> II CPUCore<T>::inc_xhl() {
3231 return {1, T::CC_INC_XHL};
3233 template<
typename T>
template<Reg16 IXY> II CPUCore<T>::inc_xix() {
3234 int8_t ofst = RDMEM_OPCODE<1>(T::CC_DD + T::CC_INC_XIX_1);
3235 unsigned addr = (get16<IXY>() + ofst) & 0xFFFF;
3237 INC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3238 return {2, T::CC_INC_XHL + T::CC_DD + T::EE_INC_XIX};
3243 template<
typename T>
template<Reg16 REG>
inline II CPUCore<T>::adc_hl_SS() {
3244 unsigned reg = get16<REG>();
3245 T::setMemPtr(getHL() + 1);
3246 unsigned res = getHL() + reg + ((getF() &
C_FLAG) ? 1 : 0);
3247 byte f = (res >> 16) |
3249 if constexpr (T::IS_R800) {
3253 f |= ((getHL() ^ res ^ reg) >> 8) &
H_FLAG;
3255 f |= ((getHL() ^ res) & (reg ^ res) & 0x8000) >> 13;
3256 if constexpr (T::IS_R800) {
3257 f |= (res >> 8) &
S_FLAG;
3262 f |= ((getHL() ^ reg) >> 8) &
H_FLAG;
3264 f |= (getHL() & reg & 0x8000) >> 13;
3269 return {1, T::CC_ADC_HL_SS};
3271 template<
typename T> II CPUCore<T>::adc_hl_hl() {
3272 T::setMemPtr(getHL() + 1);
3273 unsigned res = 2 * getHL() + ((getF() &
C_FLAG) ? 1 : 0);
3274 byte f = (res >> 16) |
3276 if constexpr (T::IS_R800) {
3281 f |= ((getHL() ^ res) & 0x8000) >> 13;
3282 if constexpr (T::IS_R800) {
3289 f |= (getHL() & 0x8000) >> 13;
3294 return {1, T::CC_ADC_HL_SS};
3298 template<
typename T>
template<Reg16 REG1, Reg16 REG2,
int EE> II CPUCore<T>::add_SS_TT() {
3299 unsigned reg1 = get16<REG1>();
3300 unsigned reg2 = get16<REG2>();
3301 T::setMemPtr(reg1 + 1);
3302 unsigned res = reg1 + reg2;
3303 byte f = (((reg1 ^ res ^ reg2) >> 8) &
H_FLAG) |
3306 if constexpr (T::IS_R800) {
3313 set16<REG1>(res & 0xFFFF);
3314 return {1, T::CC_ADD_HL_SS + EE};
3316 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::add_SS_SS() {
3317 unsigned reg = get16<REG>();
3318 T::setMemPtr(reg + 1);
3319 unsigned res = 2 * reg;
3320 byte f = (res >> 16) |
3322 if constexpr (T::IS_R800) {
3324 f |= (res >> 8) &
H_FLAG;
3330 set16<REG>(res & 0xFFFF);
3331 return {1, T::CC_ADD_HL_SS + EE};
3335 template<
typename T>
template<Reg16 REG>
inline II CPUCore<T>::sbc_hl_SS() {
3336 unsigned reg = get16<REG>();
3337 T::setMemPtr(getHL() + 1);
3338 unsigned res = getHL() - reg - ((getF() &
C_FLAG) ? 1 : 0);
3339 byte f = ((res & 0x10000) ?
C_FLAG : 0) |
3341 if constexpr (T::IS_R800) {
3345 f |= ((getHL() ^ res ^ reg) >> 8) &
H_FLAG;
3347 f |= ((reg ^ getHL()) & (getHL() ^ res) & 0x8000) >> 13;
3348 if constexpr (T::IS_R800) {
3349 f |= (res >> 8) &
S_FLAG;
3354 f |= ((getHL() ^ reg) >> 8) &
H_FLAG;
3356 f |= ((reg ^ getHL()) & getHL() & 0x8000) >> 13;
3361 return {1, T::CC_ADC_HL_SS};
3363 template<
typename T> II CPUCore<T>::sbc_hl_hl() {
3364 T::setMemPtr(getHL() + 1);
3365 byte f = T::IS_R800 ? (getF() & (
X_FLAG |
Y_FLAG)) : 0;
3368 if constexpr (!T::IS_R800) {
3377 return {1, T::CC_ADC_HL_SS};
3381 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::dec_SS() {
3382 set16<REG>(get16<REG>() - 1);
return {1, T::CC_INC_SS + EE};
3386 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::inc_SS() {
3387 set16<REG>(get16<REG>() + 1);
return {1, T::CC_INC_SS + EE};
3392 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::bit_N_R() {
3393 byte reg = get8<REG>();
3395 if constexpr (T::IS_R800) {
3399 f |= (reg & (1 <<
N)) ? 0 :
Z_FLAG;
3406 return {1, T::CC_BIT_R};
3408 template<
typename T>
template<
unsigned N>
inline II CPUCore<T>::bit_N_xhl() {
3409 byte m = RDMEM(getHL(), T::CC_BIT_XHL_1) & (1 <<
N);
3411 if constexpr (T::IS_R800) {
3421 return {1, T::CC_BIT_XHL};
3423 template<
typename T>
template<
unsigned N>
inline II CPUCore<T>::bit_N_xix(
unsigned addr) {
3425 byte m = RDMEM(addr, T::CC_DD + T::CC_BIT_XIX_1) & (1 <<
N);
3427 if constexpr (T::IS_R800) {
3437 return {3, T::CC_DD + T::CC_BIT_XIX};
3441 static constexpr
byte RES(
unsigned b,
byte reg) {
3442 return reg & ~(1 << b);
3444 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::res_N_R() {
3445 set8<REG>(RES(
N, get8<REG>()));
return {1, T::CC_SET_R};
3447 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RES_X(
unsigned bit,
unsigned addr) {
3448 byte res = RES(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3449 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3452 template<
typename T>
template<
unsigned N> II CPUCore<T>::res_N_xhl() {
3453 RES_X<0>(
N, getHL());
return {1, T::CC_SET_XHL};
3455 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::res_N_xix_R(
unsigned a) {
3457 set8<REG>(RES_X<T::CC_DD + T::EE_SET_XIX>(
N, a));
3458 return {3, T::CC_DD + T::CC_SET_XIX};
3462 static constexpr
byte SET(
unsigned b,
byte reg) {
3463 return reg | (1 << b);
3465 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::set_N_R() {
3466 set8<REG>(SET(
N, get8<REG>()));
return {1, T::CC_SET_R};
3468 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SET_X(
unsigned bit,
unsigned addr) {
3469 byte res = SET(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3470 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3473 template<
typename T>
template<
unsigned N> II CPUCore<T>::set_N_xhl() {
3474 SET_X<0>(
N, getHL());
return {1, T::CC_SET_XHL};
3476 template<
typename T>
template<
unsigned N, Reg8 REG> II CPUCore<T>::set_N_xix_R(
unsigned a) {
3478 set8<REG>(SET_X<T::CC_DD + T::EE_SET_XIX>(
N, a));
3479 return {3, T::CC_DD + T::CC_SET_XIX};
3483 template<
typename T>
inline byte CPUCore<T>::RL(
byte reg) {
3485 reg = (reg << 1) | ((getF() &
C_FLAG) ? 0x01 : 0);
3487 if constexpr (T::IS_R800) {
3496 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RL_X(
unsigned x) {
3497 byte res = RL(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3498 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3501 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rl_R() {
3502 set8<REG>(RL(get8<REG>()));
return {1, T::CC_SET_R};
3504 template<
typename T> II CPUCore<T>::rl_xhl() {
3505 RL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3507 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rl_xix_R(
unsigned a) {
3509 set8<REG>(RL_X<T::CC_DD + T::EE_SET_XIX>(a));
3510 return {3, T::CC_DD + T::CC_SET_XIX};
3514 template<
typename T>
inline byte CPUCore<T>::RLC(
byte reg) {
3516 reg = (reg << 1) | c;
3518 if constexpr (T::IS_R800) {
3527 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RLC_X(
unsigned x) {
3528 byte res = RLC(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3529 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3532 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rlc_R() {
3533 set8<REG>(RLC(get8<REG>()));
return {1, T::CC_SET_R};
3535 template<
typename T> II CPUCore<T>::rlc_xhl() {
3536 RLC_X<0>(getHL());
return {1, T::CC_SET_XHL};
3538 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rlc_xix_R(
unsigned a) {
3540 set8<REG>(RLC_X<T::CC_DD + T::EE_SET_XIX>(a));
3541 return {3, T::CC_DD + T::CC_SET_XIX};
3545 template<
typename T>
inline byte CPUCore<T>::RR(
byte reg) {
3547 reg = (reg >> 1) | ((getF() &
C_FLAG) << 7);
3549 if constexpr (T::IS_R800) {
3558 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RR_X(
unsigned x) {
3559 byte res = RR(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3560 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3563 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rr_R() {
3564 set8<REG>(RR(get8<REG>()));
return {1, T::CC_SET_R};
3566 template<
typename T> II CPUCore<T>::rr_xhl() {
3567 RR_X<0>(getHL());
return {1, T::CC_SET_XHL};
3569 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rr_xix_R(
unsigned a) {
3571 set8<REG>(RR_X<T::CC_DD + T::EE_SET_XIX>(a));
3572 return {3, T::CC_DD + T::CC_SET_XIX};
3576 template<
typename T>
inline byte CPUCore<T>::RRC(
byte reg) {
3578 reg = (reg >> 1) | (c << 7);
3580 if constexpr (T::IS_R800) {
3589 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::RRC_X(
unsigned x) {
3590 byte res = RRC(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3591 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3594 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rrc_R() {
3595 set8<REG>(RRC(get8<REG>()));
return {1, T::CC_SET_R};
3597 template<
typename T> II CPUCore<T>::rrc_xhl() {
3598 RRC_X<0>(getHL());
return {1, T::CC_SET_XHL};
3600 template<
typename T>
template<Reg8 REG> II CPUCore<T>::rrc_xix_R(
unsigned a) {
3602 set8<REG>(RRC_X<T::CC_DD + T::EE_SET_XIX>(a));
3603 return {3, T::CC_DD + T::CC_SET_XIX};
3607 template<
typename T>
inline byte CPUCore<T>::SLA(
byte reg) {
3611 if constexpr (T::IS_R800) {
3620 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SLA_X(
unsigned x) {
3621 byte res = SLA(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3622 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3625 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sla_R() {
3626 set8<REG>(SLA(get8<REG>()));
return {1, T::CC_SET_R};
3628 template<
typename T> II CPUCore<T>::sla_xhl() {
3629 SLA_X<0>(getHL());
return {1, T::CC_SET_XHL};
3631 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sla_xix_R(
unsigned a) {
3633 set8<REG>(SLA_X<T::CC_DD + T::EE_SET_XIX>(a));
3634 return {3, T::CC_DD + T::CC_SET_XIX};
3638 template<
typename T>
inline byte CPUCore<T>::SLL(
byte reg) {
3639 assert(!T::IS_R800);
3641 reg = (reg << 1) | 1;
3647 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SLL_X(
unsigned x) {
3648 byte res = SLL(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3649 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3652 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sll_R() {
3653 set8<REG>(SLL(get8<REG>()));
return {1, T::CC_SET_R};
3655 template<
typename T> II CPUCore<T>::sll_xhl() {
3656 SLL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3658 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sll_xix_R(
unsigned a) {
3660 set8<REG>(SLL_X<T::CC_DD + T::EE_SET_XIX>(a));
3661 return {3, T::CC_DD + T::CC_SET_XIX};
3663 template<
typename T> II CPUCore<T>::sll2() {
3669 return {3, T::CC_DD + T::CC_SET_XIX};
3673 template<
typename T>
inline byte CPUCore<T>::SRA(
byte reg) {
3675 reg = (reg >> 1) | (reg & 0x80);
3677 if constexpr (T::IS_R800) {
3686 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SRA_X(
unsigned x) {
3687 byte res = SRA(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3688 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3691 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sra_R() {
3692 set8<REG>(SRA(get8<REG>()));
return {1, T::CC_SET_R};
3694 template<
typename T> II CPUCore<T>::sra_xhl() {
3695 SRA_X<0>(getHL());
return {1, T::CC_SET_XHL};
3697 template<
typename T>
template<Reg8 REG> II CPUCore<T>::sra_xix_R(
unsigned a) {
3699 set8<REG>(SRA_X<T::CC_DD + T::EE_SET_XIX>(a));
3700 return {3, T::CC_DD + T::CC_SET_XIX};
3704 template<
typename T>
inline byte CPUCore<T>::SRL(
byte reg) {
3708 if constexpr (T::IS_R800) {
3717 template<
typename T>
template<
int EE>
inline byte CPUCore<T>::SRL_X(
unsigned x) {
3718 byte res = SRL(RDMEM(
x, T::CC_SET_XHL_1 + EE));
3719 WRMEM(
x, res, T::CC_SET_XHL_2 + EE);
3722 template<
typename T>
template<Reg8 REG> II CPUCore<T>::srl_R() {
3723 set8<REG>(SRL(get8<REG>()));
return {1, T::CC_SET_R};
3725 template<
typename T> II CPUCore<T>::srl_xhl() {
3726 SRL_X<0>(getHL());
return {1, T::CC_SET_XHL};
3728 template<
typename T>
template<Reg8 REG> II CPUCore<T>::srl_xix_R(
unsigned a) {
3730 set8<REG>(SRL_X<T::CC_DD + T::EE_SET_XIX>(a));
3731 return {3, T::CC_DD + T::CC_SET_XIX};
3735 template<
typename T> II CPUCore<T>::rla() {
3736 byte c = getF() &
C_FLAG;
3737 byte f = (getA() & 0x80) ?
C_FLAG : 0;
3738 if constexpr (T::IS_R800) {
3743 setA((getA() << 1) | (c ? 1 : 0));
3744 if constexpr (!T::IS_R800) {
3748 return {1, T::CC_RLA};
3750 template<
typename T> II CPUCore<T>::rlca() {
3751 setA((getA() << 1) | (getA() >> 7));
3753 if constexpr (T::IS_R800) {
3761 return {1, T::CC_RLA};
3763 template<
typename T> II CPUCore<T>::rra() {
3764 byte c = (getF() &
C_FLAG) << 7;
3765 byte f = (getA() & 0x01) ?
C_FLAG : 0;
3766 if constexpr (T::IS_R800) {
3771 setA((getA() >> 1) | c);
3772 if constexpr (!T::IS_R800) {
3776 return {1, T::CC_RLA};
3778 template<
typename T> II CPUCore<T>::rrca() {
3779 byte f = getA() &
C_FLAG;
3780 if constexpr (T::IS_R800) {
3785 setA((getA() >> 1) | (getA() << 7));
3786 if constexpr (!T::IS_R800) {
3790 return {1, T::CC_RLA};
3795 template<
typename T> II CPUCore<T>::rld() {
3796 byte val = RDMEM(getHL(), T::CC_RLD_1);
3797 T::setMemPtr(getHL() + 1);
3798 WRMEM(getHL(), (val << 4) | (getA() & 0x0F), T::CC_RLD_2);
3799 setA((getA() & 0xF0) | (val >> 4));
3801 if constexpr (T::IS_R800) {
3809 return {1, T::CC_RLD};
3813 template<
typename T> II CPUCore<T>::rrd() {
3814 byte val = RDMEM(getHL(), T::CC_RLD_1);
3815 T::setMemPtr(getHL() + 1);
3816 WRMEM(getHL(), (val >> 4) | (getA() << 4), T::CC_RLD_2);
3817 setA((getA() & 0xF0) | (val & 0x0F));
3819 if constexpr (T::IS_R800) {
3827 return {1, T::CC_RLD};
3832 template<
typename T>
template<
int EE>
inline void CPUCore<T>::PUSH(
unsigned reg) {
3834 WR_WORD_rev<true, true>(getSP(), reg, T::CC_PUSH_1 + EE);
3836 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::push_SS() {
3837 PUSH<EE>(get16<REG>());
return {1, T::CC_PUSH + EE};
3841 template<
typename T>
template<
int EE>
inline unsigned CPUCore<T>::POP() {
3842 unsigned addr = getSP();
3844 if constexpr (T::IS_R800) {
3846 if constexpr (EE == 0) {
3854 return RD_WORD(addr, T::CC_POP_1 + EE);
3856 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::pop_SS() {
3857 set16<REG>(POP<EE>());
return {1, T::CC_POP + EE};
3862 template<
typename T>
template<
typename COND> II CPUCore<T>::call(COND cond) {
3863 unsigned addr = RD_WORD_PC<1>(T::CC_CALL_1);
3866 PUSH<T::EE_CALL>(getPC() + 3);
3868 if constexpr (T::IS_R800) {
3870 setSlowInstructions();
3872 return {0, T::CC_CALL_A};
3874 return {3, T::CC_CALL_B};
3880 template<
typename T>
template<
unsigned ADDR> II CPUCore<T>::rst() {
3881 PUSH<0>(getPC() + 1);
3884 if constexpr (T::IS_R800) {
3886 setSlowInstructions();
3888 return {0, T::CC_RST};
3893 template<
typename T>
template<
int EE,
typename COND>
inline II CPUCore<T>::RET(COND cond) {
3895 unsigned addr = POP<EE>();
3898 return {0, T::CC_RET_A + EE};
3900 return {1, T::CC_RET_B + EE};
3903 template<
typename T>
template<
typename COND> II CPUCore<T>::ret(COND cond) {
3904 return RET<T::EE_RET_C>(cond);
3906 template<
typename T> II CPUCore<T>::ret() {
3907 return RET<0>(CondTrue());
3909 template<
typename T> II CPUCore<T>::retn() {
3911 setSlowInstructions();
3912 return RET<T::EE_RETN>(CondTrue());
3917 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::jp_SS() {
3918 setPC(get16<REG>()); T::R800ForcePageBreak();
return {0, T::CC_JP_HL + EE};
3922 template<
typename T>
template<
typename COND> II CPUCore<T>::jp(COND cond) {
3923 unsigned addr = RD_WORD_PC<1>(T::CC_JP_1);
3927 T::R800ForcePageBreak();
3928 return {0, T::CC_JP_A};
3930 return {3, T::CC_JP_B};
3935 template<
typename T>
template<
typename COND> II CPUCore<T>::jr(COND cond) {
3936 int8_t ofst = RDMEM_OPCODE<1>(T::CC_JR_1);
3938 if (((getPC() + 2) & 0xFF) == 0) {
3966 T::R800ForcePageBreak();
3968 setPC((getPC() + 2 + ofst) & 0xFFFF);
3969 T::setMemPtr(getPC());
3970 return {0, T::CC_JR_A};
3972 return {2, T::CC_JR_B};
3977 template<
typename T> II CPUCore<T>::djnz() {
3978 byte b = getB() - 1;
3980 int8_t ofst = RDMEM_OPCODE<1>(T::CC_JR_1 + T::EE_DJNZ);
3982 if (((getPC() + 2) & 0xFF) == 0) {
3984 T::R800ForcePageBreak();
3986 setPC((getPC() + 2 + ofst) & 0xFFFF);
3987 T::setMemPtr(getPC());
3988 return {0, T::CC_JR_A + T::EE_DJNZ};
3990 return {2, T::CC_JR_B + T::EE_DJNZ};
3995 template<
typename T>
template<Reg16 REG,
int EE> II CPUCore<T>::ex_xsp_SS() {
3996 unsigned res = RD_WORD_impl<true, false>(getSP(), T::CC_EX_SP_HL_1 + EE);
3998 WR_WORD_rev<false, true>(getSP(), get16<REG>(), T::CC_EX_SP_HL_2 + EE);
4000 return {1, T::CC_EX_SP_HL + EE};
4004 template<
typename T>
template<Reg8 REG> II CPUCore<T>::in_R_c() {
4005 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_IN_R_C_1);
4006 T::setMemPtr(getBC() + 1);
4007 byte res = READ_PORT(getBC(), T::CC_IN_R_C_1);
4009 if constexpr (T::IS_R800) {
4018 return {1, T::CC_IN_R_C};
4022 template<
typename T> II CPUCore<T>::in_a_byte() {
4023 unsigned y = RDMEM_OPCODE<1>(T::CC_IN_A_N_1) + 256 * getA();
4024 T::setMemPtr(y + 1);
4025 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_IN_A_N_2);
4026 setA(READ_PORT(y, T::CC_IN_A_N_2));
4027 return {2, T::CC_IN_A_N};
4031 template<
typename T>
template<Reg8 REG> II CPUCore<T>::out_c_R() {
4032 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_OUT_C_R_1);
4033 T::setMemPtr(getBC() + 1);
4034 WRITE_PORT(getBC(), get8<REG>(), T::CC_OUT_C_R_1);
4035 return {1, T::CC_OUT_C_R};
4037 template<
typename T> II CPUCore<T>::out_c_0() {
4039 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_OUT_C_R_1);
4040 T::setMemPtr(getBC() + 1);
4041 byte out_c_x = isCMOS ? 255 : 0;
4042 WRITE_PORT(getBC(), out_c_x, T::CC_OUT_C_R_1);
4043 return {1, T::CC_OUT_C_R};
4047 template<
typename T> II CPUCore<T>::out_byte_a() {
4048 byte port = RDMEM_OPCODE<1>(T::CC_OUT_N_A_1);
4049 unsigned y = (getA() << 8) | port;
4050 T::setMemPtr((getA() << 8) | ((port + 1) & 255));
4051 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_OUT_N_A_2);
4052 WRITE_PORT(y, getA(), T::CC_OUT_N_A_2);
4053 return {2, T::CC_OUT_N_A};
4058 template<
typename T>
inline II CPUCore<T>::BLOCK_CP(
int increase,
bool repeat) {
4059 T::setMemPtr(T::getMemPtr() + increase);
4060 byte val = RDMEM(getHL(), T::CC_CPI_1);
4061 byte res = getA() - val;
4062 setHL(getHL() + increase);
4064 byte f = ((getA() ^ val ^ res) &
H_FLAG) |
4068 if constexpr (T::IS_R800) {
4072 unsigned k = res - ((f &
H_FLAG) >> 4);
4077 if (
repeat && getBC() && res) {
4079 T::setMemPtr(getPC() + 1);
4080 return {-1, T::CC_CPIR};
4082 return {1, T::CC_CPI};
4085 template<
typename T> II CPUCore<T>::cpd() {
return BLOCK_CP(-1,
false); }
4086 template<
typename T> II CPUCore<T>::cpi() {
return BLOCK_CP( 1,
false); }
4087 template<
typename T> II CPUCore<T>::cpdr() {
return BLOCK_CP(-1,
true ); }
4088 template<
typename T> II CPUCore<T>::cpir() {
return BLOCK_CP( 1,
true ); }
4092 template<
typename T>
inline II CPUCore<T>::BLOCK_LD(
int increase,
bool repeat) {
4093 byte val = RDMEM(getHL(), T::CC_LDI_1);
4094 WRMEM(getDE(), val, T::CC_LDI_2);
4095 setHL(getHL() + increase);
4096 setDE(getDE() + increase);
4098 byte f = getBC() ?
V_FLAG : 0;
4099 if constexpr (T::IS_R800) {
4103 f |= ((getA() + val) << 4) &
Y_FLAG;
4104 f |= (getA() + val) &
X_FLAG;
4109 T::setMemPtr(getPC() + 1);
4110 return {-1, T::CC_LDIR};
4112 return {1, T::CC_LDI};
4115 template<
typename T> II CPUCore<T>::ldd() {
return BLOCK_LD(-1,
false); }
4116 template<
typename T> II CPUCore<T>::ldi() {
return BLOCK_LD( 1,
false); }
4117 template<
typename T> II CPUCore<T>::lddr() {
return BLOCK_LD(-1,
true ); }
4118 template<
typename T> II CPUCore<T>::ldir() {
return BLOCK_LD( 1,
true ); }
4122 template<
typename T>
inline II CPUCore<T>::BLOCK_IN(
int increase,
bool repeat) {
4123 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_INI_1);
4124 T::setMemPtr(getBC() + increase);
4125 setBC(getBC() - 0x100);
4126 byte val = READ_PORT(getBC(), T::CC_INI_1);
4127 WRMEM(getHL(), val, T::CC_INI_2);
4128 setHL(getHL() + increase);
4129 unsigned k = val + ((getC() + increase) & 0xFF);
4131 if constexpr (T::IS_R800) {
4134 setF(((val &
S_FLAG) >> 6) |
4141 return {-1, T::CC_INIR};
4143 return {1, T::CC_INI};
4146 template<
typename T> II CPUCore<T>::ind() {
return BLOCK_IN(-1,
false); }
4147 template<
typename T> II CPUCore<T>::ini() {
return BLOCK_IN( 1,
false); }
4148 template<
typename T> II CPUCore<T>::indr() {
return BLOCK_IN(-1,
true ); }
4149 template<
typename T> II CPUCore<T>::inir() {
return BLOCK_IN( 1,
true ); }
4153 template<
typename T>
inline II CPUCore<T>::BLOCK_OUT(
int increase,
bool repeat) {
4154 byte val = RDMEM(getHL(), T::CC_OUTI_1);
4155 setHL(getHL() + increase);
4156 if constexpr (T::IS_R800) T::waitForEvenCycle(T::CC_OUTI_2);
4157 WRITE_PORT(getBC(), val, T::CC_OUTI_2);
4158 setBC(getBC() - 0x100);
4159 T::setMemPtr(getBC() + increase);
4160 unsigned k = val + getL();
4162 if constexpr (T::IS_R800) {
4165 setF(((val &
S_FLAG) >> 6) |
4172 return {-1, T::CC_OTIR};
4174 return {1, T::CC_OUTI};
4177 template<
typename T> II CPUCore<T>::outd() {
return BLOCK_OUT(-1,
false); }
4178 template<
typename T> II CPUCore<T>::outi() {
return BLOCK_OUT( 1,
false); }
4179 template<
typename T> II CPUCore<T>::otdr() {
return BLOCK_OUT(-1,
true ); }
4180 template<
typename T> II CPUCore<T>::otir() {
return BLOCK_OUT( 1,
true ); }
4184 template<
typename T> II CPUCore<T>::nop() {
return {1, T::CC_NOP}; }
4185 template<
typename T> II CPUCore<T>::ccf() {
4187 if constexpr (T::IS_R800) {
4191 f |= (getF() &
C_FLAG) << 4;
4196 f |= (getF() | getA()) &
X_FLAG;
4204 return {1, T::CC_CCF};
4206 template<
typename T> II CPUCore<T>::cpl() {
4207 setA(getA() ^ 0xFF);
4209 if constexpr (T::IS_R800) {
4216 return {1, T::CC_CPL};
4218 template<
typename T> II CPUCore<T>::daa() {
4222 if ((f &
H_FLAG) || ((getA() & 0xf) > 9)) adjust += 6;
4223 if ((f &
C_FLAG) || (getA() > 0x99)) adjust += 0x60;
4224 if (f &
N_FLAG) a -= adjust;
else a += adjust;
4225 if constexpr (T::IS_R800) {
4232 f |= (getA() > 0x99) | ((getA() ^ a) &
H_FLAG);
4235 return {1, T::CC_DAA};
4237 template<
typename T> II CPUCore<T>::neg() {
4239 unsigned a = getA();
4240 unsigned res = -signed(a);
4241 byte f = ((res & 0x100) ?
C_FLAG : 0) |
4244 ((a & res & 0x80) >> 5);
4245 if constexpr (T::IS_R800) {
4253 return {1, T::CC_NEG};
4255 template<
typename T> II CPUCore<T>::scf() {
4257 if constexpr (T::IS_R800) {
4264 f |= (getF() | getA()) &
X_FLAG;
4271 return {1, T::CC_SCF};
4274 template<
typename T> II CPUCore<T>::ex_af_af() {
4275 unsigned t = getAF2(); setAF2(getAF()); setAF(
t);
4276 return {1, T::CC_EX};
4278 template<
typename T> II CPUCore<T>::ex_de_hl() {
4279 unsigned t = getDE(); setDE(getHL()); setHL(
t);
4280 return {1, T::CC_EX};
4282 template<
typename T> II CPUCore<T>::exx() {
4283 unsigned t1 = getBC2(); setBC2(getBC()); setBC(t1);
4284 unsigned t2 = getDE2(); setDE2(getDE()); setDE(t2);
4285 unsigned t3 = getHL2(); setHL2(getHL()); setHL(t3);
4286 return {1, T::CC_EX};
4289 template<
typename T> II CPUCore<T>::di() {
4292 return {1, T::CC_DI};
4294 template<
typename T> II CPUCore<T>::ei() {
4298 setSlowInstructions();
4299 return {1, T::CC_EI};
4301 template<
typename T> II CPUCore<T>::halt() {
4303 setSlowInstructions();
4305 if (!(getIFF1() || getIFF2())) {
4306 diHaltCallback.execute();
4308 return {1, T::CC_HALT};
4310 template<
typename T>
template<
unsigned N> II CPUCore<T>::im_N() {
4311 setIM(
N);
return {1, T::CC_IM};
4315 template<
typename T>
template<Reg8 REG> II CPUCore<T>::ld_a_IR() {
4317 byte f = getIFF2() ?
V_FLAG : 0;
4318 if constexpr (T::IS_R800) {
4326 setSlowInstructions();
4329 return {1, T::CC_LD_A_I};
4333 template<
typename T> II CPUCore<T>::ld_r_a() {
4342 if constexpr (T::IS_R800) val -= 1;
4344 return {1, T::CC_LD_A_I};
4346 template<
typename T> II CPUCore<T>::ld_i_a() {
4348 return {1, T::CC_LD_A_I};
4352 template<
typename T>
template<Reg8 REG> II CPUCore<T>::mulub_a_R() {
4359 setHL(
unsigned(getA()) * get8<REG>());
4363 ((getHL() & 0xFF00) ?
C_FLAG : 0));
4364 return {1, T::CC_MULUB};
4368 template<
typename T>
template<Reg16 REG> II CPUCore<T>::muluw_hl_SS() {
4375 unsigned res = unsigned(getHL()) * get16<REG>();
4377 setHL(res & 0xffff);
4381 ((res & 0xFFFF0000) ?
C_FLAG : 0));
4382 return {1, T::CC_MULUW};
4392 template<
typename T>
template<
typename Archive>
4396 ar.serialize(
"regs",
static_cast<CPURegs&
>(*
this));
4397 if (ar.versionBelow(version, 2)) {
4399 ar.serialize(
"memptr", mPtr);
4403 if (ar.versionBelow(version, 5)) {
4412 ar.serialize(
"nmiEdge", nmiEdge);
4421 if constexpr (T::IS_R800) {
4422 if (ar.versionBelow(version, 4)) {
4423 motherboard.getMSXCliComm().printWarning(
4424 "Loading an old savestate: the timing of the R800 "
4425 "emulation has changed. This may cause synchronization "
4426 "problems in replay.");
void lowerIRQ()
Lowers the maskable interrupt count.
void setNextSyncPoint(EmuTime::param time)
void disasmCommand(Interpreter &interp, span< const TclObject > tokens, TclObject &result) const
void setFreq(unsigned freq)
Change the clock freq.
void execute(bool fastForward)
void warp(EmuTime::param time)
CPUCore(MSXMotherBoard &motherboard, const std::string &name, const BooleanSetting &traceSetting, TclCallback &diHaltCallback, EmuTime::param time)
void lowerNMI()
Lowers the non-maskable interrupt count.
void exitCPULoopSync()
Request to exit the main CPU emulation loop.
EmuTime::param getCurrentTime() const
void exitCPULoopAsync()
Similar to exitCPULoopSync(), but this method may be called from any thread.
void raiseNMI()
Raises the non-maskable interrupt count.
void serialize(Archive &ar, unsigned version)
void doReset(EmuTime::param time)
Reset the CPU.
void wait(EmuTime::param time)
EmuTime waitCycles(EmuTime::param time, unsigned cycles)
bool isM1Cycle(unsigned address) const
void raiseIRQ()
Raises the maskable interrupt count.
void addListElement(const T &t)
constexpr index_type size() const noexcept
ALWAYS_INLINE uint16_t read_UA_L16(const void *p)
ALWAYS_INLINE void write_UA_L16(void *p, uint16_t x)
bool isMainThread()
Returns true when called from the main thread.
This file implemented 3 utility functions:
unsigned dasm(const MSXCPUInterface &interf, word pc, byte buf[4], std::string &dest, EmuTime::param time)
Disassemble.
uint16_t word
16 bit unsigned integer
constexpr KeyMatrixPosition x
Keyboard bindings.
void serialize(Archive &ar, T &t, unsigned version)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
TemporaryString tmpStrCat(Ts &&... ts)
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte f) const
bool operator()(byte) const
bool operator()(byte f) const
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
constexpr auto xrange(T e)