mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
i960.cpp: support for burst mode stalling save and restore [Angelo Salese] (#3199)
* i960.cpp: experimental FIFO burst mechanism. Known status (difference from before): daytona: runs at better speed, crashes/hangs at expert course; dynabb / dynabb97: enters in-game, needs bat swing input; dynamcop: playable; fvipers: playable if you coin it up fast enough, crashes in attract otherwise; indy500: playable; lastbrnx: runs a bit further, needs a few extra geometry opcodes; motoraid: playable; vcop2: playable; vf2: playable; overrev/sgt24h/zerogun: 3d regressions (?); * model2.cpp: dynamite baseball bat swing inputs (nw) * cleanups and commentary (nw)
This commit is contained in:
parent
77aff96456
commit
17d7f3c4e3
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user