Attempt to fix Last Bronx booting, still uses a shitload of unsupported opcodes, fun ...

This commit is contained in:
Angelo Salese 2014-04-15 04:44:20 +00:00
parent fa8a5baad6
commit 77da31b99c
7 changed files with 101 additions and 11 deletions

View File

@ -1236,10 +1236,47 @@ void adsp21062_device::compute_fmul_fix_scaled(int fm, int fxm, int fym, int fa,
/* TODO: AV flag */
FREG(fm) = r_mul.f;
REG(fa) = alu_i;
REG(fa) = alu_i; // TODO: check this, should be RA?
m_astat |= AF;
}
void adsp21062_device::compute_fmul_avg(int fm, int fxm, int fym, int fa, int fxa, int fya)
{
INT32 alu_i;
SHARC_REG r_mul, r_alu;
r_mul.f = FREG(fxm) * FREG(fym);
r_alu.f = (FREG(fxa) * FREG(fya))/((float) 2.0);
/* TODO: are flags right for this? */
if (m_mode1 & MODE1_TRUNCATE)
{
alu_i = (INT32)(r_alu.f);
}
else
{
alu_i = (INT32)(r_alu.f < 0 ? (r_alu.f - 0.5f) : (r_alu.f + 0.5f));
}
CLEAR_MULTIPLIER_FLAGS();
SET_FLAG_MN(r_mul.r);
/* TODO: MV flag */
/* TODO: MU flag */
/* TODO: MI flag */
CLEAR_ALU_FLAGS();
SET_FLAG_AN(alu_i);
// AZ
SET_FLAG_AZ(alu_i);
// AU
m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
m_astat |= (IS_FLOAT_NAN(REG(fxa))) ? AI : 0;
/* TODO: AV flag */
FREG(fm) = r_mul.f;
REG(fa) = alu_i;
m_astat |= AF;
}
/* Fm = Fxm * Fym, Fa = MAX(Fxa, Fya) */
void adsp21062_device::compute_fmul_fmax(int fm, int fxm, int fym, int fa, int fxa, int fya)

View File

