MSXHawk: Z80 with prebuilt instruction tables

This commit is contained in:
alyosha-tas 2020-01-19 22:41:41 -05:00
parent ebfccf51de
commit 6b99a792b9
1 changed files with 284 additions and 131 deletions

View File

@ -51,6 +51,7 @@ namespace MSXHawk
bool nonMaskableInterrupt;
bool nonMaskableInterruptPending;
bool jp_cond_chk;
bool cond_chk_fail;
uint8_t opcode;
uint8_t temp_R;
@ -58,6 +59,9 @@ namespace MSXHawk
uint8_t interruptMode;
// when connected devices do not output a value on the BUS, they are responsible for determining open bus behaviour and returning it
uint8_t ExternalDB;
// since absolute pointer locations are not saved, we need to know where current pointer is looking in order to load it
// this combined with opcode and instr_pntr gives the current cpu execution location
uint8_t instr_bank;
uint8_t Regs[36] = {};
uint32_t PRE_SRC;
@ -67,20 +71,17 @@ namespace MSXHawk
uint32_t mem_pntr = 0;
uint32_t irq_pntr = 0;
uint32_t IRQS;
uint32_t Ztemp2_saver = 0;
uint32_t IRQS_cond_offset;
// since absolute pointer locations are not saved, we need to know where current pointer is looking in order to load it
// this combined with opcode and instr_pntr gives the current cpu execution location
uint8_t instr_bank;
uint64_t TotalExecutedCycles;
uint32_t* cur_instr_ofst = nullptr;
uint32_t* cur_bus_ofst = nullptr;
uint32_t* cur_mem_ofst = nullptr;
uint32_t* cur_irqs_ofst = nullptr;
uint64_t TotalExecutedCycles;
// non-state variables
// EXCEPTION!: Ztemp2 must be stated to restore the instruction vector
bool checker;
uint32_t Ztemp1, Ztemp2, Ztemp3, Ztemp4;
uint32_t Reg16_d, Reg16_s, ans, temp, carry, dest_t, src_t;
@ -341,6 +342,90 @@ namespace MSXHawk
uint32_t REP_OP_O_MEMRQ[5] = { 0, 0, 0, 0, 0 };
uint32_t REP_OP_O_IRQS = 5;
// halt
uint32_t HALT_INST[4] = { IDLE,
WAIT,
OP_F,
OP };
uint32_t HALT_BUSRQ[4] = { PCh, 0, 0, 0 };
uint32_t HALT_MEMRQ[4] = { PCh, 0, 0, 0 };
uint32_t HALT_IRQS = 4;
// NMI
uint32_t NMI_INST[25] = { IDLE,
IDLE,
IDLE,
IDLE,
DEC16, SPl, SPh,
TR, ALU, PCl,
WAIT,
WR_DEC, SPl, SPh, PCh,
TR16, PCl, PCh, NMI_V, ZERO,
WAIT,
WR, SPl, SPh, ALU };
uint32_t NMI_BUSRQ[11] = { 0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 };
uint32_t NMI_MEMRQ[11] = { 0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 };
uint32_t NMI_IRQS = 11;
// IRQ0
uint32_t IRQ0_INST[10] = { IDLE,
IDLE,
IORQ,
WAIT,
IDLE,
WAIT,
RD_INC, ALU, PCl, PCh };
uint32_t IRQ0_BUSRQ[7] = { 0, 0, 0, 0, PCh, 0, 0 };
uint32_t IRQ0_MEMRQ[7] = { 0, 0, 0, 0, PCh, 0, 0 };
uint32_t IRQ0_IRQS = 7;
// IRQ1
uint32_t IRQ1_INST[27] = { IDLE,
IDLE,
IORQ,
WAIT,
IDLE,
TR, ALU, PCl,
DEC16, SPl, SPh,
IDLE,
WAIT,
WR_DEC, SPl, SPh, PCh,
TR16, PCl, PCh, IRQ_V, ZERO,
WAIT,
WR, SPl, SPh, ALU };
uint32_t IRQ1_BUSRQ[13] = { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0 };
uint32_t IRQ1_MEMRQ[13] = { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0 };
uint32_t IRQ1_IRQS = 13;
// IRQ2
uint32_t IRQ2_INST[37] = { IDLE,
IDLE,
IORQ,
WAIT,
FTCH_DB,
IDLE,
DEC16, SPl, SPh,
TR16, Z, W, DB, I,
WAIT,
WR_DEC, SPl, SPh, PCh,
IDLE,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
WAIT,
RD_INC, PCl, Z, W,
IDLE,
WAIT,
RD, PCh, Z, W };
uint32_t IRQ2_BUSRQ[19] = { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0 };
uint32_t IRQ2_MEMRQ[19] = { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0 };
uint32_t IRQ2_IRQS = 19;
#pragma endregion
#pragma region Z80 functions
@ -413,7 +498,7 @@ namespace MSXHawk
NO_prefix = true;
}
void FetchInstruction()
inline void FetchInstruction()
{
if (NO_prefix)
{
@ -494,6 +579,7 @@ namespace MSXHawk
void ExecuteOne()
{
bus_pntr++; mem_pntr++;
switch (cur_instr_ofst[instr_pntr++])
{
case IDLE:
@ -845,7 +931,7 @@ namespace MSXHawk
if (((Regs[C] | (Regs[B] << 8)) != 0) && (Ztemp3 > 0))
{
cur_instr_ofst = &LD_OP_R_INST[0];
cur_instr_ofst[14] = Ztemp2;
cur_instr_ofst[14] = Ztemp2; Ztemp2_saver = Ztemp2;
cur_bus_ofst = &LD_OP_R_BUSRQ[0];
cur_mem_ofst = &LD_OP_R_MEMRQ[0];
cur_irqs_ofst = &LD_OP_R_IRQS;
@ -871,7 +957,7 @@ namespace MSXHawk
if (((Regs[C] | (Regs[B] << 8)) != 0) && (Ztemp3 > 0) && !FlagZget())
{
cur_instr_ofst = &LD_CP_R_INST[0];
cur_instr_ofst[14] = Ztemp2;
cur_instr_ofst[14] = Ztemp2; Ztemp2_saver = Ztemp2;
cur_bus_ofst = &LD_CP_R_BUSRQ[0];
cur_mem_ofst = &LD_CP_R_MEMRQ[0];
cur_irqs_ofst = &LD_CP_R_IRQS;
@ -945,7 +1031,7 @@ namespace MSXHawk
if ((Regs[B] != 0) && (Ztemp3 > 0))
{
cur_instr_ofst = &REP_OP_I_INST[0];
cur_instr_ofst[8] = Ztemp2;
cur_instr_ofst[8] = Ztemp2; Ztemp2_saver = Ztemp2;
cur_bus_ofst = &REP_OP_I_BUSRQ[0];
cur_mem_ofst = &REP_OP_I_MEMRQ[0];
cur_irqs_ofst = &REP_OP_I_IRQS;
@ -1086,22 +1172,28 @@ namespace MSXHawk
}
else
{
cond_chk_fail = true;
switch (cur_instr_ofst[instr_pntr++])
{
case 0: // DJNZ
cur_irqs_ofst = &False_IRQS[0];
IRQS_cond_offset = 0;
break;
case 1: // JR COND
cur_irqs_ofst = &False_IRQS[1];
IRQS_cond_offset = 1;
break;
case 2: // JP COND
cur_irqs_ofst = &False_IRQS[2];
IRQS_cond_offset = 2;
break;
case 3: // RET COND
cur_irqs_ofst = &False_IRQS[3];
IRQS_cond_offset = 3;
break;
case 4: // CALL
cur_irqs_ofst = &False_IRQS[4];
IRQS_cond_offset = 4;
break;
}
}
@ -1116,6 +1208,8 @@ namespace MSXHawk
}
else if (++irq_pntr == cur_irqs_ofst[0])
{
cond_chk_fail = false;
if (EI_pending > 0)
{
EI_pending--;
@ -1177,15 +1271,12 @@ namespace MSXHawk
// otherwise start a new normal access
else if (!halted)
{
PopulateCURINSTR
(IDLE,
WAIT,
OP_F,
OP);
cur_instr_ofst = &HALT_INST[0];
cur_bus_ofst = &HALT_BUSRQ[0];
cur_mem_ofst = &HALT_MEMRQ[0];
cur_irqs_ofst = &HALT_IRQS;
PopulateBUSRQ(PCh, 0, 0, 0);
PopulateMEMRQ(PCh, 0, 0, 0);
IRQS = 4;
instr_bank = 11;
instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0;
}
@ -1285,21 +1376,12 @@ namespace MSXHawk
#pragma region Interrupts
void NMI_()
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
DEC16, SPl, SPh,
TR, ALU, PCl,
WAIT,
WR_DEC, SPl, SPh, PCh,
TR16, PCl, PCh, NMI_V, ZERO,
WAIT,
WR, SPl, SPh, ALU);
cur_instr_ofst = &NMI_INST[0];
cur_bus_ofst = &NMI_BUSRQ[0];
cur_mem_ofst = &NMI_MEMRQ[0];
cur_irqs_ofst = &NMI_IRQS;
PopulateBUSRQ(0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0);
PopulateMEMRQ(0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0);
IRQS = 11;
instr_bank = 12;
}
// Mode 0 interrupts only take effect if a CALL or RST is on the data bus
@ -1309,67 +1391,34 @@ namespace MSXHawk
//NOTE: TODO: When a CALL is present on the data bus, adjust WZ accordingly
void INTERRUPT_0(uint32_t src)
{
PopulateCURINSTR(IDLE,
IDLE,
IORQ,
WAIT,
IDLE,
WAIT,
RD_INC, ALU, PCl, PCh);
cur_instr_ofst = &IRQ0_INST[0];
cur_bus_ofst = &IRQ0_BUSRQ[0];
cur_mem_ofst = &IRQ0_MEMRQ[0];
cur_irqs_ofst = &IRQ0_IRQS;
PopulateBUSRQ(0, 0, 0, 0, PCh, 0, 0);
PopulateMEMRQ(0, 0, 0, 0, PCh, 0, 0);
IRQS = 7;
instr_bank = 13;
}
// Just jump to $0038
void INTERRUPT_1()
{
PopulateCURINSTR(IDLE,
IDLE,
IORQ,
WAIT,
IDLE,
TR, ALU, PCl,
DEC16, SPl, SPh,
IDLE,
WAIT,
WR_DEC, SPl, SPh, PCh,
TR16, PCl, PCh, IRQ_V, ZERO,
WAIT,
WR, SPl, SPh, ALU);
cur_instr_ofst = &IRQ1_INST[0];
cur_bus_ofst = &IRQ1_BUSRQ[0];
cur_mem_ofst = &IRQ1_MEMRQ[0];
cur_irqs_ofst = &IRQ1_IRQS;
PopulateBUSRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0);
PopulateMEMRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0);
IRQS = 13;
instr_bank = 14;
}
// Interrupt mode 2 uses the I vector combined with a byte on the data bus
void INTERRUPT_2()
{
PopulateCURINSTR(IDLE,
IDLE,
IORQ,
WAIT,
FTCH_DB,
IDLE,
DEC16, SPl, SPh,
TR16, Z, W, DB, I,
WAIT,
WR_DEC, SPl, SPh, PCh,
IDLE,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
WAIT,
RD_INC, PCl, Z, W,
IDLE,
WAIT,
RD, PCh, Z, W);
cur_instr_ofst = &IRQ2_INST[0];
cur_bus_ofst = &IRQ2_BUSRQ[0];
cur_mem_ofst = &IRQ2_MEMRQ[0];
cur_irqs_ofst = &IRQ2_IRQS;
PopulateBUSRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0);
PopulateMEMRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0);
IRQS = 19;
instr_bank = 15;
}
void ResetInterrupts()
@ -2641,12 +2690,12 @@ namespace MSXHawk
case 0xFF: RST_(0x38); break; // RST 0x38
}
std::memcpy(&NoIndex[i * 38], &cur_instr, 38);
std::memcpy(&NoIndexBUSRQ[i * 19], &BUSRQ, 19);
std::memcpy(&NoIndexMEMRQ[i * 19], &MEMRQ, 19);
std::memcpy(&NoIndex[i * 38], &cur_instr, sizeof(uint32_t) * 38);
std::memcpy(&NoIndexBUSRQ[i * 19], &BUSRQ, sizeof(uint32_t) * 19);
std::memcpy(&NoIndexMEMRQ[i * 19], &MEMRQ, sizeof(uint32_t) * 19);
NoIndexIRQS[i] = IRQS;
switch (opcode)
switch (i)
{
case 0x00: INT_OP(RLC, B); break; // RLC B
case 0x01: INT_OP(RLC, C); break; // RLC C
@ -2906,12 +2955,12 @@ namespace MSXHawk
case 0xFF: BIT_OP(SET, 7, A); break; // SET 7, A
}
std::memcpy(&CBIndex[i * 38], &cur_instr, 38);
std::memcpy(&CBIndexBUSRQ[i * 19], &BUSRQ, 19);
std::memcpy(&CBIndexMEMRQ[i * 19], &MEMRQ, 19);
std::memcpy(&CBIndex[i * 38], &cur_instr, sizeof(uint32_t) * 38);
std::memcpy(&CBIndexBUSRQ[i * 19], &BUSRQ, sizeof(uint32_t) * 19);
std::memcpy(&CBIndexMEMRQ[i * 19], &MEMRQ, sizeof(uint32_t) * 19);
CBIndexIRQS[i] = IRQS;
switch (opcode)
switch (i)
{
case 0x40: IN_REG_(B, C); break; // IN B, (C)
case 0x41: OUT_REG_(C, B); break; // OUT (C), B
@ -2997,12 +3046,12 @@ namespace MSXHawk
}
std::memcpy(&EXTIndex[i * 38], &cur_instr, 38);
std::memcpy(&EXTIndexBUSRQ[i * 19], &BUSRQ, 19);
std::memcpy(&EXTIndexMEMRQ[i * 19], &MEMRQ, 19);
std::memcpy(&EXTIndex[i * 38], &cur_instr, sizeof(uint32_t) * 38);
std::memcpy(&EXTIndexBUSRQ[i * 19], &BUSRQ, sizeof(uint32_t) * 19);
std::memcpy(&EXTIndexMEMRQ[i * 19], &MEMRQ, sizeof(uint32_t) * 19);
EXTIndexIRQS[i] = IRQS;
switch (opcode)
switch (i)
{
case 0x00: NOP_(); break; // NOP
case 0x01: LD_IND_16(C, B, PCl, PCh); break; // LD BC, nn
@ -3262,12 +3311,12 @@ namespace MSXHawk
case 0xFF: RST_(0x38); break; // RST $38
}
std::memcpy(&IXIndex[i * 38], &cur_instr, 38);
std::memcpy(&IXIndexBUSRQ[i * 19], &BUSRQ, 19);
std::memcpy(&IXIndexMEMRQ[i * 19], &MEMRQ, 19);
std::memcpy(&IXIndex[i * 38], &cur_instr, sizeof(uint32_t) * 38);
std::memcpy(&IXIndexBUSRQ[i * 19], &BUSRQ, sizeof(uint32_t) * 19);
std::memcpy(&IXIndexMEMRQ[i * 19], &MEMRQ, sizeof(uint32_t) * 19);
IXIndexIRQS[i] = IRQS;
switch (opcode)
switch (i)
{
case 0x00: NOP_(); break; // NOP
case 0x01: LD_IND_16(C, B, PCl, PCh); break; // LD BC, nn
@ -3527,12 +3576,12 @@ namespace MSXHawk
case 0xFF: RST_(0x38); break; // RST $38
}
std::memcpy(&IYIndex[i * 38], &cur_instr, 38);
std::memcpy(&IYIndexBUSRQ[i * 19], &BUSRQ, 19);
std::memcpy(&IYIndexMEMRQ[i * 19], &MEMRQ, 19);
std::memcpy(&IYIndex[i * 38], &cur_instr, sizeof(uint32_t) * 38);
std::memcpy(&IYIndexBUSRQ[i * 19], &BUSRQ, sizeof(uint32_t) * 19);
std::memcpy(&IYIndexMEMRQ[i * 19], &MEMRQ, sizeof(uint32_t) * 19);
IYIndexIRQS[i] = IRQS;
switch (opcode)
switch (i)
{
case 0x00: I_INT_OP(RLC, B); break; // RLC (I* + n) -> B
case 0x01: I_INT_OP(RLC, C); break; // RLC (I* + n) -> C
@ -3792,9 +3841,9 @@ namespace MSXHawk
case 0xFF: I_BIT_OP(SET, 7, A); break; // SET 7, (I* + n) -> A
}
std::memcpy(&IXYCBIndex[i * 38], &cur_instr, 38);
std::memcpy(&IXYCBIndexBUSRQ[i * 19], &BUSRQ, 19);
std::memcpy(&IXYCBIndexMEMRQ[i * 19], &MEMRQ, 19);
std::memcpy(&IXYCBIndex[i * 38], &cur_instr, sizeof(uint32_t) * 38);
std::memcpy(&IXYCBIndexBUSRQ[i * 19], &BUSRQ, sizeof(uint32_t) * 19);
std::memcpy(&IXYCBIndexMEMRQ[i * 19], &MEMRQ, sizeof(uint32_t) * 19);
IXYCBIndexIRQS[i] = IRQS;
}
}
@ -5340,12 +5389,15 @@ namespace MSXHawk
*saver = (uint8_t)(IFF2 ? 1 : 0); saver++;
*saver = (uint8_t)(nonMaskableInterrupt ? 1 : 0); saver++;
*saver = (uint8_t)(nonMaskableInterruptPending ? 1 : 0); saver++;
*saver = (uint8_t)(jp_cond_chk ? 1 : 0); saver++;
*saver = (uint8_t)(cond_chk_fail ? 1 : 0); saver++;
*saver = opcode; saver++;
*saver = temp_R; saver++;
*saver = EI_pending; saver++;
*saver = interruptMode; saver++;
*saver = ExternalDB; saver++;
*saver = instr_bank; saver++;
for (int i = 0; i < 36; i++) { *saver = Regs[i]; saver++; }
@ -5367,23 +5419,11 @@ namespace MSXHawk
*saver = (uint8_t)(IRQS & 0xFF); saver++; *saver = (uint8_t)((IRQS >> 8) & 0xFF); saver++;
*saver = (uint8_t)((IRQS >> 16) & 0xFF); saver++; *saver = (uint8_t)((IRQS >> 24) & 0xFF); saver++;
for (int i = 0; i < 38; i++)
{
*saver = (uint8_t)(cur_instr[i] & 0xFF); saver++; *saver = (uint8_t)((cur_instr[i] >> 8) & 0xFF); saver++;
*saver = (uint8_t)((cur_instr[i] >> 16) & 0xFF); saver++; *saver = (uint8_t)((cur_instr[i] >> 24) & 0xFF); saver++;
}
*saver = (uint8_t)(Ztemp2_saver & 0xFF); saver++; *saver = (uint8_t)((Ztemp2_saver >> 8) & 0xFF); saver++;
*saver = (uint8_t)((Ztemp2_saver >> 16) & 0xFF); saver++; *saver = (uint8_t)((Ztemp2_saver >> 24) & 0xFF); saver++;
for (int i = 0; i < 19; i++)
{
*saver = (uint8_t)(BUSRQ[i] & 0xFF); saver++; *saver = (uint8_t)((BUSRQ[i] >> 8) & 0xFF); saver++;
*saver = (uint8_t)((BUSRQ[i] >> 16) & 0xFF); saver++; *saver = (uint8_t)((BUSRQ[i] >> 24) & 0xFF); saver++;
}
for (int i = 0; i < 19; i++)
{
*saver = (uint8_t)(MEMRQ[i] & 0xFF); saver++; *saver = (uint8_t)((MEMRQ[i] >> 8) & 0xFF); saver++;
*saver = (uint8_t)((MEMRQ[i] >> 16) & 0xFF); saver++; *saver = (uint8_t)((MEMRQ[i] >> 24) & 0xFF); saver++;
}
*saver = (uint8_t)(IRQS_cond_offset & 0xFF); saver++; *saver = (uint8_t)((IRQS_cond_offset >> 8) & 0xFF); saver++;
*saver = (uint8_t)((IRQS_cond_offset >> 16) & 0xFF); saver++; *saver = (uint8_t)((IRQS_cond_offset >> 24) & 0xFF); saver++;
*saver = (uint8_t)(TotalExecutedCycles & 0xFF); saver++; *saver = (uint8_t)((TotalExecutedCycles >> 8) & 0xFF); saver++;
*saver = (uint8_t)((TotalExecutedCycles >> 16) & 0xFF); saver++; *saver = (uint8_t)((TotalExecutedCycles >> 24) & 0xFF); saver++;
@ -5410,12 +5450,15 @@ namespace MSXHawk
IFF2 = *loader == 1; loader++;
nonMaskableInterrupt = *loader == 1; loader++;
nonMaskableInterruptPending = *loader == 1; loader++;
jp_cond_chk = *loader == 1; loader++;
cond_chk_fail = *loader == 1; loader++;
opcode = *loader; loader++;
temp_R = *loader; loader++;
EI_pending = *loader; loader++;
interruptMode = *loader; loader++;
ExternalDB = *loader; loader++;
instr_bank = *loader; loader++;
for (int i = 0; i < 36; i++) { Regs[i] = *loader; loader++; }
@ -5437,22 +5480,132 @@ namespace MSXHawk
IRQS = *loader; loader++; IRQS |= (*loader << 8); loader++;
IRQS |= (*loader << 16); loader++; IRQS |= (*loader << 24); loader++;
for (int i = 0; i < 38; i++)
Ztemp2_saver = *loader; loader++; Ztemp2_saver |= (*loader << 8); loader++;
Ztemp2_saver |= (*loader << 16); loader++; Ztemp2_saver |= (*loader << 24); loader++;
IRQS_cond_offset = *loader; loader++; IRQS_cond_offset |= (*loader << 8); loader++;
IRQS_cond_offset |= (*loader << 16); loader++; IRQS_cond_offset |= (*loader << 24); loader++;
// load instruction pointers based on state
if (instr_bank == 0)
{
cur_instr[i] = *loader; loader++; cur_instr[i] |= (*loader << 8); loader++;
cur_instr[i] |= (*loader << 16); loader++; cur_instr[i] |= (*loader << 24); loader++;
cur_instr_ofst = &NoIndex[opcode * 38];
cur_bus_ofst = &NoIndexBUSRQ[opcode * 19];
cur_mem_ofst = &NoIndexMEMRQ[opcode * 19];
cur_irqs_ofst = &NoIndexIRQS[opcode];
}
else if (instr_bank == 1)
{
cur_instr_ofst = &CBIndex[opcode * 38];
cur_bus_ofst = &CBIndexBUSRQ[opcode * 19];
cur_mem_ofst = &CBIndexMEMRQ[opcode * 19];
cur_irqs_ofst = &CBIndexIRQS[opcode];
}
else if (instr_bank == 2)
{
cur_instr_ofst = &EXTIndex[opcode * 38];
cur_bus_ofst = &EXTIndexBUSRQ[opcode * 19];
cur_mem_ofst = &EXTIndexMEMRQ[opcode * 19];
cur_irqs_ofst = &EXTIndexIRQS[opcode];
}
else if (instr_bank == 3)
{
cur_instr_ofst = &IXIndex[opcode * 38];
cur_bus_ofst = &IXIndexBUSRQ[opcode * 19];
cur_mem_ofst = &IXIndexMEMRQ[opcode * 19];
cur_irqs_ofst = &IXIndexIRQS[opcode];
}
else if (instr_bank == 4)
{
cur_instr_ofst = &IYIndex[opcode * 38];
cur_bus_ofst = &IYIndexBUSRQ[opcode * 19];
cur_mem_ofst = &IYIndexMEMRQ[opcode * 19];
cur_irqs_ofst = &IYIndexIRQS[opcode];
}
else if (instr_bank == 5)
{
cur_instr_ofst = &IXYCBIndex[opcode * 38];
cur_bus_ofst = &IXYCBIndexBUSRQ[opcode * 19];
cur_mem_ofst = &IXYCBIndexMEMRQ[opcode * 19];
cur_irqs_ofst = &IXYCBIndexIRQS[opcode];
}
else if (instr_bank == 6)
{
cur_instr_ofst = &Reset_CPU[0];
cur_bus_ofst = &Reset_BUSRQ[0];
cur_mem_ofst = &Reset_MEMRQ[0];
cur_irqs_ofst = &Reset_IRQS;
}
else if (instr_bank == 7)
{
cur_instr_ofst = &LD_OP_R_INST[0];
cur_instr_ofst[14] = Ztemp2_saver;
cur_bus_ofst = &LD_OP_R_BUSRQ[0];
cur_mem_ofst = &LD_OP_R_MEMRQ[0];
cur_irqs_ofst = &LD_OP_R_IRQS;
}
else if (instr_bank == 8)
{
cur_instr_ofst = &LD_CP_R_INST[0];
cur_instr_ofst[14] = Ztemp2_saver;
cur_bus_ofst = &LD_CP_R_BUSRQ[0];
cur_mem_ofst = &LD_CP_R_MEMRQ[0];
cur_irqs_ofst = &LD_CP_R_IRQS;
}
else if (instr_bank == 9)
{
cur_instr_ofst = &REP_OP_I_INST[0];
cur_instr_ofst[8] = Ztemp2_saver;
cur_bus_ofst = &REP_OP_I_BUSRQ[0];
cur_mem_ofst = &REP_OP_I_MEMRQ[0];
cur_irqs_ofst = &REP_OP_I_IRQS;
}
else if (instr_bank == 10)
{
cur_instr_ofst = &REP_OP_O_INST[0];
cur_bus_ofst = &REP_OP_O_BUSRQ[0];
cur_mem_ofst = &REP_OP_O_MEMRQ[0];
cur_irqs_ofst = &REP_OP_O_IRQS;
}
else if (instr_bank == 11)
{
cur_instr_ofst = &HALT_INST[0];
cur_bus_ofst = &HALT_BUSRQ[0];
cur_mem_ofst = &HALT_MEMRQ[0];
cur_irqs_ofst = &HALT_IRQS;
}
else if (instr_bank == 12)
{
cur_instr_ofst = &NMI_INST[0];
cur_bus_ofst = &NMI_BUSRQ[0];
cur_mem_ofst = &NMI_MEMRQ[0];
cur_irqs_ofst = &NMI_IRQS;
}
else if (instr_bank == 13)
{
cur_instr_ofst = &IRQ0_INST[0];
cur_bus_ofst = &IRQ0_BUSRQ[0];
cur_mem_ofst = &IRQ0_MEMRQ[0];
cur_irqs_ofst = &IRQ0_IRQS;
}
else if (instr_bank == 14)
{
cur_instr_ofst = &IRQ1_INST[0];
cur_bus_ofst = &IRQ1_BUSRQ[0];
cur_mem_ofst = &IRQ1_MEMRQ[0];
cur_irqs_ofst = &IRQ1_IRQS;
}
else if (instr_bank == 15)
{
cur_instr_ofst = &IRQ2_INST[0];
cur_bus_ofst = &IRQ2_BUSRQ[0];
cur_mem_ofst = &IRQ2_MEMRQ[0];
cur_irqs_ofst = &IRQ2_IRQS;
}
for (int i = 0; i < 19; i++)
if (cond_chk_fail)
{
BUSRQ[i] = *loader; loader++; BUSRQ[i] |= (*loader << 8); loader++;
BUSRQ[i] |= (*loader << 16); loader++; BUSRQ[i] |= (*loader << 24); loader++;
}
for (int i = 0; i < 19; i++)
{
MEMRQ[i] = *loader; loader++; MEMRQ[i] |= (*loader << 8); loader++;
MEMRQ[i] |= (*loader << 16); loader++; MEMRQ[i] |= (*loader << 24); loader++;
cur_irqs_ofst = &False_IRQS[IRQS_cond_offset];
}
TotalExecutedCycles = *loader; loader++; TotalExecutedCycles |= ((uint64_t)*loader << 8); loader++;