diff options
Diffstat (limited to 'src/devices/cpu/i960/i960.cpp')
-rw-r--r-- | src/devices/cpu/i960/i960.cpp | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/src/devices/cpu/i960/i960.cpp b/src/devices/cpu/i960/i960.cpp index 148cc1a8996..d7b3c4a0fde 100644 --- a/src/devices/cpu/i960/i960.cpp +++ b/src/devices/cpu/i960/i960.cpp @@ -599,11 +599,50 @@ void i960_cpu_device::do_ret() } } +// if last opcode was a multi dword burst read opcode save the data here +// i.e. Model 2 FIFO reads with ldl, ldt, ldq +void i960_cpu_device::burst_stall_save(uint32_t t1, uint32_t t2, int index, int size) +{ + m_stall_state.t1 = t1; + m_stall_state.t2 = t2; + m_stall_state.index = index; + m_stall_state.size = size; + m_stall_state.burst_mode = true; +} + +// resume from a burst stall opcode +void i960_cpu_device::execute_burst_stall_op(uint32_t opcode) +{ + int i; + // in case opcode uses an operand call effective address function to fix IP register + (void)get_ea(opcode); + + // check if our data is ready + for(i=m_stall_state.index ; i<m_stall_state.size ;i++) + { + // count down 1 icount for every read + m_icount--; + m_r[m_stall_state.t2+i] = i960_read_dword_unaligned(m_stall_state.t1); + + // if the host returned stall just save the index and try again on a later moment + if(m_stalled == true) + { + m_stall_state.index = i; + return; + } + } + + // clear stall burst mode + m_stall_state.burst_mode = false; + // now that we are done we might as well check if there's a pending irq too + check_irqs(); +} + void i960_cpu_device::execute_op(uint32_t opcode) { uint32_t t1, t2; double t1f, t2f; - + switch(opcode >> 24) { case 0x08: // b m_icount--; @@ -1911,6 +1950,11 @@ void i960_cpu_device::execute_op(uint32_t opcode) m_bursting = 1; for(i=0; i<2; i++) { m_r[t2+i] = i960_read_dword_unaligned(t1); + if(m_stalled) + { + burst_stall_save(t1,t2,i,2); + return; + } if(m_bursting) t1 += 4; } @@ -1939,6 +1983,11 @@ void i960_cpu_device::execute_op(uint32_t opcode) m_bursting = 1; for(i=0; i<3; i++) { m_r[t2+i] = i960_read_dword_unaligned(t1); + if(m_stalled) + { + burst_stall_save(t1,t2,i,3); + return; + } if(m_bursting) t1 += 4; } @@ -1967,6 +2016,11 @@ void i960_cpu_device::execute_op(uint32_t opcode) m_bursting = 1; for(i=0; i<4; i++) { m_r[t2+i] = i960_read_dword_unaligned(t1); + if(m_stalled) + { + burst_stall_save(t1,t2,i,4); + return; + } if(m_bursting) t1 += 4; } @@ -2017,7 +2071,10 @@ void i960_cpu_device::execute_run() { uint32_t opcode; - check_irqs(); + // delay checking irqs if we are in burst stall mode + if(m_stall_state.burst_mode == false) + check_irqs(); + while(m_icount > 0) { m_PIP = m_IP; debugger_instruction_hook(this, m_IP); @@ -2027,7 +2084,12 @@ void i960_cpu_device::execute_run() opcode = m_direct->read_dword(m_IP); m_IP += 4; - execute_op(opcode); + m_stalled = false; + + if(m_stall_state.burst_mode == true) + execute_burst_stall_op(opcode); + else + execute_op(opcode); } } @@ -2121,7 +2183,14 @@ void i960_cpu_device::device_start() save_item(NAME(m_immediate_vector)); save_item(NAME(m_immediate_pri)); save_item(NAME(m_bursting)); - + save_item(NAME(m_stalled)); + save_item(NAME(m_stall_state.index)); + save_item(NAME(m_stall_state.size)); + save_item(NAME(m_stall_state.t1)); + save_item(NAME(m_stall_state.t2)); + save_item(NAME(m_stall_state.burst_mode)); + + state_add( I960_SAT, "sat", m_SAT).formatstr("%08X"); state_add( I960_PRCB, "prcb", m_PRCB).formatstr("%08X"); state_add( I960_PC, "pc", m_PC).formatstr("%08X"); |