From 77da31b99cd341ee1ce659daae59f92d93815fae Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Tue, 15 Apr 2014 04:44:20 +0000 Subject: [PATCH] Attempt to fix Last Bronx booting, still uses a shitload of unsupported opcodes, fun ... --- src/emu/cpu/sharc/compute.inc | 39 +++++++++++++++++++++++++++++++++- src/emu/cpu/sharc/sharc.c | 22 +++++++++++++++++++ src/emu/cpu/sharc/sharc.h | 2 ++ src/emu/cpu/sharc/sharcmem.inc | 12 +++++------ src/emu/cpu/sharc/sharcops.inc | 9 ++++++++ src/mame/drivers/model2.c | 26 +++++++++++++++++++---- src/mame/includes/model2.h | 2 ++ 7 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/emu/cpu/sharc/compute.inc b/src/emu/cpu/sharc/compute.inc index 0d60de824e8..e366e7588f8 100644 --- a/src/emu/cpu/sharc/compute.inc +++ b/src/emu/cpu/sharc/compute.inc @@ -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) diff --git a/src/emu/cpu/sharc/sharc.c b/src/emu/cpu/sharc/sharc.c index 65a06fb6b37..8735841b65c 100644 --- a/src/emu/cpu/sharc/sharc.c +++ b/src/emu/cpu/sharc/sharc.c @@ -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; diff --git a/src/emu/cpu/sharc/sharc.h b/src/emu/cpu/sharc/sharc.h index b699fdc519d..99f36a06ae1 100644 --- a/src/emu/cpu/sharc/sharc.h +++ b/src/emu/cpu/sharc/sharc.h @@ -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); diff --git a/src/emu/cpu/sharc/sharcmem.inc b/src/emu/cpu/sharc/sharcmem.inc index ed65d66d891..f578b49cecd 100644 --- a/src/emu/cpu/sharc/sharcmem.inc +++ b/src/emu/cpu/sharc/sharcmem.inc @@ -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); } } diff --git a/src/emu/cpu/sharc/sharcops.inc b/src/emu/cpu/sharc/sharcops.inc index 46af2932c02..b11b93f1e22 100644 --- a/src/emu/cpu/sharc/sharcops.inc +++ b/src/emu/cpu/sharc/sharcops.inc @@ -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 : (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); diff --git a/src/mame/drivers/model2.c b/src/mame/drivers/model2.c index 3a1658e5fad..4d6bbe1c9fb 100644 --- a/src/mame/drivers/model2.c +++ b/src/mame/drivers/model2.c @@ -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("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) diff --git a/src/mame/includes/model2.h b/src/mame/includes/model2.h index eada1e84cc6..474b4164072 100644 --- a/src/mame/includes/model2.h +++ b/src/mame/includes/model2.h @@ -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);