-unsp: Added DIVQ and extended BIT_OP opcodes. [Ryan Holtz]

This commit is contained in:
Ryan Holtz 2020-05-16 20:49:54 +02:00
parent 79f08d5431
commit 4feb71b0a7
5 changed files with 151 additions and 30 deletions

View File

@ -2879,7 +2879,7 @@ end
--
--@src/devices/machine/spg2xx.h,MACHINES["SPG2XX"] = true
--@src/devices/machine/spg110.h,MACHINES["SPG2XX"] = true
--@src/devices/machine/sunplus_gpl16250soc.h,MACHINES["SPG2XX"] = true
--@src/devices/machine/generalplus_gpl16250soc.h,MACHINES["SPG2XX"] = true
---------------------------------------------------
if (MACHINES["SPG2XX"]~=null) then

View File

@ -506,6 +506,9 @@ inline void unsp_device::execute_one(const uint16_t op)
const uint16_t opa = (op >> 9) & 7;
const uint16_t op1 = (op >> 6) & 7;
if (!op_is_divq(op))
m_core->m_divq_active = 0;
if (op0 == 0xf)
return execute_fxxx_group(op);

View File

@ -193,6 +193,9 @@ protected:
uint32_t m_ine;
uint32_t m_pri;
uint32_t m_divq_active;
uint32_t m_divq_dividend;
uint32_t m_arg0;
uint32_t m_arg1;
uint32_t m_jmpdest;
@ -229,7 +232,7 @@ protected:
virtual void execute_fxxx_101_group(uint16_t op);
void execute_fxxx_110_group(uint16_t op);
void execute_fxxx_111_group(uint16_t op);
void execute_fxxx_group(uint16_t op);;
void execute_fxxx_group(uint16_t op);
void execute_fxxx_100_group(uint16_t op);
virtual void execute_extended_group(uint16_t op);
virtual void execute_exxx_group(uint16_t op);
@ -237,6 +240,7 @@ protected:
void unimplemented_opcode(uint16_t op);
void unimplemented_opcode(uint16_t op, uint16_t ximm);
void unimplemented_opcode(uint16_t op, uint16_t ximm, uint16_t ximm_2);
virtual bool op_is_divq(const uint16_t op) { return false; }
int m_iso;
@ -369,7 +373,8 @@ protected:
virtual void execute_fxxx_101_group(uint16_t op) override;
virtual void execute_exxx_group(uint16_t op) override;
void execute_divq(uint16_t op);
bool op_is_divq(const uint16_t op) override;
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};

View File

