mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
Fix MT07823: nbagold (vegas) watchdog reset when select other game menu from service menu (#9560)
mips3: Add new DRC option to add extra validation to hash jumps vegas: Use new MIPS DRC option atlantis: Use new MIPS DRC option
This commit is contained in:
parent
f95883ac29
commit
30ec2aaaa7
@ -133,6 +133,8 @@ public:
|
||||
|
||||
// describe a block
|
||||
opcode_desc const *describe_code(offs_t startpc);
|
||||
// get last opcode of block
|
||||
opcode_desc const* get_last() { return m_desc_live_list.last(); };
|
||||
|
||||
protected:
|
||||
// required overrides
|
||||
|
@ -309,6 +309,7 @@ public:
|
||||
void add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base);
|
||||
void clear_fastram(uint32_t select_start);
|
||||
void mips3drc_set_options(uint32_t options);
|
||||
uint32_t mips3drc_get_options();
|
||||
void mips3drc_add_hotspot(offs_t pc, uint32_t opcode, uint32_t cycles);
|
||||
|
||||
protected:
|
||||
@ -623,7 +624,7 @@ private:
|
||||
|
||||
void generate_update_mode(drcuml_block &block);
|
||||
void generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param, bool allow_exception);
|
||||
void generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
|
||||
void generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast, const opcode_desc* codelast);
|
||||
void generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc);
|
||||
void generate_delay_slot_and_branch(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t linkreg);
|
||||
|
||||
@ -968,8 +969,6 @@ private:
|
||||
/***************************************************************************
|
||||
COMPILER-SPECIFIC OPTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/* fix me -- how do we make this work?? */
|
||||
#define MIPS3DRC_STRICT_VERIFY 0x0001 /* verify all instructions */
|
||||
#define MIPS3DRC_STRICT_COP0 0x0002 /* validate all COP0 instructions */
|
||||
#define MIPS3DRC_STRICT_COP1 0x0004 /* validate all COP1 instructions */
|
||||
@ -977,9 +976,13 @@ COMPILER-SPECIFIC OPTIONS
|
||||
#define MIPS3DRC_DISABLE_INTRABLOCK 0x0010 /* disable intrablock branching */
|
||||
#define MIPS3DRC_CHECK_OVERFLOWS 0x0020 /* actually check overflows on add/sub instructions */
|
||||
#define MIPS3DRC_ACCURATE_DIVZERO 0x0040 /* load correct values into HI/LO on integer divide-by-zero */
|
||||
#define MIPS3DRC_EXTRA_INSTR_CHECK 0x0080 /* adds the last instruction value to all validation entry locations, used with STRICT_VERIFY */
|
||||
|
||||
#define MIPS3DRC_COMPATIBLE_OPTIONS (MIPS3DRC_STRICT_VERIFY | MIPS3DRC_STRICT_COP1 | MIPS3DRC_STRICT_COP0 | MIPS3DRC_STRICT_COP2)
|
||||
#define MIPS3DRC_FASTEST_OPTIONS (0)
|
||||
|
||||
/* Use with STRICT_VERIFY to print debug info to console for extra validation checks */
|
||||
/* Set to 1 to activate and use MIPS3DRC_STRICT_VERIFY in the drc options */
|
||||
#define DEBUG_STRICT_VERIFY 0
|
||||
|
||||
#endif // MAME_CPU_MIPS_MIPS3_H
|
||||
|
@ -155,6 +155,15 @@ void mips3_device::mips3drc_set_options(uint32_t options)
|
||||
m_drcoptions = options;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mips3drc_get_options - return current DRC options
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint32_t mips3_device::mips3drc_get_options()
|
||||
{
|
||||
return m_drcoptions;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mips3drc_clears_fastram - clears fastram
|
||||
region starting at index select_start
|
||||
@ -282,6 +291,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
{
|
||||
compiler_state compiler = { 0 };
|
||||
const opcode_desc *seqhead, *seqlast;
|
||||
const opcode_desc* codelast;
|
||||
const opcode_desc *desclist;
|
||||
bool override = false;
|
||||
|
||||
@ -289,6 +299,8 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
|
||||
/* get a description of this sequence */
|
||||
desclist = m_drcfe->describe_code(pc);
|
||||
/* get last instruction of the code (potentially used in generate_checksum) */
|
||||
codelast = m_drcfe->get_last();
|
||||
if (m_drcuml->logging() || m_drcuml->logging_native())
|
||||
log_opcode_desc(desclist, 0);
|
||||
|
||||
@ -340,7 +352,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
|
||||
/* validate this code block if we're not pointing into ROM */
|
||||
if (m_program->get_write_ptr(seqhead->physpc) != nullptr)
|
||||
generate_checksum_block(block, compiler, seqhead, seqlast);
|
||||
generate_checksum_block(block, compiler, seqhead, seqlast, codelast);
|
||||
|
||||
/* label this instruction, if it may be jumped to locally */
|
||||
if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
|
||||
@ -1097,7 +1109,7 @@ void mips3_device::generate_update_cycles(drcuml_block &block, compiler_state &c
|
||||
validate a sequence of opcodes
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast)
|
||||
void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast, const opcode_desc* codelast)
|
||||
{
|
||||
const opcode_desc *curdesc;
|
||||
if (m_drcuml->logging())
|
||||
@ -1149,16 +1161,29 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
|
||||
uint32_t low_bits = (seqhead->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
|
||||
sum += seqhead->opptr.l[0];
|
||||
if ((m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK) && !(codelast->flags & OPFLAG_VIRTUAL_NOOP) && codelast->physpc != seqhead->physpc)
|
||||
{
|
||||
base = m_prptr(codelast->physpc);
|
||||
assert(base != nullptr);
|
||||
low_bits = (codelast->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
sum += codelast->opptr.l[0];
|
||||
}
|
||||
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
|
||||
{
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
base = m_prptr(curdesc->physpc);
|
||||
assert(base != nullptr);
|
||||
uint32_t low_bits = (curdesc->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
sum += curdesc->opptr.l[0];
|
||||
// Skip the last if it was already included above
|
||||
if (!(m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK) || curdesc->physpc != codelast->physpc)
|
||||
{
|
||||
base = m_prptr(curdesc->physpc);
|
||||
assert(base != nullptr);
|
||||
low_bits = (curdesc->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
sum += curdesc->opptr.l[0];
|
||||
}
|
||||
|
||||
if (curdesc->delay.first() != nullptr
|
||||
&& !(curdesc->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
|
||||
@ -1166,7 +1191,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
|
||||
{
|
||||
base = m_prptr(curdesc->delay.first()->physpc);
|
||||
assert(base != nullptr);
|
||||
uint32_t low_bits = (curdesc->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
low_bits = (curdesc->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
sum += curdesc->delay.first()->opptr.l[0];
|
||||
@ -1175,6 +1200,57 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
|
||||
}
|
||||
UML_CMP(block, I0, sum); // cmp i0,sum
|
||||
UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
|
||||
if (DEBUG_STRICT_VERIFY)
|
||||
{
|
||||
// This code will do additional checks on the last instruction and last delay slot and indicate if the check failed
|
||||
uml::code_label check_passed, check_failed, check_second;
|
||||
check_second = compiler.labelnum++;
|
||||
check_failed = compiler.labelnum++;
|
||||
check_passed = compiler.labelnum++;
|
||||
// Check the last instruction
|
||||
if (!(codelast->flags & OPFLAG_VIRTUAL_NOOP) && codelast->physpc != seqhead->physpc)
|
||||
{
|
||||
base = m_prptr(codelast->physpc);
|
||||
assert(base != nullptr);
|
||||
low_bits = (codelast->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
sum = codelast->opptr.l[0];
|
||||
UML_CMP(block, I0, sum); // cmp i0,sum
|
||||
UML_JMPc(block, COND_E, check_second);
|
||||
static const char text[] = "Last instr validation fail seq: %08X end: %08x\n";
|
||||
UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text
|
||||
UML_MOV(block, mem(&m_core->arg0), seqhead->pc);
|
||||
UML_MOV(block, mem(&m_core->arg1), codelast->physpc); // mov [arg0],desc->pc
|
||||
UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug
|
||||
//UML_CALLC(block, cfunc_debug_break, this);
|
||||
// Skip delay slot check
|
||||
UML_JMP(block, check_failed);
|
||||
// Check the last instruction delay slot
|
||||
UML_LABEL(block, check_second);
|
||||
if (codelast->delay.first() != nullptr && !(codelast->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
|
||||
&& codelast->physpc != seqhead->physpc)
|
||||
{
|
||||
base = m_prptr(codelast->delay.first()->physpc);
|
||||
assert(base != nullptr);
|
||||
low_bits = (codelast->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
sum = codelast->delay.first()->opptr.l[0];
|
||||
UML_CMP(block, I0, sum); // cmp i0,sum
|
||||
UML_JMPc(block, COND_E, check_passed);
|
||||
static const char text[] = "Last delay slot validation fail seq: %08X end: %08x\n";
|
||||
UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text
|
||||
UML_MOV(block, mem(&m_core->arg0), seqhead->pc);
|
||||
UML_MOV(block, mem(&m_core->arg1), codelast->physpc); // mov [arg0],desc->pc
|
||||
UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug
|
||||
//UML_CALLC(block, cfunc_debug_break, this);
|
||||
UML_JMP(block, check_failed);
|
||||
}
|
||||
}
|
||||
UML_JMP(block, check_passed);
|
||||
UML_LABEL(block, check_failed);
|
||||
UML_EXH(block, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
|
||||
UML_LABEL(block, check_passed);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1189,7 +1265,6 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
|
||||
{
|
||||
offs_t expc;
|
||||
int hotnum;
|
||||
|
||||
/* add an entry for the log */
|
||||
if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
|
||||
@ -1334,7 +1409,7 @@ void mips3_device::generate_delay_slot_and_branch(drcuml_block &block, compiler_
|
||||
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
|
||||
{
|
||||
generate_update_cycles(block, compiler_temp, desc->targetpc, true); // <subtract cycles>
|
||||
if (!(m_drcoptions & MIPS3DRC_DISABLE_INTRABLOCK) && desc->flags & OPFLAG_INTRABLOCK_BRANCH)
|
||||
if (!(m_drcoptions & MIPS3DRC_DISABLE_INTRABLOCK) && (desc->flags & OPFLAG_INTRABLOCK_BRANCH))
|
||||
{
|
||||
UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ void atlantis_state::a2d_data_w(uint16_t data)
|
||||
void atlantis_state::machine_start()
|
||||
{
|
||||
/* set the fastest DRC options */
|
||||
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS);
|
||||
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS | MIPS3DRC_STRICT_VERIFY | MIPS3DRC_EXTRA_INSTR_CHECK);
|
||||
|
||||
// Allocate adc timer
|
||||
m_adc_ready_timer = timer_alloc(0);
|
||||
|
@ -485,7 +485,10 @@ private:
|
||||
void vegas_state::machine_start()
|
||||
{
|
||||
/* set the fastest DRC options, but strict verification */
|
||||
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS + MIPS3DRC_STRICT_VERIFY);
|
||||
/* need to check the current options since some drivers add options in their init */
|
||||
uint32_t new_options = m_maincpu->mips3drc_get_options();
|
||||
new_options |= MIPS3DRC_FASTEST_OPTIONS | MIPS3DRC_STRICT_VERIFY;
|
||||
m_maincpu->mips3drc_set_options(new_options);
|
||||
|
||||
m_system_led.resolve();
|
||||
m_wheel_driver.resolve();
|
||||
@ -2034,14 +2037,14 @@ void vegas_state::denver(machine_config &config)
|
||||
m_uart2->out_rts_callback().set("ttys02", FUNC(rs232_port_device::write_rts));
|
||||
m_uart2->out_int_callback().set("duart_irq", FUNC(input_merger_device::in_w<1>));
|
||||
|
||||
rs232_port_device &ttys01(RS232_PORT(config, "ttys01", 0));
|
||||
rs232_port_device &ttys01(RS232_PORT(config, "ttys01", default_rs232_devices, nullptr));
|
||||
ttys01.rxd_handler().set(m_uart1, FUNC(ins8250_uart_device::rx_w));
|
||||
ttys01.dcd_handler().set(m_uart1, FUNC(ins8250_uart_device::dcd_w));
|
||||
ttys01.dsr_handler().set(m_uart1, FUNC(ins8250_uart_device::dsr_w));
|
||||
ttys01.ri_handler().set(m_uart1, FUNC(ins8250_uart_device::ri_w));
|
||||
ttys01.cts_handler().set(m_uart1, FUNC(ins8250_uart_device::cts_w));
|
||||
|
||||
rs232_port_device &ttys02(RS232_PORT(config, "ttys02", 0));
|
||||
rs232_port_device &ttys02(RS232_PORT(config, "ttys02", default_rs232_devices, nullptr));
|
||||
ttys02.rxd_handler().set(m_uart2, FUNC(ins8250_uart_device::rx_w));
|
||||
ttys02.dcd_handler().set(m_uart2, FUNC(ins8250_uart_device::dcd_w));
|
||||
ttys02.dsr_handler().set(m_uart2, FUNC(ins8250_uart_device::dsr_w));
|
||||
@ -2621,11 +2624,13 @@ void vegas_state::init_roadburn()
|
||||
|
||||
void vegas_state::init_nbashowt()
|
||||
{
|
||||
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS | MIPS3DRC_STRICT_VERIFY | MIPS3DRC_EXTRA_INSTR_CHECK);
|
||||
}
|
||||
|
||||
|
||||
void vegas_state::init_nbanfl()
|
||||
{
|
||||
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS | MIPS3DRC_STRICT_VERIFY | MIPS3DRC_EXTRA_INSTR_CHECK);
|
||||
// The first three bytes of the blitz00_nov30_1999.u27 ROM are FF's which breaks the reset vector.
|
||||
// These bytes are from blitz00_sep22_1999.u27 which allows the other ROM to start.
|
||||
// The last byte which is part of the checksum is also FF. By changing it to 0x01 the 4 byte checksum matches with the other 3 changes.
|
||||
@ -2639,6 +2644,7 @@ void vegas_state::init_nbanfl()
|
||||
|
||||
void vegas_state::init_nbagold()
|
||||
{
|
||||
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS | MIPS3DRC_STRICT_VERIFY | MIPS3DRC_EXTRA_INSTR_CHECK);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user