unsp: Macro removal cleanup, nw

This commit is contained in:
MooglyGuy 2019-01-11 13:58:09 +01:00
parent 42d1a6d6e5
commit e0b485582e
2 changed files with 214 additions and 236 deletions

View File

@ -54,18 +54,8 @@ std::unique_ptr<util::disasm_interface> unsp_device::create_disassembler()
/*****************************************************************************/
#define OP0 (op >> 12)
#define OPA ((op >> 9) & 7)
#define OP1 ((op >> 6) & 7)
#define OPN ((op >> 3) & 7)
#define OPB (op & 7)
#define OPIMM (op & 0x3f)
#define UNSP_LPC (((UNSP_REG(SR) & 0x3f) << 16) | UNSP_REG(PC))
#define UNSP_REG(reg) m_r[UNSP_##reg - 1]
#define UNSP_REG_I(reg) m_r[reg]
#define UNSP_LREG_I(reg) (((UNSP_REG(SR) << 6) & 0x3f0000) | UNSP_REG_I(reg))
#define UNSP_LPC (((m_r[REG_SR] & 0x3f) << 16) | m_r[REG_PC])
#define UNSP_LREG_I(reg) (((m_r[REG_SR] << 6) & 0x3f0000) | m_r[reg])
#define UNSP_N 0x0200
#define UNSP_Z 0x0100
@ -108,14 +98,14 @@ void unsp_device::device_start()
m_program = &space(AS_PROGRAM);
state_add(STATE_GENFLAGS, "GENFLAGS", UNSP_REG(SR)).callimport().callexport().formatstr("%4s").noshow();
state_add(UNSP_SP, "SP", UNSP_REG(SP)).formatstr("%04X");
state_add(UNSP_R1, "R1", UNSP_REG(R1)).formatstr("%04X");
state_add(UNSP_R2, "R2", UNSP_REG(R2)).formatstr("%04X");
state_add(UNSP_R3, "R3", UNSP_REG(R3)).formatstr("%04X");
state_add(UNSP_R4, "R4", UNSP_REG(R4)).formatstr("%04X");
state_add(UNSP_BP, "BP", UNSP_REG(BP)).formatstr("%04X");
state_add(UNSP_SR, "SR", UNSP_REG(SR)).formatstr("%04X");
state_add(STATE_GENFLAGS, "GENFLAGS", m_r[REG_SR]).callimport().callexport().formatstr("%4s").noshow();
state_add(UNSP_SP, "SP", m_r[REG_SP]).formatstr("%04X");
state_add(UNSP_R1, "R1", m_r[REG_R1]).formatstr("%04X");
state_add(UNSP_R2, "R2", m_r[REG_R2]).formatstr("%04X");
state_add(UNSP_R3, "R3", m_r[REG_R3]).formatstr("%04X");
state_add(UNSP_R4, "R4", m_r[REG_R4]).formatstr("%04X");
state_add(UNSP_BP, "BP", m_r[REG_BP]).formatstr("%04X");
state_add(UNSP_SR, "SR", m_r[REG_SR]).formatstr("%04X");
state_add(UNSP_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%06X");
state_add(UNSP_IRQ_EN, "IRQE", m_enable_irq).formatstr("%1u");
state_add(UNSP_FIQ_EN, "FIQE", m_enable_fiq).formatstr("%1u");
@ -148,7 +138,7 @@ void unsp_device::state_string_export(const device_state_entry &entry, std::stri
{
case STATE_GENFLAGS:
{
const uint16_t sr = UNSP_REG(SR);
const uint16_t sr = m_r[REG_SR];
str = string_format("%c%c%c%c", (sr & UNSP_N) ? 'N' : ' ', (sr & UNSP_Z) ? 'Z' : ' ', (sr & UNSP_S) ? 'S' : ' ', (sr & UNSP_C) ? 'C' : ' ');
}
}
@ -171,8 +161,8 @@ void unsp_device::state_import(const device_state_entry &entry)
switch (entry.index())
{
case UNSP_PC:
UNSP_REG(PC) = m_debugger_temp & 0x0000ffff;
UNSP_REG(SR) = (UNSP_REG(SR) & 0xffc0) | ((m_debugger_temp & 0x003f0000) >> 16);
m_r[REG_PC] = m_debugger_temp & 0x0000ffff;
m_r[REG_SR] = (m_r[REG_SR] & 0xffc0) | ((m_debugger_temp & 0x003f0000) >> 16);
break;
}
}
@ -181,7 +171,7 @@ void unsp_device::device_reset()
{
memset(m_r, 0, sizeof(uint16_t) * 16);
UNSP_REG(PC) = read16(0xfff7);
m_r[REG_PC] = read16(0xfff7);
m_enable_irq = false;
m_enable_fiq = false;
m_irq = false;
@ -190,31 +180,26 @@ void unsp_device::device_reset()
/*****************************************************************************/
void unsp_device::update_nz(uint32_t value)
void unsp_device::update_nzsc(uint32_t value, uint16_t r0, uint16_t r1)
{
UNSP_REG(SR) &= ~(UNSP_N | UNSP_Z);
m_r[REG_SR] &= ~(UNSP_N | UNSP_Z | UNSP_S | UNSP_C);
if(value & 0x8000)
{
UNSP_REG(SR) |= UNSP_N;
}
m_r[REG_SR] |= UNSP_N;
if((uint16_t)value == 0)
{
UNSP_REG(SR) |= UNSP_Z;
}
m_r[REG_SR] |= UNSP_Z;
if(value != (uint16_t)value)
m_r[REG_SR] |= UNSP_C;
if((int16_t)r0 < (int16_t)r1)
m_r[REG_SR] |= UNSP_S;
}
void unsp_device::update_sc(uint32_t value, uint16_t r0, uint16_t r1)
void unsp_device::update_nz(uint32_t value)
{
UNSP_REG(SR) &= ~(UNSP_C | UNSP_S);
if(value != (uint16_t)value)
{
UNSP_REG(SR) |= UNSP_C;
}
if((int16_t)r0 < (int16_t)r1)
{
UNSP_REG(SR) |= UNSP_S;
}
m_r[REG_SR] &= ~(UNSP_N | UNSP_Z);
if(value & 0x8000)
m_r[REG_SR] |= UNSP_N;
if((uint16_t)value == 0)
m_r[REG_SR] |= UNSP_Z;
}
void unsp_device::push(uint16_t value, uint16_t *reg)
@ -239,10 +224,10 @@ void unsp_device::trigger_fiq()
m_saved_sb[m_irq ? 1 : 0] = m_sb;
m_sb = m_saved_sb[2];
push(UNSP_REG(PC), &UNSP_REG(SP));
push(UNSP_REG(SR), &UNSP_REG(SP));
UNSP_REG(PC) = read16(0xfff6);
UNSP_REG(SR) = 0;
push(m_r[REG_PC], &m_r[REG_SP]);
push(m_r[REG_SR], &m_r[REG_SP]);
m_r[REG_PC] = read16(0xfff6);
m_r[REG_SR] = 0;
}
void unsp_device::trigger_irq(int line)
@ -255,10 +240,10 @@ void unsp_device::trigger_irq(int line)
m_saved_sb[0] = m_sb;
m_sb = m_saved_sb[1];
push(UNSP_REG(PC), &UNSP_REG(SP));
push(UNSP_REG(SR), &UNSP_REG(SP));
UNSP_REG(PC) = read16(0xfff8 + line);
UNSP_REG(SR) = 0;
push(m_r[REG_PC], &m_r[REG_SP]);
push(m_r[REG_SR], &m_r[REG_SP]);
m_r[REG_PC] = read16(0xfff8 + line);
m_r[REG_SR] = 0;
}
void unsp_device::check_irqs()
@ -285,9 +270,9 @@ void unsp_device::check_irqs()
void unsp_device::add_lpc(const int32_t offset)
{
const uint32_t new_lpc = UNSP_LPC + offset;
UNSP_REG(PC) = (uint16_t)new_lpc;
UNSP_REG(SR) &= 0xffc0;
UNSP_REG(SR) |= (new_lpc >> 16) & 0x3f;
m_r[REG_PC] = (uint16_t)new_lpc;
m_r[REG_SR] &= 0xffc0;
m_r[REG_SR] |= (new_lpc >> 16) & 0x3f;
}
inline void unsp_device::execute_one(const uint16_t op)
@ -297,17 +282,24 @@ inline void unsp_device::execute_one(const uint16_t op)
uint16_t r1 = 0;
uint32_t r2 = 0;
const uint8_t lower_op = (OP1 << 4) | OP0;
const uint16_t op0 = (op >> 12) & 15;
const uint16_t opa = (op >> 9) & 7;
const uint16_t op1 = (op >> 6) & 7;
const uint16_t opn = (op >> 3) & 7;
const uint16_t opb = op & 7;
if(OP0 < 0xf && OPA == 0x7 && OP1 < 2)
const uint8_t lower_op = (op1 << 4) | op0;
if(op0 < 0xf && opa == 0x7 && op1 < 2)
{
switch(OP0)
const uint32_t opimm = op & 0x3f;
switch(op0)
{
case 0: // JB
if(!(UNSP_REG(SR) & UNSP_C))
if(!(m_r[REG_SR] & UNSP_C))
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -315,10 +307,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 1: // JAE
if(UNSP_REG(SR) & UNSP_C)
if(m_r[REG_SR] & UNSP_C)
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -326,10 +318,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 2: // JGE
if(!(UNSP_REG(SR) & UNSP_S))
if(!(m_r[REG_SR] & UNSP_S))
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -337,10 +329,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 3: // JL
if(UNSP_REG(SR) & UNSP_S)
if(m_r[REG_SR] & UNSP_S)
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -348,10 +340,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 4: // JNE
if(!(UNSP_REG(SR) & UNSP_Z))
if(!(m_r[REG_SR] & UNSP_Z))
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -359,10 +351,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 5: // JE
if(UNSP_REG(SR) & UNSP_Z)
if(m_r[REG_SR] & UNSP_Z)
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -370,10 +362,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 6: // JPL
if(!(UNSP_REG(SR) & UNSP_N))
if(!(m_r[REG_SR] & UNSP_N))
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -381,10 +373,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 7: // JMI
if(UNSP_REG(SR) & UNSP_N)
if(m_r[REG_SR] & UNSP_N)
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -392,10 +384,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 8: // JBE
if((UNSP_REG(SR) & (UNSP_Z | UNSP_C)) != UNSP_C)
if((m_r[REG_SR] & (UNSP_Z | UNSP_C)) != UNSP_C)
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -403,10 +395,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 9: // JA
if((UNSP_REG(SR) & (UNSP_Z | UNSP_C)) == UNSP_C)
if((m_r[REG_SR] & (UNSP_Z | UNSP_C)) == UNSP_C)
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -414,10 +406,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 10: // JLE
if(UNSP_REG(SR) & (UNSP_Z | UNSP_S))
if(m_r[REG_SR] & (UNSP_Z | UNSP_S))
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -425,10 +417,10 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 11: // JG
if(!(UNSP_REG(SR) & (UNSP_Z | UNSP_S)))
if(!(m_r[REG_SR] & (UNSP_Z | UNSP_S)))
{
m_icount -= 4;
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
}
else
{
@ -436,7 +428,7 @@ inline void unsp_device::execute_one(const uint16_t op)
}
return;
case 14: // JMP
add_lpc((OP1 == 0) ? OPIMM : (0 - OPIMM));
add_lpc((op1 == 0) ? opimm : (0 - opimm));
m_icount -= 4;
return;
default:
@ -446,13 +438,13 @@ inline void unsp_device::execute_one(const uint16_t op)
}
else if (lower_op == 0x2d) // Push
{
r0 = OPN;
r1 = OPA;
r0 = opn;
r1 = opa;
m_icount -= 4 + 2 * r0;
while (r0--)
{
push(UNSP_REG_I(r1--), &UNSP_REG_I(OPB));
push(m_r[r1--], &m_r[opb]);
}
return;
}
@ -461,8 +453,8 @@ inline void unsp_device::execute_one(const uint16_t op)
if (op == 0x9a98) // reti
{
m_icount -= 8;
UNSP_REG(SR) = pop(&UNSP_REG(SP));
UNSP_REG(PC) = pop(&UNSP_REG(SP));
m_r[REG_SR] = pop(&m_r[REG_SP]);
m_r[REG_PC] = pop(&m_r[REG_SP]);
if(m_fiq)
{
@ -483,32 +475,32 @@ inline void unsp_device::execute_one(const uint16_t op)
}
else
{
r0 = OPN;
r1 = OPA;
r0 = opn;
r1 = opa;
m_icount -= 4 + 2 * r0;
while (r0--)
{
UNSP_REG_I(++r1) = pop(&UNSP_REG_I(OPB));
m_r[++r1] = pop(&m_r[opb]);
}
return;
}
}
else if (OP0 == 0xf)
else if (op0 == 0xf)
{
switch (OP1)
switch (op1)
{
case 0x00: // Multiply, Unsigned * Signed
if(OPN == 1 && OPA != 7)
if(opn == 1 && opa != 7)
{
m_icount -= 12;
lres = UNSP_REG_I(OPA) * UNSP_REG_I(OPB);
if(UNSP_REG_I(OPB) & 0x8000)
lres = m_r[opa] * m_r[opb];
if(m_r[opb] & 0x8000)
{
lres -= UNSP_REG_I(OPA) << 16;
lres -= m_r[opa] << 16;
}
UNSP_REG(R4) = lres >> 16;
UNSP_REG(R3) = (uint16_t)lres;
m_r[REG_R4] = lres >> 16;
m_r[REG_R3] = (uint16_t)lres;
}
else
{
@ -517,16 +509,16 @@ inline void unsp_device::execute_one(const uint16_t op)
return;
case 0x01: // Call
if(!(OPA & 1))
if(!(opa & 1))
{
m_icount -= 9;
r1 = read16(UNSP_LPC);
add_lpc(1);
push(UNSP_REG(PC), &UNSP_REG(SP));
push(UNSP_REG(SR), &UNSP_REG(SP));
UNSP_REG(PC) = r1;
UNSP_REG(SR) &= 0xffc0;
UNSP_REG(SR) |= OPIMM;
push(m_r[REG_PC], &m_r[REG_SP]);
push(m_r[REG_SR], &m_r[REG_SP]);
m_r[REG_PC] = r1;
m_r[REG_SR] &= 0xffc0;
m_r[REG_SR] |= op & 0x3f;
}
else
{
@ -535,12 +527,12 @@ inline void unsp_device::execute_one(const uint16_t op)
return;
case 0x02: // Far Jump
if (OPA == 7)
if (opa == 7)
{
m_icount -= 5;
UNSP_REG(PC) = read16(UNSP_LPC);
UNSP_REG(SR) &= 0xffc0;
UNSP_REG(SR) |= OPIMM;
m_r[REG_PC] = read16(UNSP_LPC);
m_r[REG_SR] &= 0xffc0;
m_r[REG_SR] |= op & 0x3f;
}
else
{
@ -549,20 +541,20 @@ inline void unsp_device::execute_one(const uint16_t op)
return;
case 0x04: // Multiply, Signed * Signed
if(OPN == 1 && OPA != 7)
if(opn == 1 && opa != 7)
{
m_icount -= 12;
lres = UNSP_REG_I(OPA) * UNSP_REG_I(OPB);
if(UNSP_REG_I(OPB) & 0x8000)
lres = m_r[opa] * m_r[opb];
if(m_r[opb] & 0x8000)
{
lres -= UNSP_REG_I(OPA) << 16;
lres -= m_r[opa] << 16;
}
if(UNSP_REG_I(OPA) & 0x8000)
if(m_r[opa] & 0x8000)
{
lres -= UNSP_REG_I(OPB) << 16;
lres -= m_r[opb] << 16;
}
UNSP_REG(R4) = lres >> 16;
UNSP_REG(R3) = (uint16_t)lres;
m_r[REG_R4] = lres >> 16;
m_r[REG_R3] = (uint16_t)lres;
}
else
{
@ -572,7 +564,7 @@ inline void unsp_device::execute_one(const uint16_t op)
case 0x05: // Interrupt flags
m_icount -= 2;
switch(OPIMM)
switch(op & 0x3f)
{
case 0:
m_enable_irq = false;
@ -618,65 +610,60 @@ inline void unsp_device::execute_one(const uint16_t op)
// At this point, we should be dealing solely with ALU ops.
r0 = UNSP_REG_I(OPA);
r0 = m_r[opa];
switch (OP1)
switch (op1)
{
case 0x00: // r, [bp+imm6]
m_icount -= 6;
r2 = (uint16_t)(UNSP_REG(BP) + OPIMM);
if (OP0 != 0x0d)
r2 = (uint16_t)(m_r[REG_BP] + (op & 0x3f));
if (op0 != 0x0d)
r1 = read16(r2);
break;
case 0x01: // r, imm6
m_icount -= 2;
r1 = OPIMM;
r1 = op & 0x3f;
break;
case 0x03: // Indirect
{
m_icount -= 6;
if (OPA == 7)
{
m_icount -= 1;
}
m_icount -= (opa == 7 ? 7 : 6);
const uint8_t lsbits = OPN & 3;
const uint8_t opb = OPB;
if (OPN & 4)
const uint8_t lsbits = opn & 3;
if (opn & 4)
{
switch (lsbits)
{
case 0: // r, [r]
r2 = UNSP_LREG_I(opb);
if (OP0 != 0x0d)
if (op0 != 0x0d)
r1 = read16(r2);
break;
case 1: // r, [<ds:>r--]
r2 = UNSP_LREG_I(opb);
if (OP0 != 0x0d)
if (op0 != 0x0d)
r1 = read16(r2);
UNSP_REG_I(opb)--;
if (UNSP_REG_I(opb) == 0xffff)
UNSP_REG(SR) -= 0x0400;
m_r[opb]--;
if (m_r[opb] == 0xffff)
m_r[REG_SR] -= 0x0400;
break;
case 2: // r, [<ds:>r++]
r2 = UNSP_LREG_I(opb);
if (OP0 != 0x0d)
if (op0 != 0x0d)
r1 = read16(r2);
UNSP_REG_I(opb)++;
if (UNSP_REG_I(opb) == 0x0000)
UNSP_REG(SR) += 0x0400;
m_r[opb]++;
if (m_r[opb] == 0x0000)
m_r[REG_SR] += 0x0400;
break;
case 3: // r, [<ds:>++r]
UNSP_REG_I(opb)++;
if (UNSP_REG_I(opb) == 0x0000)
UNSP_REG(SR) += 0x0400;
m_r[opb]++;
if (m_r[opb] == 0x0000)
m_r[REG_SR] += 0x0400;
r2 = UNSP_LREG_I(opb);
if (OP0 != 0x0d)
if (op0 != 0x0d)
r1 = read16(r2);
break;
default:
@ -688,26 +675,26 @@ inline void unsp_device::execute_one(const uint16_t op)
switch (lsbits)
{
case 0: // r, [r]
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
r2 = m_r[opb];
if (op0 != 0x0d)
r1 = read16(r2);
break;
case 1: // r, [r--]
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
r2 = m_r[opb];
if (op0 != 0x0d)
r1 = read16(r2);
UNSP_REG_I(opb)--;
m_r[opb]--;
break;
case 2: // r, [r++]
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
r2 = m_r[opb];
if (op0 != 0x0d)
r1 = read16(r2);
UNSP_REG_I(opb)++;
m_r[opb]++;
break;
case 3: // r, [++r]
UNSP_REG_I(opb)++;
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
m_r[opb]++;
r2 = m_r[opb];
if (op0 != 0x0d)
r1 = read16(r2);
break;
default:
@ -718,72 +705,47 @@ inline void unsp_device::execute_one(const uint16_t op)
}
case 0x04: // 16-bit ops
switch (OPN)
switch (opn)
{
case 0x00: // r
m_icount -= 3;
if (OPA == 7)
{
m_icount -= 2;
}
r1 = UNSP_REG_I(OPB);
m_icount -= (opa == 7 ? 5 : 3);
r1 = m_r[opb];
break;
case 0x01: // imm16
m_icount -= 4;
if (OPA == 7)
{
m_icount -= 1;
}
r0 = UNSP_REG_I(OPB);
m_icount -= (opa == 7 ? 5 : 4);
r0 = m_r[opb];
r1 = read16(UNSP_LPC);
add_lpc(1);
break;
case 0x02: // [imm16]
m_icount -= 7;
if (OPA == 7)
{
m_icount -= 1;
}
r0 = UNSP_REG_I(OPB);
m_icount -= (opa == 7 ? 8 : 7);
r0 = m_r[opb];
r2 = read16(UNSP_LPC);
add_lpc(1);
if (OP0 != 0x0d)
if (op0 != 0x0d)
{
r1 = read16(r2);
}
break;
case 0x03: // store [imm16], r
m_icount -= 7;
if (OPA == 7)
{
m_icount -= 1;
}
m_icount -= (opa == 7 ? 8 : 7);
r1 = r0;
r0 = UNSP_REG_I(OPB);
r0 = m_r[opb];
r2 = read16(UNSP_LPC);
add_lpc(1);
break;
default: // Shifted ops
{
m_icount -= 3;
if (OPA == 7)
{
m_icount -= 2;
}
uint32_t shift = (UNSP_REG_I(OPB) << 4) | m_sb;
m_icount -= (opa == 7 ? 5 : 3);
uint32_t shift = (m_r[opb] << 4) | m_sb;
if (shift & 0x80000)
shift |= 0xf00000;
shift >>= (OPN - 3);
shift >>= (opn - 3);
m_sb = shift & 0x0f;
r1 = (uint16_t)(shift >> 4);
break;
@ -792,21 +754,17 @@ inline void unsp_device::execute_one(const uint16_t op)
break;
case 0x05: // More shifted ops
m_icount -= 3;
if (OPA == 7)
{
m_icount -= 2;
}
m_icount -= (opa == 7 ? 5 : 3);
if (OPN & 4) // Shift right
if (opn & 4) // Shift right
{
const uint32_t shift = ((UNSP_REG_I(OPB) << 4) | m_sb) >> (OPN - 3);
const uint32_t shift = ((m_r[opb] << 4) | m_sb) >> (opn - 3);
m_sb = shift & 0x0f;
r1 = (uint16_t)(shift >> 4);
}
else // Shift left
{
const uint32_t shift = ((m_sb << 16) | UNSP_REG_I(OPB)) << (OPN + 1);
const uint32_t shift = ((m_sb << 16) | m_r[opb]) << (opn + 1);
m_sb = (shift >> 16) & 0x0f;
r1 = (uint16_t)shift;
}
@ -814,21 +772,17 @@ inline void unsp_device::execute_one(const uint16_t op)
case 0x06: // Rotated ops
{
m_icount -= 3;
if (OPA == 7)
{
m_icount -= 2;
}
m_icount -= (opa == 7 ? 5 : 3);
uint32_t shift = (((m_sb << 16) | UNSP_REG_I(OPB)) << 4) | m_sb;
if (OPN & 4) // Rotate right
uint32_t shift = (((m_sb << 16) | m_r[opb]) << 4) | m_sb;
if (opn & 4) // Rotate right
{
shift >>= (OPN - 3);
shift >>= (opn - 3);
m_sb = shift & 0x0f;
}
else
{
shift <<= (OPN + 1);
shift <<= (opn + 1);
m_sb = (shift >> 20) & 0x0f;
}
r1 = (uint16_t)(shift >> 4);
@ -836,78 +790,90 @@ inline void unsp_device::execute_one(const uint16_t op)
}
case 0x07: // Direct 8
m_icount -= 5;
if (OPA == 7)
{
m_icount -= 1;
}
r2 = OPIMM;
r1 = read16(OPIMM);
m_icount -= (opa == 7 ? 6 : 5);
r2 = op & 0x3f;
r1 = read16(r2);
break;
default:
break;
}
switch (OP0)
switch (op0)
{
case 0x00: // Add
lres = r0 + r1;
if (opa != 7)
update_nzsc(lres, r0, r1);
break;
case 0x01: // Add w/ carry
lres = r0 + r1;
if(UNSP_REG(SR) & UNSP_C)
if(m_r[REG_SR] & UNSP_C)
lres++;
if (opa != 7)
update_nzsc(lres, r0, r1);
break;
case 0x02: // Subtract
case 0x04: // Compare
lres = r0 + (uint16_t)(~r1) + 1;
if (opa != 7)
update_nzsc(lres, r0, r1);
break;
case 0x03: // Subtract w/ carry
lres = r0 + (uint16_t)(~r1);
if(UNSP_REG(SR) & UNSP_C)
if(m_r[REG_SR] & UNSP_C)
lres++;
if (opa != 7)
update_nzsc(lres, r0, r1);
break;
case 0x04: // Compare
lres = r0 + (uint16_t)(~r1) + 1;
if (opa != 7)
update_nzsc(lres, r0, r1);
return;
case 0x06: // Negate
lres = -r1;
if (opa != 7)
update_nz(lres);
break;
case 0x08: // XOR
lres = r0 ^ r1;
if (opa != 7)
update_nz(lres);
break;
case 0x09: // Load
lres = r1;
if (opa != 7)
update_nz(lres);
break;
case 0x0a: // OR
lres = r0 | r1;
if (opa != 7)
update_nz(lres);
break;
case 0x0b: // AND
lres = r0 & r1;
if (opa != 7)
update_nz(lres);
break;
case 0x0c: // Test
lres = r0 & r1;
break;
if (opa != 7)
update_nz(lres);
return;
case 0x0d: // Store
write16(r2, r0);
return;
default:
unimplemented_opcode(op);
if (opa != 7)
update_nz(lres);
return;
}
if (OP0 != 0x0d && OPA != 7) // If not a store opcode and not updating the PC, update negative/zero flags.
{
update_nz(lres);
}
if (OP0 < 0x05 && OPA != 7) // If Add, Add w/ Carry, Subtract, Subtract w/ Carry, Compare, and not updating the PC, update sign/carry flags.
update_sc(lres, r0, r1);
if (OP0 == 0x04 || OP0 == 0x0c) // Compare and Test don't write back results.
return;
if (OP1 == 0x04 && OPN == 0x03) // store [imm16], r
if (op1 == 0x04 && opn == 0x03) // store [imm16], r
write16(r2, lres);
else
UNSP_REG_I(OPA) = lres;
m_r[opa] = lres;
}
void unsp_device::execute_run()

View File

@ -94,6 +94,18 @@ protected:
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
enum
{
REG_SP = 0,
REG_R1,
REG_R2,
REG_R3,
REG_R4,
REG_BP,
REG_SR,
REG_PC
};
void add_lpc(const int32_t offset);
inline void execute_one(const uint16_t op);
@ -122,7 +134,7 @@ private:
inline uint16_t read16(uint32_t address);
inline void write16(uint32_t address, uint16_t data);
inline void update_nz(uint32_t value);
inline void update_sc(uint32_t value, uint16_t r0, uint16_t r1);
inline void update_nzsc(uint32_t value, uint16_t r0, uint16_t r1);
inline void push(uint16_t value, uint16_t *reg);
inline uint16_t pop(uint16_t *reg);
inline void trigger_fiq();