mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
unsp: Macro removal cleanup, nw
This commit is contained in:
parent
42d1a6d6e5
commit
e0b485582e
@ -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()
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user