43 static const char *memop[4] = {
".d",
"",
".h",
".b" };
48 static const char *m88k_cr_name(
int i)
50 const char **cr_names = m88k_cr_names;
62 , m_m88k_type(
"88100")
67 memset((
void*) &m_type, 0,
sizeof(m_type));
68 for (
size_t j=0; cpu_type_defs[j].
name != NULL; j++) {
69 if (m_m88k_type == cpu_type_defs[j].name) {
70 m_type = cpu_type_defs[j];
75 if (m_type.name == NULL) {
76 std::cerr <<
"Internal error: Unimplemented M88K type?\n";
77 throw std::exception();
100 m_initial_r31 = 0x00000000;
114 settings[
"model"] =
"88100";
115 settings[
"r31"] =
"0x00000000";
171 "must contain the value 0.\n");
175 if (
m_pc > (uint64_t)0xffffffff) {
177 "must be a 32-bit value.\n");
183 " its lower two bits clear!\n");
189 "register following r31 must mimic the r0 register.\nIf" 190 " you encounter this message, please write a bug report!\n");
205 "must contain the value 0.\n");
210 if (m_m88k_type != m_type.
name) {
212 for (
size_t j=0; cpu_type_defs[j].
name != NULL; j++) {
213 if (m_m88k_type == cpu_type_defs[j].name) {
214 m_type = cpu_type_defs[j];
223 ss <<
"Unknown model \"" + m_m88k_type +
"\". Available types are:\n";
224 for (
size_t j=0; cpu_type_defs[j].
name != NULL; j++) {
227 ss << cpu_type_defs[j].
name;
246 ss.flags(std::ios::hex);
248 if (arguments.size() == 0 ||
249 find(arguments.begin(), arguments.end(),
"r") != arguments.end()) {
250 ss <<
" pc = 0x" << std::setfill(
'0') << std::setw(8) <<
m_pc;
254 ss <<
" <" << symbol <<
">";
258 stringstream regname;
261 ss << std::setfill(
' ');
262 ss << std::setw(5) << regname.str() <<
" = 0x";
263 ss << std::setfill(
'0') << std::setw(8) << m_r[i];
273 if (find(arguments.begin(), arguments.end(),
"cr") != arguments.end()) {
275 stringstream regname;
276 regname <<
"cr" << i;
278 ss << std::setfill(
' ');
279 ss << std::setw(5) << regname.str() <<
" = 0x";
280 ss << std::setfill(
'0') << std::setw(8) << m_cr[i];
290 if (find(arguments.begin(), arguments.end(),
"crn") != arguments.end()) {
292 ss << std::setfill(
' ');
293 ss << std::setw(5) << m88k_cr_name(i) <<
" = 0x";
294 ss << std::setfill(
'0') << std::setw(8) << m_cr[i];
304 if (find(arguments.begin(), arguments.end(),
"fcr") != arguments.end()) {
306 stringstream regname;
307 regname <<
"fcr" << i;
309 ss << std::setfill(
' ');
310 ss << std::setw(5) << regname.str() <<
" = 0x";
311 ss << std::setfill(
'0') << std::setw(8) << m_fcr[i];
322 ss <<
"M88K usage: .registers [r] [cr] [crn] [fcr]\n" 323 "r = pc and general purpose registers (default)\n" 324 "cr = control registers\n" 325 "crn = control registers with symbolic names instead of crX\n" 326 "fcr = floating point control registers\n";
342 return instr_ToBeTranslated;
351 paddr = vaddr & 0xffffffff;
357 void M88K_CPUComponent::Exception(
int vector,
int is_trap)
359 std::cerr <<
"TODO: M88K exception\n";
360 throw std::exception();
365 unsigned char *instruction, vector<string>& result)
367 const size_t instrSize =
sizeof(uint32_t);
369 if (maxLen < instrSize) {
375 uint32_t instructionWord = *((uint32_t *)(
void*) instruction);
381 const uint32_t iw = instructionWord;
386 ss.flags(std::ios::hex);
387 ss << std::setfill(
'0') << std::setw(8) << (uint32_t) iw;
389 ss <<
" (delayslot)";
390 result.push_back(ss.str());
393 const uint32_t op26 = (iw >> 26) & 0x3f;
394 const uint32_t op11 = (iw >> 11) & 0x1f;
395 const uint32_t op10 = (iw >> 10) & 0x3f;
396 const uint32_t d = (iw >> 21) & 0x1f;
397 const uint32_t s1 = (iw >> 16) & 0x1f;
398 const uint32_t s2 = iw & 0x1f;
399 const uint32_t op3d = (iw >> 8) & 0xff;
400 const uint32_t imm16 = iw & 0xffff;
401 const uint32_t w5 = (iw >> 5) & 0x1f;
402 const uint32_t cr6 = (iw >> 5) & 0x3f;
403 const int32_t d16 = ((int16_t) (iw & 0xffff)) * 4;
404 const int32_t d26 = ((int32_t)((iw & 0x03ffffff) << 6)) >> 4;
436 if (iw == 0x00000000) {
437 result.push_back(
"-");
440 result.push_back(opcode_names[op26]);
443 ss <<
"r" << d <<
",r" << s1;
444 ss.flags(std::ios::hex | std::ios::showbase);
446 result.push_back(ss.str());
451 if ((iw & 0x001ff81f) == 0x00004000) {
452 result.push_back(
"ldcr");
454 ss <<
"r" << d <<
",cr" << cr6;
455 result.push_back(ss.str());
457 stringstream comment;
458 comment <<
"; cr" << cr6 <<
" = " << m88k_cr_name(cr6);
459 result.push_back(comment.str());
460 }
else if ((iw & 0x001ff81f) == 0x00004800) {
461 result.push_back(
"fldcr");
463 ss <<
"r" << d <<
",fcr" << cr6;
464 result.push_back(ss.str());
465 }
else if ((iw & 0x03e0f800) == 0x00008000) {
466 result.push_back(
"stcr");
468 ss <<
"r" << s1 <<
",cr" << cr6;
469 result.push_back(ss.str());
471 result.push_back(
"; Weird encoding: s1 != s2");
473 stringstream comment;
474 comment <<
"; cr" << cr6 <<
" = " << m88k_cr_name(cr6);
475 result.push_back(comment.str());
476 }
else if ((iw & 0x03e0f800) == 0x00008800) {
477 result.push_back(
"fstcr");
479 ss <<
"r" << s1 <<
",fcr" << cr6;
480 result.push_back(ss.str());
482 result.push_back(
"; Weird encoding: s1 != s2");
483 }
else if ((iw & 0x0000f800) == 0x0000c000) {
484 result.push_back(
"xcr");
486 ss <<
"r" << d <<
",r" << s1 <<
",cr" << cr6;
487 result.push_back(ss.str());
489 result.push_back(
"; Weird encoding: s1 != s2");
491 stringstream comment;
492 comment <<
"; cr" << cr6 <<
" = " << m88k_cr_name(cr6);
493 result.push_back(comment.str());
494 }
else if ((iw & 0x0000f800) == 0x0000c800) {
495 result.push_back(
"fxcr");
497 ss <<
"r" << d <<
",r" << s1 <<
",fcr" << cr6;
498 result.push_back(ss.str());
500 result.push_back(
"; Weird encoding: s1 != s2");
502 result.push_back(
"unimpl_0x20_variant");
516 case 0x00: ss <<
"fmul";
break;
517 case 0x05: ss <<
"fadd";
break;
518 case 0x06: ss <<
"fsub";
break;
519 case 0x07: ss <<
"fcmp";
break;
520 case 0x0e: ss <<
"fdiv";
break;
523 (((iw >> 5) & 1)?
"d" :
"s") <<
524 (((iw >> 9) & 1)?
"d" :
"s") <<
525 (((iw >> 7) & 1)?
"d" :
"s");
526 result.push_back(ss.str());
529 ss2 <<
"r" << d <<
",r" << s1 <<
",r" << s2;
530 result.push_back(ss2.str());
537 case 0x04: ss <<
"flt";
break;
539 ss <<
"." << (((iw >> 5) & 1)?
"d" :
"s") <<
"s";
540 result.push_back(ss.str());
543 ss2 <<
"r" << d <<
",r" << s2;
544 result.push_back(ss2.str());
553 case 0x09: ss <<
"int";
break;
554 case 0x0a: ss <<
"nint";
break;
555 case 0x0b: ss <<
"trnc";
break;
557 ss <<
".s" << (((iw >> 7) & 1)?
"d" :
"s");
558 result.push_back(ss.str());
561 ss2 <<
"r" << d <<
",r" << s2;
562 result.push_back(ss2.str());
567 ss <<
"unimpl_0x21, op11=" << op11;
568 result.push_back(ss.str());
578 result.push_back(opcode_names[op26]);
581 ss.flags(std::ios::hex | std::ios::showbase);
582 ss << ((uint32_t) (vaddr + d26));
583 result.push_back(ss.str());
586 (uint32_t) (vaddr + d26),
true);
588 result.push_back(
"; <" + symbol +
">");
599 result.push_back(opcode_names[op26]);
602 if (op26 == 0x3a || op26 == 0x3b) {
605 case 0x1: ss <<
"gt0";
break;
606 case 0x2: ss <<
"eq0";
break;
607 case 0x3: ss <<
"ge0";
break;
608 case 0x7: ss <<
"not_maxneg";
break;
609 case 0x8: ss <<
"maxneg";
break;
610 case 0xc: ss <<
"lt0";
break;
611 case 0xd: ss <<
"ne0";
break;
612 case 0xe: ss <<
"le0";
break;
613 default: ss <<
"unk_" << d;
619 ss <<
",r" << s1 <<
",";
621 ss.flags(std::ios::hex | std::ios::showbase);
622 ss << ((uint32_t) (vaddr + d16));
623 result.push_back(ss.str());
626 (uint32_t) (vaddr + d16),
true);
628 result.push_back(
"; <" + symbol +
">");
634 if ((iw & 0x0000f000)==0x1000 || (iw & 0x0000f000)==0x2000) {
637 ss << ((iw & 0x0000f000) == 0x1000?
"ld" :
"st");
639 switch (iw & 0x00000c00) {
640 case 0x000: ss <<
".d";
break;
642 case 0x800: ss <<
".x";
break;
643 default: ss <<
".UNIMPLEMENTED";
651 result.push_back(ss.str());
654 ss2 <<
"r" << d <<
",r" << s1;
656 ss2 <<
"[r" << s2 <<
"]";
660 result.push_back(ss2.str());
661 }
else switch (op10) {
670 result.push_back(opcode_names_3c[op10]);
673 ss <<
"r" << d <<
",r" << s1 <<
",";
680 ss <<
"<" << s2 <<
">";
682 result.push_back(ss.str());
689 result.push_back(opcode_names_3c[op10]);
692 ss << d <<
",r" << s1 <<
",";
693 ss.flags(std::ios::hex | std::ios::showbase);
695 result.push_back(ss.str());
700 ss <<
"unimpl_" << opcode_names_3c[op10];
701 result.push_back(ss.str());
707 if ((iw & 0xf000) <= 0x3fff) {
711 switch (iw & 0xf000) {
712 case 0x2000: op <<
"st";
break;
713 case 0x3000: op <<
"lda";
break;
714 default:
if ((iw & 0xf800) >= 0x0800)
720 if ((iw & 0xf000) >= 0x1000) {
722 op << memop[(iw >> 10) & 3];
723 }
else if ((iw & 0xf800) == 0x0000) {
729 if ((iw & 0xf00) < 0xc00)
740 result.push_back(op.str());
743 ss <<
"r" << d <<
",r" << s1;
745 ss <<
"[r" << s2 <<
"]";
749 result.push_back(ss.str());
750 }
else switch (op3d) {
788 result.push_back(opcode_names_3d[op3d]);
791 ss <<
"r" << d <<
",r" << s1 <<
",r" << s2;
792 result.push_back(ss.str());
801 result.push_back(opcode_names_3d[op3d]);
804 ss <<
"(r" << s2 <<
")";
805 result.push_back(ss.str());
812 result.push_back(opcode_names_3d[op3d]);
815 ss <<
"r" << d <<
",r" << s2;
816 result.push_back(ss.str());
822 result.push_back(opcode_names_3d[op3d]);
825 ss <<
"r" << s1 <<
",r" << s2;
826 result.push_back(ss.str());
832 result.push_back(
"rte");
839 ss <<
"illop" << (iw & 0xff);
840 result.push_back(ss.str());
844 result.push_back(
"gxemul_prom_call");
847 result.push_back(
"gxemul_fail_early");
850 result.push_back(
"gxemul_fail_late");
854 ss <<
"unimpl_3d_0xfc_" << (iw & 0xff);
855 result.push_back(ss.str());
861 ss <<
"unimpl_" << opcode_names_3d[op3d];
862 result.push_back(ss.str());
869 result.push_back(opcode_names[op26]);
873 ss.flags(std::ios::hex | std::ios::showbase);
875 result.push_back(ss.str());
882 ss <<
"unimpl_" << opcode_names[op26];
883 result.push_back(ss.str());
894 if (attributeName ==
"stable")
897 if (attributeName ==
"description")
898 return "Motorola 88000 processor.";
907 void M88K_CPUComponent::stcr(
int cr, uint32_t value,
bool is_rte)
909 uint32_t old = m_cr[cr];
916 std::cerr <<
"TODO: attempt to change endianness by flipping" 917 " the endianness bit in the PSR. How should this" 918 " be handled? Aborting.\n";
919 std::cerr <<
"TODO: abort in a nicer way\n";
920 throw std::exception();
923 if (!is_rte && (old &
M88K_PSR_MODE) && !(value & M88K_PSR_MODE)) {
927 " cleared; this should be done using the RTE " 928 "instruction only, according to the M88100 " 929 "manual! Continuing anyway.\n");
934 std::cerr <<
"m88k stcr: TODO: MXM support\n";
935 std::cerr <<
"TODO: abort in a nicer way\n";
936 throw std::exception();
939 if ((old & M88K_PSR_MODE) != (value & M88K_PSR_MODE)) {
942 std::cerr <<
"m88k stcr: TODO: PSR mode switch.\n";
943 std::cerr <<
"TODO: abort in a nicer way\n";
944 throw std::exception();
964 ui->
ShowDebugMessage(
this,
"WARNING! bit 0 non-zero when writing to SSBR\n");
971 if (value & 0x00000fff) {
974 ui->
ShowDebugMessage(
this,
"WARNING! bits 0..11 non-zero when writing to VBR\n");
993 default:std::cerr <<
"m88k stcr: UNIMPLEMENTED cr = " << cr <<
"\n";
994 std::cerr <<
"TODO: abort in a nicer way\n";
995 throw std::exception();
1008 void M88K_CPUComponent::m88k_cmp(
struct DyntransIC *
ic, uint32_t y)
1021 if ((int32_t)x > (int32_t)y)
1055 void M88K_CPUComponent::m88k_extu(
struct DyntransIC *ic,
int w,
int o)
1057 uint32_t x =
REG32(ic->
arg[1]) >> o;
1065 void M88K_CPUComponent::m88k_ext(
struct DyntransIC *ic,
int w,
int o)
1106 void M88K_CPUComponent::m88k_mak(
struct DyntransIC *ic,
int w,
int o)
1149 }
else if (ic->
arg[2].
u32 == 0) {
1179 cpu->DyntransPCtoPointers();
1202 bool continueExecution =
cpu->FunctionTraceCall();
1203 cpu->DyntransPCtoPointers();
1205 if (!continueExecution)
1206 cpu->m_nextIC = &
cpu->m_abortIC;
1218 cpu->m_exceptionOrAbortInDelaySlot =
false;
1219 cpu->m_inDelaySlot =
true;
1220 cpu->m_delaySlotTarget = (uint32_t) (startOfPage + ic->
arg[1].
u32);
1224 cpu->m_executedCycles ++;
1227 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1228 cpu->m_pc = (uint32_t) (startOfPage + ic->
arg[1].
u32);
1229 cpu->DyntransPCtoPointers();
1231 cpu->m_inDelaySlot =
false;
1236 cpu->m_exceptionOrAbortInDelaySlot =
false;
1248 cpu->m_inDelaySlot =
true;
1249 cpu->m_exceptionOrAbortInDelaySlot =
false;
1253 cpu->m_executedCycles ++;
1256 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1257 cpu->m_pc = (uint32_t) (startOfPage + ic->
arg[1].
u32);
1259 bool continueExecution =
cpu->FunctionTraceCall();
1260 cpu->DyntransPCtoPointers();
1262 cpu->m_inDelaySlot =
false;
1264 if (!continueExecution)
1265 cpu->m_nextIC = &
cpu->m_abortIC;
1270 cpu->m_exceptionOrAbortInDelaySlot =
false;
1281 cpu->m_inDelaySlot =
true;
1282 cpu->m_exceptionOrAbortInDelaySlot =
false;
1287 uint32_t old_pc =
cpu->m_pc;
1291 if (
cpu->m_showFunctionTraceCall)
1292 cpu->FunctionTraceCall();
1294 cpu->m_delaySlotTarget =
cpu->m_pc;
1297 cpu->m_nextIC = ic + 1;
1313 if (
op == 1) cond = ((int32_t)
REG32(ic->
arg[0]) > 0);
1314 else if (
op == 2) cond = ((int32_t)
REG32(ic->
arg[0]) == 0);
1315 else if (
op == 3) cond = ((int32_t)
REG32(ic->
arg[0]) >= 0);
1316 else if (
op == 7) cond = ((uint32_t)
REG32(ic->
arg[0]) != 0x80000000UL);
1317 else if (
op == 8) cond = ((uint32_t)
REG32(ic->
arg[0]) == 0x80000000UL);
1318 else if (
op == 12) cond = ((int32_t)
REG32(ic->
arg[0]) < 0);
1319 else if (
op == 13) cond = ((int32_t)
REG32(ic->
arg[0]) != 0);
1320 else cond = ((int32_t)
REG32(ic->
arg[0]) <= 0);
1327 cpu->m_inDelaySlot =
true;
1328 cpu->m_exceptionOrAbortInDelaySlot =
false;
1332 cpu->m_delaySlotTarget = (uint32_t) (
cpu->m_delaySlotTarget + ic->
arg[2].
u32);
1334 cpu->m_delaySlotTarget =
cpu->m_pc + 8;
1337 cpu->m_nextIC = ic + 1;
1340 cpu->m_inDelaySlot =
true;
1341 cpu->m_exceptionOrAbortInDelaySlot =
false;
1345 cpu->m_executedCycles ++;
1348 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1352 cpu->DyntransPCtoPointers();
1354 cpu->m_nextIC = ic + 2;
1357 cpu->m_inDelaySlot =
false;
1363 cpu->m_exceptionOrAbortInDelaySlot =
false;
1370 cpu->DyntransPCtoPointers();
1397 cpu->DyntransPCtoPointers();
1410 cpu->m_inDelaySlot =
true;
1411 cpu->m_exceptionOrAbortInDelaySlot =
false;
1415 cpu->m_executedCycles ++;
1418 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1422 cpu->DyntransPCtoPointers();
1424 cpu->m_nextIC = ic + 2;
1427 cpu->m_inDelaySlot =
false;
1433 cpu->m_exceptionOrAbortInDelaySlot =
false;
1446 cpu->m_inDelaySlot =
true;
1447 cpu->m_exceptionOrAbortInDelaySlot =
false;
1451 cpu->m_delaySlotTarget = (uint32_t) (
cpu->m_delaySlotTarget + ic->
arg[2].
u32);
1453 cpu->m_delaySlotTarget =
cpu->m_pc + 8;
1456 cpu->m_nextIC = ic + 1;
1463 bool continueExecution =
true;
1466 continueExecution =
cpu->FunctionTraceReturn();
1469 cpu->DyntransPCtoPointers();
1471 if (!continueExecution)
1472 cpu->m_nextIC = &
cpu->m_abortIC;
1481 cpu->m_inDelaySlot =
true;
1482 cpu->m_exceptionOrAbortInDelaySlot =
false;
1483 uint32_t branchTarget =
REG32(ic->
arg[2]);
1487 cpu->m_executedCycles ++;
1490 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1491 cpu->m_pc = branchTarget;
1492 cpu->DyntransPCtoPointers();
1494 cpu->m_inDelaySlot =
false;
1500 cpu->m_exceptionOrAbortInDelaySlot =
false;
1509 cpu->m_inDelaySlot =
true;
1510 cpu->m_exceptionOrAbortInDelaySlot =
false;
1511 uint32_t branchTarget =
REG32(ic->
arg[2]);
1515 cpu->m_executedCycles ++;
1518 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1519 bool continueExecution =
true;
1521 continueExecution =
cpu->FunctionTraceReturn();
1523 cpu->m_pc = branchTarget;
1524 cpu->DyntransPCtoPointers();
1526 cpu->m_inDelaySlot =
false;
1528 if (!continueExecution)
1529 cpu->m_nextIC = &
cpu->m_abortIC;
1535 cpu->m_exceptionOrAbortInDelaySlot =
false;
1546 cpu->FunctionTraceReturn();
1549 cpu->m_inDelaySlot =
true;
1550 cpu->m_exceptionOrAbortInDelaySlot =
false;
1597 cpu->m_nextIC = ic + 1;
1647 template<
bool store,
typename T,
bool doubleword,
bool regofs,
bool scaled,
bool signedLoad>
void M88K_CPUComponent::instr_loadstore(
CPUDyntransComponent* cpubase,
DyntransIC* ic)
1657 (scaled? (doubleword?
sizeof(uint64_t) :
sizeof(T)) : 1) *
1660 if (
sizeof(T) > 1 && (addr & (
sizeof(T)-1))) {
1666 cpu->AddressSelect(addr);
1680 if (
sizeof(T) ==
sizeof(uint16_t))
1681 data = (int16_t)data;
1682 if (
sizeof(T) ==
sizeof(uint8_t))
1683 data = (int8_t)data;
1692 uint32_t data2 = (* (((uint32_t*)(ic->
arg[0].
p)) + 1) );
1693 cpu->AddressSelect(addr +
sizeof(uint32_t));
1699 cpu->AddressSelect(addr +
sizeof(uint32_t));
1704 (* (((uint32_t*)(ic->
arg[0].
p)) + 1) ) = data2;
1727 cpu->m_executedCycles --;
1730 cpu->m_nextIC = &
cpu->m_abortIC;
1731 if (
cpu->m_inDelaySlot)
1732 cpu->m_exceptionOrAbortInDelaySlot =
true;
1744 cpu->m_pc +=
sizeof(uint32_t);
1747 cpu->m_nextIC = &
cpu->m_abortIC;
1748 if (
cpu->m_inDelaySlot)
1749 cpu->m_exceptionOrAbortInDelaySlot =
true;
1756 void M88K_CPUComponent::Translate(uint32_t iw,
struct DyntransIC* ic)
1761 uint32_t op26 = (iw >> 26) & 0x3f;
1763 uint32_t op10 = (iw >> 10) & 0x3f;
1764 uint32_t d = (iw >> 21) & 0x1f;
1765 uint32_t s1 = (iw >> 16) & 0x1f;
1766 uint32_t s2 = iw & 0x1f;
1768 uint32_t imm16 = iw & 0xffff;
1770 uint32_t cr6 = (iw >> 5) & 0x3f;
1771 int32_t d16 = ((int16_t) (iw & 0xffff)) * 4;
1772 int32_t d26 = ((int32_t)((iw & 0x03ffffff) << 6)) >> 4;
1787 bool store = op26 >= 0x08;
1790 ic->
arg[0].
p = &m_r[d];
1791 ic->
arg[1].
p = &m_r[s1];
1795 case 0x02: ic->
f = instr_loadstore<false, uint16_t, false, false, false, false>; opsize = 1;
break;
1796 case 0x03: ic->
f = instr_loadstore<false, uint8_t, false, false, false, false>; opsize = 0;
break;
1797 case 0x04: ic->
f = instr_loadstore<false, uint32_t, true, false, false, false>; opsize = 3;
break;
1798 case 0x05: ic->
f = instr_loadstore<false, uint32_t, false, false, false, false>; opsize = 2;
break;
1799 case 0x06: ic->
f = instr_loadstore<false, uint16_t, false, false, false, true>; opsize = 1;
break;
1800 case 0x07: ic->
f = instr_loadstore<false, uint8_t, false, false, false, true>; opsize = 0;
break;
1801 case 0x08: ic->
f = instr_loadstore<true, uint32_t, true, false, false, false>; opsize = 3;
break;
1802 case 0x09: ic->
f = instr_loadstore<true, uint32_t, false, false, false, false>; opsize = 2;
break;
1803 case 0x0a: ic->
f = instr_loadstore<true, uint16_t, false, false, false, false>; opsize = 1;
break;
1804 case 0x0b: ic->
f = instr_loadstore<true, uint8_t, false, false, false, false>; opsize = 0;
break;
1807 if (opsize == 3 && d == 31) {
1818 ic->
arg[0].
p = &m_zero_scratch;
1838 case 0x10: ic->
f = instr_and_u32_u32_immu32;
break;
1839 case 0x11: ic->
f = instr_and_u32_u32_immu32; shift = 16;
break;
1840 case 0x12: ic->
f = instr_and_u32_u32_immu32;
break;
1841 case 0x13: ic->
f = instr_and_u32_u32_immu32; shift = 16;
break;
1842 case 0x14: ic->
f = instr_xor_u32_u32_immu32;
break;
1843 case 0x15: ic->
f = instr_xor_u32_u32_immu32; shift = 16;
break;
1844 case 0x16: ic->
f = instr_or_u32_u32_immu32;
break;
1845 case 0x17: ic->
f = instr_or_u32_u32_immu32; shift = 16;
break;
1846 case 0x18: ic->
f = instr_add_u32_u32_immu32;
break;
1847 case 0x19: ic->
f = instr_sub_u32_u32_immu32;
break;
1848 case 0x1a: ic->
f = instr_divu_imm;
break;
1849 case 0x1b: ic->
f = instr_mulu_imm;
break;
1853 case 0x1f: ic->
f = instr_cmp_imm;
break;
1856 ic->
arg[0].
p = &m_r[d];
1857 ic->
arg[1].
p = &m_r[s1];
1858 ic->
arg[2].
u32 = imm16 << shift;
1864 ic->
arg[2].
u32 |= 0xffff0000;
1866 ic->
arg[2].
u32 |= 0x0000ffff;
1874 if ((iw & 0x001ff81f) == 0x00004000) {
1876 ic->
arg[0].
p = &m_r[d];
1879 ic->
arg[0].
p = &m_zero_scratch;
1887 }
else if ((iw & 0x03e0f800) == 0x00008000) {
1889 ic->
arg[0].
p = &m_r[s1];
1895 ss.flags(std::ios::hex);
1896 ss <<
"stcr with s1 != s2? TODO: how " 1897 "should this be handled? s1=0x" 1898 << s1 <<
", s2=0x" << s2;
1915 }
else if (ui != NULL) {
1932 samepage_function = instr_branch_samepage;
1941 samepage_function = instr_bsr_samepage;
1944 ic->
f = instr_bsr_n;
1946 f_singleStepping = instr_bsr_n_functioncalltrace_singlestep;
1950 if (singleInstructionLeft && (op26 == 0x31 || op26 == 0x33)) {
1951 ic->
f = f_singleStepping;
1952 samepage_function = NULL;
1955 int offset = (
m_pc & 0xffc) + d26;
1963 ic->
arg[2].
u32 = (
m_pc & 0xffc) + ((op26 & 1)? 8 : 4);
1965 if (offset >= 0 && offset <= 0xffc && samepage_function != NULL)
1966 ic->
f = samepage_function;
1970 ic->
f = instr_bsr_functioncalltrace;
1972 if (singleInstructionLeft)
1973 ic->
f = instr_bsr_n_functioncalltrace_singlestep;
1975 ic->
f = instr_bsr_n_functioncalltrace;
1991 ic->
f = instr_bb<false,false>;
1992 samepage_function = instr_bb<false,true>;
1995 ic->
f = instr_bb_n<false>;
1996 singlestep_function = instr_bb_n_singlestep<false>;
1999 ic->
f = instr_bb<true,false>;
2000 samepage_function = instr_bb<true,true>;
2003 ic->
f = instr_bb_n<true>;
2004 singlestep_function = instr_bb_n_singlestep<true>;
2008 ic->
arg[0].
p = &m_r[s1];
2009 ic->
arg[1].
u32 = (1 << d);
2011 int offset = (
m_pc & 0xffc) + d16;
2014 if (singleInstructionLeft && singlestep_function != NULL)
2015 ic->
f = singlestep_function;
2016 else if (offset >= 0 && offset <= 0xffc && samepage_function != NULL) {
2017 ic->
f = samepage_function;
2031 case 1: ic->
f = instr_bcnd<true,1, false>; singlestep_f = instr_bcnd<true,1, true>;
break;
2032 case 2: ic->
f = instr_bcnd<true,2, false>; singlestep_f = instr_bcnd<true,2, true>;
break;
2033 case 3: ic->
f = instr_bcnd<true,3, false>; singlestep_f = instr_bcnd<true,3, true>;
break;
2034 case 7: ic->
f = instr_bcnd<true,7, false>; singlestep_f = instr_bcnd<true,7, true>;
break;
2035 case 8: ic->
f = instr_bcnd<true,8, false>; singlestep_f = instr_bcnd<true,8, true>;
break;
2036 case 12: ic->
f = instr_bcnd<true,12,false>; singlestep_f = instr_bcnd<true,12,true>;
break;
2037 case 13: ic->
f = instr_bcnd<true,13,false>; singlestep_f = instr_bcnd<true,13,true>;
break;
2038 case 14: ic->
f = instr_bcnd<true,14,false>; singlestep_f = instr_bcnd<true,14,true>;
break;
2042 case 1: ic->
f = instr_bcnd<false,1, false>;
break;
2043 case 2: ic->
f = instr_bcnd<false,2, false>;
break;
2044 case 3: ic->
f = instr_bcnd<false,3, false>;
break;
2045 case 7: ic->
f = instr_bcnd<false,7, false>;
break;
2046 case 8: ic->
f = instr_bcnd<false,8, false>;
break;
2047 case 12: ic->
f = instr_bcnd<false,12,false>;
break;
2048 case 13: ic->
f = instr_bcnd<false,13,false>;
break;
2049 case 14: ic->
f = instr_bcnd<false,14,false>;
break;
2057 if (ic->
f == NULL) {
2060 ss.flags(std::ios::hex);
2061 ss <<
"unimplemented bcnd condition code d = " << d;
2068 ic->
arg[0].
p = &m_r[s1];
2070 int offset = (
m_pc & 0xffc) + d16;
2073 if (singleInstructionLeft && singlestep_f != NULL) {
2074 ic->
f = singlestep_f;
2075 }
else if (offset >= 0 && offset <= 0xffc && samepage_function != NULL) {
2076 ic->
f = samepage_function;
2090 ic->
arg[0].
p = &m_r[d];
2091 ic->
arg[1].
p = &m_r[s1];
2092 ic->
arg[2].
u32 = iw & 0x3ff;
2115 case 0x24: ic->
f = instr_ext_imm;
break;
2116 case 0x26: ic->
f = instr_extu_imm;
break;
2117 case 0x28: ic->
f = instr_mak_imm;
break;
2127 ic->
arg[1].
p = &m_r[s1];
2128 ic->
arg[2].
u32 = iw & 0x1ff;
2130 case 0x34: ic->
f = instr_tb<false>;
break;
2131 case 0x36: ic->
f = instr_tb<true>;
break;
2138 ss.flags(std::ios::hex);
2139 ss <<
"unimplemented opcode 0x" << op26 <<
",0x" << op10;
2146 if ((iw & 0xf000) <= 0x3fff ) {
2148 int op = 0, opsize, user = 0, wt = 0;
2149 int signedness = 1, scaled = 0;
2151 switch (iw & 0xf000) {
2152 case 0x2000: op = 1;
break;
2153 case 0x3000: op = 2;
break;
2154 default:
if ((iw & 0xf800) >= 0x0800)
2161 opsize = (iw >> 10) & 3;
2164 opsize = 3 - opsize;
2169 switch ((iw >> 10) & 3) {
2170 case 0: opsize = 0;
break;
2171 case 1: opsize = 2;
break;
2178 if ((iw & 0xf800) == 0x800) {
2180 if ((iw & 0xf00) < 0xc00)
2185 if (opsize >= 2 || op == 1)
2203 ic->
arg[0].
p = &m_r[d];
2204 ic->
arg[1].
p = &m_r[s1];
2205 ic->
arg[2].
p = &m_r[s2];
2207 if (op == 0 || op == 1) {
2211 ((op == 1)? 4 : 0) +
2212 (signedness? 8 : 0) +
2221 case 0 + 0 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<false, uint8_t, false, true, false, false>;
break;
2222 case 0 + 0 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<false, uint8_t, false, true, true, false>;
break;
2223 case 0 + 0 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<false, uint8_t, false, true, false, false>;
break;
2224 case 0 + 0 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<false, uint8_t, false, true, true, false>;
break;
2225 case 1 + 0 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<false, uint16_t, false, true, false, false>;
break;
2226 case 1 + 0 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<false, uint16_t, false, true, true, false>;
break;
2227 case 1 + 0 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<false, uint16_t, false, true, false, false>;
break;
2228 case 1 + 0 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<false, uint16_t, false, true, true, false>;
break;
2229 case 2 + 0 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<false, uint32_t, false, true, false, false>;
break;
2230 case 2 + 0 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<false, uint32_t, false, true, true, false>;
break;
2231 case 2 + 0 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<false, uint32_t, false, true, false, false>;
break;
2232 case 2 + 0 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<false, uint32_t, false, true, true, false>;
break;
2233 case 3 + 0 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<false, uint32_t, true, true, false, false>;
break;
2234 case 3 + 0 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<false, uint32_t, true, true, true, false>;
break;
2235 case 3 + 0 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<false, uint32_t, true, true, false, false>;
break;
2236 case 3 + 0 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<false, uint32_t, true, true, true, false>;
break;
2238 case 0 + 4 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<true, uint8_t, false, true, false, false>;
break;
2239 case 0 + 4 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<true, uint8_t, false, true, true, false>;
break;
2240 case 0 + 4 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<true, uint8_t, false, true, false, false>;
break;
2241 case 0 + 4 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<true, uint8_t, false, true, true, false>;
break;
2242 case 1 + 4 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<true, uint16_t, false, true, false, false>;
break;
2243 case 1 + 4 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<true, uint16_t, false, true, true, false>;
break;
2244 case 1 + 4 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<true, uint16_t, false, true, false, false>;
break;
2245 case 1 + 4 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<true, uint16_t, false, true, true, false>;
break;
2246 case 2 + 4 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<true, uint32_t, false, true, false, false>;
break;
2247 case 2 + 4 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<true, uint32_t, false, true, true, false>;
break;
2248 case 2 + 4 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<true, uint32_t, false, true, false, false>;
break;
2249 case 2 + 4 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<true, uint32_t, false, true, true, false>;
break;
2250 case 3 + 4 + 0 + 0 + 0 + 0: ic->
f = instr_loadstore<true, uint32_t, true, true, false, false>;
break;
2251 case 3 + 4 + 0 + 0 + 32 + 0: ic->
f = instr_loadstore<true, uint32_t, true, true, true, false>;
break;
2252 case 3 + 4 + 0 + 16 + 0 + 0: ic->
f = instr_loadstore<true, uint32_t, true, true, false, false>;
break;
2253 case 3 + 4 + 0 + 16 + 32 + 0: ic->
f = instr_loadstore<true, uint32_t, true, true, true, false>;
break;
2255 std::cerr <<
"TODO generalize! scaled="<<scaled <<
" user="<<
2256 user<<
" signedness="<<signedness <<
" opsize=" << opsize <<
"\n";
2264 ic->
arg[0].
p = &m_zero_scratch;
2266 if (opsize == 3 && d == 31) {
2272 }
else if (op == 2) {
2277 case 1: ic->
f = instr_lda<2>;
break;
2278 case 2: ic->
f = instr_lda<4>;
break;
2279 case 3: ic->
f = instr_lda<8>;
break;
2297 }
else switch ((iw >> 8) & 0xff) {
2321 ic->
arg[0].
p = &m_r[d];
2322 ic->
arg[1].
p = &m_r[s1];
2323 ic->
arg[2].
p = &m_r[s2];
2325 switch ((iw >> 8) & 0xff) {
2328 case 0x50: ic->
f = instr_xor_u32_u32_u32;
break;
2330 case 0x58: ic->
f = instr_or_u32_u32_u32;
break;
2332 case 0x60: ic->
f = instr_add_u32_u32_u32;
break;
2335 case 0x64: ic->
f = instr_sub_u32_u32_u32;
break;
2342 case 0x7c: ic->
f = instr_cmp;
break;
2345 case 0x90: ic->
f = instr_ext;
break;
2346 case 0x98: ic->
f = instr_extu;
break;
2347 case 0xa0: ic->
f = instr_mak;
break;
2361 int opc = (iw >> 8) & 0xff;
2362 if (opc != 0x61 && opc != 0x63 &&
2363 opc != 0x65 && opc != 0x67 &&
2364 opc != 0x71 && opc != 0x73 &&
2365 opc != 0x75 && opc != 0x77 &&
2366 opc != 0x68 && opc != 0x69 &&
2367 opc != 0x6c && opc != 0x6d &&
2368 opc != 0x6e && opc != 0x78 )
2371 ic->
arg[0].
p = &m_zero_scratch;
2374 if (ic->
f == NULL && ui != NULL) {
2376 ss.flags(std::ios::hex);
2377 ss <<
"unimplemented opcode 0x3d,0x" << ((iw >> 8) & 0xff);
2389 switch ((iw >> 8) & 0xff) {
2390 case 0xc0: ic->
f = instr_jmp;
break;
2391 case 0xc4: ic->
f = instr_jmp_n; f_ss = instr_jmp_n_functioncalltrace_singlestep;
break;
2397 ic->
arg[2].
p = &m_r[s2];
2399 if (((iw >> 8) & 0x04) == 0x04)
2403 if (ic->
f == instr_jmp_n) {
2404 ic->
f = instr_jmp_n_functioncalltrace;
2405 f_ss = instr_jmp_n_functioncalltrace_singlestep;
2418 if (singleInstructionLeft && f_ss != NULL)
2426 switch (iw & 0xff) {
2433 ic->
f = instr_fail_early;
2437 default:
if (ui != NULL) {
2439 ss.flags(std::ios::hex);
2440 ss <<
"unimplemented opcode 0x3d,0xfc,0x" << (iw & 0xff);
2448 ss.flags(std::ios::hex);
2449 ss <<
"unimplemented opcode 0x3d,0x" << ((iw >> 8) & 0xff);
2458 ss.flags(std::ios::hex);
2459 ss <<
"unimplemented opcode 0x" << op26;
2470 cpu->DyntransToBeTranslatedBegin(ic);
2473 if (
cpu->DyntransReadInstruction(iword))
2474 cpu->Translate(iword, ic);
2476 if (
cpu->m_inDelaySlot && ic->
f == NULL)
2477 ic->
f = instr_abort;
2479 cpu->DyntransToBeTranslatedDone(ic);
2486 #ifdef WITHUNITTESTS 2490 static void Test_M88K_CPUComponent_IsStable()
2496 static void Test_M88K_CPUComponent_Create()
2511 static void Test_M88K_CPUComponent_Create_with_r31()
2536 static void Test_M88K_CPUComponent_IsCPU()
2545 static void Test_M88K_CPUComponent_DefaultModel()
2557 static void Test_M88K_CPUComponent_Disassembly_Basic()
2563 vector<string> result;
2565 unsigned char instruction[
sizeof(uint32_t)];
2567 instruction[0] = 0x63;
2568 instruction[1] = 0xdf;
2569 instruction[2] = 0x00;
2570 instruction[3] = 0x10;
2573 instruction, result);
2582 static void Test_M88K_CPUComponent_Execute_Basic()
2595 uint32_t data32 = 0x63df0010;
2596 bus->AddressSelect(48);
2599 bus->AddressSelect(52);
2622 static void Test_M88K_CPUComponent_Execute_DelayBranchWithValidInstruction()
2633 uint32_t data32 = 0xcc000010;
2634 bus->AddressSelect(0x1000ULL);
2637 data32 = 0x63df0010;
2638 bus->AddressSelect(0x1004ULL);
2657 static void Test_M88K_CPUComponent_Execute_DelayBranchWithValidInstruction_SingleStepping()
2668 uint32_t data32 = 0xcc000010;
2669 bus->AddressSelect(0x1000ULL);
2672 data32 = 0x63df0010;
2673 bus->AddressSelect(0x1004ULL);
2701 static void Test_M88K_CPUComponent_Execute_DelayBranchWithValidInstruction_RunTwoTimes()
2712 uint32_t data32 = 0xcc000010;
2713 bus->AddressSelect(0x1000ULL);
2716 data32 = 0x63df0010;
2717 bus->AddressSelect(0x1004ULL);
2745 static void Test_M88K_CPUComponent_Execute_DelayBranchWithFault()
2756 uint32_t data32 = 0xcc000010;
2757 bus->AddressSelect(0x1000ULL);
2760 data32 = 0xffffffff;
2761 bus->AddressSelect(0x1004ULL);
2784 static void Test_M88K_CPUComponent_Execute_EarlyAbortDuringRuntime_Singlestep()
2795 uint32_t data32 = 0xcc000010;
2796 bus->AddressSelect(0x1000ULL);
2799 data32 = 0xf400fc93;
2801 bus->AddressSelect(0x1004ULL);
2826 static void Test_M88K_CPUComponent_Execute_EarlyAbortDuringRuntime_Running()
2837 uint32_t data32 = 0xcc000010;
2838 bus->AddressSelect(0x1000ULL);
2841 data32 = 0xf400fc93;
2843 bus->AddressSelect(0x1004ULL);
2870 UNITTEST(Test_M88K_CPUComponent_IsStable);
2871 UNITTEST(Test_M88K_CPUComponent_Create);
2872 UNITTEST(Test_M88K_CPUComponent_Create_with_r31);
2873 UNITTEST(Test_M88K_CPUComponent_IsCPU);
2874 UNITTEST(Test_M88K_CPUComponent_DefaultModel);
2877 UNITTEST(Test_M88K_CPUComponent_Disassembly_Basic);
2880 UNITTEST(Test_M88K_CPUComponent_Execute_Basic);
2881 UNITTEST(Test_M88K_CPUComponent_Execute_DelayBranchWithValidInstruction);
2882 UNITTEST(Test_M88K_CPUComponent_Execute_DelayBranchWithValidInstruction_SingleStepping);
2883 UNITTEST(Test_M88K_CPUComponent_Execute_DelayBranchWithValidInstruction_RunTwoTimes);
2884 UNITTEST(Test_M88K_CPUComponent_Execute_DelayBranchWithFault);
2885 UNITTEST(Test_M88K_CPUComponent_Execute_EarlyAbortDuringRuntime_Singlestep);
2886 UNITTEST(Test_M88K_CPUComponent_Execute_EarlyAbortDuringRuntime_Running);
void SetRunState(RunState newState)
Sets the RunState.
virtual CPUComponent * AsCPUComponent()
Returns the component's CPUComponent interface.
virtual bool VirtualToPhysical(uint64_t vaddr, uint64_t &paddr, bool &writable)
Virtual to physical address translation (MMU).
#define M88K_FPECR_FUNIMP
#define M88K_EXCEPTION_ILLEGAL_INTEGER_DIVIDE
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
StateVariable * GetVariable(const string &name)
Gets a pointer to a state variable.
#define M88K_EXCEPTION_USER_TRAPS_START
virtual void ShowRegisters(GXemul *gxemul, const vector< string > &arguments) const
static refcount_ptr< Component > CreateComponent(const string &componentNameAndOptionalArgs, GXemul *gxemul=NULL)
Creates a component given a short component name.
void(* f)(CPUDyntransComponent *, DyntransIC *)
struct arm_instr_call * ic
#define M88K_IC_ENTRIES_PER_PAGE
uint64_t m_delaySlotTarget
static refcount_ptr< Component > Create(const ComponentCreateArgs &args)
Creates a M88K_CPUComponent.
bool RunCommand(const string &command, bool *pSuccess=NULL)
Runs a command, given as a string.
bool AddVariable(const string &name, T *variablePointer)
Adds a state variable of type T to the Component.
UI * GetUI()
Gets an UI reference for outputting debug messages during runtime.
int m_nrOfCyclesToExecute
union DyntransIC::@0 arg[N_DYNTRANS_IC_ARGS]
A dyntrans instruction call.
A Component representing a Motorola 88000 processor.
#define N_M88K_CONTROL_REGS
An interface for implementing components that read/write data via an address bus. ...
static string GetAttribute(const string &attributeName)
Creates a Component.
#define M88K_EXCEPTION_SFU1_PRECISE
#define M88K_OPCODE_NAMES
#define M88K_EXCEPTION_MISALIGNED_ACCESS
#define UNITTESTS(class)
Helper for unit test case execution.
CommandInterpreter & GetCommandInterpreter()
Gets a reference to the CommandInterpreter.
map< string, string > ComponentCreationSettings
#define M88K_STACKPOINTER_REG
bool m_showFunctionTraceCall
struct DyntransIC * m_firstIConPage
M88K_CPUComponent()
Constructs a M88K_CPUComponent.
virtual void(*)(CPUDyntransComponent *, DyntransIC *) GetDyntransToBeTranslated()
#define M88K_FAIL_LATE_INSTR
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
string LookupAddress(uint64_t vaddr, bool allowOffset) const
Looks up an address.
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
string ToString() const
Returns the variable as a readable string.
static bool HasAttribute(const string &name, const string &attributeName)
Checks if a component has a specific attribute.
#define DYNTRANS_SYNCH_PC
#define M88K_3D_OPCODE_NAMES
#define M88K_3C_OPCODE_NAMES
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
#define M88K_EXCEPTION_PRIVILEGE_VIOLATION
SymbolRegistry & GetSymbolRegistry()
Gets a reference to the CPU's symbol registry.
virtual size_t DisassembleInstruction(uint64_t vaddr, size_t maxlen, unsigned char *instruction, vector< string > &result)
Disassembles an instruction into readable strings.
A base-class for processors Component implementations that use dynamic translation.
uint64_t ToInteger() const
Returns the variable as an unsignedinteger value.
#define M88K_CPU_TYPE_DEFS
DYNTRANS_INSTR(M88K_CPUComponent, cmp)
StateVariables make up the persistent state of Component objects.
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
virtual void ResetState()
Resets the state variables of this component.
A base-class for processors Component implementations.
virtual size_t DisassembleInstruction(uint64_t vaddr, size_t maxLen, unsigned char *instruction, vector< string > &result)=0
Disassembles an instruction into readable strings.
#define N_M88K_FPU_CONTROL_REGS
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
virtual int GetDyntransICshift() const
virtual void ResetState()
Resets the state variables of this component.
bool SetVariableValue(const string &name, const string &expression)
Sets a variable to a new value.
refcount_ptr< Component > GetRootComponent()
Gets a pointer to the root configuration component.
virtual AddressDataBus * AsAddressDataBus()
Returns the component's AddressDataBus interface, if any.
void Reset()
Resets the state of this component and all its children.
#define DYNTRANS_INSTR_HEAD(class)
UI * GetUI()
Gets a pointer to the GXemul instance' active UI.
static bool GetCreationArgOverrides(ComponentCreationSettings &settings, const ComponentCreateArgs &createArgs)
Get override arguments for component creation.
static string GetAttribute(const string &attributeName)
Base class for a User Interface.
const refcount_ptr< Component > LookupPath(string path) const
Looks up a path from this Component, and returns a pointer to the found Component, if any.
#define M88K_INSTR_ALIGNMENT_SHIFT
void Execute(const int longestTotalRun=100000)
Run the emulation for "a while".
#define M88K_FAIL_EARLY_INSTR
#define UNITTEST(functionname)
Helper for unit test case execution.
bool IsNULL() const
Checks whether or not an object is referenced by the reference counted pointer.