@ -49,14 +49,15 @@ void unsp_12_device::execute_exxx_group(uint16_t op)
else if (((op & 0xf1c0) == 0xe040))
{
// Register BITOP BITOP Rd,offset
uint8_t bitop = (op & 0x0030) >> 4;
uint8_t rd = (op & 0x0e00) >> 9;
uint8_t offset = (op & 0x000f) >> 0;
const uint8_t bitop = (op & 0x0030) >> 4;
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t offset = (op & 0x000f) >> 0;
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
switch (bitop)
{
case 0x00:
fatalerror("UNSP: unknown opcode tstb Rd,offset (%04x) at %04x\n", op, UNSP_LPC);
case 0x00: // tstb
return;
case 0x01: // setb
@ -76,41 +77,123 @@ void unsp_12_device::execute_exxx_group(uint16_t op)
else if (((op & 0xf1c0) == 0xe180))
{
// Memory BITOP BITOP [Rd], offset
uint8_t bitop = (op & 0x0030) >> 4;
uint8_t rd = (op & 0x0e00) >> 9;
uint8_t offset = (op & 0x000f) >> 0;
logerror("%s [%s],%d\n", bitops[bitop], regs[rd], offset);
unimplemented_opcode(op);
const uint8_t bitop = (op & 0x0030) >> 4;
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t offset = (op & 0x000f) >> 0;
const uint16_t addr = m_core->m_r[rd];
const uint16_t orig = read16(addr);
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
switch (bitop)
{
case 0x00: // tstb
return;
case 0x01: // setb
write16(addr, orig | (1 << offset));
return;
case 0x02: // clrb
write16(addr, orig & ~(1 << offset));
return;
case 0x03:
write16(addr, orig ^ (1 << offset));
return;
}
return;
}
else if (((op & 0xf1c0) == 0xe1c0))
{
// Memory BITOP BITOP ds:[Rd], offset
uint8_t bitop = (op & 0x0030) >> 4;
uint8_t rd = (op & 0x0e00) >> 9;
uint8_t offset = (op & 0x000f) >> 0;
logerror("%s ds:[%s],%d\n", bitops[bitop], regs[rd], offset);
unimplemented_opcode(op);
const uint8_t bitop = (op & 0x0030) >> 4;
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t offset = (op & 0x000f) >> 0;
const uint16_t addr = m_core->m_r[rd] | (get_ds() << 16);
const uint16_t orig = read16(addr);
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
switch (bitop)
{
case 0x00: // tstb
return;
case 0x01: // setb
write16(addr, orig | (1 << offset));
return;
case 0x02: // clrb
write16(addr, orig & ~(1 << offset));
return;
case 0x03:
write16(addr, orig ^ (1 << offset));
return;
}
return;
}
else if (((op & 0xf1c8) == 0xe100))
{
// Memory BITOP BITOP [Rd], Rs
uint8_t bitop = (op & 0x0030) >> 4;
uint8_t rd = (op & 0x0e00) >> 9;
uint8_t rs = (op & 0x0007) >> 0;
logerror("%s [%s],%s\n", bitops[bitop], regs[rd], regs[rs]);
unimplemented_opcode(op);
const uint8_t bitop = (op & 0x0030) >> 4;
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t rs = (op & 0x0007) >> 0;
const uint8_t offset = (1 << m_core->m_r[rs]);
const uint16_t addr = m_core->m_r[rd];
const uint16_t orig = read16(addr);
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
switch (bitop)
{
case 0x00: // tstb
return;
case 0x01: // setb
write16(addr, orig | (1 << offset));
return;
case 0x02: // clrb
write16(addr, orig & ~(1 << offset));
return;
case 0x03:
write16(addr, orig ^ (1 << offset));
return;
}
return;
}
else if (((op & 0xf1c8) == 0xe140))
{
// Memory BITOP BITOP ds:[Rd], Rs
uint8_t bitop = (op & 0x0030) >> 4;
uint8_t rd = (op & 0x0e00) >> 9;
uint8_t rs = (op & 0x0007) >> 0;
logerror("%s ds:[%s],%s\n", bitops[bitop], regs[rd], regs[rs]);
unimplemented_opcode(op);
const uint8_t bitop = (op & 0x0030) >> 4;
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t rs = (op & 0x0007) >> 0;
const uint8_t offset = (1 << m_core->m_r[rs]);
const uint16_t addr = m_core->m_r[rd] | (get_ds() << 16);
const uint16_t orig = read16(addr);
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
switch (bitop)
{
case 0x00: // tstb
return;
case 0x01: // setb
write16(addr, orig | (1 << offset));
return;
case 0x02: // clrb
write16(addr, orig & ~(1 << offset));
return;
case 0x03:
write16(addr, orig ^ (1 << offset));
return;
}
return;
}
else if (((op & 0xf0f8) == 0xe008))

View File

@ -248,6 +248,32 @@ inline void unsp_device::execute_fxxx_100_group(uint16_t op)
return;
}
void unsp_12_device::execute_divq(uint16_t op)
{
const uint16_t sign_a = m_core->m_aq;
if (m_core->m_divq_active == 0)
{
m_core->m_divq_active = 1;
m_core->m_divq_dividend = (m_core->m_r[REG_R4] << 16) | m_core->m_r[REG_R3];
m_core->m_r[REG_R3] = 0;
}
m_core->m_aq = BIT(m_core->m_divq_dividend, 31);
if (sign_a)
{
m_core->m_r[REG_R3] += m_core->m_r[REG_R2];
}
else
{
m_core->m_r[REG_R3] -= m_core->m_r[REG_R3];
}
m_core->m_divq_dividend <<= 1;
m_core->m_divq_dividend |= m_core->m_aq ? 0 : 1;
}
bool unsp_12_device::op_is_divq(const uint16_t op)
{
return (op & 0xf163) == 0xf163;
}
void unsp_12_device::execute_fxxx_101_group(uint16_t op)
{
@ -336,8 +362,7 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op)
case 0xf16b: case 0xf36b: case 0xf56b: case 0xf76b: case 0xf96b: case 0xfb6b: case 0xfd6b: case 0xff6b:
case 0xf173: case 0xf373: case 0xf573: case 0xf773: case 0xf973: case 0xfb73: case 0xfd73: case 0xff73:
case 0xf17b: case 0xf37b: case 0xf57b: case 0xf77b: case 0xf97b: case 0xfb7b: case 0xfd7b: case 0xff7b:
logerror("divq mr, r2\n");
unimplemented_opcode(op);
execute_divq(op);
return;
case 0xf164: case 0xf364: case 0xf564: case 0xf764: case 0xf964: case 0xfb64: case 0xfd64: case 0xff64:
@ -525,18 +550,23 @@ void unsp_device::execute_fxxx_group(uint16_t op)
switch ((op & 0x01c0) >> 6)
{
case 0x0:
m_core->m_divq_active = 0;
return execute_fxxx_000_group(op);
case 0x1:
m_core->m_divq_active = 0;
return execute_fxxx_001_group(op);
case 0x2:
m_core->m_divq_active = 0;
return execute_fxxx_010_group(op);
case 0x3:
m_core->m_divq_active = 0;
return execute_fxxx_011_group(op);
case 0x4:
m_core->m_divq_active = 0;
return execute_fxxx_100_group(op);
case 0x5: