summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/i960/i960.cpp77
-rw-r--r--src/devices/cpu/i960/i960.h18
-rw-r--r--src/mame/drivers/model2.cpp17
3 files changed, 103 insertions, 9 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");
diff --git a/src/devices/cpu/i960/i960.h b/src/devices/cpu/i960/i960.h
index 2b2b53e2729..9aa873f637f 100644
--- a/src/devices/cpu/i960/i960.h
+++ b/src/devices/cpu/i960/i960.h
@@ -73,8 +73,12 @@ public:
// on the real hardware (e.g. Model 2's interrupt control registers)
void i960_noburst() { m_bursting = 0; }
- void i960_stall() { m_IP = m_PIP; }
-
+ void i960_stall()
+ {
+ m_stalled = true;
+ m_IP = m_PIP;
+ }
+
protected:
enum { I960_RCACHE_SIZE = 4 };
@@ -100,6 +104,15 @@ protected:
virtual util::disasm_interface *create_disassembler() override;
private:
+ void burst_stall_save(uint32_t t1, uint32_t t2, int index, int size);
+
+ struct {
+ uint32_t t1,t2;
+ int index,size;
+ bool burst_mode;
+ }m_stall_state;
+ bool m_stalled;
+
address_space_config m_program_config;
uint32_t m_r[0x20];
@@ -161,6 +174,7 @@ private:
void fxx(uint32_t opcode, int mask);
void test(uint32_t opcode, int mask);
void execute_op(uint32_t opcode);
+ void execute_burst_stall_op(uint32_t opcode);
void take_interrupt(int vector, int lvl);
void check_irqs();
void do_call(uint32_t adr, int type, uint32_t stack);
diff --git a/src/mame/drivers/model2.cpp b/src/mame/drivers/model2.cpp
index d678804fbf7..55108ac0e08 100644
--- a/src/mame/drivers/model2.cpp
+++ b/src/mame/drivers/model2.cpp
@@ -234,6 +234,8 @@ uint32_t model2_state::copro_fifoout_pop(address_space &space,uint32_t offset, u
{
uint32_t r;
+ m_maincpu->i960_noburst();
+
if (m_copro_fifoout_num == 0)
{
/* Reading from empty FIFO causes the i960 to enter wait state */
@@ -242,7 +244,7 @@ uint32_t model2_state::copro_fifoout_pop(address_space &space,uint32_t offset, u
/* spin the main cpu and let the TGP catch up */
// TODO: Daytona needs a much shorter spin time (like 25 usecs), but that breaks other games even moreso
// @seealso http://www.mameworld.info/ubbthreads/showflat.php?Cat=&Number=358069&page=&view=&sb=5&o=&vc=1
- m_maincpu->spin_until_time(attotime::from_usec(100));
+ m_maincpu->spin_until_time(attotime::from_usec(25));
return 0;
}
@@ -1978,6 +1980,15 @@ static INPUT_PORTS_START( skytargt )
MODEL2_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4)
INPUT_PORTS_END
+static INPUT_PORTS_START( dynabb )
+ PORT_INCLUDE(model2)
+
+ PORT_START("ANA0")
+ PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_SENSITIVITY(100) PORT_KEYDELTA(50) PORT_PLAYER(1) PORT_NAME("P1 Bat Swing")
+
+ PORT_START("ANA1")
+ PORT_BIT(0xff, 0x00, IPT_PEDAL2) PORT_SENSITIVITY(100) PORT_KEYDELTA(50) PORT_PLAYER(2) PORT_NAME("P2 Bat Swing")
+INPUT_PORTS_END
TIMER_DEVICE_CALLBACK_MEMBER(model2_state::model2_interrupt)
{
@@ -6063,8 +6074,8 @@ GAME( 1996, lastbrnxu, lastbrnx, model2b, model2, model2_state, 0,
GAME( 1996, lastbrnxj, lastbrnx, model2b, model2, model2_state, 0, ROT0, "Sega", "Last Bronx (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, doa, 0, model2b_0229, model2, model2_state, doa, ROT0, "Sega", "Dead or Alive (Model 2B, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, sgt24h, 0, indy500, srallyc, model2_state, sgt24h, ROT0, "Jaleco", "Super GT 24h", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1996, dynabb, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Dynamite Baseball", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1997, dynabb97, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Dynamite Baseball 97 (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1996, dynabb, 0, model2b, dynabb, model2_state, 0, ROT0, "Sega", "Dynamite Baseball", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1997, dynabb97, 0, model2b, dynabb, model2_state, 0, ROT0, "Sega", "Dynamite Baseball 97 (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, overrevb, overrev, indy500, srallyc, model2_state, 0, ROT0, "Jaleco", "Over Rev (Model 2B, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, zerogun, 0, model2b_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Export, Model 2B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, zerogunj, zerogun, model2b_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Japan, Model 2B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS )