mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
-jak_care: Hooked up spg2xx software wave-in channel, hooked up muls and fir_mov ops in unsp. Allows voice to work. [Ryan Holtz, Tahg, smf]
This commit is contained in:
parent
8e98c7e905
commit
3e6ace480a
@ -228,6 +228,7 @@ void unsp_device::device_start()
|
||||
m_drcuml->symbol_add(&m_core->m_r[REG_PC], sizeof(uint32_t), "PC");
|
||||
m_drcuml->symbol_add(&m_core->m_enable_irq, sizeof(uint32_t), "IRQE");
|
||||
m_drcuml->symbol_add(&m_core->m_enable_fiq, sizeof(uint32_t), "FIQE");
|
||||
m_drcuml->symbol_add(&m_core->m_fir_move, sizeof(uint32_t), "FIR_MOV");
|
||||
m_drcuml->symbol_add(&m_core->m_irq, sizeof(uint32_t), "IRQ");
|
||||
m_drcuml->symbol_add(&m_core->m_fiq, sizeof(uint32_t), "FIQ");
|
||||
m_drcuml->symbol_add(&m_core->m_sb, sizeof(uint32_t), "SB");
|
||||
@ -251,9 +252,10 @@ void unsp_device::device_start()
|
||||
state_add(UNSP_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%06X");
|
||||
state_add(UNSP_IRQ_EN, "IRQE", m_core->m_enable_irq).formatstr("%1u");
|
||||
state_add(UNSP_FIQ_EN, "FIQE", m_core->m_enable_fiq).formatstr("%1u");
|
||||
state_add(UNSP_FIR_MOV_EN, "FIR_MOV", m_core->m_fir_move).formatstr("%1u");
|
||||
state_add(UNSP_IRQ, "IRQ", m_core->m_irq).formatstr("%1u");
|
||||
state_add(UNSP_FIQ, "FIQ", m_core->m_fiq).formatstr("%1u");
|
||||
state_add(UNSP_SB, "SB", m_core->m_sb).formatstr("%1u");
|
||||
state_add(UNSP_SB, "SB", m_core->m_sb).formatstr("%1X");
|
||||
#if UNSP_LOG_OPCODES || UNSP_LOG_REGS
|
||||
state_add(UNSP_LOG_OPS,"LOG", m_log_ops).formatstr("%1u");
|
||||
#endif
|
||||
@ -264,6 +266,7 @@ void unsp_device::device_start()
|
||||
save_item(NAME(m_core->m_r));
|
||||
save_item(NAME(m_core->m_enable_irq));
|
||||
save_item(NAME(m_core->m_enable_fiq));
|
||||
save_item(NAME(m_core->m_fir_move));
|
||||
save_item(NAME(m_core->m_irq));
|
||||
save_item(NAME(m_core->m_fiq));
|
||||
save_item(NAME(m_core->m_curirq));
|
||||
@ -307,6 +310,7 @@ void unsp_device::device_reset()
|
||||
m_core->m_r[REG_PC] = read16(0xfff7);
|
||||
m_core->m_enable_irq = 0;
|
||||
m_core->m_enable_fiq = 0;
|
||||
m_core->m_fir_move = 0;
|
||||
m_core->m_irq = 0;
|
||||
m_core->m_fiq = 0;
|
||||
}
|
||||
@ -389,10 +393,10 @@ void unsp_device::state_import(const device_state_entry &entry)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void unsp_device::update_nzsc(uint32_t value, uint16_t r0, uint16_t r1)
|
||||
void unsp_device::update_nzsc(uint32_t value, int32_t svalue)
|
||||
{
|
||||
m_core->m_r[REG_SR] &= ~(UNSP_N | UNSP_Z | UNSP_S | UNSP_C);
|
||||
if (int16_t(r0) < int16_t(~r1))
|
||||
if (svalue < 0)
|
||||
m_core->m_r[REG_SR] |= UNSP_S;
|
||||
if (BIT(value, 15))
|
||||
m_core->m_r[REG_SR] |= UNSP_N;
|
||||
|
@ -60,6 +60,7 @@ enum
|
||||
|
||||
UNSP_IRQ_EN,
|
||||
UNSP_FIQ_EN,
|
||||
UNSP_FIR_MOV_EN,
|
||||
UNSP_IRQ,
|
||||
UNSP_FIQ,
|
||||
#if UNSP_LOG_OPCODES || UNSP_LOG_REGS
|
||||
@ -164,9 +165,10 @@ protected:
|
||||
|
||||
struct internal_unsp_state
|
||||
{
|
||||
uint32_t m_r[16]; // why are these 32-bit? they're 16-bit regs? (changing to uint16_t causes crashes tho, so something is depending on this)
|
||||
uint32_t m_r[16]; // required to be 32 bits due to DRC
|
||||
uint32_t m_enable_irq;
|
||||
uint32_t m_enable_fiq;
|
||||
uint32_t m_fir_move;
|
||||
uint32_t m_irq;
|
||||
uint32_t m_fiq;
|
||||
uint32_t m_curirq;
|
||||
@ -214,6 +216,7 @@ protected:
|
||||
void execute_fxxx_100_group(uint16_t op);
|
||||
virtual void execute_extended_group(uint16_t op);
|
||||
virtual void execute_exxx_group(uint16_t op);
|
||||
void execute_muls(const uint16_t rd, const uint16_t rs, const uint16_t size);
|
||||
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);
|
||||
@ -231,7 +234,7 @@ protected:
|
||||
uint16_t pop(uint32_t *reg);
|
||||
|
||||
void update_nz(uint32_t value);
|
||||
void update_nzsc(uint32_t value, uint16_t r0, uint16_t r1);
|
||||
void update_nzsc(uint32_t value, int32_t svalue);
|
||||
bool do_basic_alu_ops(const uint16_t& op0, uint32_t& lres, uint16_t& r0, uint16_t& r1, uint32_t& r2, bool update_flags);
|
||||
|
||||
private:
|
||||
|
@ -60,15 +60,11 @@ inline void unsp_device::execute_fxxx_000_group(uint16_t op)
|
||||
|
||||
// MUL us ( signed * unsigned )
|
||||
// MUL 1 1 1 1* r r r 0* 0 0 0 0 1 r r r (** = sign bits, fixed here)
|
||||
const uint16_t opa = (op >> 9) & 7;
|
||||
const uint16_t opb = op & 7;
|
||||
const uint16_t rd = (op >> 9) & 7;
|
||||
const uint16_t rs = op & 7;
|
||||
m_core->m_icount -= 12;
|
||||
uint32_t lres = m_core->m_r[opa] * m_core->m_r[opb];
|
||||
if (m_core->m_r[opb] & 0x8000)
|
||||
{
|
||||
lres -= m_core->m_r[opa] << 16;
|
||||
}
|
||||
m_core->m_r[REG_R4] = lres >> 16;
|
||||
int32_t lres = (int32_t)(uint32_t)m_core->m_r[rd] * (int32_t)(int16_t)m_core->m_r[rs];
|
||||
m_core->m_r[REG_R4] = (uint16_t)(lres >> 16);
|
||||
m_core->m_r[REG_R3] = (uint16_t)lres;
|
||||
|
||||
return;
|
||||
@ -290,15 +286,13 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op)
|
||||
return;
|
||||
|
||||
case 0xf144: case 0xf344: case 0xf544: case 0xf744: case 0xf944: case 0xfb44: case 0xfd44: case 0xff44:
|
||||
logerror("unimplemented: fir_mov on\n");
|
||||
m_core->m_icount -= 1;
|
||||
//unimplemented_opcode(op); // generalplus_gpac800 games do this on startup
|
||||
m_core->m_fir_move = 1;
|
||||
return;
|
||||
|
||||
case 0xf145: case 0xf345: case 0xf545: case 0xf745: case 0xf945: case 0xfb45: case 0xfd45: case 0xff45:
|
||||
logerror("unimplemented: fir_mov off\n");
|
||||
m_core->m_icount -= 1;
|
||||
//unimplemented_opcode(op); // generalplus_gpac800 games do this on startup
|
||||
m_core->m_fir_move = 0;
|
||||
return;
|
||||
|
||||
case 0xf161: case 0xf361: case 0xf561: case 0xf761: case 0xf961: case 0xfb61: case 0xfd61: case 0xff61:
|
||||
@ -392,13 +386,11 @@ void unsp_device::execute_fxxx_101_group(uint16_t op)
|
||||
return;
|
||||
|
||||
case 0xf144: case 0xf344: case 0xf544: case 0xf744: case 0xf944: case 0xfb44: case 0xfd44: case 0xff44:
|
||||
logerror("fir_mov on (shouldn't exist on 1.0, is this 1.2 or does it act as a NOP?)\n");
|
||||
//unimplemented_opcode(op); // jak_care triggers this, which again strongly suggests that everything we have is 1.2 or above even if most new features are unused
|
||||
m_core->m_fir_move = 1;
|
||||
return;
|
||||
|
||||
case 0xf145: case 0xf345: case 0xf545: case 0xf745: case 0xf945: case 0xfb45: case 0xfd45: case 0xff45:
|
||||
logerror("fir_mov off (shouldn't exist on 1.0, is this 1.2 or does it act as a NOP?)\n");
|
||||
//unimplemented_opcode(op); // jak_care triggers this, see above
|
||||
m_core->m_fir_move = 0;
|
||||
return;
|
||||
|
||||
case 0xf160: case 0xf360: case 0xf560: case 0xf760: case 0xf960: case 0xfb60: case 0xfd60: case 0xff60:
|
||||
@ -458,8 +450,45 @@ inline void unsp_device::execute_fxxx_110_group(uint16_t op)
|
||||
// MULS 1 1 1 1* r r r 1* 1 0*s s s r r r (1* = sign bit, 1* = sign bit 0* = upper size bit)
|
||||
|
||||
// MULS ss with upper size bit not set
|
||||
//unimplemented_opcode(op);
|
||||
//return;
|
||||
const uint16_t size = ((op >> 3) & 7) ? ((op >> 3) & 7) : 16;
|
||||
const uint16_t rd = (op >> 9) & 7;
|
||||
const uint16_t rs = op & 7;
|
||||
execute_muls(rd, rs, size);
|
||||
}
|
||||
|
||||
inline void unsp_device::execute_muls(const uint16_t rd, const uint16_t rs, const uint16_t size)
|
||||
{
|
||||
const uint32_t rdv = m_core->m_r[rd];
|
||||
const uint32_t rsv = m_core->m_r[rs];
|
||||
int64_t lres = 0;
|
||||
uint16_t values[16];
|
||||
for (uint16_t i = 0; i < size; i++)
|
||||
{
|
||||
values[i] = read16(rdv + i);
|
||||
const uint16_t rhs = read16(rsv + i);
|
||||
uint32_t tres = values[i] * rhs;
|
||||
if (values[i] & 0x8000)
|
||||
{
|
||||
tres -= rhs << 16;
|
||||
}
|
||||
if (rhs & 0x8000)
|
||||
{
|
||||
tres -= values[i] << 16;
|
||||
}
|
||||
lres += (int64_t)(int32_t)tres;
|
||||
}
|
||||
m_core->m_sb = 0;
|
||||
if (m_core->m_fir_move)
|
||||
{
|
||||
for (uint16_t i = size - 1; i > 0; i--)
|
||||
{
|
||||
write16(rdv + i, values[i - 1]);
|
||||
}
|
||||
}
|
||||
m_core->m_r[rd] += size;
|
||||
m_core->m_r[rs] += size;
|
||||
m_core->m_r[REG_R4] = (uint16_t)(lres >> 16);
|
||||
m_core->m_r[REG_R3] = (uint16_t)lres;
|
||||
}
|
||||
|
||||
inline void unsp_device::execute_fxxx_111_group(uint16_t op)
|
||||
@ -472,8 +501,9 @@ inline void unsp_device::execute_fxxx_111_group(uint16_t op)
|
||||
// MULS 1 1 1 1* r r r 1* 1 1*s s s r r r (1* = sign bit, 1* = sign bit 1* = upper size bit)
|
||||
|
||||
// MULS ss with upper size bit set.
|
||||
//unimplemented_opcode(op);
|
||||
//return;
|
||||
const uint16_t rd = (op >> 9) & 7;
|
||||
const uint16_t rs = op & 7;
|
||||
execute_muls(rd, rs, ((op >> 3) & 7) + 8);
|
||||
}
|
||||
|
||||
void unsp_device::execute_fxxx_group(uint16_t op)
|
||||
|
@ -281,40 +281,46 @@ void unsp_device::execute_remaining(const uint16_t op)
|
||||
|
||||
bool unsp_device::do_basic_alu_ops(const uint16_t &op0, uint32_t &lres, uint16_t &r0, uint16_t &r1, uint32_t &r2, bool update_flags)
|
||||
{
|
||||
int32_t sres = 0;
|
||||
switch (op0)
|
||||
{
|
||||
case 0x00: // Add
|
||||
{
|
||||
lres = r0 + r1;
|
||||
sres = (int16_t)r0 + (int16_t)r1;
|
||||
if (update_flags)
|
||||
update_nzsc(lres, r0, r1);
|
||||
update_nzsc(lres, sres);
|
||||
break;
|
||||
}
|
||||
case 0x01: // Add w/ carry
|
||||
{
|
||||
uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0;
|
||||
lres = r0 + r1 + c;
|
||||
sres = (int16_t)r0 + (int16_t)r1 + (int16_t)c;
|
||||
if (update_flags)
|
||||
update_nzsc(lres, r0, r1);
|
||||
update_nzsc(lres, sres);
|
||||
break;
|
||||
}
|
||||
case 0x02: // Subtract
|
||||
lres = r0 + (uint16_t)(~r1) + uint32_t(1);
|
||||
sres = (int16_t)r0 - (int16_t)r1;
|
||||
if (update_flags)
|
||||
update_nzsc(lres, r0, ~r1);
|
||||
update_nzsc(lres, sres);
|
||||
break;
|
||||
case 0x03: // Subtract w/ carry
|
||||
{
|
||||
uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0;
|
||||
lres = r0 + (uint16_t)(~r1) + c;
|
||||
sres = (int16_t)r0 - ((int16_t)r1 - (int16_t)c);
|
||||
if (update_flags)
|
||||
update_nzsc(lres, r0, ~r1);
|
||||
update_nzsc(lres, sres);
|
||||
break;
|
||||
}
|
||||
case 0x04: // Compare
|
||||
lres = r0 + (uint16_t)(~r1) + uint32_t(1);
|
||||
sres = (int16_t)r0 - (int16_t)r1;
|
||||
if (update_flags)
|
||||
update_nzsc(lres, r0, ~r1);
|
||||
update_nzsc(lres, sres);
|
||||
return false;
|
||||
case 0x06: // Negate
|
||||
lres = -r1;
|
||||
|
@ -265,6 +265,14 @@ offs_t unsp_disassembler::disassemble_fxxx_101_group(std::ostream& stream, offs_
|
||||
util::stream_format(stream, "int fiq,irq");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
case 0xf144: case 0xf344: case 0xf544: case 0xf744: case 0xf944: case 0xfb44: case 0xfd44: case 0xff44:
|
||||
util::stream_format(stream, "fir_mov on");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
case 0xf145: case 0xf345: case 0xf545: case 0xf745: case 0xf945: case 0xfb45: case 0xfd45: case 0xff45:
|
||||
util::stream_format(stream, "fir_mov off");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
case 0xf160: case 0xf360: case 0xf560: case 0xf760: case 0xf960: case 0xfb60: case 0xfd60: case 0xff60:
|
||||
case 0xf168: case 0xf368: case 0xf568: case 0xf768: case 0xf968: case 0xfb68: case 0xfd68: case 0xff68:
|
||||
case 0xf170: case 0xf370: case 0xf570: case 0xf770: case 0xf970: case 0xfb70: case 0xfd70: case 0xff70:
|
||||
|
@ -67,7 +67,6 @@ sunplus_gcm394_audio_device::sunplus_gcm394_audio_device(const machine_config &m
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void spg2xx_audio_device::device_start()
|
||||
{
|
||||
m_audio_beat = timer_alloc(TIMER_BEAT);
|
||||
@ -636,11 +635,13 @@ WRITE16_MEMBER(spg2xx_audio_device::audio_ctrl_w)
|
||||
|
||||
case AUDIO_WAVE_IN_L:
|
||||
LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Wave In (L) / FIFO Write Data: %04x\n", data);
|
||||
m_stream->update();
|
||||
m_audio_ctrl_regs[offset] = data;
|
||||
break;
|
||||
|
||||
case AUDIO_WAVE_IN_R:
|
||||
LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Wave In (R) / Software Channel FIFO IRQ Control: %04x\n", data);
|
||||
m_stream->update();
|
||||
m_audio_ctrl_regs[offset] = data;
|
||||
break;
|
||||
|
||||
@ -945,6 +946,11 @@ void spg2xx_audio_device::sound_stream_update(sound_stream &stream, stream_sampl
|
||||
}
|
||||
}
|
||||
|
||||
if (m_audio_ctrl_regs[AUDIO_WAVE_IN_L])
|
||||
left_total += (int32_t)(m_audio_ctrl_regs[AUDIO_WAVE_IN_L] - 0x8000);
|
||||
if (m_audio_ctrl_regs[AUDIO_WAVE_IN_R])
|
||||
right_total += (int32_t)(m_audio_ctrl_regs[AUDIO_WAVE_IN_R] - 0x8000);
|
||||
|
||||
switch (get_vol_sel())
|
||||
{
|
||||
case 0: // 1/16
|
||||
@ -958,8 +964,12 @@ void spg2xx_audio_device::sound_stream_update(sound_stream &stream, stream_sampl
|
||||
right_total >>= 2;
|
||||
break;
|
||||
}
|
||||
*out_l++ = (left_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7;
|
||||
*out_r++ = (right_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7;
|
||||
|
||||
int32_t left_final = (int16_t)((left_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7);
|
||||
int32_t right_final = (int16_t)((right_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7);
|
||||
|
||||
*out_l++ = (int16_t)left_final;
|
||||
*out_r++ = (int16_t)right_final;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user