summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i960/i960.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i960/i960.cpp')
-rw-r--r--src/devices/cpu/i960/i960.cpp77
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");