161 #if (__GNUC__ == 4) && (__GNUC_MINOR__ == 0) \
162 && defined(__i386__) && defined(NDEBUG)
163 #warning Applying workaround for GCC 4.0 internal compiler error.
170 #define WORK_AROUND_GCC40_SEGFAULT
245 static word start_pc;
260 static std::unique_ptr<BooleanSetting> createFreqLockedSetting(
263 return make_unique<BooleanSetting>(
264 commandController, name +
"_freq_locked",
265 "real (locked) or custom (unlocked) " + name +
" frequency",
273 : T(time, motherboard_.getScheduler())
275 , motherboard(motherboard_)
276 , scheduler(motherboard.getScheduler())
278 , traceSetting(traceSetting_)
279 , diHaltCallback(diHaltCallback_)
280 , IRQStatus(motherboard.getDebugger(), name +
".pendingIRQ",
281 "Non-zero if there are pending IRQs (thus CPU would enter "
282 "interrupt routine in EI mode).",
284 , IRQAccept(motherboard.getDebugger(), name +
".acceptIRQ",
285 "This probe is only useful to set a breakpoint on (the value "
286 "return by read is meaningless). The breakpoint gets triggered "
287 "right after the CPU accepted an IRQ.")
288 , freqLocked(createFreqLockedSetting(
289 motherboard.getCommandController(), name))
291 motherboard.getCommandController(), name +
"_freq",
292 "custom " + name +
" frequency (only valid when unlocked)",
293 T::CLOCK_FREQ, 1000000, 1000000000))
294 , freq(T::CLOCK_FREQ)
298 , isTurboR(motherboard.isTurboR())
301 freqLocked->attach(*
this);
302 freqValue->attach(*
this);
308 freqValue->detach(*
this);
309 freqLocked->detach(*
this);
319 assert(T::getTimeFast() <= time);
330 unsigned first = start / CacheLine::SIZE;
331 unsigned num = (size + CacheLine::SIZE - 1) / CacheLine::SIZE;
332 memset(&readCacheLine [first], 0, num *
sizeof(
byte*));
333 memset(&writeCacheLine [first], 0, num *
sizeof(
byte*));
334 memset(&readCacheTried [first], 0, num *
sizeof(
bool));
335 memset(&writeCacheTried[first], 0, num *
sizeof(
bool));
364 T::setMemPtr(0xFFFF);
365 invalidateMemCache(0x0000, 0x10000);
367 assert(T::getTimeFast() <= time);
370 assert(NMIStatus == 0);
371 assert(IRQStatus == 0);
400 template <
class T>
void CPUCore<T>::setSlowInstructions()
402 slowInstructions = 2;
408 assert(IRQStatus >= 0);
409 if (IRQStatus == 0) {
410 setSlowInstructions();
412 IRQStatus = IRQStatus + 1;
417 IRQStatus = IRQStatus - 1;
418 assert(IRQStatus >= 0);
426 assert(NMIStatus >= 0);
427 if (NMIStatus == 0) {
429 setSlowInstructions();
437 assert(NMIStatus >= 0);
443 return address == ((R.getPC() - 1) & 0xFFFF);
448 assert(time >= getCurrentTime());
449 scheduler.schedule(time);
450 T::advanceTime(time);
464 static inline char toHex(
byte x)
466 return (x < 10) ? (x +
'0') : (x - 10 +
'A');
468 static void toHex(
byte x,
char* buf)
470 buf[0] = toHex(x / 16);
471 buf[1] = toHex(x & 15);
475 const std::vector<TclObject>& tokens,
478 word address = (tokens.size() < 3) ? R.getPC() : tokens[2].getInt();
480 std::string dasmOutput;
481 unsigned len =
dasm(*interface, address, outBuf, dasmOutput,
484 char tmp[3]; tmp[2] = 0;
485 for (
unsigned i = 0; i < len; ++i) {
486 toHex(outBuf[i], tmp);
493 if (&setting == freqLocked.get()) {
495 }
else if (&setting == freqValue.get()) {
510 if (freqLocked->getValue()) {
515 T::setFreq(freqValue->getValue());
520 template <
class T>
inline byte CPUCore<T>::READ_PORT(
unsigned port,
unsigned cc)
522 EmuTime time = T::getTimeFast(cc);
523 scheduler.schedule(time);
524 byte result = interface->readIO(port, time);
529 template <
class T>
inline void CPUCore<T>::WRITE_PORT(
unsigned port,
byte value,
unsigned cc)
531 EmuTime time = T::getTimeFast(cc);
532 scheduler.schedule(time);
533 interface->writeIO(port, value, time);
537 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
541 unsigned high = address >> CacheLine::BITS;
542 if (!readCacheTried[high]) {
544 unsigned addrBase = address & CacheLine::HIGH;
545 if (
const byte* line = interface->getReadCacheLine(addrBase)) {
547 T::template PRE_MEM<PRE_PB, POST_PB>(address);
548 T::template POST_MEM< POST_PB>(address);
549 readCacheLine[high] = line - addrBase;
550 return readCacheLine[high][address];
554 readCacheTried[high] =
true;
555 T::template PRE_MEM<PRE_PB, POST_PB>(address);
556 EmuTime time = T::getTimeFast(cc);
557 scheduler.schedule(time);
558 byte result = interface->readMem(address, time);
559 T::template POST_MEM<POST_PB>(address);
562 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
565 const byte* line = readCacheLine[address >> CacheLine::BITS];
566 if (
likely(line !=
nullptr)) {
568 T::template PRE_MEM<PRE_PB, POST_PB>(address);
569 T::template POST_MEM< POST_PB>(address);
570 return line[address];
572 return RDMEMslow<PRE_PB, POST_PB>(address, cc);
575 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
578 static const bool PRE = T::template Normalize<PRE_PB >::value;
579 static const bool POST = T::template Normalize<POST_PB>::value;
580 return RDMEM_impl2<PRE, POST>(address, cc);
584 unsigned address = R.getPC();
585 R.setPC(address + 1);
586 return RDMEM_impl<false, false>(address, cc);
588 template <
class T>
ALWAYS_INLINE byte CPUCore<T>::RDMEM(
unsigned address,
unsigned cc)
590 return RDMEM_impl<true, true>(address, cc);
593 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
594 NEVER_INLINE unsigned CPUCore<T>::RD_WORD_slow(
unsigned address,
unsigned cc)
596 unsigned res = RDMEM_impl<PRE_PB, false>(address, cc);
597 res += RDMEM_impl<false, POST_PB>((address + 1) & 0xFFFF, cc + T::CC_RDMEM) << 8;
600 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
601 ALWAYS_INLINE unsigned CPUCore<T>::RD_WORD_impl2(
unsigned address,
unsigned cc)
603 const byte* line = readCacheLine[address >> CacheLine::BITS];
604 if (
likely(((address & CacheLine::LOW) != CacheLine::LOW) && line)) {
606 T::template PRE_WORD<PRE_PB, POST_PB>(address);
607 T::template POST_WORD< POST_PB>(address);
608 return Endian::read_UA_L16(&line[address]);
611 return RD_WORD_slow<PRE_PB, POST_PB>(address, cc);
614 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
615 ALWAYS_INLINE unsigned CPUCore<T>::RD_WORD_impl(
unsigned address,
unsigned cc)
617 static const bool PRE = T::template Normalize<PRE_PB >::value;
618 static const bool POST = T::template Normalize<POST_PB>::value;
619 return RD_WORD_impl2<PRE, POST>(address, cc);
621 template <
class T>
ALWAYS_INLINE unsigned CPUCore<T>::RD_WORD_PC(
unsigned cc)
623 unsigned addr = R.getPC();
625 return RD_WORD_impl<false, false>(addr, cc);
627 template <
class T>
ALWAYS_INLINE unsigned CPUCore<T>::RD_WORD(
628 unsigned address,
unsigned cc)
630 return RD_WORD_impl<true, true>(address, cc);
633 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
634 NEVER_INLINE void CPUCore<T>::WRMEMslow(
unsigned address,
byte value,
unsigned cc)
637 unsigned high = address >> CacheLine::BITS;
638 if (!writeCacheTried[high]) {
640 unsigned addrBase = address & CacheLine::HIGH;
641 if (
byte* line = interface->getWriteCacheLine(addrBase)) {
643 T::template PRE_MEM<PRE_PB, POST_PB>(address);
644 T::template POST_MEM< POST_PB>(address);
645 writeCacheLine[high] = line - addrBase;
646 writeCacheLine[high][address] = value;
651 writeCacheTried[high] =
true;
652 T::template PRE_MEM<PRE_PB, POST_PB>(address);
653 EmuTime time = T::getTimeFast(cc);
654 scheduler.schedule(time);
655 interface->writeMem(address, value, time);
656 T::template POST_MEM<POST_PB>(address);
658 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
660 unsigned address,
byte value,
unsigned cc)
662 byte* line = writeCacheLine[address >> CacheLine::BITS];
663 if (
likely(line !=
nullptr)) {
665 T::template PRE_MEM<PRE_PB, POST_PB>(address);
666 T::template POST_MEM< POST_PB>(address);
667 line[address] = value;
669 WRMEMslow<PRE_PB, POST_PB>(address, value, cc);
672 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
674 unsigned address,
byte value,
unsigned cc)
676 static const bool PRE = T::template Normalize<PRE_PB >::value;
677 static const bool POST = T::template Normalize<POST_PB>::value;
678 WRMEM_impl2<PRE, POST>(address, value, cc);
681 unsigned address,
byte value,
unsigned cc)
683 WRMEM_impl<true, true>(address, value, cc);
686 template <
class T>
NEVER_INLINE void CPUCore<T>::WR_WORD_slow(
687 unsigned address,
unsigned value,
unsigned cc)
689 WRMEM_impl<true, false>( address, value & 255, cc);
690 WRMEM_impl<false, true>((address + 1) & 0xFFFF, value >> 8, cc + T::CC_WRMEM);
693 unsigned address,
unsigned value,
unsigned cc)
695 byte* line = writeCacheLine[address >> CacheLine::BITS];
696 if (
likely(((address & CacheLine::LOW) != CacheLine::LOW) && line)) {
698 T::template PRE_WORD<true, true>(address);
699 T::template POST_WORD< true>(address);
700 Endian::write_UA_L16(&line[address], value);
703 WR_WORD_slow(address, value, cc);
708 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
710 unsigned address,
unsigned value,
unsigned cc)
712 WRMEM_impl<PRE_PB, false>((address + 1) & 0xFFFF, value >> 8, cc);
713 WRMEM_impl<false, POST_PB>( address, value & 255, cc + T::CC_WRMEM);
715 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
717 unsigned address,
unsigned value,
unsigned cc)
719 byte* line = writeCacheLine[address >> CacheLine::BITS];
720 if (
likely(((address & CacheLine::LOW) != CacheLine::LOW) && line)) {
722 T::template PRE_WORD<PRE_PB, POST_PB>(address);
723 T::template POST_WORD< POST_PB>(address);
724 Endian::write_UA_L16(&line[address], value);
727 WR_WORD_rev_slow<PRE_PB, POST_PB>(address, value, cc);
730 template <
class T>
template <
bool PRE_PB,
bool POST_PB>
732 unsigned address,
unsigned value,
unsigned cc)
734 static const bool PRE = T::template Normalize<PRE_PB >::value;
735 static const bool POST = T::template Normalize<POST_PB>::value;
736 WR_WORD_rev2<PRE, POST>(address, value, cc);
741 template <
class T>
inline void CPUCore<T>::nmi()
746 PUSH<T::EE_NMI_1>(R.getPC());
752 template <
class T>
inline void CPUCore<T>::irq0()
756 assert(interface->readIRQVector() == 0xFF);
761 PUSH<T::EE_IRQ0_1>(R.getPC());
763 T::setMemPtr(R.getPC());
768 template <
class T>
inline void CPUCore<T>::irq1()
774 PUSH<T::EE_IRQ1_1>(R.getPC());
776 T::setMemPtr(R.getPC());
781 template <
class T>
inline void CPUCore<T>::irq2()
787 PUSH<T::EE_IRQ2_1>(R.getPC());
788 unsigned x = interface->readIRQVector() | (R.getI() << 8);
789 R.setPC(RD_WORD(x, T::CC_IRQ2_2));
790 T::setMemPtr(R.getPC());
795 void CPUCore<T>::executeInstructions()
797 assert(R.isNextAfterClear());
799 #ifdef USE_COMPUTED_GOTO
802 static void* opcodeTable[256] = {
803 &&op00, &&op01, &&op02, &&op03, &&op04, &&op05, &&op06, &&op07,
804 &&op08, &&op09, &&op0A, &&op0B, &&op0C, &&op0D, &&op0E, &&op0F,
805 &&op10, &&op11, &&op12, &&op13, &&op14, &&op15, &&op16, &&op17,
806 &&op18, &&op19, &&op1A, &&op1B, &&op1C, &&op1D, &&op1E, &&op1F,
807 &&op20, &&op21, &&op22, &&op23, &&op24, &&op25, &&op26, &&op27,
808 &&op28, &&op29, &&op2A, &&op2B, &&op2C, &&op2D, &&op2E, &&op2F,
809 &&op30, &&op31, &&op32, &&op33, &&op34, &&op35, &&op36, &&op37,
810 &&op38, &&op39, &&op3A, &&op3B, &&op3C, &&op3D, &&op3E, &&op3F,
811 &&op00, &&op41, &&op42, &&op43, &&op44, &&op45, &&op46, &&op47,
812 &&op48, &&op00, &&op4A, &&op4B, &&op4C, &&op4D, &&op4E, &&op4F,
813 &&op50, &&op51, &&op00, &&op53, &&op54, &&op55, &&op56, &&op57,
814 &&op58, &&op59, &&op5A, &&op00, &&op5C, &&op5D, &&op5E, &&op5F,
815 &&op60, &&op61, &&op62, &&op63, &&op00, &&op65, &&op66, &&op67,
816 &&op68, &&op69, &&op6A, &&op6B, &&op6C, &&op00, &&op6E, &&op6F,
817 &&op70, &&op71, &&op72, &&op73, &&op74, &&op75, &&op76, &&op77,
818 &&op78, &&op79, &&op7A, &&op7B, &&op7C, &&op7D, &&op7E, &&op00,
819 &&op80, &&op81, &&op82, &&op83, &&op84, &&op85, &&op86, &&op87,
820 &&op88, &&op89, &&op8A, &&op8B, &&op8C, &&op8D, &&op8E, &&op8F,
821 &&op90, &&op91, &&op92, &&op93, &&op94, &&op95, &&op96, &&op97,
822 &&op98, &&op99, &&op9A, &&op9B, &&op9C, &&op9D, &&op9E, &&op9F,
823 &&opA0, &&opA1, &&opA2, &&opA3, &&opA4, &&opA5, &&opA6, &&opA7,
824 &&opA8, &&opA9, &&opAA, &&opAB, &&opAC, &&opAD, &&opAE, &&opAF,
825 &&opB0, &&opB1, &&opB2, &&opB3, &&opB4, &&opB5, &&opB6, &&opB7,
826 &&opB8, &&opB9, &&opBA, &&opBB, &&opBC, &&opBD, &&opBE, &&opBF,
827 &&opC0, &&opC1, &&opC2, &&opC3, &&opC4, &&opC5, &&opC6, &&opC7,
828 &&opC8, &&opC9, &&opCA, &&opCB, &&opCC, &&opCD, &&opCE, &&opCF,
829 &&opD0, &&opD1, &&opD2, &&opD3, &&opD4, &&opD5, &&opD6, &&opD7,
830 &&opD8, &&opD9, &&opDA, &&opDB, &&opDC, &&opDD, &&opDE, &&opDF,
831 &&opE0, &&opE1, &&opE2, &&opE3, &&opE4, &&opE5, &&opE6, &&opE7,
832 &&opE8, &&opE9, &&opEA, &&opEB, &&opEC, &&opED, &&opEE, &&opEF,
833 &&opF0, &&opF1, &&opF2, &&opF3, &&opF4, &&opF5, &&opF6, &&opF7,
834 &&opF8, &&opF9, &&opFA, &&opFB, &&opFC, &&opFD, &&opFE, &&opFF,
842 if (likely(!T::limitReached())) { \
844 unsigned address = R.getPC(); \
845 const byte* line = readCacheLine[address >> CacheLine::BITS]; \
846 if (likely(line != nullptr)) { \
847 R.setPC(address + 1); \
848 T::template PRE_MEM<false, false>(address); \
849 T::template POST_MEM< false>(address); \
850 byte op = line[address]; \
851 goto *(opcodeTable[op]); \
862 assert(T::limitReached()); \
868 assert(T::limitReached()); \
872 #define CASE(X) op##X:
874 #else // USE_COMPUTED_GOTO
879 if (likely(!T::limitReached())) { \
887 assert(T::limitReached()); \
893 assert(T::limitReached()); \
896 #define CASE(X) case 0x##X:
898 #endif // USE_COMPUTED_GOTO
900 #ifndef USE_COMPUTED_GOTO
904 byte opcodeMain = RDMEM_OPCODE(T::CC_MAIN);
906 #ifdef USE_COMPUTED_GOTO
907 goto *(opcodeTable[opcodeMain]);
910 unsigned address = R.getPC();
911 R.setPC(address + 1);
912 byte opcodeSlow = RDMEMslow<false, false>(address, T::CC_MAIN);
913 goto *(opcodeTable[opcodeSlow]);
917 #ifndef USE_COMPUTED_GOTO
919 switch (opcodeMain) {
933 CASE(08) {
int c = ex_af_af();
NEXT; }
938 CASE(20) {
int c = jr(CondNZ());
NEXT; }
939 CASE(28) {
int c = jr(CondZ ());
NEXT; }
940 CASE(30) {
int c = jr(CondNC());
NEXT; }
941 CASE(38) {
int c = jr(CondC ());
NEXT; }
942 CASE(18) {
int c = jr(CondTrue());
NEXT; }
944 CASE(32) {
int c = ld_xbyte_a();
NEXT; }
945 CASE(3A) {
int c = ld_a_xbyte();
NEXT; }
946 CASE(22) {
int c = ld_xword_SS<HL,0>();
NEXT; }
947 CASE(2A) {
int c = ld_SS_xword<HL,0>();
NEXT; }
948 CASE(02) {
int c = ld_SS_a<BC>();
NEXT; }
949 CASE(12) {
int c = ld_SS_a<DE>();
NEXT; }
950 CASE(1A) {
int c = ld_a_SS<DE>();
NEXT; }
951 CASE(0A) {
int c = ld_a_SS<BC>();
NEXT; }
952 CASE(03) {
int c = inc_SS<BC,0>();
NEXT; }
953 CASE(13) {
int c = inc_SS<DE,0>();
NEXT; }
954 CASE(23) {
int c = inc_SS<HL,0>();
NEXT; }
955 CASE(33) {
int c = inc_SS<SP,0>();
NEXT; }
956 CASE(0B) {
int c = dec_SS<BC,0>();
NEXT; }
957 CASE(1B) {
int c = dec_SS<DE,0>();
NEXT; }
958 CASE(2B) {
int c = dec_SS<HL,0>();
NEXT; }
959 CASE(3B) {
int c = dec_SS<SP,0>();
NEXT; }
960 CASE(09) {
int c = add_SS_TT<HL,BC,0>();
NEXT; }
961 CASE(19) {
int c = add_SS_TT<HL,DE,0>();
NEXT; }
962 CASE(29) {
int c = add_SS_SS<HL ,0>();
NEXT; }
963 CASE(39) {
int c = add_SS_TT<HL,SP,0>();
NEXT; }
964 CASE(01) {
int c = ld_SS_word<BC,0>();
NEXT; }
965 CASE(11) {
int c = ld_SS_word<DE,0>();
NEXT; }
966 CASE(21) {
int c = ld_SS_word<HL,0>();
NEXT; }
967 CASE(31) {
int c = ld_SS_word<SP,0>();
NEXT; }
968 CASE(04) {
int c = inc_R<B,0>();
NEXT; }
969 CASE(0C) {
int c = inc_R<C,0>();
NEXT; }
970 CASE(14) {
int c = inc_R<D,0>();
NEXT; }
971 CASE(1C) {
int c = inc_R<E,0>();
NEXT; }
972 CASE(24) {
int c = inc_R<H,0>();
NEXT; }
973 CASE(2C) {
int c = inc_R<L,0>();
NEXT; }
974 CASE(3C) {
int c = inc_R<A,0>();
NEXT; }
975 CASE(34) {
int c = inc_xhl();
NEXT; }
976 CASE(05) {
int c = dec_R<B,0>();
NEXT; }
977 CASE(0D) {
int c = dec_R<C,0>();
NEXT; }
978 CASE(15) {
int c = dec_R<D,0>();
NEXT; }
979 CASE(1D) {
int c = dec_R<E,0>();
NEXT; }
980 CASE(25) {
int c = dec_R<H,0>();
NEXT; }
981 CASE(2D) {
int c = dec_R<L,0>();
NEXT; }
982 CASE(3D) {
int c = dec_R<A,0>();
NEXT; }
983 CASE(35) {
int c = dec_xhl();
NEXT; }
984 CASE(06) {
int c = ld_R_byte<B,0>();
NEXT; }
985 CASE(0E) {
int c = ld_R_byte<C,0>();
NEXT; }
986 CASE(16) {
int c = ld_R_byte<D,0>();
NEXT; }
987 CASE(1E) {
int c = ld_R_byte<E,0>();
NEXT; }
988 CASE(26) {
int c = ld_R_byte<H,0>();
NEXT; }
989 CASE(2E) {
int c = ld_R_byte<L,0>();
NEXT; }
990 CASE(3E) {
int c = ld_R_byte<A,0>();
NEXT; }
991 CASE(36) {
int c = ld_xhl_byte();
NEXT; }
993 CASE(41) {
int c = ld_R_R<B,C,0>();
NEXT; }
994 CASE(42) {
int c = ld_R_R<B,D,0>();
NEXT; }
995 CASE(43) {
int c = ld_R_R<B,E,0>();
NEXT; }
996 CASE(44) {
int c = ld_R_R<B,H,0>();
NEXT; }
997 CASE(45) {
int c = ld_R_R<B,L,0>();
NEXT; }
998 CASE(47) {
int c = ld_R_R<B,A,0>();
NEXT; }
999 CASE(48) {
int c = ld_R_R<C,B,0>();
NEXT; }
1000 CASE(4A) {
int c = ld_R_R<C,D,0>();
NEXT; }
1001 CASE(4B) {
int c = ld_R_R<C,E,0>();
NEXT; }
1002 CASE(4C) {
int c = ld_R_R<C,H,0>();
NEXT; }
1003 CASE(4D) {
int c = ld_R_R<C,L,0>();
NEXT; }
1004 CASE(4
F) {
int c = ld_R_R<C,A,0>();
NEXT; }
1005 CASE(50) {
int c = ld_R_R<D,B,0>();
NEXT; }
1006 CASE(51) {
int c = ld_R_R<D,C,0>();
NEXT; }
1007 CASE(53) {
int c = ld_R_R<D,E,0>();
NEXT; }
1008 CASE(54) {
int c = ld_R_R<D,H,0>();
NEXT; }
1009 CASE(55) {
int c = ld_R_R<D,L,0>();
NEXT; }
1010 CASE(57) {
int c = ld_R_R<D,A,0>();
NEXT; }
1011 CASE(58) {
int c = ld_R_R<E,B,0>();
NEXT; }
1012 CASE(59) {
int c = ld_R_R<E,C,0>();
NEXT; }
1013 CASE(5A) {
int c = ld_R_R<E,D,0>();
NEXT; }
1014 CASE(5C) {
int c = ld_R_R<E,H,0>();
NEXT; }
1015 CASE(5D) {
int c = ld_R_R<E,L,0>();
NEXT; }
1016 CASE(5
F) {
int c = ld_R_R<E,A,0>();
NEXT; }
1017 CASE(60) {
int c = ld_R_R<H,B,0>();
NEXT; }
1018 CASE(61) {
int c = ld_R_R<H,C,0>();
NEXT; }
1019 CASE(62) {
int c = ld_R_R<H,D,0>();
NEXT; }
1020 CASE(63) {
int c = ld_R_R<H,E,0>();
NEXT; }
1021 CASE(65) {
int c = ld_R_R<H,L,0>();
NEXT; }
1022 CASE(67) {
int c = ld_R_R<H,A,0>();
NEXT; }
1023 CASE(68) {
int c = ld_R_R<L,B,0>();
NEXT; }
1024 CASE(69) {
int c = ld_R_R<L,C,0>();
NEXT; }
1025 CASE(6A) {
int c = ld_R_R<L,D,0>();
NEXT; }
1026 CASE(6B) {
int c = ld_R_R<L,E,0>();
NEXT; }
1027 CASE(6C) {
int c = ld_R_R<L,H,0>();
NEXT; }
1028 CASE(6
F) {
int c = ld_R_R<L,A,0>();
NEXT; }
1029 CASE(78) {
int c = ld_R_R<A,B,0>();
NEXT; }
1030 CASE(79) {
int c = ld_R_R<A,C,0>();
NEXT; }
1031 CASE(7A) {
int c = ld_R_R<A,D,0>();
NEXT; }
1032 CASE(7B) {
int c = ld_R_R<A,E,0>();
NEXT; }
1033 CASE(7C) {
int c = ld_R_R<A,H,0>();
NEXT; }
1034 CASE(7D) {
int c = ld_R_R<A,L,0>();
NEXT; }
1035 CASE(70) {
int c = ld_xhl_R<B>();
NEXT; }
1036 CASE(71) {
int c = ld_xhl_R<C>();
NEXT; }
1037 CASE(72) {
int c = ld_xhl_R<D>();
NEXT; }
1038 CASE(73) {
int c = ld_xhl_R<E>();
NEXT; }
1039 CASE(74) {
int c = ld_xhl_R<H>();
NEXT; }
1040 CASE(75) {
int c = ld_xhl_R<L>();
NEXT; }
1041 CASE(77) {
int c = ld_xhl_R<A>();
NEXT; }
1042 CASE(46) {
int c = ld_R_xhl<B>();
NEXT; }
1043 CASE(4E) {
int c = ld_R_xhl<C>();
NEXT; }
1044 CASE(56) {
int c = ld_R_xhl<D>();
NEXT; }
1045 CASE(5E) {
int c = ld_R_xhl<E>();
NEXT; }
1046 CASE(66) {
int c = ld_R_xhl<H>();
NEXT; }
1047 CASE(6E) {
int c = ld_R_xhl<L>();
NEXT; }
1048 CASE(7E) {
int c = ld_R_xhl<A>();
NEXT; }
1051 CASE(80) {
int c = add_a_R<B,0>();
NEXT; }
1052 CASE(81) {
int c = add_a_R<C,0>();
NEXT; }
1053 CASE(82) {
int c = add_a_R<D,0>();
NEXT; }
1054 CASE(83) {
int c = add_a_R<E,0>();
NEXT; }
1055 CASE(84) {
int c = add_a_R<H,0>();
NEXT; }
1056 CASE(85) {
int c = add_a_R<L,0>();
NEXT; }
1057 CASE(86) {
int c = add_a_xhl();
NEXT; }
1058 CASE(87) {
int c = add_a_a();
NEXT; }
1059 CASE(88) {
int c = adc_a_R<B,0>();
NEXT; }
1060 CASE(89) {
int c = adc_a_R<C,0>();
NEXT; }
1061 CASE(8A) {
int c = adc_a_R<D,0>();
NEXT; }
1062 CASE(8B) {
int c = adc_a_R<E,0>();
NEXT; }
1063 CASE(8C) {
int c = adc_a_R<H,0>();
NEXT; }
1064 CASE(8D) {
int c = adc_a_R<L,0>();
NEXT; }
1065 CASE(8E) {
int c = adc_a_xhl();
NEXT; }
1067 CASE(90) {
int c = sub_R<B,0>();
NEXT; }
1068 CASE(91) {
int c = sub_R<C,0>();
NEXT; }
1069 CASE(92) {
int c = sub_R<D,0>();
NEXT; }
1070 CASE(93) {
int c = sub_R<E,0>();
NEXT; }
1071 CASE(94) {
int c = sub_R<H,0>();
NEXT; }
1072 CASE(95) {
int c = sub_R<L,0>();
NEXT; }
1073 CASE(96) {
int c = sub_xhl();
NEXT; }
1074 CASE(97) {
int c = sub_a();
NEXT; }
1075 CASE(98) {
int c = sbc_a_R<B,0>();
NEXT; }
1076 CASE(99) {
int c = sbc_a_R<C,0>();
NEXT; }
1077 CASE(9A) {
int c = sbc_a_R<D,0>();
NEXT; }
1078 CASE(9B) {
int c = sbc_a_R<E,0>();
NEXT; }
1079 CASE(9C) {
int c = sbc_a_R<H,0>();
NEXT; }
1080 CASE(9D) {
int c = sbc_a_R<L,0>();
NEXT; }
1081 CASE(9E) {
int c = sbc_a_xhl();
NEXT; }
1083 CASE(A0) {
int c = and_R<B,0>();
NEXT; }
1084 CASE(A1) {
int c = and_R<C,0>();
NEXT; }
1085 CASE(A2) {
int c = and_R<D,0>();
NEXT; }
1086 CASE(A3) {
int c = and_R<E,0>();
NEXT; }
1087 CASE(A4) {
int c = and_R<H,0>();
NEXT; }
1088 CASE(A5) {
int c = and_R<L,0>();
NEXT; }
1089 CASE(A6) {
int c = and_xhl();
NEXT; }
1090 CASE(A7) {
int c = and_a();
NEXT; }
1091 CASE(A8) {
int c = xor_R<B,0>();
NEXT; }
1092 CASE(A9) {
int c = xor_R<C,0>();
NEXT; }
1093 CASE(AA) {
int c = xor_R<D,0>();
NEXT; }
1094 CASE(AB) {
int c = xor_R<E,0>();
NEXT; }
1095 CASE(AC) {
int c = xor_R<H,0>();
NEXT; }
1096 CASE(AD) {
int c = xor_R<L,0>();
NEXT; }
1097 CASE(AE) {
int c = xor_xhl();
NEXT; }
1098 CASE(AF) {
int c = xor_a();
NEXT; }
1107 CASE(B8) {
int c = cp_R<B,0>();
NEXT; }
1108 CASE(B9) {
int c = cp_R<C,0>();
NEXT; }
1109 CASE(BA) {
int c = cp_R<D,0>();
NEXT; }
1110 CASE(BB) {
int c = cp_R<E,0>();
NEXT; }
1111 CASE(BC) {
int c = cp_R<H,0>();
NEXT; }
1112 CASE(BD) {
int c = cp_R<L,0>();
NEXT; }
1113 CASE(BE) {
int c = cp_xhl();
NEXT; }
1116 CASE(D3) {
int c = out_byte_a();
NEXT; }
1117 CASE(DB) {
int c = in_a_byte();
NEXT; }
1119 CASE(E3) {
int c = ex_xsp_SS<HL,0>();
NEXT; }
1120 CASE(EB) {
int c = ex_de_hl();
NEXT; }
1121 CASE(E9) {
int c = jp_SS<HL,0>();
NEXT; }
1122 CASE(F9) {
int c = ld_sp_SS<HL,0>();
NEXT; }
1125 CASE(C6) {
int c = add_a_byte();
NEXT; }
1126 CASE(CE) {
int c = adc_a_byte();
NEXT; }
1127 CASE(D6) {
int c = sub_byte();
NEXT; }
1128 CASE(DE) {
int c = sbc_a_byte();
NEXT; }
1129 CASE(E6) {
int c = and_byte();
NEXT; }
1130 CASE(EE) {
int c = xor_byte();
NEXT; }
1131 CASE(F6) {
int c = or_byte();
NEXT; }
1132 CASE(FE) {
int c = cp_byte();
NEXT; }
1133 CASE(C0) {
int c = ret(CondNZ());
NEXT; }
1134 CASE(C8) {
int c = ret(CondZ ());
NEXT; }
1135 CASE(D0) {
int c = ret(CondNC());
NEXT; }
1136 CASE(D8) {
int c = ret(CondC ());
NEXT; }
1137 CASE(E0) {
int c = ret(CondPO());
NEXT; }
1138 CASE(E8) {
int c = ret(CondPE());
NEXT; }
1139 CASE(F0) {
int c = ret(CondP ());
NEXT; }
1140 CASE(F8) {
int c = ret(CondM ());
NEXT; }
1142 CASE(C2) {
int c = jp(CondNZ());
NEXT; }
1143 CASE(CA) {
int c = jp(CondZ ());
NEXT; }
1144 CASE(D2) {
int c = jp(CondNC());
NEXT; }
1145 CASE(DA) {
int c = jp(CondC ());
NEXT; }
1146 CASE(E2) {
int c = jp(CondPO());
NEXT; }
1147 CASE(EA) {
int c = jp(CondPE());
NEXT; }
1148 CASE(F2) {
int c = jp(CondP ());
NEXT; }
1149 CASE(FA) {
int c = jp(CondM ());
NEXT; }
1150 CASE(C3) {
int c = jp(CondTrue());
NEXT; }
1151 CASE(C4) {
int c = call(CondNZ());
NEXT; }
1152 CASE(CC) {
int c = call(CondZ ());
NEXT; }
1153 CASE(D4) {
int c = call(CondNC());
NEXT; }
1154 CASE(DC) {
int c = call(CondC ());
NEXT; }
1155 CASE(E4) {
int c = call(CondPO());
NEXT; }
1156 CASE(EC) {
int c = call(CondPE());
NEXT; }
1157 CASE(F4) {
int c = call(CondP ());
NEXT; }
1158 CASE(FC) {
int c = call(CondM ());
NEXT; }
1159 CASE(CD) {
int c = call(CondTrue());
NEXT; }
1160 CASE(C1) {
int c = pop_SS <BC,0>();
NEXT; }
1161 CASE(D1) {
int c = pop_SS <DE,0>();
NEXT; }
1162 CASE(E1) {
int c = pop_SS <HL,0>();
NEXT; }
1163 CASE(F1) {
int c = pop_SS <AF,0>();
NEXT; }
1164 CASE(C5) {
int c = push_SS<BC,0>();
NEXT; }
1165 CASE(D5) {
int c = push_SS<DE,0>();
NEXT; }
1166 CASE(E5) {
int c = push_SS<HL,0>();
NEXT; }
1167 CASE(F5) {
int c = push_SS<AF,0>();
NEXT; }
1168 CASE(C7) {
int c = rst<0x00>();
NEXT; }
1169 CASE(CF) {
int c = rst<0x08>();
NEXT; }
1170 CASE(D7) {
int c = rst<0x10>();
NEXT; }
1171 CASE(DF) {
int c = rst<0x18>();
NEXT; }
1172 CASE(E7) {
int c = rst<0x20>();
NEXT; }
1173 CASE(EF) {
int c = rst<0x28>();
NEXT; }
1174 CASE(F7) {
int c = rst<0x30>();
NEXT; }
1175 CASE(FF) {
int c = rst<0x38>();
NEXT; }
1177 byte cb_opcode = RDMEM_OPCODE(T::CC_PREFIX);
1179 switch (cb_opcode) {
1180 case 0x00: {
int c = rlc_R<B>();
NEXT; }
1181 case 0x01: {
int c = rlc_R<C>();
NEXT; }
1182 case 0x02: {
int c = rlc_R<D>();
NEXT; }
1183 case 0x03: {
int c = rlc_R<E>();
NEXT; }
1184 case 0x04: {
int c = rlc_R<H>();
NEXT; }
1185 case 0x05: {
int c = rlc_R<L>();
NEXT; }
1186 case 0x07: {
int c = rlc_R<A>();
NEXT; }
1187 case 0x06: {
int c = rlc_xhl();
NEXT; }
1188 case 0x08: {
int c = rrc_R<B>();
NEXT; }
1189 case 0x09: {
int c = rrc_R<C>();
NEXT; }
1190 case 0x0a: {
int c = rrc_R<D>();
NEXT; }
1191 case 0x0b: {
int c = rrc_R<E>();
NEXT; }
1192 case 0x0c: {
int c = rrc_R<H>();
NEXT; }
1193 case 0x0d: {
int c = rrc_R<L>();
NEXT; }
1194 case 0x0f: {
int c = rrc_R<A>();
NEXT; }
1195 case 0x0e: {
int c = rrc_xhl();
NEXT; }
1196 case 0x10: {
int c = rl_R<B>();
NEXT; }
1197 case 0x11: {
int c = rl_R<C>();
NEXT; }
1198 case 0x12: {
int c = rl_R<D>();
NEXT; }
1199 case 0x13: {
int c = rl_R<E>();
NEXT; }
1200 case 0x14: {
int c = rl_R<H>();
NEXT; }
1201 case 0x15: {
int c = rl_R<L>();
NEXT; }
1202 case 0x17: {
int c = rl_R<A>();
NEXT; }
1203 case 0x16: {
int c = rl_xhl();
NEXT; }
1204 case 0x18: {
int c = rr_R<B>();
NEXT; }
1205 case 0x19: {
int c = rr_R<C>();
NEXT; }
1206 case 0x1a: {
int c = rr_R<D>();
NEXT; }
1207 case 0x1b: {
int c = rr_R<E>();
NEXT; }
1208 case 0x1c: {
int c = rr_R<H>();
NEXT; }
1209 case 0x1d: {
int c = rr_R<L>();
NEXT; }
1210 case 0x1f: {
int c = rr_R<A>();
NEXT; }
1211 case 0x1e: {
int c = rr_xhl();
NEXT; }
1212 case 0x20: {
int c = sla_R<B>();
NEXT; }
1213 case 0x21: {
int c = sla_R<C>();
NEXT; }
1214 case 0x22: {
int c = sla_R<D>();
NEXT; }
1215 case 0x23: {
int c = sla_R<E>();
NEXT; }
1216 case 0x24: {
int c = sla_R<H>();
NEXT; }
1217 case 0x25: {
int c = sla_R<L>();
NEXT; }
1218 case 0x27: {
int c = sla_R<A>();
NEXT; }
1219 case 0x26: {
int c = sla_xhl();
NEXT; }
1220 case 0x28: {
int c = sra_R<B>();
NEXT; }
1221 case 0x29: {
int c = sra_R<C>();
NEXT; }
1222 case 0x2a: {
int c = sra_R<D>();
NEXT; }
1223 case 0x2b: {
int c = sra_R<E>();
NEXT; }
1224 case 0x2c: {
int c = sra_R<H>();
NEXT; }
1225 case 0x2d: {
int c = sra_R<L>();
NEXT; }
1226 case 0x2f: {
int c = sra_R<A>();
NEXT; }
1227 case 0x2e: {
int c = sra_xhl();
NEXT; }
1228 case 0x30: {
int c = T::isR800() ? sla_R<B>() : sll_R<B>();
NEXT; }
1229 case 0x31: {
int c = T::isR800() ? sla_R<C>() : sll_R<C>();
NEXT; }
1230 case 0x32: {
int c = T::isR800() ? sla_R<D>() : sll_R<D>();
NEXT; }
1231 case 0x33: {
int c = T::isR800() ? sla_R<E>() : sll_R<E>();
NEXT; }
1232 case 0x34: {
int c = T::isR800() ? sla_R<H>() : sll_R<H>();
NEXT; }
1233 case 0x35: {
int c = T::isR800() ? sla_R<L>() : sll_R<L>();
NEXT; }
1234 case 0x37: {
int c = T::isR800() ? sla_R<A>() : sll_R<A>();
NEXT; }
1235 case 0x36: {
int c = T::isR800() ? sla_xhl() : sll_xhl();
NEXT; }
1236 case 0x38: {
int c = srl_R<B>();
NEXT; }
1237 case 0x39: {
int c = srl_R<C>();
NEXT; }
1238 case 0x3a: {
int c = srl_R<D>();
NEXT; }
1239 case 0x3b: {
int c = srl_R<E>();
NEXT; }
1240 case 0x3c: {
int c = srl_R<H>();
NEXT; }
1241 case 0x3d: {
int c = srl_R<L>();
NEXT; }
1242 case 0x3f: {
int c = srl_R<A>();
NEXT; }
1243 case 0x3e: {
int c = srl_xhl();
NEXT; }
1245 case 0x40: {
int c = bit_N_R<0,B>();
NEXT; }
1246 case 0x41: {
int c = bit_N_R<0,C>();
NEXT; }
1247 case 0x42: {
int c = bit_N_R<0,D>();
NEXT; }
1248 case 0x43: {
int c = bit_N_R<0,E>();
NEXT; }
1249 case 0x44: {
int c = bit_N_R<0,H>();
NEXT; }
1250 case 0x45: {
int c = bit_N_R<0,L>();
NEXT; }
1251 case 0x47: {
int c = bit_N_R<0,A>();
NEXT; }
1252 case 0x48: {
int c = bit_N_R<1,B>();
NEXT; }
1253 case 0x49: {
int c = bit_N_R<1,C>();
NEXT; }
1254 case 0x4a: {
int c = bit_N_R<1,D>();
NEXT; }
1255 case 0x4b: {
int c = bit_N_R<1,E>();
NEXT; }
1256 case 0x4c: {
int c = bit_N_R<1,H>();
NEXT; }
1257 case 0x4d: {
int c = bit_N_R<1,L>();
NEXT; }
1258 case 0x4f: {
int c = bit_N_R<1,A>();
NEXT; }
1259 case 0x50: {
int c = bit_N_R<2,B>();
NEXT; }
1260 case 0x51: {
int c = bit_N_R<2,C>();
NEXT; }
1261 case 0x52: {
int c = bit_N_R<2,D>();
NEXT; }
1262 case 0x53: {
int c = bit_N_R<2,E>();
NEXT; }
1263 case 0x54: {
int c = bit_N_R<2,H>();
NEXT; }
1264 case 0x55: {
int c = bit_N_R<2,L>();
NEXT; }
1265 case 0x57: {
int c = bit_N_R<2,A>();
NEXT; }
1266 case 0x58: {
int c = bit_N_R<3,B>();
NEXT; }
1267 case 0x59: {
int c = bit_N_R<3,C>();
NEXT; }
1268 case 0x5a: {
int c = bit_N_R<3,D>();
NEXT; }
1269 case 0x5b: {
int c = bit_N_R<3,E>();
NEXT; }
1270 case 0x5c: {
int c = bit_N_R<3,H>();
NEXT; }
1271 case 0x5d: {
int c = bit_N_R<3,L>();
NEXT; }
1272 case 0x5f: {
int c = bit_N_R<3,A>();
NEXT; }
1273 case 0x60: {
int c = bit_N_R<4,B>();
NEXT; }
1274 case 0x61: {
int c = bit_N_R<4,C>();
NEXT; }
1275 case 0x62: {
int c = bit_N_R<4,D>();
NEXT; }
1276 case 0x63: {
int c = bit_N_R<4,E>();
NEXT; }
1277 case 0x64: {
int c = bit_N_R<4,H>();
NEXT; }
1278 case 0x65: {
int c = bit_N_R<4,L>();
NEXT; }
1279 case 0x67: {
int c = bit_N_R<4,A>();
NEXT; }
1280 case 0x68: {
int c = bit_N_R<5,B>();
NEXT; }
1281 case 0x69: {
int c = bit_N_R<5,C>();
NEXT; }
1282 case 0x6a: {
int c = bit_N_R<5,D>();
NEXT; }
1283 case 0x6b: {
int c = bit_N_R<5,E>();
NEXT; }
1284 case 0x6c: {
int c = bit_N_R<5,H>();
NEXT; }
1285 case 0x6d: {
int c = bit_N_R<5,L>();
NEXT; }
1286 case 0x6f: {
int c = bit_N_R<5,A>();
NEXT; }
1287 case 0x70: {
int c = bit_N_R<6,B>();
NEXT; }
1288 case 0x71: {
int c = bit_N_R<6,C>();
NEXT; }
1289 case 0x72: {
int c = bit_N_R<6,D>();
NEXT; }
1290 case 0x73: {
int c = bit_N_R<6,E>();
NEXT; }
1291 case 0x74: {
int c = bit_N_R<6,H>();
NEXT; }
1292 case 0x75: {
int c = bit_N_R<6,L>();
NEXT; }
1293 case 0x77: {
int c = bit_N_R<6,A>();
NEXT; }
1294 case 0x78: {
int c = bit_N_R<7,B>();
NEXT; }
1295 case 0x79: {
int c = bit_N_R<7,C>();
NEXT; }
1296 case 0x7a: {
int c = bit_N_R<7,D>();
NEXT; }
1297 case 0x7b: {
int c = bit_N_R<7,E>();
NEXT; }
1298 case 0x7c: {
int c = bit_N_R<7,H>();
NEXT; }
1299 case 0x7d: {
int c = bit_N_R<7,L>();
NEXT; }
1300 case 0x7f: {
int c = bit_N_R<7,A>();
NEXT; }
1301 case 0x46: {
int c = bit_N_xhl<0>();
NEXT; }
1302 case 0x4e: {
int c = bit_N_xhl<1>();
NEXT; }
1303 case 0x56: {
int c = bit_N_xhl<2>();
NEXT; }
1304 case 0x5e: {
int c = bit_N_xhl<3>();
NEXT; }
1305 case 0x66: {
int c = bit_N_xhl<4>();
NEXT; }
1306 case 0x6e: {
int c = bit_N_xhl<5>();
NEXT; }
1307 case 0x76: {
int c = bit_N_xhl<6>();
NEXT; }
1308 case 0x7e: {
int c = bit_N_xhl<7>();
NEXT; }
1310 case 0x80: {
int c = res_N_R<0,B>();
NEXT; }
1311 case 0x81: {
int c = res_N_R<0,C>();
NEXT; }
1312 case 0x82: {
int c = res_N_R<0,D>();
NEXT; }
1313 case 0x83: {
int c = res_N_R<0,E>();
NEXT; }
1314 case 0x84: {
int c = res_N_R<0,H>();
NEXT; }
1315 case 0x85: {
int c = res_N_R<0,L>();
NEXT; }
1316 case 0x87: {
int c = res_N_R<0,A>();
NEXT; }
1317 case 0x88: {
int c = res_N_R<1,B>();
NEXT; }
1318 case 0x89: {
int c = res_N_R<1,C>();
NEXT; }
1319 case 0x8a: {
int c = res_N_R<1,D>();
NEXT; }
1320 case 0x8b: {
int c = res_N_R<1,E>();
NEXT; }
1321 case 0x8c: {
int c = res_N_R<1,H>();
NEXT; }
1322 case 0x8d: {
int c = res_N_R<1,L>();
NEXT; }
1323 case 0x8f: {
int c = res_N_R<1,A>();
NEXT; }
1324 case 0x90: {
int c = res_N_R<2,B>();
NEXT; }
1325 case 0x91: {
int c = res_N_R<2,C>();
NEXT; }
1326 case 0x92: {
int c = res_N_R<2,D>();
NEXT; }
1327 case 0x93: {
int c = res_N_R<2,E>();
NEXT; }
1328 case 0x94: {
int c = res_N_R<2,H>();
NEXT; }
1329 case 0x95: {
int c = res_N_R<2,L>();
NEXT; }
1330 case 0x97: {
int c = res_N_R<2,A>();
NEXT; }
1331 case 0x98: {
int c = res_N_R<3,B>();
NEXT; }
1332 case 0x99: {
int c = res_N_R<3,C>();
NEXT; }
1333 case 0x9a: {
int c = res_N_R<3,D>();
NEXT; }
1334 case 0x9b: {
int c = res_N_R<3,E>();
NEXT; }
1335 case 0x9c: {
int c = res_N_R<3,H>();
NEXT; }
1336 case 0x9d: {
int c = res_N_R<3,L>();
NEXT; }
1337 case 0x9f: {
int c = res_N_R<3,A>();
NEXT; }
1338 case 0xa0: {
int c = res_N_R<4,B>();
NEXT; }
1339 case 0xa1: {
int c = res_N_R<4,C>();
NEXT; }
1340 case 0xa2: {
int c = res_N_R<4,D>();
NEXT; }
1341 case 0xa3: {
int c = res_N_R<4,E>();
NEXT; }
1342 case 0xa4: {
int c = res_N_R<4,H>();
NEXT; }
1343 case 0xa5: {
int c = res_N_R<4,L>();
NEXT; }
1344 case 0xa7: {
int c = res_N_R<4,A>();
NEXT; }
1345 case 0xa8: {
int c = res_N_R<5,B>();
NEXT; }
1346 case 0xa9: {
int c = res_N_R<5,C>();
NEXT; }
1347 case 0xaa: {
int c = res_N_R<5,D>();
NEXT; }
1348 case 0xab: {
int c = res_N_R<5,E>();
NEXT; }
1349 case 0xac: {
int c = res_N_R<5,H>();
NEXT; }
1350 case 0xad: {
int c = res_N_R<5,L>();
NEXT; }
1351 case 0xaf: {
int c = res_N_R<5,A>();
NEXT; }
1352 case 0xb0: {
int c = res_N_R<6,B>();
NEXT; }
1353 case 0xb1: {
int c = res_N_R<6,C>();
NEXT; }
1354 case 0xb2: {
int c = res_N_R<6,D>();
NEXT; }
1355 case 0xb3: {
int c = res_N_R<6,E>();
NEXT; }
1356 case 0xb4: {
int c = res_N_R<6,H>();
NEXT; }
1357 case 0xb5: {
int c = res_N_R<6,L>();
NEXT; }
1358 case 0xb7: {
int c = res_N_R<6,A>();
NEXT; }
1359 case 0xb8: {
int c = res_N_R<7,B>();
NEXT; }
1360 case 0xb9: {
int c = res_N_R<7,C>();
NEXT; }
1361 case 0xba: {
int c = res_N_R<7,D>();
NEXT; }
1362 case 0xbb: {
int c = res_N_R<7,E>();
NEXT; }
1363 case 0xbc: {
int c = res_N_R<7,H>();
NEXT; }
1364 case 0xbd: {
int c = res_N_R<7,L>();
NEXT; }
1365 case 0xbf: {
int c = res_N_R<7,A>();
NEXT; }
1366 case 0x86: {
int c = res_N_xhl<0>();
NEXT; }
1367 case 0x8e: {
int c = res_N_xhl<1>();
NEXT; }
1368 case 0x96: {
int c = res_N_xhl<2>();
NEXT; }
1369 case 0x9e: {
int c = res_N_xhl<3>();
NEXT; }
1370 case 0xa6: {
int c = res_N_xhl<4>();
NEXT; }
1371 case 0xae: {
int c = res_N_xhl<5>();
NEXT; }
1372 case 0xb6: {
int c = res_N_xhl<6>();
NEXT; }
1373 case 0xbe: {
int c = res_N_xhl<7>();
NEXT; }
1375 case 0xc0: {
int c = set_N_R<0,B>();
NEXT; }
1376 case 0xc1: {
int c = set_N_R<0,C>();
NEXT; }
1377 case 0xc2: {
int c = set_N_R<0,D>();
NEXT; }
1378 case 0xc3: {
int c = set_N_R<0,E>();
NEXT; }
1379 case 0xc4: {
int c = set_N_R<0,H>();
NEXT; }
1380 case 0xc5: {
int c = set_N_R<0,L>();
NEXT; }
1381 case 0xc7: {
int c = set_N_R<0,A>();
NEXT; }
1382 case 0xc8: {
int c = set_N_R<1,B>();
NEXT; }
1383 case 0xc9: {
int c = set_N_R<1,C>();
NEXT; }
1384 case 0xca: {
int c = set_N_R<1,D>();
NEXT; }
1385 case 0xcb: {
int c = set_N_R<1,E>();
NEXT; }
1386 case 0xcc: {
int c = set_N_R<1,H>();
NEXT; }
1387 case 0xcd: {
int c = set_N_R<1,L>();
NEXT; }
1388 case 0xcf: {
int c = set_N_R<1,A>();
NEXT; }
1389 case 0xd0: {
int c = set_N_R<2,B>();
NEXT; }
1390 case 0xd1: {
int c = set_N_R<2,C>();
NEXT; }
1391 case 0xd2: {
int c = set_N_R<2,D>();
NEXT; }
1392 case 0xd3: {
int c = set_N_R<2,E>();
NEXT; }
1393 case 0xd4: {
int c = set_N_R<2,H>();
NEXT; }
1394 case 0xd5: {
int c = set_N_R<2,L>();
NEXT; }
1395 case 0xd7: {
int c = set_N_R<2,A>();
NEXT; }
1396 case 0xd8: {
int c = set_N_R<3,B>();
NEXT; }
1397 case 0xd9: {
int c = set_N_R<3,C>();
NEXT; }
1398 case 0xda: {
int c = set_N_R<3,D>();
NEXT; }
1399 case 0xdb: {
int c = set_N_R<3,E>();
NEXT; }
1400 case 0xdc: {
int c = set_N_R<3,H>();
NEXT; }
1401 case 0xdd: {
int c = set_N_R<3,L>();
NEXT; }
1402 case 0xdf: {
int c = set_N_R<3,A>();
NEXT; }
1403 case 0xe0: {
int c = set_N_R<4,B>();
NEXT; }
1404 case 0xe1: {
int c = set_N_R<4,C>();
NEXT; }
1405 case 0xe2: {
int c = set_N_R<4,D>();
NEXT; }
1406 case 0xe3: {
int c = set_N_R<4,E>();
NEXT; }
1407 case 0xe4: {
int c = set_N_R<4,H>();
NEXT; }
1408 case 0xe5: {
int c = set_N_R<4,L>();
NEXT; }
1409 case 0xe7: {
int c = set_N_R<4,A>();
NEXT; }
1410 case 0xe8: {
int c = set_N_R<5,B>();
NEXT; }
1411 case 0xe9: {
int c = set_N_R<5,C>();
NEXT; }
1412 case 0xea: {
int c = set_N_R<5,D>();
NEXT; }
1413 case 0xeb: {
int c = set_N_R<5,E>();
NEXT; }
1414 case 0xec: {
int c = set_N_R<5,H>();
NEXT; }
1415 case 0xed: {
int c = set_N_R<5,L>();
NEXT; }
1416 case 0xef: {
int c = set_N_R<5,A>();
NEXT; }
1417 case 0xf0: {
int c = set_N_R<6,B>();
NEXT; }
1418 case 0xf1: {
int c = set_N_R<6,C>();
NEXT; }
1419 case 0xf2: {
int c = set_N_R<6,D>();
NEXT; }
1420 case 0xf3: {
int c = set_N_R<6,E>();
NEXT; }
1421 case 0xf4: {
int c = set_N_R<6,H>();
NEXT; }
1422 case 0xf5: {
int c = set_N_R<6,L>();
NEXT; }
1423 case 0xf7: {
int c = set_N_R<6,A>();
NEXT; }
1424 case 0xf8: {
int c = set_N_R<7,B>();
NEXT; }
1425 case 0xf9: {
int c = set_N_R<7,C>();
NEXT; }
1426 case 0xfa: {
int c = set_N_R<7,D>();
NEXT; }
1427 case 0xfb: {
int c = set_N_R<7,E>();
NEXT; }
1428 case 0xfc: {
int c = set_N_R<7,H>();
NEXT; }
1429 case 0xfd: {
int c = set_N_R<7,L>();
NEXT; }
1430 case 0xff: {
int c = set_N_R<7,A>();
NEXT; }
1431 case 0xc6: {
int c = set_N_xhl<0>();
NEXT; }
1432 case 0xce: {
int c = set_N_xhl<1>();
NEXT; }
1433 case 0xd6: {
int c = set_N_xhl<2>();
NEXT; }
1434 case 0xde: {
int c = set_N_xhl<3>();
NEXT; }
1435 case 0xe6: {
int c = set_N_xhl<4>();
NEXT; }
1436 case 0xee: {
int c = set_N_xhl<5>();
NEXT; }
1437 case 0xf6: {
int c = set_N_xhl<6>();
NEXT; }
1438 case 0xfe: {
int c = set_N_xhl<7>();
NEXT; }
1443 byte ed_opcode = RDMEM_OPCODE(T::CC_PREFIX);
1445 switch (ed_opcode) {
1446 case 0x00:
case 0x01:
case 0x02:
case 0x03:
1447 case 0x04:
case 0x05:
case 0x06:
case 0x07:
1448 case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
1449 case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
1450 case 0x10:
case 0x11:
case 0x12:
case 0x13:
1451 case 0x14:
case 0x15:
case 0x16:
case 0x17:
1452 case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
1453 case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f:
1454 case 0x20:
case 0x21:
case 0x22:
case 0x23:
1455 case 0x24:
case 0x25:
case 0x26:
case 0x27:
1456 case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
1457 case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
1458 case 0x30:
case 0x31:
case 0x32:
case 0x33:
1459 case 0x34:
case 0x35:
case 0x36:
case 0x37:
1460 case 0x38:
case 0x39:
case 0x3a:
case 0x3b:
1461 case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
1463 case 0x77:
case 0x7f:
1465 case 0x80:
case 0x81:
case 0x82:
case 0x83:
1466 case 0x84:
case 0x85:
case 0x86:
case 0x87:
1467 case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
1468 case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
1469 case 0x90:
case 0x91:
case 0x92:
case 0x93:
1470 case 0x94:
case 0x95:
case 0x96:
case 0x97:
1471 case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
1472 case 0x9c:
case 0x9d:
case 0x9e:
case 0x9f:
1473 case 0xa4:
case 0xa5:
case 0xa6:
case 0xa7:
1474 case 0xac:
case 0xad:
case 0xae:
case 0xaf:
1475 case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
1476 case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
1478 case 0xc0:
case 0xc2:
1479 case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
1480 case 0xc8:
case 0xca:
case 0xcb:
1481 case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
1482 case 0xd0:
case 0xd2:
case 0xd3:
1483 case 0xd4:
case 0xd5:
case 0xd6:
case 0xd7:
1484 case 0xd8:
case 0xda:
case 0xdb:
1485 case 0xdc:
case 0xdd:
case 0xde:
case 0xdf:
1486 case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
1487 case 0xe4:
case 0xe5:
case 0xe6:
case 0xe7:
1488 case 0xe8:
case 0xe9:
case 0xea:
case 0xeb:
1489 case 0xec:
case 0xed:
case 0xee:
case 0xef:
1490 case 0xf0:
case 0xf1:
case 0xf2:
1491 case 0xf4:
case 0xf5:
case 0xf6:
case 0xf7:
1492 case 0xf8:
case 0xf9:
case 0xfa:
case 0xfb:
1493 case 0xfc:
case 0xfd:
case 0xfe:
case 0xff:
1494 {
int c = nop();
NEXT; }
1496 case 0x40: {
int c = in_R_c<B>();
NEXT; }
1497 case 0x48: {
int c = in_R_c<C>();
NEXT; }
1498 case 0x50: {
int c = in_R_c<D>();
NEXT; }
1499 case 0x58: {
int c = in_R_c<E>();
NEXT; }
1500 case 0x60: {
int c = in_R_c<H>();
NEXT; }
1501 case 0x68: {
int c = in_R_c<L>();
NEXT; }
1502 case 0x70: {
int c = in_R_c<DUMMY>();
NEXT; }
1503 case 0x78: {
int c = in_R_c<A>();
NEXT; }
1505 case 0x41: {
int c = out_c_R<B>();
NEXT; }
1506 case 0x49: {
int c = out_c_R<C>();
NEXT; }
1507 case 0x51: {
int c = out_c_R<D>();
NEXT; }
1508 case 0x59: {
int c = out_c_R<E>();
NEXT; }
1509 case 0x61: {
int c = out_c_R<H>();
NEXT; }
1510 case 0x69: {
int c = out_c_R<L>();
NEXT; }
1511 case 0x71: {
int c = out_c_0();
NEXT; }
1512 case 0x79: {
int c = out_c_R<A>();
NEXT; }
1514 case 0x42: {
int c = sbc_hl_SS<BC>();
NEXT; }
1515 case 0x52: {
int c = sbc_hl_SS<DE>();
NEXT; }
1516 case 0x62: {
int c = sbc_hl_hl ();
NEXT; }
1517 case 0x72: {
int c = sbc_hl_SS<SP>();
NEXT; }
1519 case 0x4a: {
int c = adc_hl_SS<BC>();
NEXT; }
1520 case 0x5a: {
int c = adc_hl_SS<DE>();
NEXT; }
1521 case 0x6a: {
int c = adc_hl_hl ();
NEXT; }
1522 case 0x7a: {
int c = adc_hl_SS<SP>();
NEXT; }
1524 case 0x43: {
int c = ld_xword_SS_ED<BC>();
NEXT; }
1525 case 0x53: {
int c = ld_xword_SS_ED<DE>();
NEXT; }
1526 case 0x63: {
int c = ld_xword_SS_ED<HL>();
NEXT; }
1527 case 0x73: {
int c = ld_xword_SS_ED<SP>();
NEXT; }
1529 case 0x4b: {
int c = ld_SS_xword_ED<BC>();
NEXT; }
1530 case 0x5b: {
int c = ld_SS_xword_ED<DE>();
NEXT; }
1531 case 0x6b: {
int c = ld_SS_xword_ED<HL>();
NEXT; }
1532 case 0x7b: {
int c = ld_SS_xword_ED<SP>();
NEXT; }
1534 case 0x47: {
int c = ld_i_a();
NEXT; }
1535 case 0x4f: {
int c = ld_r_a();
NEXT; }
1536 case 0x57: {
int c = ld_a_IR<REG_I>();
if (T::isR800()) {
NEXT; }
else {
NEXT_STOP; }}
1537 case 0x5f: {
int c = ld_a_IR<REG_R>();
if (T::isR800()) {
NEXT; }
else {
NEXT_STOP; }}
1539 case 0x67: {
int c = rrd();
NEXT; }
1540 case 0x6f: {
int c = rld();
NEXT; }
1542 case 0x45:
case 0x4d:
case 0x55:
case 0x5d:
1543 case 0x65:
case 0x6d:
case 0x75:
case 0x7d:
1545 case 0x46:
case 0x4e:
case 0x66:
case 0x6e:
1546 {
int c = im_N<0>();
NEXT; }
1547 case 0x56:
case 0x76:
1548 {
int c = im_N<1>();
NEXT; }
1549 case 0x5e:
case 0x7e:
1550 {
int c = im_N<2>();
NEXT; }
1551 case 0x44:
case 0x4c:
case 0x54:
case 0x5c:
1552 case 0x64:
case 0x6c:
case 0x74:
case 0x7c:
1553 {
int c = neg();
NEXT; }
1555 case 0xa0: {
int c = ldi();
NEXT; }
1556 case 0xa1: {
int c = cpi();
NEXT; }
1557 case 0xa2: {
int c = ini();
NEXT; }
1558 case 0xa3: {
int c = outi();
NEXT; }
1559 case 0xa8: {
int c = ldd();
NEXT; }
1560 case 0xa9: {
int c = cpd();
NEXT; }
1561 case 0xaa: {
int c = ind();
NEXT; }
1562 case 0xab: {
int c = outd();
NEXT; }
1563 case 0xb0: {
int c = ldir();
NEXT; }
1564 case 0xb1: {
int c = cpir();
NEXT; }
1565 case 0xb2: {
int c = inir();
NEXT; }
1566 case 0xb3: {
int c = otir();
NEXT; }
1567 case 0xb8: {
int c = lddr();
NEXT; }
1568 case 0xb9: {
int c = cpdr();
NEXT; }
1569 case 0xba: {
int c = indr();
NEXT; }
1570 case 0xbb: {
int c = otdr();
NEXT; }
1572 case 0xc1: {
int c = T::isR800() ? mulub_a_R<B>() : nop();
NEXT; }
1573 case 0xc9: {
int c = T::isR800() ? mulub_a_R<C>() : nop();
NEXT; }
1574 case 0xd1: {
int c = T::isR800() ? mulub_a_R<D>() : nop();
NEXT; }
1575 case 0xd9: {
int c = T::isR800() ? mulub_a_R<E>() : nop();
NEXT; }
1576 case 0xc3: {
int c = T::isR800() ? muluw_hl_SS<BC>() : nop();
NEXT; }
1577 case 0xf3: {
int c = T::isR800() ? muluw_hl_SS<SP>() : nop();
NEXT; }
1583 byte opcodeDD = RDMEM_OPCODE(T::CC_DD + T::CC_MAIN);
1760 int c = T::CC_DD + nop();
NEXT;
1763 #ifdef USE_COMPUTED_GOTO
1764 goto *(opcodeTable[opcodeDD]);
1766 opcodeMain = opcodeDD;
1771 case 0x09: {
int c = add_SS_TT<IX,BC,T::CC_DD>();
NEXT; }
1772 case 0x19: {
int c = add_SS_TT<IX,DE,T::CC_DD>();
NEXT; }
1773 case 0x29: {
int c = add_SS_SS<IX ,T::CC_DD>();
NEXT; }
1774 case 0x39: {
int c = add_SS_TT<IX,SP,T::CC_DD>();
NEXT; }
1775 case 0x21: {
int c = ld_SS_word<IX,T::CC_DD>();
NEXT; }
1776 case 0x22: {
int c = ld_xword_SS<IX,T::CC_DD>();
NEXT; }
1777 case 0x2a: {
int c = ld_SS_xword<IX,T::CC_DD>();
NEXT; }
1778 case 0x23: {
int c = inc_SS<IX,T::CC_DD>();
NEXT; }
1779 case 0x2b: {
int c = dec_SS<IX,T::CC_DD>();
NEXT; }
1780 case 0x24: {
int c = inc_R<IXH,T::CC_DD>();
NEXT; }
1781 case 0x2c: {
int c = inc_R<IXL,T::CC_DD>();
NEXT; }
1782 case 0x25: {
int c = dec_R<IXH,T::CC_DD>();
NEXT; }
1783 case 0x2d: {
int c = dec_R<IXL,T::CC_DD>();
NEXT; }
1784 case 0x26: {
int c = ld_R_byte<IXH,T::CC_DD>();
NEXT; }
1785 case 0x2e: {
int c = ld_R_byte<IXL,T::CC_DD>();
NEXT; }
1786 case 0x34: {
int c = inc_xix<IX>();
NEXT; }
1787 case 0x35: {
int c = dec_xix<IX>();
NEXT; }
1788 case 0x36: {
int c = ld_xix_byte<IX>();
NEXT; }
1790 case 0x44: {
int c = ld_R_R<B,IXH,T::CC_DD>();
NEXT; }
1791 case 0x45: {
int c = ld_R_R<B,IXL,T::CC_DD>();
NEXT; }
1792 case 0x4c: {
int c = ld_R_R<C,IXH,T::CC_DD>();
NEXT; }
1793 case 0x4d: {
int c = ld_R_R<C,IXL,T::CC_DD>();
NEXT; }
1794 case 0x54: {
int c = ld_R_R<D,IXH,T::CC_DD>();
NEXT; }
1795 case 0x55: {
int c = ld_R_R<D,IXL,T::CC_DD>();
NEXT; }
1796 case 0x5c: {
int c = ld_R_R<E,IXH,T::CC_DD>();
NEXT; }
1797 case 0x5d: {
int c = ld_R_R<E,IXL,T::CC_DD>();
NEXT; }
1798 case 0x7c: {
int c = ld_R_R<A,IXH,T::CC_DD>();
NEXT; }
1799 case 0x7d: {
int c = ld_R_R<A,IXL,T::CC_DD>();
NEXT; }
1800 case 0x60: {
int c = ld_R_R<IXH,B,T::CC_DD>();
NEXT; }
1801 case 0x61: {
int c = ld_R_R<IXH,C,T::CC_DD>();
NEXT; }
1802 case 0x62: {
int c = ld_R_R<IXH,D,T::CC_DD>();
NEXT; }
1803 case 0x63: {
int c = ld_R_R<IXH,E,T::CC_DD>();
NEXT; }
1804 case 0x65: {
int c = ld_R_R<IXH,IXL,T::CC_DD>();
NEXT; }
1805 case 0x67: {
int c = ld_R_R<IXH,A,T::CC_DD>();
NEXT; }
1806 case 0x68: {
int c = ld_R_R<IXL,B,T::CC_DD>();
NEXT; }
1807 case 0x69: {
int c = ld_R_R<IXL,C,T::CC_DD>();
NEXT; }
1808 case 0x6a: {
int c = ld_R_R<IXL,D,T::CC_DD>();
NEXT; }
1809 case 0x6b: {
int c = ld_R_R<IXL,E,T::CC_DD>();
NEXT; }
1810 case 0x6c: {
int c = ld_R_R<IXL,IXH,T::CC_DD>();
NEXT; }
1811 case 0x6f: {
int c = ld_R_R<IXL,A,T::CC_DD>();
NEXT; }
1812 case 0x70: {
int c = ld_xix_R<IX,B>();
NEXT; }
1813 case 0x71: {
int c = ld_xix_R<IX,C>();
NEXT; }
1814 case 0x72: {
int c = ld_xix_R<IX,D>();
NEXT; }
1815 case 0x73: {
int c = ld_xix_R<IX,E>();
NEXT; }
1816 case 0x74: {
int c = ld_xix_R<IX,H>();
NEXT; }
1817 case 0x75: {
int c = ld_xix_R<IX,L>();
NEXT; }
1818 case 0x77: {
int c = ld_xix_R<IX,A>();
NEXT; }
1819 case 0x46: {
int c = ld_R_xix<B,IX>();
NEXT; }
1820 case 0x4e: {
int c = ld_R_xix<C,IX>();
NEXT; }
1821 case 0x56: {
int c = ld_R_xix<D,IX>();
NEXT; }
1822 case 0x5e: {
int c = ld_R_xix<E,IX>();
NEXT; }
1823 case 0x66: {
int c = ld_R_xix<H,IX>();
NEXT; }
1824 case 0x6e: {
int c = ld_R_xix<L,IX>();
NEXT; }
1825 case 0x7e: {
int c = ld_R_xix<A,IX>();
NEXT; }
1827 case 0x84: {
int c = add_a_R<IXH,T::CC_DD>();
NEXT; }
1828 case 0x85: {
int c = add_a_R<IXL,T::CC_DD>();
NEXT; }
1829 case 0x86: {
int c = add_a_xix<IX>();
NEXT; }
1830 case 0x8c: {
int c = adc_a_R<IXH,T::CC_DD>();
NEXT; }
1831 case 0x8d: {
int c = adc_a_R<IXL,T::CC_DD>();
NEXT; }
1832 case 0x8e: {
int c = adc_a_xix<IX>();
NEXT; }
1833 case 0x94: {
int c = sub_R<IXH,T::CC_DD>();
NEXT; }
1834 case 0x95: {
int c = sub_R<IXL,T::CC_DD>();
NEXT; }
1835 case 0x96: {
int c = sub_xix<IX>();
NEXT; }
1836 case 0x9c: {
int c = sbc_a_R<IXH,T::CC_DD>();
NEXT; }
1837 case 0x9d: {
int c = sbc_a_R<IXL,T::CC_DD>();
NEXT; }
1838 case 0x9e: {
int c = sbc_a_xix<IX>();
NEXT; }
1839 case 0xa4: {
int c = and_R<IXH,T::CC_DD>();
NEXT; }
1840 case 0xa5: {
int c = and_R<IXL,T::CC_DD>();
NEXT; }
1841 case 0xa6: {
int c = and_xix<IX>();
NEXT; }
1842 case 0xac: {
int c = xor_R<IXH,T::CC_DD>();
NEXT; }
1843 case 0xad: {
int c = xor_R<IXL,T::CC_DD>();
NEXT; }
1844 case 0xae: {
int c = xor_xix<IX>();
NEXT; }
1845 case 0xb4: {
int c = or_R<IXH,T::CC_DD>();
NEXT; }
1846 case 0xb5: {
int c = or_R<IXL,T::CC_DD>();
NEXT; }
1847 case 0xb6: {
int c = or_xix<IX>();
NEXT; }
1848 case 0xbc: {
int c = cp_R<IXH,T::CC_DD>();
NEXT; }
1849 case 0xbd: {
int c = cp_R<IXL,T::CC_DD>();
NEXT; }
1850 case 0xbe: {
int c = cp_xix<IX>();
NEXT; }
1852 case 0xe1: {
int c = pop_SS <IX,T::CC_DD>();
NEXT; }
1853 case 0xe5: {
int c = push_SS<IX,T::CC_DD>();
NEXT; }
1854 case 0xe3: {
int c = ex_xsp_SS<IX,T::CC_DD>();
NEXT; }
1855 case 0xe9: {
int c = jp_SS<IX,T::CC_DD>();
NEXT; }
1856 case 0xf9: {
int c = ld_sp_SS<IX,T::CC_DD>();
NEXT; }
1857 case 0xcb: ixy = R.getIX();
goto xx_cb;
1858 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
1859 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
1865 byte opcodeFD = RDMEM_OPCODE(T::CC_DD + T::CC_MAIN);
2042 int c = T::CC_DD + nop();
NEXT;
2045 #ifdef USE_COMPUTED_GOTO
2046 goto *(opcodeTable[opcodeFD]);
2048 opcodeMain = opcodeFD;
2053 case 0x09: {
int c = add_SS_TT<IY,BC,T::CC_DD>();
NEXT; }
2054 case 0x19: {
int c = add_SS_TT<IY,DE,T::CC_DD>();
NEXT; }
2055 case 0x29: {
int c = add_SS_SS<IY ,T::CC_DD>();
NEXT; }
2056 case 0x39: {
int c = add_SS_TT<IY,SP,T::CC_DD>();
NEXT; }
2057 case 0x21: {
int c = ld_SS_word<IY,T::CC_DD>();
NEXT; }
2058 case 0x22: {
int c = ld_xword_SS<IY,T::CC_DD>();
NEXT; }
2059 case 0x2a: {
int c = ld_SS_xword<IY,T::CC_DD>();
NEXT; }
2060 case 0x23: {
int c = inc_SS<IY,T::CC_DD>();
NEXT; }
2061 case 0x2b: {
int c = dec_SS<IY,T::CC_DD>();
NEXT; }
2062 case 0x24: {
int c = inc_R<IYH,T::CC_DD>();
NEXT; }
2063 case 0x2c: {
int c = inc_R<IYL,T::CC_DD>();
NEXT; }
2064 case 0x25: {
int c = dec_R<IYH,T::CC_DD>();
NEXT; }
2065 case 0x2d: {
int c = dec_R<IYL,T::CC_DD>();
NEXT; }
2066 case 0x26: {
int c = ld_R_byte<IYH,T::CC_DD>();
NEXT; }
2067 case 0x2e: {
int c = ld_R_byte<IYL,T::CC_DD>();
NEXT; }
2068 case 0x34: {
int c = inc_xix<IY>();
NEXT; }
2069 case 0x35: {
int c = dec_xix<IY>();
NEXT; }
2070 case 0x36: {
int c = ld_xix_byte<IY>();
NEXT; }
2072 case 0x44: {
int c = ld_R_R<B,IYH,T::CC_DD>();
NEXT; }
2073 case 0x45: {
int c = ld_R_R<B,IYL,T::CC_DD>();
NEXT; }
2074 case 0x4c: {
int c = ld_R_R<C,IYH,T::CC_DD>();
NEXT; }
2075 case 0x4d: {
int c = ld_R_R<C,IYL,T::CC_DD>();
NEXT; }
2076 case 0x54: {
int c = ld_R_R<D,IYH,T::CC_DD>();
NEXT; }
2077 case 0x55: {
int c = ld_R_R<D,IYL,T::CC_DD>();
NEXT; }
2078 case 0x5c: {
int c = ld_R_R<E,IYH,T::CC_DD>();
NEXT; }
2079 case 0x5d: {
int c = ld_R_R<E,IYL,T::CC_DD>();
NEXT; }
2080 case 0x7c: {
int c = ld_R_R<A,IYH,T::CC_DD>();
NEXT; }
2081 case 0x7d: {
int c = ld_R_R<A,IYL,T::CC_DD>();
NEXT; }
2082 case 0x60: {
int c = ld_R_R<IYH,B,T::CC_DD>();
NEXT; }
2083 case 0x61: {
int c = ld_R_R<IYH,C,T::CC_DD>();
NEXT; }
2084 case 0x62: {
int c = ld_R_R<IYH,D,T::CC_DD>();
NEXT; }
2085 case 0x63: {
int c = ld_R_R<IYH,E,T::CC_DD>();
NEXT; }
2086 case 0x65: {
int c = ld_R_R<IYH,IYL,T::CC_DD>();
NEXT; }
2087 case 0x67: {
int c = ld_R_R<IYH,A,T::CC_DD>();
NEXT; }
2088 case 0x68: {
int c = ld_R_R<IYL,B,T::CC_DD>();
NEXT; }
2089 case 0x69: {
int c = ld_R_R<IYL,C,T::CC_DD>();
NEXT; }
2090 case 0x6a: {
int c = ld_R_R<IYL,D,T::CC_DD>();
NEXT; }
2091 case 0x6b: {
int c = ld_R_R<IYL,E,T::CC_DD>();
NEXT; }
2092 case 0x6c: {
int c = ld_R_R<IYL,IYH,T::CC_DD>();
NEXT; }
2093 case 0x6f: {
int c = ld_R_R<IYL,A,T::CC_DD>();
NEXT; }
2094 case 0x70: {
int c = ld_xix_R<IY,B>();
NEXT; }
2095 case 0x71: {
int c = ld_xix_R<IY,C>();
NEXT; }
2096 case 0x72: {
int c = ld_xix_R<IY,D>();
NEXT; }
2097 case 0x73: {
int c = ld_xix_R<IY,E>();
NEXT; }
2098 case 0x74: {
int c = ld_xix_R<IY,H>();
NEXT; }
2099 case 0x75: {
int c = ld_xix_R<IY,L>();
NEXT; }
2100 case 0x77: {
int c = ld_xix_R<IY,A>();
NEXT; }
2101 case 0x46: {
int c = ld_R_xix<B,IY>();
NEXT; }
2102 case 0x4e: {
int c = ld_R_xix<C,IY>();
NEXT; }
2103 case 0x56: {
int c = ld_R_xix<D,IY>();
NEXT; }
2104 case 0x5e: {
int c = ld_R_xix<E,IY>();
NEXT; }
2105 case 0x66: {
int c = ld_R_xix<H,IY>();
NEXT; }
2106 case 0x6e: {
int c = ld_R_xix<L,IY>();
NEXT; }
2107 case 0x7e: {
int c = ld_R_xix<A,IY>();
NEXT; }
2109 case 0x84: {
int c = add_a_R<IYH,T::CC_DD>();
NEXT; }
2110 case 0x85: {
int c = add_a_R<IYL,T::CC_DD>();
NEXT; }
2111 case 0x86: {
int c = add_a_xix<IY>();
NEXT; }
2112 case 0x8c: {
int c = adc_a_R<IYH,T::CC_DD>();
NEXT; }
2113 case 0x8d: {
int c = adc_a_R<IYL,T::CC_DD>();
NEXT; }
2114 case 0x8e: {
int c = adc_a_xix<IY>();
NEXT; }
2115 case 0x94: {
int c = sub_R<IYH,T::CC_DD>();
NEXT; }
2116 case 0x95: {
int c = sub_R<IYL,T::CC_DD>();
NEXT; }
2117 case 0x96: {
int c = sub_xix<IY>();
NEXT; }
2118 case 0x9c: {
int c = sbc_a_R<IYH,T::CC_DD>();
NEXT; }
2119 case 0x9d: {
int c = sbc_a_R<IYL,T::CC_DD>();
NEXT; }
2120 case 0x9e: {
int c = sbc_a_xix<IY>();
NEXT; }
2121 case 0xa4: {
int c = and_R<IYH,T::CC_DD>();
NEXT; }
2122 case 0xa5: {
int c = and_R<IYL,T::CC_DD>();
NEXT; }
2123 case 0xa6: {
int c = and_xix<IY>();
NEXT; }
2124 case 0xac: {
int c = xor_R<IYH,T::CC_DD>();
NEXT; }
2125 case 0xad: {
int c = xor_R<IYL,T::CC_DD>();
NEXT; }
2126 case 0xae: {
int c = xor_xix<IY>();
NEXT; }
2127 case 0xb4: {
int c = or_R<IYH,T::CC_DD>();
NEXT; }
2128 case 0xb5: {
int c = or_R<IYL,T::CC_DD>();
NEXT; }
2129 case 0xb6: {
int c = or_xix<IY>();
NEXT; }
2130 case 0xbc: {
int c = cp_R<IYH,T::CC_DD>();
NEXT; }
2131 case 0xbd: {
int c = cp_R<IYL,T::CC_DD>();
NEXT; }
2132 case 0xbe: {
int c = cp_xix<IY>();
NEXT; }
2134 case 0xe1: {
int c = pop_SS <IY,T::CC_DD>();
NEXT; }
2135 case 0xe5: {
int c = push_SS<IY,T::CC_DD>();
NEXT; }
2136 case 0xe3: {
int c = ex_xsp_SS<IY,T::CC_DD>();
NEXT; }
2137 case 0xe9: {
int c = jp_SS<IY,T::CC_DD>();
NEXT; }
2138 case 0xf9: {
int c = ld_sp_SS<IY,T::CC_DD>();
NEXT; }
2139 case 0xcb: ixy = R.getIY();
goto xx_cb;
2140 case 0xdd: T::add(T::CC_DD);
goto opDD_2;
2141 case 0xfd: T::add(T::CC_DD);
goto opFD_2;
2145 #ifndef USE_COMPUTED_GOTO
2151 unsigned tmp = RD_WORD_PC(T::CC_DD + T::CC_DD_CB);
2152 offset ofst = tmp & 0xFF;
2153 unsigned addr = (ixy + ofst) & 0xFFFF;
2154 byte xxcb_opcode = tmp >> 8;
2155 switch (xxcb_opcode) {
2156 case 0x00: {
int c = rlc_xix_R<B>(addr);
NEXT; }
2157 case 0x01: {
int c = rlc_xix_R<C>(addr);
NEXT; }
2158 case 0x02: {
int c = rlc_xix_R<D>(addr);
NEXT; }
2159 case 0x03: {
int c = rlc_xix_R<E>(addr);
NEXT; }
2160 case 0x04: {
int c = rlc_xix_R<H>(addr);
NEXT; }
2161 case 0x05: {
int c = rlc_xix_R<L>(addr);
NEXT; }
2162 case 0x06: {
int c = rlc_xix_R<DUMMY>(addr);
NEXT; }
2163 case 0x07: {
int c = rlc_xix_R<A>(addr);
NEXT; }
2164 case 0x08: {
int c = rrc_xix_R<B>(addr);
NEXT; }
2165 case 0x09: {
int c = rrc_xix_R<C>(addr);
NEXT; }
2166 case 0x0a: {
int c = rrc_xix_R<D>(addr);
NEXT; }
2167 case 0x0b: {
int c = rrc_xix_R<E>(addr);
NEXT; }
2168 case 0x0c: {
int c = rrc_xix_R<H>(addr);
NEXT; }
2169 case 0x0d: {
int c = rrc_xix_R<L>(addr);
NEXT; }
2170 case 0x0e: {
int c = rrc_xix_R<DUMMY>(addr);
NEXT; }
2171 case 0x0f: {
int c = rrc_xix_R<A>(addr);
NEXT; }
2172 case 0x10: {
int c = rl_xix_R<B>(addr);
NEXT; }
2173 case 0x11: {
int c = rl_xix_R<C>(addr);
NEXT; }
2174 case 0x12: {
int c = rl_xix_R<D>(addr);
NEXT; }
2175 case 0x13: {
int c = rl_xix_R<E>(addr);
NEXT; }
2176 case 0x14: {
int c = rl_xix_R<H>(addr);
NEXT; }
2177 case 0x15: {
int c = rl_xix_R<L>(addr);
NEXT; }
2178 case 0x16: {
int c = rl_xix_R<DUMMY>(addr);
NEXT; }
2179 case 0x17: {
int c = rl_xix_R<A>(addr);
NEXT; }
2180 case 0x18: {
int c = rr_xix_R<B>(addr);
NEXT; }
2181 case 0x19: {
int c = rr_xix_R<C>(addr);
NEXT; }
2182 case 0x1a: {
int c = rr_xix_R<D>(addr);
NEXT; }
2183 case 0x1b: {
int c = rr_xix_R<E>(addr);
NEXT; }
2184 case 0x1c: {
int c = rr_xix_R<H>(addr);
NEXT; }
2185 case 0x1d: {
int c = rr_xix_R<L>(addr);
NEXT; }
2186 case 0x1e: {
int c = rr_xix_R<DUMMY>(addr);
NEXT; }
2187 case 0x1f: {
int c = rr_xix_R<A>(addr);
NEXT; }
2188 case 0x20: {
int c = sla_xix_R<B>(addr);
NEXT; }
2189 case 0x21: {
int c = sla_xix_R<C>(addr);
NEXT; }
2190 case 0x22: {
int c = sla_xix_R<D>(addr);
NEXT; }
2191 case 0x23: {
int c = sla_xix_R<E>(addr);
NEXT; }
2192 case 0x24: {
int c = sla_xix_R<H>(addr);
NEXT; }
2193 case 0x25: {
int c = sla_xix_R<L>(addr);
NEXT; }
2194 case 0x26: {
int c = sla_xix_R<DUMMY>(addr);
NEXT; }
2195 case 0x27: {
int c = sla_xix_R<A>(addr);
NEXT; }
2196 case 0x28: {
int c = sra_xix_R<B>(addr);
NEXT; }
2197 case 0x29: {
int c = sra_xix_R<C>(addr);
NEXT; }
2198 case 0x2a: {
int c = sra_xix_R<D>(addr);
NEXT; }
2199 case 0x2b: {
int c = sra_xix_R<E>(addr);
NEXT; }
2200 case 0x2c: {
int c = sra_xix_R<H>(addr);
NEXT; }
2201 case 0x2d: {
int c = sra_xix_R<L>(addr);
NEXT; }
2202 case 0x2e: {
int c = sra_xix_R<DUMMY>(addr);
NEXT; }
2203 case 0x2f: {
int c = sra_xix_R<A>(addr);
NEXT; }
2204 case 0x30: {
int c = T::isR800() ? sll2() : sll_xix_R<B>(addr);
NEXT; }
2205 case 0x31: {
int c = T::isR800() ? sll2() : sll_xix_R<C>(addr);
NEXT; }
2206 case 0x32: {
int c = T::isR800() ? sll2() : sll_xix_R<D>(addr);
NEXT; }
2207 case 0x33: {
int c = T::isR800() ? sll2() : sll_xix_R<E>(addr);
NEXT; }
2208 case 0x34: {
int c = T::isR800() ? sll2() : sll_xix_R<H>(addr);
NEXT; }
2209 case 0x35: {
int c = T::isR800() ? sll2() : sll_xix_R<L>(addr);
NEXT; }
2210 case 0x36: {
int c = T::isR800() ? sll2() : sll_xix_R<
DUMMY>(addr);
NEXT; }
2211 case 0x37: {
int c = T::isR800() ? sll2() : sll_xix_R<A>(addr);
NEXT; }
2212 case 0x38: {
int c = srl_xix_R<B>(addr);
NEXT; }
2213 case 0x39: {
int c = srl_xix_R<C>(addr);
NEXT; }
2214 case 0x3a: {
int c = srl_xix_R<D>(addr);
NEXT; }
2215 case 0x3b: {
int c = srl_xix_R<E>(addr);
NEXT; }
2216 case 0x3c: {
int c = srl_xix_R<H>(addr);
NEXT; }
2217 case 0x3d: {
int c = srl_xix_R<L>(addr);
NEXT; }
2218 case 0x3e: {
int c = srl_xix_R<DUMMY>(addr);
NEXT; }
2219 case 0x3f: {
int c = srl_xix_R<A>(addr);
NEXT; }
2221 case 0x40:
case 0x41:
case 0x42:
case 0x43:
2222 case 0x44:
case 0x45:
case 0x46:
case 0x47:
2223 {
int c = bit_N_xix<0>(addr);
NEXT; }
2224 case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
2225 case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
2226 {
int c = bit_N_xix<1>(addr);
NEXT; }
2227 case 0x50:
case 0x51:
case 0x52:
case 0x53:
2228 case 0x54:
case 0x55:
case 0x56:
case 0x57:
2229 {
int c = bit_N_xix<2>(addr);
NEXT; }
2230 case 0x58:
case 0x59:
case 0x5a:
case 0x5b:
2231 case 0x5c:
case 0x5d:
case 0x5e:
case 0x5f:
2232 {
int c = bit_N_xix<3>(addr);
NEXT; }
2233 case 0x60:
case 0x61:
case 0x62:
case 0x63:
2234 case 0x64:
case 0x65:
case 0x66:
case 0x67:
2235 {
int c = bit_N_xix<4>(addr);
NEXT; }
2236 case 0x68:
case 0x69:
case 0x6a:
case 0x6b:
2237 case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
2238 {
int c = bit_N_xix<5>(addr);
NEXT; }
2239 case 0x70:
case 0x71:
case 0x72:
case 0x73:
2240 case 0x74:
case 0x75:
case 0x76:
case 0x77:
2241 {
int c = bit_N_xix<6>(addr);
NEXT; }
2242 case 0x78:
case 0x79:
case 0x7a:
case 0x7b:
2243 case 0x7c:
case 0x7d:
case 0x7e:
case 0x7f:
2244 {
int c = bit_N_xix<7>(addr);
NEXT; }
2246 case 0x80: {
int c = res_N_xix_R<0,B>(addr);
NEXT; }
2247 case 0x81: {
int c = res_N_xix_R<0,C>(addr);
NEXT; }
2248 case 0x82: {
int c = res_N_xix_R<0,D>(addr);
NEXT; }
2249 case 0x83: {
int c = res_N_xix_R<0,E>(addr);
NEXT; }
2250 case 0x84: {
int c = res_N_xix_R<0,H>(addr);
NEXT; }
2251 case 0x85: {
int c = res_N_xix_R<0,L>(addr);
NEXT; }
2252 case 0x87: {
int c = res_N_xix_R<0,A>(addr);
NEXT; }
2253 case 0x88: {
int c = res_N_xix_R<1,B>(addr);
NEXT; }
2254 case 0x89: {
int c = res_N_xix_R<1,C>(addr);
NEXT; }
2255 case 0x8a: {
int c = res_N_xix_R<1,D>(addr);
NEXT; }
2256 case 0x8b: {
int c = res_N_xix_R<1,E>(addr);
NEXT; }
2257 case 0x8c: {
int c = res_N_xix_R<1,H>(addr);
NEXT; }
2258 case 0x8d: {
int c = res_N_xix_R<1,L>(addr);
NEXT; }
2259 case 0x8f: {
int c = res_N_xix_R<1,A>(addr);
NEXT; }
2260 case 0x90: {
int c = res_N_xix_R<2,B>(addr);
NEXT; }
2261 case 0x91: {
int c = res_N_xix_R<2,C>(addr);
NEXT; }
2262 case 0x92: {
int c = res_N_xix_R<2,D>(addr);
NEXT; }
2263 case 0x93: {
int c = res_N_xix_R<2,E>(addr);
NEXT; }
2264 case 0x94: {
int c = res_N_xix_R<2,H>(addr);
NEXT; }
2265 case 0x95: {
int c = res_N_xix_R<2,L>(addr);
NEXT; }
2266 case 0x97: {
int c = res_N_xix_R<2,A>(addr);
NEXT; }
2267 case 0x98: {
int c = res_N_xix_R<3,B>(addr);
NEXT; }
2268 case 0x99: {
int c = res_N_xix_R<3,C>(addr);
NEXT; }
2269 case 0x9a: {
int c = res_N_xix_R<3,D>(addr);
NEXT; }
2270 case 0x9b: {
int c = res_N_xix_R<3,E>(addr);
NEXT; }
2271 case 0x9c: {
int c = res_N_xix_R<3,H>(addr);
NEXT; }
2272 case 0x9d: {
int c = res_N_xix_R<3,L>(addr);
NEXT; }
2273 case 0x9f: {
int c = res_N_xix_R<3,A>(addr);
NEXT; }
2274 case 0xa0: {
int c = res_N_xix_R<4,B>(addr);
NEXT; }
2275 case 0xa1: {
int c = res_N_xix_R<4,C>(addr);
NEXT; }
2276 case 0xa2: {
int c = res_N_xix_R<4,D>(addr);
NEXT; }
2277 case 0xa3: {
int c = res_N_xix_R<4,E>(addr);
NEXT; }
2278 case 0xa4: {
int c = res_N_xix_R<4,H>(addr);
NEXT; }
2279 case 0xa5: {
int c = res_N_xix_R<4,L>(addr);
NEXT; }
2280 case 0xa7: {
int c = res_N_xix_R<4,A>(addr);
NEXT; }
2281 case 0xa8: {
int c = res_N_xix_R<5,B>(addr);
NEXT; }
2282 case 0xa9: {
int c = res_N_xix_R<5,C>(addr);
NEXT; }
2283 case 0xaa: {
int c = res_N_xix_R<5,D>(addr);
NEXT; }
2284 case 0xab: {
int c = res_N_xix_R<5,E>(addr);
NEXT; }
2285 case 0xac: {
int c = res_N_xix_R<5,H>(addr);
NEXT; }
2286 case 0xad: {
int c = res_N_xix_R<5,L>(addr);
NEXT; }
2287 case 0xaf: {
int c = res_N_xix_R<5,A>(addr);
NEXT; }
2288 case 0xb0: {
int c = res_N_xix_R<6,B>(addr);
NEXT; }
2289 case 0xb1: {
int c = res_N_xix_R<6,C>(addr);
NEXT; }
2290 case 0xb2: {
int c = res_N_xix_R<6,D>(addr);
NEXT; }
2291 case 0xb3: {
int c = res_N_xix_R<6,E>(addr);
NEXT; }
2292 case 0xb4: {
int c = res_N_xix_R<6,H>(addr);
NEXT; }
2293 case 0xb5: {
int c = res_N_xix_R<6,L>(addr);
NEXT; }
2294 case 0xb7: {
int c = res_N_xix_R<6,A>(addr);
NEXT; }
2295 case 0xb8: {
int c = res_N_xix_R<7,B>(addr);
NEXT; }
2296 case 0xb9: {
int c = res_N_xix_R<7,C>(addr);
NEXT; }
2297 case 0xba: {
int c = res_N_xix_R<7,D>(addr);
NEXT; }
2298 case 0xbb: {
int c = res_N_xix_R<7,E>(addr);
NEXT; }
2299 case 0xbc: {
int c = res_N_xix_R<7,H>(addr);
NEXT; }
2300 case 0xbd: {
int c = res_N_xix_R<7,L>(addr);
NEXT; }
2301 case 0xbf: {
int c = res_N_xix_R<7,A>(addr);
NEXT; }
2302 case 0x86: {
int c = res_N_xix_R<0,DUMMY>(addr);
NEXT; }
2303 case 0x8e: {
int c = res_N_xix_R<1,DUMMY>(addr);
NEXT; }
2304 case 0x96: {
int c = res_N_xix_R<2,DUMMY>(addr);
NEXT; }
2305 case 0x9e: {
int c = res_N_xix_R<3,DUMMY>(addr);
NEXT; }
2306 case 0xa6: {
int c = res_N_xix_R<4,DUMMY>(addr);
NEXT; }
2307 case 0xae: {
int c = res_N_xix_R<5,DUMMY>(addr);
NEXT; }
2308 case 0xb6: {
int c = res_N_xix_R<6,DUMMY>(addr);
NEXT; }
2309 case 0xbe: {
int c = res_N_xix_R<7,DUMMY>(addr);
NEXT; }
2311 case 0xc0: {
int c = set_N_xix_R<0,B>(addr);
NEXT; }
2312 case 0xc1: {
int c = set_N_xix_R<0,C>(addr);
NEXT; }
2313 case 0xc2: {
int c = set_N_xix_R<0,D>(addr);
NEXT; }
2314 case 0xc3: {
int c = set_N_xix_R<0,E>(addr);
NEXT; }
2315 case 0xc4: {
int c = set_N_xix_R<0,H>(addr);
NEXT; }
2316 case 0xc5: {
int c = set_N_xix_R<0,L>(addr);
NEXT; }
2317 case 0xc7: {
int c = set_N_xix_R<0,A>(addr);
NEXT; }
2318 case 0xc8: {
int c = set_N_xix_R<1,B>(addr);
NEXT; }
2319 case 0xc9: {
int c = set_N_xix_R<1,C>(addr);
NEXT; }
2320 case 0xca: {
int c = set_N_xix_R<1,D>(addr);
NEXT; }
2321 case 0xcb: {
int c = set_N_xix_R<1,E>(addr);
NEXT; }
2322 case 0xcc: {
int c = set_N_xix_R<1,H>(addr);
NEXT; }
2323 case 0xcd: {
int c = set_N_xix_R<1,L>(addr);
NEXT; }
2324 case 0xcf: {
int c = set_N_xix_R<1,A>(addr);
NEXT; }
2325 case 0xd0: {
int c = set_N_xix_R<2,B>(addr);
NEXT; }
2326 case 0xd1: {
int c = set_N_xix_R<2,C>(addr);
NEXT; }
2327 case 0xd2: {
int c = set_N_xix_R<2,D>(addr);
NEXT; }
2328 case 0xd3: {
int c = set_N_xix_R<2,E>(addr);
NEXT; }
2329 case 0xd4: {
int c = set_N_xix_R<2,H>(addr);
NEXT; }
2330 case 0xd5: {
int c = set_N_xix_R<2,L>(addr);
NEXT; }
2331 case 0xd7: {
int c = set_N_xix_R<2,A>(addr);
NEXT; }
2332 case 0xd8: {
int c = set_N_xix_R<3,B>(addr);
NEXT; }
2333 case 0xd9: {
int c = set_N_xix_R<3,C>(addr);
NEXT; }
2334 case 0xda: {
int c = set_N_xix_R<3,D>(addr);
NEXT; }
2335 case 0xdb: {
int c = set_N_xix_R<3,E>(addr);
NEXT; }
2336 case 0xdc: {
int c = set_N_xix_R<3,H>(addr);
NEXT; }
2337 case 0xdd: {
int c = set_N_xix_R<3,L>(addr);
NEXT; }
2338 case 0xdf: {
int c = set_N_xix_R<3,A>(addr);
NEXT; }
2339 case 0xe0: {
int c = set_N_xix_R<4,B>(addr);
NEXT; }
2340 case 0xe1: {
int c = set_N_xix_R<4,C>(addr);
NEXT; }
2341 case 0xe2: {
int c = set_N_xix_R<4,D>(addr);
NEXT; }
2342 case 0xe3: {
int c = set_N_xix_R<4,E>(addr);
NEXT; }
2343 case 0xe4: {
int c = set_N_xix_R<4,H>(addr);
NEXT; }
2344 case 0xe5: {
int c = set_N_xix_R<4,L>(addr);
NEXT; }
2345 case 0xe7: {
int c = set_N_xix_R<4,A>(addr);
NEXT; }
2346 case 0xe8: {
int c = set_N_xix_R<5,B>(addr);
NEXT; }
2347 case 0xe9: {
int c = set_N_xix_R<5,C>(addr);
NEXT; }
2348 case 0xea: {
int c = set_N_xix_R<5,D>(addr);
NEXT; }
2349 case 0xeb: {
int c = set_N_xix_R<5,E>(addr);
NEXT; }
2350 case 0xec: {
int c = set_N_xix_R<5,H>(addr);
NEXT; }
2351 case 0xed: {
int c = set_N_xix_R<5,L>(addr);
NEXT; }
2352 case 0xef: {
int c = set_N_xix_R<5,A>(addr);
NEXT; }
2353 case 0xf0: {
int c = set_N_xix_R<6,B>(addr);
NEXT; }
2354 case 0xf1: {
int c = set_N_xix_R<6,C>(addr);
NEXT; }
2355 case 0xf2: {
int c = set_N_xix_R<6,D>(addr);
NEXT; }
2356 case 0xf3: {
int c = set_N_xix_R<6,E>(addr);
NEXT; }
2357 case 0xf4: {
int c = set_N_xix_R<6,H>(addr);
NEXT; }
2358 case 0xf5: {
int c = set_N_xix_R<6,L>(addr);
NEXT; }
2359 case 0xf7: {
int c = set_N_xix_R<6,A>(addr);
NEXT; }
2360 case 0xf8: {
int c = set_N_xix_R<7,B>(addr);
NEXT; }
2361 case 0xf9: {
int c = set_N_xix_R<7,C>(addr);
NEXT; }
2362 case 0xfa: {
int c = set_N_xix_R<7,D>(addr);
NEXT; }
2363 case 0xfb: {
int c = set_N_xix_R<7,E>(addr);
NEXT; }
2364 case 0xfc: {
int c = set_N_xix_R<7,H>(addr);
NEXT; }
2365 case 0xfd: {
int c = set_N_xix_R<7,L>(addr);
NEXT; }
2366 case 0xff: {
int c = set_N_xix_R<7,A>(addr);
NEXT; }
2367 case 0xc6: {
int c = set_N_xix_R<0,DUMMY>(addr);
NEXT; }
2368 case 0xce: {
int c = set_N_xix_R<1,DUMMY>(addr);
NEXT; }
2369 case 0xd6: {
int c = set_N_xix_R<2,DUMMY>(addr);
NEXT; }
2370 case 0xde: {
int c = set_N_xix_R<3,DUMMY>(addr);
NEXT; }
2371 case 0xe6: {
int c = set_N_xix_R<4,DUMMY>(addr);
NEXT; }
2372 case 0xee: {
int c = set_N_xix_R<5,DUMMY>(addr);
NEXT; }
2373 case 0xf6: {
int c = set_N_xix_R<6,DUMMY>(addr);
NEXT; }
2374 case 0xfe: {
int c = set_N_xix_R<7,DUMMY>(addr);
NEXT; }
2380 template <
class T>
inline void CPUCore<T>::cpuTracePre()
2382 start_pc = R.getPC();
2384 template <
class T>
inline void CPUCore<T>::cpuTracePost()
2386 if (
unlikely(traceSetting.getValue())) {
2387 cpuTracePost_slow();
2390 template <
class T>
void CPUCore<T>::cpuTracePost_slow()
2394 dasm(*interface, start_pc, opbuf, dasmOutput, T::getTimeFast());
2395 std::cout << std::setfill(
'0') << std::hex << std::setw(4) << start_pc
2396 <<
" : " << dasmOutput
2397 <<
" AF=" << std::setw(4) << R.getAF()
2398 <<
" BC=" << std::setw(4) << R.getBC()
2399 <<
" DE=" << std::setw(4) << R.getDE()
2400 <<
" HL=" << std::setw(4) << R.getHL()
2401 <<
" IX=" << std::setw(4) << R.getIX()
2402 <<
" IY=" << std::setw(4) << R.getIY()
2403 <<
" SP=" << std::setw(4) << R.getSP()
2404 << std::endl << std::dec;
2407 template <
class T>
void CPUCore<T>::executeSlow()
2413 }
else if (
unlikely(IRQStatus && R.getIFF1() && !R.getAfterEI())) {
2433 assert(R.getF() & V_FLAG);
2434 R.setF(R.getF() & ~V_FLAG);
2437 switch (R.getIM()) {
2447 }
else if (
unlikely(R.getHALT())) {
2449 R.incR(T::advanceHalt(T::haltStates(), scheduler.getNext()));
2450 setSlowInstructions();
2452 assert(R.isSameAfter());
2455 assert(T::limitReached());
2456 executeInstructions();
2467 assert(fastForward || !interface->isBreaked());
2469 interface->setFastForward(
true);
2471 execute2(fastForward);
2472 interface->setFastForward(
false);
2481 scheduler.schedule(T::getTime());
2482 setSlowInstructions();
2484 if (!fastForward && (interface->isContinue() || interface->isStep())) {
2486 interface->setContinue(
false);
2488 scheduler.schedule(T::getTimeFast());
2490 if (interface->isStep()) {
2491 interface->setStep(
false);
2492 interface->doBreak();
2501 (!interface->anyBreakPoints() && !traceSetting.getValue())) {
2503 while (!needExitCPULoop()) {
2504 if (slowInstructions) {
2507 scheduler.schedule(T::getTimeFast());
2509 while (slowInstructions == 0) {
2511 if (
likely(!T::limitReached())) {
2513 assert(R.isSameAfter());
2514 executeInstructions();
2515 assert(R.isSameAfter());
2517 scheduler.schedule(T::getTimeFast());
2518 if (needExitCPULoop())
return;
2523 while (!needExitCPULoop()) {
2524 if (interface->checkBreakPoints(R.getPC())) {
2525 assert(interface->isBreaked());
2528 if (slowInstructions == 0) {
2530 assert(T::limitReached());
2531 assert(R.isSameAfter());
2532 executeInstructions();
2533 assert(R.isSameAfter());
2542 scheduler.schedule(T::getTime());
2549 template <
class T>
template<CPU::Reg8 DST, CPU::Reg8 SRC,
int EE>
int CPUCore<T>::ld_R_R() {
2550 R.set8<DST>(R.get8<SRC>());
return T::CC_LD_R_R + EE;
2554 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::ld_sp_SS() {
2555 R.setSP(R.get16<REG>());
return T::CC_LD_SP_HL + EE;
2559 template <
class T>
template<CPU::Reg16 REG>
int CPUCore<T>::ld_SS_a() {
2560 T::setMemPtr((R.getA() << 8) | ((R.get16<REG>() + 1) & 0xFF));
2561 WRMEM(R.get16<REG>(), R.getA(), T::CC_LD_SS_A_1);
2562 return T::CC_LD_SS_A;
2566 template <
class T>
template<CPU::Reg8 SRC>
int CPUCore<T>::ld_xhl_R() {
2567 WRMEM(R.getHL(), R.get8<SRC>(), T::CC_LD_HL_R_1);
2568 return T::CC_LD_HL_R;
2572 template <
class T>
template<CPU::Reg16 IXY, CPU::Reg8 SRC>
int CPUCore<T>::ld_xix_R() {
2573 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_LD_XIX_R_1);
2574 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2576 WRMEM(addr, R.get8<SRC>(), T::CC_DD + T::CC_LD_XIX_R_2);
2577 return T::CC_DD + T::CC_LD_XIX_R;
2581 template <
class T>
int CPUCore<T>::ld_xhl_byte() {
2582 byte val = RDMEM_OPCODE(T::CC_LD_HL_N_1);
2583 WRMEM(R.getHL(), val, T::CC_LD_HL_N_2);
2584 return T::CC_LD_HL_N;
2588 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::ld_xix_byte() {
2589 unsigned tmp = RD_WORD_PC(T::CC_DD + T::CC_LD_XIX_N_1);
2590 offset ofst = tmp & 0xFF;
2591 byte val = tmp >> 8;
2592 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2594 WRMEM(addr, val, T::CC_DD + T::CC_LD_XIX_N_2);
2595 return T::CC_DD + T::CC_LD_XIX_N;
2599 template <
class T>
int CPUCore<T>::ld_xbyte_a() {
2600 unsigned x = RD_WORD_PC(T::CC_LD_NN_A_1);
2601 T::setMemPtr((R.getA() << 8) | ((x + 1) & 0xFF));
2602 WRMEM(x, R.getA(), T::CC_LD_NN_A_2);
2603 return T::CC_LD_NN_A;
2607 template <
class T>
template<
int EE>
inline int CPUCore<T>::WR_NN_Y(
unsigned reg) {
2608 unsigned addr = RD_WORD_PC(T::CC_LD_XX_HL_1 + EE);
2609 T::setMemPtr(addr + 1);
2610 WR_WORD(addr, reg, T::CC_LD_XX_HL_2 + EE);
2611 return T::CC_LD_XX_HL + EE;
2613 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::ld_xword_SS() {
2614 return WR_NN_Y<EE >(R.get16<REG>());
2616 template <
class T>
template<CPU::Reg16 REG>
int CPUCore<T>::ld_xword_SS_ED() {
2617 return WR_NN_Y<T::EE_ED>(R.get16<REG>());
2621 template <
class T>
template<CPU::Reg16 REG>
int CPUCore<T>::ld_a_SS() {
2622 T::setMemPtr(R.get16<REG>() + 1);
2623 R.setA(RDMEM(R.get16<REG>(), T::CC_LD_A_SS_1));
2624 return T::CC_LD_A_SS;
2628 template <
class T>
int CPUCore<T>::ld_a_xbyte() {
2629 unsigned addr = RD_WORD_PC(T::CC_LD_A_NN_1);
2630 T::setMemPtr(addr + 1);
2631 R.setA(RDMEM(addr, T::CC_LD_A_NN_2));
2632 return T::CC_LD_A_NN;
2636 template <
class T>
template<CPU::Reg8 DST,
int EE>
int CPUCore<T>::ld_R_byte() {
2637 R.set8<DST>(RDMEM_OPCODE(T::CC_LD_R_N_1 + EE));
return T::CC_LD_R_N + EE;
2641 template <
class T>
template<CPU::Reg8 DST>
int CPUCore<T>::ld_R_xhl() {
2642 R.set8<DST>(RDMEM(R.getHL(), T::CC_LD_R_HL_1));
return T::CC_LD_R_HL;
2646 template <
class T>
template<CPU::Reg8 DST, CPU::Reg16 IXY>
int CPUCore<T>::ld_R_xix() {
2647 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_LD_R_XIX_1);
2648 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2650 R.set8<DST>(RDMEM(addr, T::CC_DD + T::CC_LD_R_XIX_2));
2651 return T::CC_DD + T::CC_LD_R_XIX;
2655 template <
class T>
template<
int EE>
inline unsigned CPUCore<T>::RD_P_XX() {
2656 unsigned addr = RD_WORD_PC(T::CC_LD_HL_XX_1 + EE);
2657 T::setMemPtr(addr + 1);
2658 unsigned result = RD_WORD(addr, T::CC_LD_HL_XX_2 + EE);
2661 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::ld_SS_xword() {
2662 R.set16<REG>(RD_P_XX<EE>());
return T::CC_LD_HL_XX + EE;
2664 template <
class T>
template<CPU::Reg16 REG>
int CPUCore<T>::ld_SS_xword_ED() {
2665 R.set16<REG>(RD_P_XX<T::EE_ED>());
return T::CC_LD_HL_XX + T::EE_ED;
2669 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::ld_SS_word() {
2670 R.set16<REG>(RD_WORD_PC(T::CC_LD_SS_NN_1 + EE));
return T::CC_LD_SS_NN + EE;
2675 template <
class T>
inline void CPUCore<T>::ADC(
byte reg) {
2676 unsigned res = R.getA() + reg + ((R.getF() & C_FLAG) ? 1 : 0);
2677 byte f = ((res & 0x100) ? C_FLAG : 0) |
2678 ((R.getA() ^ res ^ reg) & H_FLAG) |
2679 (((R.getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2682 f |= ZSTable[res & 0xFF];
2683 f |= R.getF() & (X_FLAG | Y_FLAG);
2685 f |= ZSXYTable[res & 0xFF];
2690 template <
class T>
inline int CPUCore<T>::adc_a_a() {
2691 unsigned res = 2 * R.getA() + ((R.getF() & C_FLAG) ? 1 : 0);
2692 byte f = ((res & 0x100) ? C_FLAG : 0) |
2694 (((R.getA() ^ res) & 0x80) >> 5) |
2697 f |= ZSTable[res & 0xFF];
2698 f |= R.getF() & (X_FLAG | Y_FLAG);
2700 f |= ZSXYTable[res & 0xFF];
2706 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::adc_a_R() {
2707 ADC(R.get8<SRC>());
return T::CC_CP_R + EE;
2709 template <
class T>
int CPUCore<T>::adc_a_byte() {
2710 ADC(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2712 template <
class T>
int CPUCore<T>::adc_a_xhl() {
2713 ADC(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2715 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::adc_a_xix() {
2716 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2717 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2719 ADC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2720 return T::CC_DD + T::CC_CP_XIX;
2724 template <
class T>
inline void CPUCore<T>::ADD(
byte reg) {
2725 unsigned res = R.getA() + reg;
2726 byte f = ((res & 0x100) ? C_FLAG : 0) |
2727 ((R.getA() ^ res ^ reg) & H_FLAG) |
2728 (((R.getA() ^ res) & (reg ^ res) & 0x80) >> 5) |
2731 f |= ZSTable[res & 0xFF];
2732 f |= R.getF() & (X_FLAG | Y_FLAG);
2734 f |= ZSXYTable[res & 0xFF];
2739 template <
class T>
inline int CPUCore<T>::add_a_a() {
2740 unsigned res = 2 * R.getA();
2741 byte f = ((res & 0x100) ? C_FLAG : 0) |
2743 (((R.getA() ^ res) & 0x80) >> 5) |
2746 f |= ZSTable[res & 0xFF];
2747 f |= R.getF() & (X_FLAG | Y_FLAG);
2749 f |= ZSXYTable[res & 0xFF];
2755 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::add_a_R() {
2756 ADD(R.get8<SRC>());
return T::CC_CP_R + EE;
2758 template <
class T>
int CPUCore<T>::add_a_byte() {
2759 ADD(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2761 template <
class T>
int CPUCore<T>::add_a_xhl() {
2762 ADD(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2764 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::add_a_xix() {
2765 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2766 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2768 ADD(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2769 return T::CC_DD + T::CC_CP_XIX;
2773 template <
class T>
inline void CPUCore<T>::AND(
byte reg) {
2774 R.setA(R.getA() & reg);
2777 f |= ZSPHTable[R.getA()];
2778 f |= R.getF() & (X_FLAG | Y_FLAG);
2780 f |= ZSPXYTable[R.getA()] | H_FLAG;
2784 template <
class T>
int CPUCore<T>::and_a() {
2787 f |= ZSPHTable[R.getA()];
2788 f |= R.getF() & (X_FLAG | Y_FLAG);
2790 f |= ZSPXYTable[R.getA()] | H_FLAG;
2795 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::and_R() {
2796 AND(R.get8<SRC>());
return T::CC_CP_R + EE;
2798 template <
class T>
int CPUCore<T>::and_byte() {
2799 AND(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2801 template <
class T>
int CPUCore<T>::and_xhl() {
2802 AND(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2804 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::and_xix() {
2805 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2806 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2808 AND(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2809 return T::CC_DD + T::CC_CP_XIX;
2813 template <
class T>
inline void CPUCore<T>::CP(
byte reg) {
2814 unsigned q = R.getA() - reg;
2815 byte f = ZSTable[q & 0xFF] |
2816 ((q & 0x100) ? C_FLAG : 0) |
2818 ((R.getA() ^ q ^ reg) & H_FLAG) |
2819 (((reg ^ R.getA()) & (R.getA() ^ q) & 0x80) >> 5);
2821 f |= R.getF() & (X_FLAG | Y_FLAG);
2823 f |= reg & (X_FLAG | Y_FLAG);
2827 template <
class T>
int CPUCore<T>::cp_a() {
2828 byte f = ZS0 | N_FLAG;
2830 f |= R.getF() & (X_FLAG | Y_FLAG);
2832 f |= R.getA() & (X_FLAG | Y_FLAG);
2837 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::cp_R() {
2838 CP(R.get8<SRC>());
return T::CC_CP_R + EE;
2840 template <
class T>
int CPUCore<T>::cp_byte() {
2841 CP(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2843 template <
class T>
int CPUCore<T>::cp_xhl() {
2844 CP(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2846 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::cp_xix() {
2847 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2848 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2850 CP(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2851 return T::CC_DD + T::CC_CP_XIX;
2855 template <
class T>
inline void CPUCore<T>::OR(
byte reg) {
2856 R.setA(R.getA() | reg);
2859 f |= ZSPTable[R.getA()];
2860 f |= R.getF() & (X_FLAG | Y_FLAG);
2862 f |= ZSPXYTable[R.getA()];
2866 template <
class T>
int CPUCore<T>::or_a() {
2869 f |= ZSPTable[R.getA()];
2870 f |= R.getF() & (X_FLAG | Y_FLAG);
2872 f |= ZSPXYTable[R.getA()];
2877 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::or_R() {
2878 OR(R.get8<SRC>());
return T::CC_CP_R + EE;
2880 template <
class T>
int CPUCore<T>::or_byte() {
2881 OR(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2883 template <
class T>
int CPUCore<T>::or_xhl() {
2884 OR(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2886 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::or_xix() {
2887 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2888 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2890 OR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2891 return T::CC_DD + T::CC_CP_XIX;
2895 template <
class T>
inline void CPUCore<T>::SBC(
byte reg) {
2896 unsigned res = R.getA() - reg - ((R.getF() & C_FLAG) ? 1 : 0);
2897 byte f = ((res & 0x100) ? C_FLAG : 0) |
2899 ((R.getA() ^ res ^ reg) & H_FLAG) |
2900 (((reg ^ R.getA()) & (R.getA() ^ res) & 0x80) >> 5);
2902 f |= ZSTable[res & 0xFF];
2903 f |= R.getF() & (X_FLAG | Y_FLAG);
2905 f |= ZSXYTable[res & 0xFF];
2910 template <
class T>
int CPUCore<T>::sbc_a_a() {
2912 word t = (R.getF() & C_FLAG)
2913 ? (255 * 256 | ZS255 | C_FLAG | H_FLAG | N_FLAG)
2914 : ( 0 * 256 | ZS0 | N_FLAG);
2915 R.setAF(t | (R.getF() & (X_FLAG | Y_FLAG)));
2917 R.setAF((R.getF() & C_FLAG) ?
2918 (255 * 256 | ZSXY255 | C_FLAG | H_FLAG | N_FLAG) :
2919 ( 0 * 256 | ZSXY0 | N_FLAG));
2923 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::sbc_a_R() {
2924 SBC(R.get8<SRC>());
return T::CC_CP_R + EE;
2926 template <
class T>
int CPUCore<T>::sbc_a_byte() {
2927 SBC(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2929 template <
class T>
int CPUCore<T>::sbc_a_xhl() {
2930 SBC(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2932 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::sbc_a_xix() {
2933 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2934 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2936 SBC(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2937 return T::CC_DD + T::CC_CP_XIX;
2941 template <
class T>
inline void CPUCore<T>::SUB(
byte reg) {
2942 unsigned res = R.getA() - reg;
2943 byte f = ((res & 0x100) ? C_FLAG : 0) |
2945 ((R.getA() ^ res ^ reg) & H_FLAG) |
2946 (((reg ^ R.getA()) & (R.getA() ^ res) & 0x80) >> 5);
2948 f |= ZSTable[res & 0xFF];
2949 f |= R.getF() & (X_FLAG | Y_FLAG);
2951 f |= ZSXYTable[res & 0xFF];
2956 template <
class T>
int CPUCore<T>::sub_a() {
2958 word t = 0 * 256 | ZS0 | N_FLAG;
2959 R.setAF(t | (R.getF() & (X_FLAG | Y_FLAG)));
2961 R.setAF(0 * 256 | ZSXY0 | N_FLAG);
2965 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::sub_R() {
2966 SUB(R.get8<SRC>());
return T::CC_CP_R + EE;
2968 template <
class T>
int CPUCore<T>::sub_byte() {
2969 SUB(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
2971 template <
class T>
int CPUCore<T>::sub_xhl() {
2972 SUB(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
2974 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::sub_xix() {
2975 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
2976 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
2978 SUB(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
2979 return T::CC_DD + T::CC_CP_XIX;
2983 template <
class T>
inline void CPUCore<T>::XOR(
byte reg) {
2984 R.setA(R.getA() ^ reg);
2987 f |= ZSPTable[R.getA()];
2988 f |= R.getF() & (X_FLAG | Y_FLAG);
2990 f |= ZSPXYTable[R.getA()];
2994 template <
class T>
int CPUCore<T>::xor_a() {
2996 word t = 0 * 256 + ZSP0;
2997 R.setAF(t | (R.getF() & (X_FLAG | Y_FLAG)));
2999 R.setAF(0 * 256 + ZSPXY0);
3003 template <
class T>
template<CPU::Reg8 SRC,
int EE>
int CPUCore<T>::xor_R() {
3004 XOR(R.get8<SRC>());
return T::CC_CP_R + EE;
3006 template <
class T>
int CPUCore<T>::xor_byte() {
3007 XOR(RDMEM_OPCODE(T::CC_CP_N_1));
return T::CC_CP_N;
3009 template <
class T>
int CPUCore<T>::xor_xhl() {
3010 XOR(RDMEM(R.getHL(), T::CC_CP_XHL_1));
return T::CC_CP_XHL;
3012 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::xor_xix() {
3013 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_CP_XIX_1);
3014 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
3016 XOR(RDMEM(addr, T::CC_DD + T::CC_CP_XIX_2));
3017 return T::CC_DD + T::CC_CP_XIX;
3022 template <
class T>
inline byte CPUCore<T>::DEC(
byte reg) {
3024 byte f = ((reg & ~res & 0x80) >> 5) |
3025 (((res & 0x0F) + 1) & H_FLAG) |
3028 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
3031 f |= R.getF() & C_FLAG;
3032 f |= ZSXYTable[res];
3037 template <
class T>
template<CPU::Reg8 REG,
int EE>
int CPUCore<T>::dec_R() {
3038 R.set8<REG>(DEC(R.get8<REG>()));
return T::CC_INC_R + EE;
3040 template <
class T>
template<
int EE>
inline int CPUCore<T>::DEC_X(
unsigned x) {
3041 byte val = DEC(RDMEM(x, T::CC_INC_XHL_1 + EE));
3042 WRMEM(x, val, T::CC_INC_XHL_2 + EE);
3043 return T::CC_INC_XHL + EE;
3045 template <
class T>
int CPUCore<T>::dec_xhl() {
3046 return DEC_X<0>(R.getHL());
3048 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::dec_xix() {
3049 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_INC_XIX_1);
3050 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
3052 return DEC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3056 template <
class T>
inline byte CPUCore<T>::INC(
byte reg) {
3058 byte f = ((reg & -reg & 0x80) >> 5) |
3059 (((reg & 0x0F) - 1) & H_FLAG) |
3062 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
3065 f |= R.getF() & C_FLAG;
3066 f |= ZSXYTable[reg];
3071 template <
class T>
template<CPU::Reg8 REG,
int EE>
int CPUCore<T>::inc_R() {
3072 R.set8<REG>(INC(R.get8<REG>()));
return T::CC_INC_R + EE;
3074 template <
class T>
template <
int EE>
inline int CPUCore<T>::INC_X(
unsigned x) {
3075 byte val = INC(RDMEM(x, T::CC_INC_XHL_1 + EE));
3076 WRMEM(x, val, T::CC_INC_XHL_2 + EE);
3077 return T::CC_INC_XHL + EE;
3079 template <
class T>
int CPUCore<T>::inc_xhl() {
3080 return INC_X<0>(R.getHL());
3082 template <
class T>
template<CPU::Reg16 IXY>
int CPUCore<T>::inc_xix() {
3083 offset ofst = RDMEM_OPCODE(T::CC_DD + T::CC_INC_XIX_1);
3084 unsigned addr = (R.get16<IXY>() + ofst) & 0xFFFF;
3086 return INC_X<T::CC_DD + T::EE_INC_XIX>(addr);
3091 template <
class T>
template<CPU::Reg16 REG>
inline int CPUCore<T>::adc_hl_SS() {
3092 unsigned reg = R.get16<REG>();
3093 T::setMemPtr(R.getHL() + 1);
3094 unsigned res = R.getHL() + reg + ((R.getF() & C_FLAG) ? 1 : 0);
3095 byte f = (res >> 16) |
3098 f |= R.getF() & (X_FLAG | Y_FLAG);
3101 f |= ((R.getHL() ^ res ^ reg) >> 8) & H_FLAG;
3103 f |= ((R.getHL() ^ res) & (reg ^ res) & 0x8000) >> 13;
3105 f |= (res >> 8) & S_FLAG;
3107 f |= (res >> 8) & (S_FLAG | X_FLAG | Y_FLAG);
3110 f |= ((R.getHL() ^ reg) >> 8) & H_FLAG;
3112 f |= (R.getHL() & reg & 0x8000) >> 13;
3117 return T::CC_ADC_HL_SS;
3119 template <
class T>
int CPUCore<T>::adc_hl_hl() {
3120 T::setMemPtr(R.getHL() + 1);
3121 unsigned res = 2 * R.getHL() + ((R.getF() & C_FLAG) ? 1 : 0);
3122 byte f = (res >> 16) |
3125 f |= R.getF() & (X_FLAG | Y_FLAG);
3129 f |= ((R.getHL() ^ res) & 0x8000) >> 13;
3131 f |= (res >> 8) & (H_FLAG | S_FLAG);
3133 f |= (res >> 8) & (H_FLAG | S_FLAG | X_FLAG | Y_FLAG);
3137 f |= (R.getHL() & 0x8000) >> 13;
3142 return T::CC_ADC_HL_SS;
3146 template <
class T>
template<CPU::Reg16 REG1, CPU::Reg16 REG2,
int EE>
int CPUCore<T>::add_SS_TT() {
3147 unsigned reg1 = R.get16<REG1>();
3148 unsigned reg2 = R.get16<REG2>();
3149 T::setMemPtr(reg1 + 1);
3150 unsigned res = reg1 + reg2;
3151 byte f = (((reg1 ^ res ^ reg2) >> 8) & H_FLAG) |
3155 f |= R.getF() & (S_FLAG | Z_FLAG | V_FLAG | X_FLAG | Y_FLAG);
3157 f |= R.getF() & (S_FLAG | Z_FLAG | V_FLAG);
3158 f |= (res >> 8) & (X_FLAG | Y_FLAG);
3161 R.set16<REG1>(res & 0xFFFF);
3162 return T::CC_ADD_HL_SS + EE;
3164 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::add_SS_SS() {
3165 unsigned reg = R.get16<REG>();
3166 T::setMemPtr(reg + 1);
3167 unsigned res = 2 * reg;
3168 byte f = (res >> 16) |
3171 f |= R.getF() & (S_FLAG | Z_FLAG | V_FLAG | X_FLAG | Y_FLAG);
3172 f |= (res >> 8) & H_FLAG;
3174 f |= R.getF() & (S_FLAG | Z_FLAG | V_FLAG);
3175 f |= (res >> 8) & (H_FLAG | X_FLAG | Y_FLAG);
3178 R.set16<REG>(res & 0xFFFF);
3179 return T::CC_ADD_HL_SS + EE;
3183 template <
class T>
template<CPU::Reg16 REG>
inline int CPUCore<T>::sbc_hl_SS() {
3184 unsigned reg = R.get16<REG>();
3185 T::setMemPtr(R.getHL() + 1);
3186 unsigned res = R.getHL() - reg - ((R.getF() & C_FLAG) ? 1 : 0);
3187 byte f = ((res & 0x10000) ? C_FLAG : 0) |
3190 f |= R.getF() & (X_FLAG | Y_FLAG);
3193 f |= ((R.getHL() ^ res ^ reg) >> 8) & H_FLAG;
3195 f |= ((reg ^ R.getHL()) & (R.getHL() ^ res) & 0x8000) >> 13;
3197 f |= (res >> 8) & S_FLAG;
3199 f |= (res >> 8) & (S_FLAG | X_FLAG | Y_FLAG);
3202 f |= ((R.getHL() ^ reg) >> 8) & H_FLAG;
3204 f |= ((reg ^ R.getHL()) & R.getHL() & 0x8000) >> 13;
3209 return T::CC_ADC_HL_SS;
3211 template <
class T>
int CPUCore<T>::sbc_hl_hl() {
3212 T::setMemPtr(R.getHL() + 1);
3213 byte f = T::isR800() ? (R.getF() & (X_FLAG | Y_FLAG)) : 0;
3214 if (R.getF() & C_FLAG) {
3215 f |= C_FLAG | H_FLAG | S_FLAG | N_FLAG;
3217 f |= X_FLAG | Y_FLAG;
3221 f |= Z_FLAG | N_FLAG;
3225 return T::CC_ADC_HL_SS;
3229 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::dec_SS() {
3230 R.set16<REG>(R.get16<REG>() - 1);
return T::CC_INC_SS + EE;
3234 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::inc_SS() {
3235 R.set16<REG>(R.get16<REG>() + 1);
return T::CC_INC_SS + EE;
3240 template <
class T>
template<
unsigned N, CPU::Reg8 REG>
int CPUCore<T>::bit_N_R() {
3241 byte reg = R.get8<REG>();
3245 f |= R.getF() & (S_FLAG | V_FLAG | C_FLAG | X_FLAG | Y_FLAG);
3247 f |= (reg & (1 << N)) ? 0 : Z_FLAG;
3249 f |= ZSPHTable[reg & (1 << N)];
3250 f |= R.getF() & C_FLAG;
3251 f |= reg & (X_FLAG | Y_FLAG);
3256 template <
class T>
template<
unsigned N>
inline int CPUCore<T>::bit_N_xhl() {
3257 byte m = RDMEM(R.getHL(), T::CC_BIT_XHL_1) & (1 << N);
3260 f |= R.getF() & (S_FLAG | V_FLAG | C_FLAG | X_FLAG | Y_FLAG);
3262 f |= m ? 0 : Z_FLAG;
3265 f |= R.getF() & C_FLAG;
3266 f |= (T::getMemPtr() >> 8) & (X_FLAG | Y_FLAG);
3269 return T::CC_BIT_XHL;
3271 template <
class T>
template<
unsigned N>
inline int CPUCore<T>::bit_N_xix(
unsigned addr) {
3273 byte m = RDMEM(addr, T::CC_DD + T::CC_BIT_XIX_1) & (1 << N);
3276 f |= R.getF() & (S_FLAG | V_FLAG | C_FLAG | X_FLAG | Y_FLAG);
3278 f |= m ? 0 : Z_FLAG;
3281 f |= R.getF() & C_FLAG;
3282 f |= (addr >> 8) & (X_FLAG | Y_FLAG);
3285 return T::CC_DD + T::CC_BIT_XIX;
3289 static inline byte RES(
unsigned b,
byte reg) {
3290 return reg & ~(1 << b);
3292 template <
class T>
template<
unsigned N, CPU::Reg8 REG>
int CPUCore<T>::res_N_R() {
3293 R.set8<REG>(RES(N, R.get8<REG>()));
return T::CC_SET_R;
3295 template <
class T>
template<
int EE>
inline byte CPUCore<T>::RES_X(
unsigned bit,
unsigned addr) {
3296 byte res = RES(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3297 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3300 template <
class T>
template<
unsigned N>
int CPUCore<T>::res_N_xhl() {
3301 RES_X<0>(N, R.getHL());
return T::CC_SET_XHL;
3303 template <
class T>
template<
unsigned N, CPU::Reg8 REG>
int CPUCore<T>::res_N_xix_R(
unsigned a) {
3305 R.set8<REG>(RES_X<T::CC_DD + T::EE_SET_XIX>(N, a));
3306 return T::CC_DD + T::CC_SET_XIX;
3310 static inline byte SET(
unsigned b,
byte reg) {
3311 return reg | (1 << b);
3313 template <
class T>
template<
unsigned N, CPU::Reg8 REG>
int CPUCore<T>::set_N_R() {
3314 R.set8<REG>(SET(N, R.get8<REG>()));
return T::CC_SET_R;
3316 template <
class T>
template<
int EE>
inline byte CPUCore<T>::SET_X(
unsigned bit,
unsigned addr) {
3317 byte res = SET(bit, RDMEM(addr, T::CC_SET_XHL_1 + EE));
3318 WRMEM(addr, res, T::CC_SET_XHL_2 + EE);
3321 template <
class T>
template<
unsigned N>
int CPUCore<T>::set_N_xhl() {
3322 SET_X<0>(N, R.getHL());
return T::CC_SET_XHL;
3324 template <
class T>
template<
unsigned N, CPU::Reg8 REG>
int CPUCore<T>::set_N_xix_R(
unsigned a) {
3326 R.set8<REG>(SET_X<T::CC_DD + T::EE_SET_XIX>(N, a));
3327 return T::CC_DD + T::CC_SET_XIX;
3331 template <
class T>
inline byte CPUCore<T>::RL(
byte reg) {
3333 reg = (reg << 1) | ((R.getF() & C_FLAG) ? 0x01 : 0);
3334 byte f = c ? C_FLAG : 0;
3337 f |= R.getF() & (X_FLAG | Y_FLAG);
3339 f |= ZSPXYTable[reg];
3344 template <
class T>
template<
int EE>
inline byte CPUCore<T>::RL_X(
unsigned x) {
3345 byte res = RL(RDMEM(x, T::CC_SET_XHL_1 + EE));
3346 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3349 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rl_R() {
3350 R.set8<REG>(RL(R.get8<REG>()));
return T::CC_SET_R;
3352 template <
class T>
int CPUCore<T>::rl_xhl() {
3353 RL_X<0>(R.getHL());
return T::CC_SET_XHL;
3355 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rl_xix_R(
unsigned a) {
3357 R.set8<REG>(RL_X<T::CC_DD + T::EE_SET_XIX>(a));
3358 return T::CC_DD + T::CC_SET_XIX;
3362 template <
class T>
inline byte CPUCore<T>::RLC(
byte reg) {
3364 reg = (reg << 1) | c;
3365 byte f = c ? C_FLAG : 0;
3368 f |= R.getF() & (X_FLAG | Y_FLAG);
3370 f |= ZSPXYTable[reg];
3375 template <
class T>
template<
int EE>
inline byte CPUCore<T>::RLC_X(
unsigned x) {
3376 byte res = RLC(RDMEM(x, T::CC_SET_XHL_1 + EE));
3377 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3380 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rlc_R() {
3381 R.set8<REG>(RLC(R.get8<REG>()));
return T::CC_SET_R;
3383 template <
class T>
int CPUCore<T>::rlc_xhl() {
3384 RLC_X<0>(R.getHL());
return T::CC_SET_XHL;
3386 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rlc_xix_R(
unsigned a) {
3388 R.set8<REG>(RLC_X<T::CC_DD + T::EE_SET_XIX>(a));
3389 return T::CC_DD + T::CC_SET_XIX;
3393 template <
class T>
inline byte CPUCore<T>::RR(
byte reg) {
3395 reg = (reg >> 1) | ((R.getF() & C_FLAG) << 7);
3396 byte f = c ? C_FLAG : 0;
3399 f |= R.getF() & (X_FLAG | Y_FLAG);
3401 f |= ZSPXYTable[reg];
3406 template <
class T>
template<
int EE>
inline byte CPUCore<T>::RR_X(
unsigned x) {
3407 byte res = RR(RDMEM(x, T::CC_SET_XHL_1 + EE));
3408 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3411 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rr_R() {
3412 R.set8<REG>(RR(R.get8<REG>()));
return T::CC_SET_R;
3414 template <
class T>
int CPUCore<T>::rr_xhl() {
3415 RR_X<0>(R.getHL());
return T::CC_SET_XHL;
3417 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rr_xix_R(
unsigned a) {
3419 R.set8<REG>(RR_X<T::CC_DD + T::EE_SET_XIX>(a));
3420 return T::CC_DD + T::CC_SET_XIX;
3424 template <
class T>
inline byte CPUCore<T>::RRC(
byte reg) {
3426 reg = (reg >> 1) | (c << 7);
3427 byte f = c ? C_FLAG : 0;
3430 f |= R.getF() & (X_FLAG | Y_FLAG);
3432 f |= ZSPXYTable[reg];
3437 template <
class T>
template<
int EE>
inline byte CPUCore<T>::RRC_X(
unsigned x) {
3438 byte res = RRC(RDMEM(x, T::CC_SET_XHL_1 + EE));
3439 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3442 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rrc_R() {
3443 R.set8<REG>(RRC(R.get8<REG>()));
return T::CC_SET_R;
3445 template <
class T>
int CPUCore<T>::rrc_xhl() {
3446 RRC_X<0>(R.getHL());
return T::CC_SET_XHL;
3448 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::rrc_xix_R(
unsigned a) {
3450 R.set8<REG>(RRC_X<T::CC_DD + T::EE_SET_XIX>(a));
3451 return T::CC_DD + T::CC_SET_XIX;
3455 template <
class T>
inline byte CPUCore<T>::SLA(
byte reg) {
3458 byte f = c ? C_FLAG : 0;
3461 f |= R.getF() & (X_FLAG | Y_FLAG);
3463 f |= ZSPXYTable[reg];
3468 template <
class T>
template<
int EE>
inline byte CPUCore<T>::SLA_X(
unsigned x) {
3469 byte res = SLA(RDMEM(x, T::CC_SET_XHL_1 + EE));
3470 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3473 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::sla_R() {
3474 R.set8<REG>(SLA(R.get8<REG>()));
return T::CC_SET_R;
3476 template <
class T>
int CPUCore<T>::sla_xhl() {
3477 SLA_X<0>(R.getHL());
return T::CC_SET_XHL;
3479 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::sla_xix_R(
unsigned a) {
3481 R.set8<REG>(SLA_X<T::CC_DD + T::EE_SET_XIX>(a));
3482 return T::CC_DD + T::CC_SET_XIX;
3486 template <
class T>
inline byte CPUCore<T>::SLL(
byte reg) {
3487 assert(!T::isR800());
3489 reg = (reg << 1) | 1;
3490 byte f = c ? C_FLAG : 0;
3491 f |= ZSPXYTable[reg];
3495 template <
class T>
template<
int EE>
inline byte CPUCore<T>::SLL_X(
unsigned x) {
3496 byte res = SLL(RDMEM(x, T::CC_SET_XHL_1 + EE));
3497 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3500 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::sll_R() {
3501 R.set8<REG>(SLL(R.get8<REG>()));
return T::CC_SET_R;
3503 template <
class T>
int CPUCore<T>::sll_xhl() {
3504 SLL_X<0>(R.getHL());
return T::CC_SET_XHL;
3506 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::sll_xix_R(
unsigned a) {
3508 R.set8<REG>(SLL_X<T::CC_DD + T::EE_SET_XIX>(a));
3509 return T::CC_DD + T::CC_SET_XIX;
3511 template <
class T>
int CPUCore<T>::sll2() {
3512 assert(T::isR800());
3513 byte f = (R.getF() & (X_FLAG | Y_FLAG)) |
3517 return T::CC_DD + T::CC_SET_XIX;
3521 template <
class T>
inline byte CPUCore<T>::SRA(
byte reg) {
3523 reg = (reg >> 1) | (reg & 0x80);
3524 byte f = c ? C_FLAG : 0;
3527 f |= R.getF() & (X_FLAG | Y_FLAG);
3529 f |= ZSPXYTable[reg];
3534 template <
class T>
template<
int EE>
inline byte CPUCore<T>::SRA_X(
unsigned x) {
3535 byte res = SRA(RDMEM(x, T::CC_SET_XHL_1 + EE));
3536 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3539 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::sra_R() {
3540 R.set8<REG>(SRA(R.get8<REG>()));
return T::CC_SET_R;
3542 template <
class T>
int CPUCore<T>::sra_xhl() {
3543 SRA_X<0>(R.getHL());
return T::CC_SET_XHL;
3545 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::sra_xix_R(
unsigned a) {
3547 R.set8<REG>(SRA_X<T::CC_DD + T::EE_SET_XIX>(a));
3548 return T::CC_DD + T::CC_SET_XIX;
3552 template <
class T>
inline byte CPUCore<T>::SRL(
byte reg) {
3555 byte f = c ? C_FLAG : 0;
3558 f |= R.getF() & (X_FLAG | Y_FLAG);
3560 f |= ZSPXYTable[reg];
3565 template <
class T>
template<
int EE>
inline byte CPUCore<T>::SRL_X(
unsigned x) {
3566 byte res = SRL(RDMEM(x, T::CC_SET_XHL_1 + EE));
3567 WRMEM(x, res, T::CC_SET_XHL_2 + EE);
3570 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::srl_R() {
3571 R.set8<REG>(SRL(R.get8<REG>()));
return T::CC_SET_R;
3573 template <
class T>
int CPUCore<T>::srl_xhl() {
3574 SRL_X<0>(R.getHL());
return T::CC_SET_XHL;
3576 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::srl_xix_R(
unsigned a) {
3578 R.set8<REG>(SRL_X<T::CC_DD + T::EE_SET_XIX>(a));
3579 return T::CC_DD + T::CC_SET_XIX;
3583 template <
class T>
int CPUCore<T>::rla() {
3584 byte c = R.getF() & C_FLAG;
3585 byte f = (R.getA() & 0x80) ? C_FLAG : 0;
3587 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG | Y_FLAG);
3589 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG);
3591 R.setA((R.getA() << 1) | (c ? 1 : 0));
3593 f |= R.getA() & (X_FLAG | Y_FLAG);
3598 template <
class T>
int CPUCore<T>::rlca() {
3599 R.setA((R.getA() << 1) | (R.getA() >> 7));
3602 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG | Y_FLAG);
3603 f |= R.getA() & C_FLAG;
3605 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG);
3606 f |= R.getA() & (Y_FLAG | X_FLAG | C_FLAG);
3611 template <
class T>
int CPUCore<T>::rra() {
3612 byte c = (R.getF() & C_FLAG) << 7;
3613 byte f = (R.getA() & 0x01) ? C_FLAG : 0;
3615 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG | Y_FLAG);
3617 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG);
3619 R.setA((R.getA() >> 1) | c);
3621 f |= R.getA() & (X_FLAG | Y_FLAG);
3626 template <
class T>
int CPUCore<T>::rrca() {
3627 byte f = R.getA() & C_FLAG;
3629 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG | Y_FLAG);
3631 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG);
3633 R.setA((R.getA() >> 1) | (R.getA() << 7));
3635 f |= R.getA() & (X_FLAG | Y_FLAG);
3643 template <
class T>
int CPUCore<T>::rld() {
3644 byte val = RDMEM(R.getHL(), T::CC_RLD_1);
3645 T::setMemPtr(R.getHL() + 1);
3646 WRMEM(R.getHL(), (val << 4) | (R.getA() & 0x0F), T::CC_RLD_2);
3647 R.setA((R.getA() & 0xF0) | (val >> 4));
3650 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
3651 f |= ZSPTable[R.getA()];
3653 f |= R.getF() & C_FLAG;
3654 f |= ZSPXYTable[R.getA()];
3661 template <
class T>
int CPUCore<T>::rrd() {
3662 byte val = RDMEM(R.getHL(), T::CC_RLD_1);
3663 T::setMemPtr(R.getHL() + 1);
3664 WRMEM(R.getHL(), (val >> 4) | (R.getA() << 4), T::CC_RLD_2);
3665 R.setA((R.getA() & 0xF0) | (val & 0x0F));
3668 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
3669 f |= ZSPTable[R.getA()];
3671 f |= R.getF() & C_FLAG;
3672 f |= ZSPXYTable[R.getA()];
3680 template <
class T>
template<
int EE>
inline void CPUCore<T>::PUSH(
unsigned reg) {
3681 R.setSP(R.getSP() - 2);
3682 WR_WORD_rev<true, true>(R.getSP(), reg, T::CC_PUSH_1 + EE);
3684 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::push_SS() {
3685 PUSH<EE>(R.get16<REG>());
return T::CC_PUSH + EE;
3689 template <
class T>
template <
int EE>
inline unsigned CPUCore<T>::POP() {
3690 unsigned addr = R.getSP();
3692 return RD_WORD(addr, T::CC_POP_1 + EE);
3694 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::pop_SS() {
3695 R.set16<REG>(POP<EE>());
return T::CC_POP + EE;
3700 template <
class T>
template<
typename COND>
int CPUCore<T>::call(COND cond) {
3701 unsigned addr = RD_WORD_PC(T::CC_CALL_1);
3703 if (cond(R.getF())) {
3704 PUSH<T::EE_CALL>(R.getPC());
3706 return T::CC_CALL_A;
3708 return T::CC_CALL_B;
3714 template <
class T>
template<
unsigned ADDR>
int CPUCore<T>::rst() {
3723 template <
class T>
template<
int EE,
typename COND>
inline int CPUCore<T>::RET(COND cond) {
3724 if (cond(R.getF())) {
3725 unsigned addr = POP<EE>();
3728 return T::CC_RET_A + EE;
3730 return T::CC_RET_B + EE;
3733 template <
class T>
template<
typename COND>
int CPUCore<T>::ret(COND cond) {
3734 return RET<T::EE_RET_C>(cond);
3736 template <
class T>
int CPUCore<T>::ret() {
3737 return RET<0>(CondTrue());
3739 template <
class T>
int CPUCore<T>::retn() {
3740 R.setIFF1(R.getIFF2());
3741 setSlowInstructions();
3742 return RET<T::EE_RETN>(CondTrue());
3747 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::jp_SS() {
3748 R.setPC(R.get16<REG>()); T::R800ForcePageBreak();
return T::CC_JP_HL + EE;
3752 template <
class T>
template<
typename COND>
int CPUCore<T>::jp(COND cond) {
3753 unsigned addr = RD_WORD_PC(T::CC_JP_1);
3755 if (cond(R.getF())) {
3757 T::R800ForcePageBreak();
3765 template <
class T>
template<
typename COND>
int CPUCore<T>::jr(COND cond) {
3766 offset ofst = RDMEM_OPCODE(T::CC_JR_1);
3767 if (cond(R.getF())) {
3768 if ((R.getPC() & 0xFF) == 0) {
3796 T::R800ForcePageBreak();
3798 R.setPC((R.getPC() + ofst) & 0xFFFF);
3799 T::setMemPtr(R.getPC());
3807 template <
class T>
int CPUCore<T>::djnz() {
3808 byte b = R.getB() - 1;
3810 offset ofst = RDMEM_OPCODE(T::CC_JR_1 + T::EE_DJNZ);
3812 if ((R.getPC() & 0xFF) == 0) {
3814 T::R800ForcePageBreak();
3816 R.setPC((R.getPC() + ofst) & 0xFFFF);
3817 T::setMemPtr(R.getPC());
3818 return T::CC_JR_A + T::EE_DJNZ;
3820 return T::CC_JR_B + T::EE_DJNZ;
3825 template <
class T>
template<CPU::Reg16 REG,
int EE>
int CPUCore<T>::ex_xsp_SS() {
3826 unsigned res = RD_WORD_impl<true, false>(R.getSP(), T::CC_EX_SP_HL_1 + EE);
3828 WR_WORD_rev<false, true>(R.getSP(), R.get16<REG>(), T::CC_EX_SP_HL_2 + EE);
3830 return T::CC_EX_SP_HL + EE;
3834 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::in_R_c() {
3835 if (T::isR800()) T::waitForEvenCycle(T::CC_IN_R_C_1);
3836 T::setMemPtr(R.getBC() + 1);
3837 byte res = READ_PORT(R.getBC(), T::CC_IN_R_C_1);
3840 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
3843 f |= R.getF() & C_FLAG;
3844 f |= ZSPXYTable[res];
3848 return T::CC_IN_R_C;
3852 template <
class T>
int CPUCore<T>::in_a_byte() {
3853 unsigned y = RDMEM_OPCODE(T::CC_IN_A_N_1) + 256 * R.getA();
3854 T::setMemPtr(y + 1);
3855 if (T::isR800()) T::waitForEvenCycle(T::CC_IN_A_N_2);
3856 R.setA(READ_PORT(y, T::CC_IN_A_N_2));
3857 return T::CC_IN_A_N;
3861 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::out_c_R() {
3862 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_C_R_1);
3863 T::setMemPtr(R.getBC() + 1);
3864 WRITE_PORT(R.getBC(), R.get8<REG>(), T::CC_OUT_C_R_1);
3865 return T::CC_OUT_C_R;
3867 template <
class T>
int CPUCore<T>::out_c_0() {
3869 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_C_R_1);
3870 T::setMemPtr(R.getBC() + 1);
3871 byte out_c_x = isTurboR ? 255 : 0;
3872 WRITE_PORT(R.getBC(), out_c_x, T::CC_OUT_C_R_1);
3873 return T::CC_OUT_C_R;
3877 template <
class T>
int CPUCore<T>::out_byte_a() {
3878 byte port = RDMEM_OPCODE(T::CC_OUT_N_A_1);
3879 unsigned y = (R.getA() << 8) | port;
3880 T::setMemPtr((R.getA() << 8) | ((port + 1) & 255));
3881 if (T::isR800()) T::waitForEvenCycle(T::CC_OUT_N_A_2);
3882 WRITE_PORT(y, R.getA(), T::CC_OUT_N_A_2);
3883 return T::CC_OUT_N_A;
3888 template <
class T>
inline int CPUCore<T>::BLOCK_CP(
int increase,
bool repeat) {
3889 T::setMemPtr(T::getMemPtr() + increase);
3890 byte val = RDMEM(R.getHL(), T::CC_CPI_1);
3891 byte res = R.getA() - val;
3892 R.setHL(R.getHL() + increase);
3893 R.setBC(R.getBC() - 1);
3894 byte f = ((R.getA() ^ val ^ res) & H_FLAG) |
3897 (R.getBC() ? V_FLAG : 0);
3899 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
3901 f |= R.getF() & C_FLAG;
3902 unsigned k = res - ((f & H_FLAG) >> 4);
3903 f |= (k << 4) & Y_FLAG;
3907 if (repeat && R.getBC() && res) {
3908 R.setPC(R.getPC() - 2);
3909 T::setMemPtr(R.getPC() + 1);
3915 template <
class T>
int CPUCore<T>::cpd() {
return BLOCK_CP(-1,
false); }
3916 template <
class T>
int CPUCore<T>::cpi() {
return BLOCK_CP( 1,
false); }
3917 template <
class T>
int CPUCore<T>::cpdr() {
return BLOCK_CP(-1,
true ); }
3918 template <
class T>
int CPUCore<T>::cpir() {
return BLOCK_CP( 1,
true ); }
3922 template <
class T>
inline int CPUCore<T>::BLOCK_LD(
int increase,
bool repeat) {
3923 byte val = RDMEM(R.getHL(), T::CC_LDI_1);
3924 WRMEM(R.getDE(), val, T::CC_LDI_2);
3925 R.setHL(R.getHL() + increase);
3926 R.setDE(R.getDE() + increase);
3927 R.setBC(R.getBC() - 1);
3928 byte f = R.getBC() ? V_FLAG : 0;
3930 f |= R.getF() & (S_FLAG | Z_FLAG | C_FLAG | X_FLAG | Y_FLAG);
3932 f |= R.getF() & (S_FLAG | Z_FLAG | C_FLAG);
3933 f |= ((R.getA() + val) << 4) & Y_FLAG;
3934 f |= (R.getA() + val) & X_FLAG;
3937 if (repeat && R.getBC()) {
3938 R.setPC(R.getPC() - 2);
3939 T::setMemPtr(R.getPC() + 1);
3945 template <
class T>
int CPUCore<T>::ldd() {
return BLOCK_LD(-1,
false); }
3946 template <
class T>
int CPUCore<T>::ldi() {
return BLOCK_LD( 1,
false); }
3947 template <
class T>
int CPUCore<T>::lddr() {
return BLOCK_LD(-1,
true ); }
3948 template <
class T>
int CPUCore<T>::ldir() {
return BLOCK_LD( 1,
true ); }
3952 template <
class T>
inline int CPUCore<T>::BLOCK_IN(
int increase,
bool repeat) {
3954 if (T::isR800()) T::waitForEvenCycle(T::CC_INI_1);
3955 T::setMemPtr(R.getBC() + increase);
3956 R.setBC(R.getBC() - 0x100);
3957 byte val = READ_PORT(R.getBC(), T::CC_INI_1);
3958 WRMEM(R.getHL(), val, T::CC_INI_2);
3959 R.setHL(R.getHL() + increase);
3960 unsigned k = val + ((R.getC() + increase) & 0xFF);
3962 R.setF(((val & S_FLAG) >> 6) |
3963 ((k & 0x100) ? (H_FLAG | C_FLAG) : 0) |
3965 (ZSPXYTable[(k & 0x07) ^ b] & P_FLAG));
3967 R.setPC(R.getPC() - 2);
3973 template <
class T>
int CPUCore<T>::ind() {
return BLOCK_IN(-1,
false); }
3974 template <
class T>
int CPUCore<T>::ini() {
return BLOCK_IN( 1,
false); }
3975 template <
class T>
int CPUCore<T>::indr() {
return BLOCK_IN(-1,
true ); }
3976 template <
class T>
int CPUCore<T>::inir() {
return BLOCK_IN( 1,
true ); }
3980 template <
class T>
inline int CPUCore<T>::BLOCK_OUT(
int increase,
bool repeat) {
3982 byte val = RDMEM(R.getHL(), T::CC_OUTI_1);
3983 R.setHL(R.getHL() + increase);
3984 if (T::isR800()) T::waitForEvenCycle(T::CC_OUTI_2);
3985 WRITE_PORT(R.getBC(), val, T::CC_OUTI_2);
3986 R.setBC(R.getBC() - 0x100);
3987 T::setMemPtr(R.getBC() + increase);
3988 unsigned k = val + R.getL();
3990 R.setF(((val & S_FLAG) >> 6) |
3991 ((k & 0x100) ? (H_FLAG | C_FLAG) : 0) |
3993 (ZSPXYTable[(k & 0x07) ^ b] & P_FLAG));
3995 R.setPC(R.getPC() - 2);
4001 template <
class T>
int CPUCore<T>::outd() {
return BLOCK_OUT(-1,
false); }
4002 template <
class T>
int CPUCore<T>::outi() {
return BLOCK_OUT( 1,
false); }
4003 template <
class T>
int CPUCore<T>::otdr() {
return BLOCK_OUT(-1,
true ); }
4004 template <
class T>
int CPUCore<T>::otir() {
return BLOCK_OUT( 1,
true ); }
4008 template <
class T>
int CPUCore<T>::nop() {
return T::CC_NOP; }
4009 template <
class T>
int CPUCore<T>::ccf() {
4013 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | C_FLAG | X_FLAG | Y_FLAG | H_FLAG);
4015 f |= (R.getF() & C_FLAG) << 4;
4019 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | C_FLAG | Y_FLAG);
4020 f |= (R.getF() | R.getA()) & X_FLAG;
4022 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | C_FLAG);
4023 f |= (R.getF() | R.getA()) & (X_FLAG | Y_FLAG);
4030 template <
class T>
int CPUCore<T>::cpl() {
4031 R.setA(R.getA() ^ 0xFF);
4032 byte f = H_FLAG | N_FLAG;
4036 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | C_FLAG);
4037 f |= R.getA() & (X_FLAG | Y_FLAG);
4042 template <
class T>
int CPUCore<T>::daa() {
4046 if ((f & H_FLAG) || ((R.getA() & 0xf) > 9)) adjust += 6;
4047 if ((f & C_FLAG) || (R.getA() > 0x99)) adjust += 0x60;
4048 if (f & N_FLAG) a -= adjust;
else a += adjust;
4050 f &= C_FLAG | N_FLAG | X_FLAG | Y_FLAG;
4053 f &= C_FLAG | N_FLAG;
4056 f |= (R.getA() > 0x99) | ((R.getA() ^ a) & H_FLAG);
4061 template <
class T>
int CPUCore<T>::neg() {
4063 unsigned a = R.getA();
4064 unsigned res = -signed(a);
4065 byte f = ((res & 0x100) ? C_FLAG : 0) |
4067 ((res ^ a) & H_FLAG) |
4068 ((a & res & 0x80) >> 5);
4070 f |= ZSTable[res & 0xFF];
4071 f |= R.getF() & (X_FLAG | Y_FLAG);
4073 f |= ZSXYTable[res & 0xFF];
4079 template <
class T>
int CPUCore<T>::scf() {
4082 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | X_FLAG | Y_FLAG);
4087 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG | Y_FLAG);
4088 f |= (R.getF() | R.getA()) & X_FLAG;
4090 f |= R.getF() & (S_FLAG | Z_FLAG | P_FLAG);
4091 f |= (R.getF() | R.getA()) & (X_FLAG | Y_FLAG);
4098 template <
class T>
int CPUCore<T>::ex_af_af() {
4099 unsigned t = R.getAF2(); R.setAF2(R.getAF()); R.setAF(t);
4102 template <
class T>
int CPUCore<T>::ex_de_hl() {
4103 unsigned t = R.getDE(); R.setDE(R.getHL()); R.setHL(t);
4106 template <
class T>
int CPUCore<T>::exx() {
4107 unsigned t1 = R.getBC2(); R.setBC2(R.getBC()); R.setBC(t1);
4108 unsigned t2 = R.getDE2(); R.setDE2(R.getDE()); R.setDE(t2);
4109 unsigned t3 = R.getHL2(); R.setHL2(R.getHL()); R.setHL(t3);
4113 template <
class T>
int CPUCore<T>::di() {
4118 template <
class T>
int CPUCore<T>::ei() {
4122 setSlowInstructions();
4125 template <
class T>
int CPUCore<T>::halt() {
4127 setSlowInstructions();
4129 if (!(R.getIFF1() || R.getIFF2())) {
4130 diHaltCallback.execute();
4134 template <
class T>
template<
unsigned N>
int CPUCore<T>::im_N() {
4135 R.setIM(N);
return T::CC_IM;
4139 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::ld_a_IR() {
4140 R.setA(R.get8<REG>());
4141 byte f = R.getIFF2() ? V_FLAG : 0;
4143 f |= R.getF() & (C_FLAG | X_FLAG | Y_FLAG);
4144 f |= ZSTable[R.getA()];
4146 f |= R.getF() & C_FLAG;
4147 f |= ZSXYTable[R.getA()];
4150 setSlowInstructions();
4153 return T::CC_LD_A_I;
4157 template <
class T>
int CPUCore<T>::ld_r_a() {
4165 byte val = R.getA();
4166 if (T::isR800()) val -= 1;
4168 return T::CC_LD_A_I;
4170 template <
class T>
int CPUCore<T>::ld_i_a() {
4172 return T::CC_LD_A_I;
4176 template <
class T>
template<CPU::Reg8 REG>
int CPUCore<T>::mulub_a_R() {
4177 assert(T::isR800());
4183 R.setHL(
unsigned(R.getA()) * R.get8<REG>());
4184 R.setF((R.getF() & (N_FLAG | H_FLAG | X_FLAG | Y_FLAG)) |
4186 (R.getHL() ? 0 : Z_FLAG) |
4187 ((R.getHL() & 0xFF00) ? C_FLAG : 0));
4192 template <
class T>
template<CPU::Reg16 REG>
int CPUCore<T>::muluw_hl_SS() {
4193 assert(T::isR800());
4199 unsigned res = unsigned(R.getHL()) * R.get16<REG>();
4201 R.setHL(res & 0xffff);
4202 R.setF((R.getF() & (N_FLAG | H_FLAG | X_FLAG | Y_FLAG)) |
4204 (res ? 0 : Z_FLAG) |
4205 ((res & 0xFFFF0000) ? C_FLAG : 0));
4214 template<
class T>
template<
typename Archive>
4218 ar.serialize(
"regs", R);
4219 if (ar.versionBelow(version, 2)) {
4220 unsigned memptr = 0;
4221 ar.serialize(
"memptr", memptr);
4222 T::setMemPtr(memptr);
4225 if (ar.isLoader()) {
4226 invalidateMemCache(0x0000, 0x10000);
4235 if (T::isR800() && ar.versionBelow(version, 3)) {
4236 motherboard.getMSXCliComm().printWarning(
4237 "Loading an old savestate: the timing of the R800 "
4238 "emulation has changed. This may cause synchronization "
4239 "problems in replay.");