@ -144,6 +144,24 @@ void adsp21062_device::sharc_iop_w(UINT32 address, UINT32 data)
{
case 0x00: break; // System configuration
case 0x02: break; // External Memory Wait State Configuration
case 0x04: // External port DMA buffer 0
/* TODO: Last Bronx uses this to init program, shift and in */
{
UINT64 r = pm_read48(m_dma[6].int_index);
r &= ~((UINT64)(0xffff) << (m_extdma_shift*16));
r |= ((UINT64)data & 0xffff) << (m_extdma_shift*16);
pm_write48(m_dma[6].int_index, r);
m_extdma_shift++;
if (m_extdma_shift == 3)
{
m_extdma_shift = 0;
m_dma[6].int_index ++;
}
}
break;
case 0x08: break; // Message Register 0
case 0x09: break; // Message Register 1
@ -154,6 +172,9 @@ void adsp21062_device::sharc_iop_w(UINT32 address, UINT32 data)
case 0x0e: break; // Message Register 6
case 0x0f: break; // Message Register 7
case 0x14: // reserved??? written by Last Bronx
case 0x17: break;
// DMA 6
case 0x1c:
{
@ -636,6 +657,7 @@ void adsp21062_device::device_reset()
}
m_pc = 0x20004;
m_extdma_shift = 0;
m_daddr = m_pc + 1;
m_faddr = m_daddr + 1;
m_nfaddr = m_faddr+1;

View File

@ -142,6 +142,7 @@ private:
SHARC_LADDR m_laddr;
UINT32 m_curlcntr;
UINT32 m_lcntr;
UINT8 m_extdma_shift;
/* Data Address Generator (DAG) */
SHARC_DAG m_dag1; // (DM bus)
@ -339,6 +340,7 @@ private:
inline void compute_fmul_fsub(int fm, int fxm, int fym, int fa, int fxa, int fya);
inline void compute_fmul_float_scaled(int fm, int fxm, int fym, int fa, int fxa, int fya);
inline void compute_fmul_fix_scaled(int fm, int fxm, int fym, int fa, int fxa, int fya);
inline void compute_fmul_avg(int fm, int fxm, int fym, int fa, int fxa, int fya);
inline void compute_fmul_fmax(int fm, int fxm, int fym, int fa, int fxa, int fya);
inline void compute_fmul_fmin(int fm, int fxm, int fym, int fa, int fxa, int fya);
inline void compute_fmul_dual_fadd_fsub(int fm, int fxm, int fym, int fa, int fs, int fxa, int fya);

View File

@ -18,7 +18,7 @@ UINT32 adsp21062_device::pm_read32(UINT32 address)
(m_internal_ram_block1[addr + 1]);
}
else {
fatalerror("SHARC: PM Bus Read %08X at %08X\n", address, m_pc);
fatalerror("SHARC: PM Bus Read32 %08X at %08X\n", address, m_pc);
}
}
@ -42,13 +42,13 @@ void adsp21062_device::pm_write32(UINT32 address, UINT32 data)
return;
}
else {
fatalerror("SHARC: PM Bus Write %08X, %08X at %08X\n", address, data, m_pc);
fatalerror("SHARC: PM Bus Write32 %08X, %08X at %08X\n", address, data, m_pc);
}
}
UINT64 adsp21062_device::pm_read48(UINT32 address)
{
if (address >= 0x20000 && address < 0x28000)
if ((address >= 0 && address < 0x8000) || (address >= 0x20000 && address < 0x28000))
{
UINT32 addr = (address & 0x7fff) * 3;
@ -66,7 +66,7 @@ UINT64 adsp21062_device::pm_read48(UINT32 address)
((UINT64)(m_internal_ram_block1[addr + 2]) << 0);
}
else {
fatalerror("SHARC: PM Bus Read %08X at %08X\n", address, m_pc);
//fatalerror("SHARC: PM Bus Read48 %08X at %08X\n", address, m_pc);
}
return 0;
@ -74,7 +74,7 @@ UINT64 adsp21062_device::pm_read48(UINT32 address)
void adsp21062_device::pm_write48(UINT32 address, UINT64 data)
{
if (address >= 0x20000 && address < 0x28000)
if ((address >= 0 && address < 0x8000) || (address >= 0x20000 && address < 0x28000))
{
UINT32 addr = (address & 0x7fff) * 3;
@ -94,7 +94,7 @@ void adsp21062_device::pm_write48(UINT32 address, UINT64 data)
return;
}
else {
fatalerror("SHARC: PM Bus Write %08X, %04X%08X at %08X\n", address, (UINT16)(data >> 32),(UINT32)data, m_pc);
//fatalerror("SHARC: PM Bus Write48 %08X, %04X%08X at %08X\n", address, (UINT16)(data >> 32),(UINT32)data, m_pc);
}
}

View File

@ -586,6 +586,9 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
break;
}
case 0x11: /* TODO */
break;
case 0x12: /* FEXT Rx BY <bit6>:<len6> (Sign Extended) */
{
UINT32 ext = (REG(rx) & MAKE_EXTRACT_MASK(bit, len)) >> bit;
@ -761,6 +764,12 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
break;
}
case 0x1c: /* TODO! fmul_avg */
{
compute_fmul_avg(fm, fxm, fym, fa, fxa, fya);
break;
}
case 0x1e: /* Fm = Fxm * Fym, Fa = MAX(Fxa, Fya) */
{
compute_fmul_fmax(fm, fxm, fym, fa, fxa, fya);

View File

@ -13,6 +13,8 @@
- desert: several 3d bugs, presumably down to FIFO;
- dynamcop: stalls at stage select screen;
- fvipers: enables timers, but then irq register is empty, hence it crashes with an "interrupt halt" at POST (regression);
- lastbrnx: uses external DMA port 0 for uploading SHARC program, hook-up might not be 100% right;
- lastbrnx: uses a shitload of unsupported SHARC opcodes (compute_fmul_avg, shift operation 0x11, ALU operation 0x89);
- manxtt: missing 3d;
- motoraid: stalls after course select;
- pltkidsa: after few secs of gameplay, background 3d disappears and everything reports a collision against the player;
@ -732,6 +734,9 @@ WRITE32_MEMBER(model2_state::copro_fifo_w)
}
else
{
// if(m_coprocnt == 0)
// return;
//mame_printf_debug("copro_fifo_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, space.device().safe_pc());
if (m_dsp_type == DSP_TYPE_SHARC)
copro_fifoin_push(machine().device("dsp"), data);
@ -742,7 +747,7 @@ WRITE32_MEMBER(model2_state::copro_fifo_w)
WRITE32_MEMBER(model2_state::copro_sharc_iop_w)
{
/* FIXME: clean this up */
/* FIXME: clean this mess */
if ((strcmp(machine().system().name, "schamp" ) == 0) ||
(strcmp(machine().system().name, "sfight" ) == 0) ||
(strcmp(machine().system().name, "fvipers" ) == 0) ||
@ -751,7 +756,10 @@ WRITE32_MEMBER(model2_state::copro_sharc_iop_w)
(strcmp(machine().system().name, "gunblade" ) == 0) ||
(strcmp(machine().system().name, "von" ) == 0) ||
(strcmp(machine().system().name, "vonj" ) == 0) ||
(strcmp(machine().system().name, "rchase2" ) == 0))
(strcmp(machine().system().name, "rchase2" ) == 0) ||
(strcmp(machine().system().name, "lastbrnx" ) == 0) ||
(strcmp(machine().system().name, "lastbrnxu" ) == 0) ||
(strcmp(machine().system().name, "lastbrnxj" ) == 0))
{
machine().device<adsp21062_device>("dsp")->external_iop_write(offset, data);
}
@ -1448,7 +1456,6 @@ static ADDRESS_MAP_START( model2_base_mem, AS_PROGRAM, 32, model2_state )
AM_RANGE(0x00900000, 0x0097ffff) AM_RAM AM_SHARE("bufferram")
AM_RANGE(0x00980004, 0x00980007) AM_READ(fifoctl_r)
AM_RANGE(0x0098000c, 0x0098000f) AM_READWRITE(videoctl_r,videoctl_w)
AM_RANGE(0x00980030, 0x0098003f) AM_READ8(tgpid_r,0xffffffff)
@ -1542,6 +1549,15 @@ static ADDRESS_MAP_START( model2o_mem, AS_PROGRAM, 32, model2_state )
AM_IMPORT_FROM(model2_base_mem)
ADDRESS_MAP_END
/* TODO: read by Sonic the Fighters (bit 1), unknown purpose */
READ32_MEMBER(model2_state::copro_status_r)
{
if(m_coprocnt == 0)
return -1;
return 0;
}
/* 2A-CRX overrides */
static ADDRESS_MAP_START( model2a_crx_mem, AS_PROGRAM, 32, model2_state )
AM_RANGE(0x00200000, 0x0023ffff) AM_RAM
@ -1552,6 +1568,7 @@ static ADDRESS_MAP_START( model2a_crx_mem, AS_PROGRAM, 32, model2_state )
AM_RANGE(0x00980000, 0x00980003) AM_READWRITE(copro_ctl1_r,copro_ctl1_w)
AM_RANGE(0x00980008, 0x0098000b) AM_WRITE(geo_ctl1_w)
AM_RANGE(0x00980014, 0x00980017) AM_READ(copro_status_r)
AM_RANGE(0x009c0000, 0x009cffff) AM_READWRITE(model2_serial_r, model2_serial_w )
AM_RANGE(0x12000000, 0x121fffff) AM_RAM_WRITE(model2o_tex_w0) AM_MIRROR(0x200000) AM_SHARE("textureram0") // texture RAM 0
@ -1583,8 +1600,8 @@ static ADDRESS_MAP_START( model2b_crx_mem, AS_PROGRAM, 32, model2_state )
AM_RANGE(0x008c0000, 0x008c0fff) AM_WRITE(copro_sharc_iop_w)
AM_RANGE(0x00980000, 0x00980003) AM_READWRITE(copro_ctl1_r,copro_ctl1_w)
AM_RANGE(0x00980008, 0x0098000b) AM_WRITE(geo_ctl1_w)
AM_RANGE(0x00980014, 0x00980017) AM_READ(copro_status_r)
//AM_RANGE(0x00980008, 0x0098000b) AM_WRITE(geo_sharc_ctl1_w )
AM_RANGE(0x009c0000, 0x009cffff) AM_READWRITE(model2_serial_r, model2_serial_w )
@ -1616,6 +1633,7 @@ static ADDRESS_MAP_START( model2c_crx_mem, AS_PROGRAM, 32, model2_state )
AM_RANGE(0x00980000, 0x00980003) AM_READWRITE(copro_ctl1_r,copro_ctl1_w)
AM_RANGE(0x00980008, 0x0098000b) AM_WRITE(geo_ctl1_w )
AM_RANGE(0x00980014, 0x00980017) AM_READ(copro_status_r)
AM_RANGE(0x009c0000, 0x009cffff) AM_READWRITE(model2_serial_r, model2_serial_w )
AM_RANGE(0x11000000, 0x111fffff) AM_RAM AM_SHARE("textureram0") // texture RAM 0 (2b/2c)

View File

@ -168,6 +168,8 @@ public:
DECLARE_READ32_MEMBER(copro_tgp_buffer_r);
DECLARE_WRITE32_MEMBER(copro_tgp_buffer_w);
DECLARE_READ8_MEMBER(tgpid_r);
DECLARE_READ32_MEMBER(copro_status_r);
DECLARE_READ8_MEMBER(driveio_port_r);
DECLARE_WRITE8_MEMBER(driveio_port_w);
DECLARE_READ8_MEMBER(driveio_port_str_r);