diff options
author | 2019-01-14 10:06:52 +0100 | |
---|---|---|
committer | 2019-01-14 10:07:45 +0100 | |
commit | 8f330896e2f8b1fc8ec54023fb5d134dc8a5c3d3 (patch) | |
tree | 8bf910fead7a70f8f7db718eba120e2992a369b1 /src | |
parent | b5e2e786719a7ce7520e728fd79bd39dcd72ac01 (diff) |
-devices/cpu/unsp: Various fixes: [Ryan Holtz]
* Fixed push and pop instructions in the DRC. Fixes Wall-E.
* Eliminated the use of intermediate register I7 in the DRC.
* Reworked DRC timing to be fully in line with the interpreter.
* Reworked DRC block checksumming to not route through the memory system.
* Fixed DRC block checksumming to include all words in an opcode. Fixes V.Smile intro graphical glitches.
* Increased cache size and reduced block size to reduce frequency of cache flushes and associated recompiles.
* Added more verbose optional register and write logging.
* Added a direct setter for IRQ lines to avoid a scheduler sync, pending merging the spg2xx_device into a unsp_device subclass.
* Added direct setters/getters for the data segment as well.
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/cpu/unsp/unsp.cpp | 61 | ||||
-rw-r--r-- | src/devices/cpu/unsp/unsp.h | 24 | ||||
-rw-r--r-- | src/devices/cpu/unsp/unspdrc.cpp | 131 | ||||
-rw-r--r-- | src/devices/machine/spg2xx.cpp | 25 |
4 files changed, 128 insertions, 113 deletions
diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp index 2a22e68b159..9ac01d757df 100644 --- a/src/devices/cpu/unsp/unsp.cpp +++ b/src/devices/cpu/unsp/unsp.cpp @@ -24,7 +24,7 @@ DEFINE_DEVICE_TYPE(UNSP, unsp_device, "unsp", "SunPlus u'nSP") /* size of the execution code cache */ -#define CACHE_SIZE (32 * 1024 * 1024) +#define CACHE_SIZE (64 * 1024 * 1024) unsp_device::unsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, UNSP, tag, owner, clock) @@ -32,13 +32,13 @@ unsp_device::unsp_device(const machine_config &mconfig, const char *tag, device_ , m_program(nullptr) , m_core(nullptr) , m_debugger_temp(0) -#if UNSP_LOG_OPCODES +#if UNSP_LOG_OPCODES || UNSP_LOG_REGS , m_log_ops(0) #endif , m_cache(CACHE_SIZE + sizeof(unsp_device)) , m_drcuml(nullptr) , m_drcfe(nullptr) - , m_drcoptions(UNSP_STRICT_VERIFY) + , m_drcoptions(0) , m_cache_dirty(0) , m_entry(nullptr) , m_nocode(nullptr) @@ -78,6 +78,9 @@ uint16_t unsp_device::read16(uint32_t address) void unsp_device::write16(uint32_t address, uint16_t data) { +#if UNSP_LOG_REGS + log_write(address, data); +#endif m_program->write_word(address, data); } @@ -148,7 +151,7 @@ void unsp_device::device_start() 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"); -#if UNSP_LOG_OPCODES +#if UNSP_LOG_OPCODES || UNSP_LOG_REGS state_add(UNSP_LOG_OPS,"LOG", m_log_ops).formatstr("%1u"); #endif @@ -197,10 +200,20 @@ void unsp_device::device_stop() #if UNSP_LOG_REGS void unsp_device::log_regs() { + if (m_log_ops == 0) + return; fwrite(m_core->m_r, sizeof(uint32_t), 8, m_log_file); fwrite(&m_core->m_sb, sizeof(uint32_t), 1, m_log_file); - fflush(m_log_file); + fwrite(&m_core->m_icount, sizeof(uint32_t), 1, m_log_file); +} + +void unsp_device::log_write(uint32_t addr, uint32_t data) +{ + addr |= 0x80000000; + fwrite(&addr, sizeof(uint32_t), 1, m_log_file); + fwrite(&data, sizeof(uint32_t), 1, m_log_file); } + #endif void unsp_device::state_string_export(const device_state_entry &entry, std::string &str) const @@ -948,11 +961,15 @@ void unsp_device::execute_run() unsp_disassembler dasm; #endif - while (m_core->m_icount > 0) + while (m_core->m_icount >= 0) { debugger_instruction_hook(UNSP_LPC); const uint32_t op = read16(UNSP_LPC); +#if UNSP_LOG_REGS + log_regs(); +#endif + #if UNSP_LOG_OPCODES if (m_log_ops) { @@ -962,10 +979,6 @@ void unsp_device::execute_run() } #endif -#if UNSP_LOG_REGS - log_regs(); -#endif - add_lpc(1); execute_one(op); @@ -977,16 +990,26 @@ void unsp_device::execute_run() /*****************************************************************************/ -void unsp_device::execute_set_input(int irqline, int state) +void unsp_device::execute_set_input(int inputnum, int state) +{ + set_state_unsynced(inputnum, state); +} + +uint8_t unsp_device::get_csb() { - m_core->m_sirq &= ~(1 << irqline); + return 1 << ((UNSP_LPC >> 20) & 3); +} + +void unsp_device::set_state_unsynced(int inputnum, int state) +{ + m_core->m_sirq &= ~(1 << inputnum); if(!state) { return; } - switch (irqline) + switch (inputnum) { case UNSP_IRQ0_LINE: case UNSP_IRQ1_LINE: @@ -997,14 +1020,20 @@ void unsp_device::execute_set_input(int irqline, int state) case UNSP_IRQ6_LINE: case UNSP_IRQ7_LINE: case UNSP_FIQ_LINE: - m_core->m_sirq |= (1 << irqline); + m_core->m_sirq |= (1 << inputnum); break; case UNSP_BRK_LINE: break; } } -uint8_t unsp_device::get_csb() +uint16_t unsp_device::get_ds() { - return 1 << ((UNSP_LPC >> 20) & 3); + return (m_core->m_r[REG_SR] >> 10) & 0x3f; +} + +void unsp_device::set_ds(uint16_t ds) +{ + m_core->m_r[REG_SR] &= 0x03ff; + m_core->m_r[REG_SR] |= (ds & 0x3f) << 10; } diff --git a/src/devices/cpu/unsp/unsp.h b/src/devices/cpu/unsp/unsp.h index 7b283eb0bf5..0186cee8869 100644 --- a/src/devices/cpu/unsp/unsp.h +++ b/src/devices/cpu/unsp/unsp.h @@ -29,8 +29,6 @@ #define MAPVAR_PC M0 #define MAPVAR_CYCLES M1 -#define UNSP_STRICT_VERIFY 0x0001 /* verify all instructions */ - #define SINGLE_INSTRUCTION_MODE (0) #define ENABLE_UNSP_DRC (1) @@ -63,7 +61,7 @@ enum UNSP_FIQ_EN, UNSP_IRQ, UNSP_FIQ, -#if UNSP_LOG_OPCODES +#if UNSP_LOG_OPCODES || UNSP_LOG_REGS UNSP_SB, UNSP_LOG_OPS #else @@ -95,12 +93,25 @@ public: // construction/destruction unsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // HACK: IRQ line state can only be modified directly by hardware on-board the SPG SoC itself. + // Therefore, to avoid an unnecessary scheduler sync when the external spg2xx_device sets or + // clears an interrupt line, we provide this direct accessor. + // A more correct but longer-term solution will be to move spg2xx_device to be internal to + // a subclass of unsp_device rather than its own standalone device. + void set_state_unsynced(int inputnum, int state); + uint8_t get_csb(); + void set_ds(uint16_t ds); + uint16_t get_ds(); + inline void ccfunc_unimplemented(); void invalidate_cache(); + #if UNSP_LOG_REGS void log_regs(); + void log_write(uint32_t addr, uint32_t data); + void cfunc_log_write(); #endif protected: @@ -176,7 +187,6 @@ private: uint32_t m_arg0; uint32_t m_arg1; - uint32_t m_arg2; uint32_t m_jmpdest; int m_icount; @@ -191,7 +201,7 @@ private: internal_unsp_state *m_core; uint32_t m_debugger_temp; -#if UNSP_LOG_OPCODES +#if UNSP_LOG_OPCODES || UNSP_LOG_REGS uint32_t m_log_ops; #endif @@ -251,11 +261,9 @@ private: void static_generate_memory_accessor(bool iswrite, const char *name, uml::code_handle *&handleptr); void generate_branch(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param); + void generate_check_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param); void generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); void generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void generate_push(drcuml_block &block, uint32_t sp); - void generate_pop(drcuml_block &block, uint32_t sp); void generate_add_lpc(drcuml_block &block, int32_t offset); void generate_update_nzsc(drcuml_block &block); void generate_update_nz(drcuml_block &block); diff --git a/src/devices/cpu/unsp/unspdrc.cpp b/src/devices/cpu/unsp/unspdrc.cpp index 0755c1f54cc..eb010bd3a37 100644 --- a/src/devices/cpu/unsp/unspdrc.cpp +++ b/src/devices/cpu/unsp/unspdrc.cpp @@ -66,10 +66,20 @@ static void cfunc_unimplemented(void *param) } #if UNSP_LOG_REGS +void unsp_device::cfunc_log_write() +{ + log_write(m_core->m_arg0, m_core->m_arg1); +} + static void cfunc_log_regs(void *param) { ((unsp_device *)param)->log_regs(); } + +static void ccfunc_log_write(void *param) +{ + ((unsp_device *)param)->cfunc_log_write(); +} #endif /*************************************************************************** @@ -140,7 +150,7 @@ void unsp_device::code_compile_block(offs_t pc) try { /* start the block */ - drcuml_block &block(m_drcuml->begin_block(32768)); + drcuml_block &block(m_drcuml->begin_block(1024*8)); /* loop until we get through all instruction sequences */ for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next()) @@ -186,22 +196,15 @@ void unsp_device::code_compile_block(offs_t pc) if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) UML_LABEL(block, seqhead->pc | 0x80000000); - UML_MOV(block, I7, 0); - UML_CALLH(block, *m_check_interrupts); - /* iterate over instructions in the sequence and compile them */ for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) { + generate_check_cycles(block, compiler, curdesc->pc + curdesc->length); generate_sequence_instruction(block, compiler, curdesc); UML_CALLH(block, *m_check_interrupts); } - if (seqlast->flags & OPFLAG_RETURN_TO_START) /* if we need to return to the start, do it */ - nextpc = pc; - else /* otherwise we just go to the next instruction */ - nextpc = seqlast->pc + seqlast->length; - - generate_update_cycles(block, compiler, nextpc); + nextpc = seqlast->pc + seqlast->length; /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc) @@ -324,7 +327,14 @@ void unsp_device::static_generate_memory_accessor(bool iswrite, const char *name UML_HANDLE(block, *handleptr); if (iswrite) + { +#if UNSP_LOG_REGS + UML_MOV(block, mem(&m_core->m_arg0), I0); + UML_MOV(block, mem(&m_core->m_arg1), I1); + UML_CALLC(block, ccfunc_log_write, this); +#endif UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); + } else UML_READ(block, I1, I0, SIZE_WORD, SPACE_PROGRAM); UML_RET(block); @@ -470,17 +480,14 @@ void unsp_device::static_generate_trigger_irq() } /*------------------------------------------------- - generate_update_cycles - generate code to - subtract cycles from the icount and generate - an exception if out + generate_check_cycles - generate code to + generate an exception if cycles are out -------------------------------------------------*/ -void unsp_device::generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param) +void unsp_device::generate_check_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param) { - UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), I7); - UML_EXHc(block, uml::COND_Z, *m_out_of_cycles, param); - UML_EXHc(block, uml::COND_S, *m_out_of_cycles, param); - UML_MOV(block, I7, 0); + UML_CMP(block, mem(&m_core->m_icount), 0); + UML_EXHc(block, uml::COND_L, *m_out_of_cycles, param); } /*------------------------------------------------- @@ -495,33 +502,35 @@ void unsp_device::generate_checksum_block(drcuml_block &block, compiler_state &c { block.append_comment("[Validation for %08X]", seqhead->pc); } - /* loose verify or single instruction: just compare and fail */ - if (!(m_drcoptions & UNSP_STRICT_VERIFY) || seqhead->next() == nullptr) + + /* full verification; sum up everything */ + void *memptr = m_program->get_write_ptr(seqhead->physpc); + UML_LOAD(block, I0, memptr, 0, SIZE_WORD, SCALE_x2); + uint32_t sum = seqhead->opptr.w[0]; + for (int i = 1; i < seqhead->length; i++) { - if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) - { - uint32_t sum = seqhead->opptr.w[0]; - UML_READ(block, I0, seqhead->physpc, SIZE_WORD, SPACE_PROGRAM); - UML_CMP(block, I0, sum); - UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); - } + UML_LOAD(block, I1, memptr, i, SIZE_WORD, SCALE_x2); + UML_ADD(block, I0, I0, I1); + sum += ((uint16_t*)memptr)[i]; } - else /* full verification; sum up everything */ + for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) { - UML_READ(block, I0, seqhead->physpc, SIZE_WORD, SPACE_PROGRAM); - uint32_t sum = seqhead->opptr.w[0]; - for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) + if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { - if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) + memptr = m_program->get_write_ptr(curdesc->physpc); + UML_LOAD(block, I1, memptr, 0, SIZE_WORD, SCALE_x2); + UML_ADD(block, I0, I0, I1); + sum += curdesc->opptr.w[0]; + for (int i = 1; i < curdesc->length; i++) { - UML_READ(block, I1, curdesc->physpc, SIZE_WORD, SPACE_PROGRAM); + UML_LOAD(block, I1, memptr, i, SIZE_WORD, SCALE_x2); UML_ADD(block, I0, I0, I1); - sum += curdesc->opptr.w[0]; + sum += ((uint16_t*)memptr)[i]; } } - UML_CMP(block, I0, sum); - UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); } + UML_CMP(block, I0, sum); + UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); } @@ -554,47 +563,17 @@ void unsp_device::generate_branch(drcuml_block &block, compiler_state &compiler, /* update the cycles and jump through the hash table to the target */ if (desc->targetpc != BRANCH_TARGET_DYNAMIC) { - generate_update_cycles(block, compiler, desc->targetpc); + UML_CALLH(block, *m_check_interrupts); UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); } else { - generate_update_cycles(block, compiler, uml::mem(&m_core->m_jmpdest)); + UML_CALLH(block, *m_check_interrupts); UML_HASHJMP(block, 0, mem(&m_core->m_jmpdest), *m_nocode); } } -/*------------------------------------------------------------------ - generate_push - pushes a register onto a stack addressed by - the specified register -------------------------------------------------------------------*/ - -void unsp_device::generate_push(drcuml_block &block, uint32_t sp) -{ - // value to push is in I1 - UML_MOV(block, I0, mem(&m_core->m_r[sp])); - UML_CALLH(block, *m_mem_write); - UML_SUB(block, I0, I0, 1); - UML_AND(block, mem(&m_core->m_r[sp]), I0, 0x0000ffff); -} - - -/*------------------------------------------------------------------ - generate_pop - pops a value off a stack addressed by the - specified register -------------------------------------------------------------------*/ - -void unsp_device::generate_pop(drcuml_block &block, uint32_t sp) -{ - // popped value is in I1 - UML_MOV(block, I0, mem(&m_core->m_r[sp])); - UML_ADD(block, I0, I0, 1); - UML_CALLH(block, *m_mem_read); - UML_AND(block, mem(&m_core->m_r[sp]), I0, 0x0000ffff); -} - - /*------------------------------------------------- generate_sequence_instruction - generate code for a single instruction in a sequence @@ -721,8 +700,6 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, uml::code_label shift_no_sign = compiler.m_labelnum++; uml::code_label no_carry = compiler.m_labelnum++; - UML_ADD(block, I7, I7, desc->cycles); - if(op0 < 0xf && opa == 0x7 && op1 < 2) { const uint32_t opimm = op & 0x3f; @@ -793,7 +770,7 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, break; case 14: // JMP - UML_ADD(block, I7, I7, 2); + UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), 4); UML_MOV(block, I0, desc->targetpc); UML_AND(block, mem(&m_core->m_r[REG_PC]), I0, 0x0000ffff); generate_branch(block, compiler, desc); @@ -802,13 +779,17 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, default: return false; } - UML_ADD(block, I7, I7, 2); + UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), 4); generate_add_lpc(block, (op1 == 0) ? opimm : (0 - opimm)); generate_branch(block, compiler, desc); UML_LABEL(block, skip_branch); + UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), 2); return true; } - else if (lower_op == 0x2d) // Push + + UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), desc->cycles); + + if (lower_op == 0x2d) // Push { uint32_t r0 = opn; uint32_t r1 = opa; @@ -818,10 +799,10 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, UML_MOV(block, I1, mem(&m_core->m_r[r1])); UML_CALLH(block, *m_mem_write); UML_SUB(block, I0, I0, 1); + UML_AND(block, mem(&m_core->m_r[opb]), I0, 0x0000ffff); r0--; r1--; } - UML_AND(block, mem(&m_core->m_r[opb]), I0, 0x0000ffff); return true; } else if (lower_op == 0x29) @@ -870,13 +851,13 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, { r1++; UML_ADD(block, I0, I0, 1); + UML_AND(block, mem(&m_core->m_r[opb]), I0, 0x0000ffff); UML_CALLH(block, *m_mem_read); UML_MOV(block, mem(&m_core->m_r[r1]), I1); if (r1 == REG_PC) do_branch = true; r0--; } - UML_AND(block, mem(&m_core->m_r[opb]), I0, 0x0000ffff); if (do_branch) generate_branch(block, compiler, desc); } diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp index 76c06f21577..ee20cc1a2ad 100644 --- a/src/devices/machine/spg2xx.cpp +++ b/src/devices/machine/spg2xx.cpp @@ -945,7 +945,7 @@ WRITE_LINE_MEMBER(spg2xx_device::vblank) void spg2xx_device::check_video_irq() { - m_cpu->set_input_line(UNSP_IRQ0_LINE, (VIDEO_IRQ_STATUS & VIDEO_IRQ_ENABLE) ? ASSERT_LINE : CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ0_LINE, (VIDEO_IRQ_STATUS & VIDEO_IRQ_ENABLE) ? ASSERT_LINE : CLEAR_LINE); } @@ -1041,7 +1041,7 @@ READ16_MEMBER(spg2xx_device::io_r) break; case 0x2f: // Data Segment - val = m_cpu->state_int(UNSP_SR) >> 10; + val = m_cpu->get_ds(); LOGMASKED(LOG_SEGMENT, "io_r: Data Segment = %04x\n", val); break; @@ -1428,12 +1428,9 @@ WRITE16_MEMBER(spg2xx_device::io_w) } case 0x2f: // Data Segment - { - uint16_t ds = m_cpu->state_int(UNSP_SR); - m_cpu->set_state_int(UNSP_SR, (ds & 0x03ff) | ((data & 0x3f) << 10)); + m_cpu->set_ds(data & 0x3f); LOGMASKED(LOG_SEGMENT, "io_w: Data Segment = %04x\n", data); break; - } case 0x30: // UART Control { @@ -1762,19 +1759,19 @@ void spg2xx_device::extint_w(int channel, bool state) void spg2xx_device::check_irqs(const uint16_t changed) { // { - // m_cpu->set_input_line(UNSP_IRQ1_LINE, ASSERT_LINE); + // m_cpu->set_state_unsynced(UNSP_IRQ1_LINE, ASSERT_LINE); // } if (changed & 0x0c00) // Timer A, Timer B IRQ { LOGMASKED(LOG_IRQS, "%ssserting IRQ2 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00)); - m_cpu->set_input_line(UNSP_IRQ2_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ2_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE); } if (changed & 0x2100) // UART, ADC IRQ { LOGMASKED(LOG_UART, "%ssserting IRQ3 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100)); - m_cpu->set_input_line(UNSP_IRQ3_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? ASSERT_LINE : CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ3_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? ASSERT_LINE : CLEAR_LINE); } if (changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) // Beat IRQ @@ -1782,31 +1779,31 @@ void spg2xx_device::check_irqs(const uint16_t changed) if ((m_audio_regs[AUDIO_BEAT_COUNT] & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) == (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) { LOGMASKED(LOG_BEAT, "Asserting beat IRQ\n"); - m_cpu->set_input_line(UNSP_IRQ4_LINE, ASSERT_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ4_LINE, ASSERT_LINE); } else { LOGMASKED(LOG_BEAT, "Clearing beat IRQ\n"); - m_cpu->set_input_line(UNSP_IRQ4_LINE, CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ4_LINE, CLEAR_LINE); } } if (changed & 0x1200) // External IRQ { LOGMASKED(LOG_UART, "%ssserting IRQ5 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200)); - m_cpu->set_input_line(UNSP_IRQ5_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ5_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE); } if (changed & 0x0070) // 1024Hz, 2048Hz, 4096Hz IRQ { LOGMASKED(LOG_IRQS, "%ssserting IRQ6 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070)); - m_cpu->set_input_line(UNSP_IRQ6_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ6_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE); } if (changed & 0x008b) // TMB1, TMB2, 4Hz, key change IRQ { LOGMASKED(LOG_IRQS, "%ssserting IRQ7 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b)); - m_cpu->set_input_line(UNSP_IRQ7_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE); + m_cpu->set_state_unsynced(UNSP_IRQ7_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE); } } |