mirror of
https://github.com/holub/mame
synced 2025-06-02 19:06:43 +03:00
smpc moved to state, need to be device-fied in future (nw)
This commit is contained in:
parent
1b5f24add6
commit
5e99f6e4c8
@ -164,28 +164,27 @@ TODO:
|
||||
*
|
||||
*******************************************/
|
||||
|
||||
static TIMER_CALLBACK( stv_bankswitch_state )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::stv_bankswitch_state )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
static const char *const banknames[] = { "game0", "game1", "game2", "game3" };
|
||||
UINT8* game_region;
|
||||
|
||||
if(state->m_prev_bankswitch != param)
|
||||
if(m_prev_bankswitch != param)
|
||||
{
|
||||
game_region = machine.root_device().memregion(banknames[param])->base();
|
||||
game_region = memregion(banknames[param])->base();
|
||||
|
||||
if (game_region)
|
||||
memcpy(machine.root_device().memregion("abus")->base(), game_region, 0x3000000);
|
||||
memcpy(memregion("abus")->base(), game_region, 0x3000000);
|
||||
else
|
||||
memset(machine.root_device().memregion("abus")->base(), 0x00, 0x3000000);
|
||||
memset(memregion("abus")->base(), 0x00, 0x3000000);
|
||||
|
||||
state->m_prev_bankswitch = param;
|
||||
m_prev_bankswitch = param;
|
||||
}
|
||||
}
|
||||
|
||||
static void stv_select_game(running_machine &machine, int gameno)
|
||||
void saturn_state::stv_select_game(int gameno)
|
||||
{
|
||||
machine.scheduler().timer_set(attotime::zero, FUNC(stv_bankswitch_state), gameno);
|
||||
machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(saturn_state::stv_bankswitch_state),this), gameno);
|
||||
}
|
||||
|
||||
/********************************************
|
||||
@ -194,178 +193,164 @@ static void stv_select_game(running_machine &machine, int gameno)
|
||||
*
|
||||
*******************************************/
|
||||
|
||||
static void smpc_master_on(running_machine &machine)
|
||||
void saturn_state::smpc_master_on()
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( smpc_slave_enable )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_slave_enable )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
state->m_slave->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
|
||||
state->m_smpc.OREG[31] = param + 0x02; //read-back for last command issued
|
||||
state->m_smpc.SF = 0x00; //clear hand-shake flag
|
||||
state->m_smpc.slave_on = param;
|
||||
// printf("%d %d\n",machine.first_screen()->hpos(),machine.first_screen()->vpos());
|
||||
m_slave->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_smpc.OREG[31] = param + 0x02; //read-back for last command issued
|
||||
m_smpc.SF = 0x00; //clear hand-shake flag
|
||||
m_smpc.slave_on = param;
|
||||
// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( smpc_sound_enable )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_sound_enable )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
state->m_audiocpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
|
||||
state->m_en_68k = param ^ 1;
|
||||
state->m_smpc.OREG[31] = param + 0x06; //read-back for last command issued
|
||||
state->m_smpc.SF = 0x00; //clear hand-shake flag
|
||||
m_audiocpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_en_68k = param ^ 1;
|
||||
m_smpc.OREG[31] = param + 0x06; //read-back for last command issued
|
||||
m_smpc.SF = 0x00; //clear hand-shake flag
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( smpc_cd_enable )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_cd_enable )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
state->m_smpc.OREG[31] = param + 0x08; //read-back for last command issued
|
||||
state->m_smpc.SF = 0x08; //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high)
|
||||
m_smpc.OREG[31] = param + 0x08; //read-back for last command issued
|
||||
m_smpc.SF = 0x08; //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high)
|
||||
}
|
||||
|
||||
static void smpc_system_reset(running_machine &machine)
|
||||
void saturn_state::smpc_system_reset()
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
/*Only backup ram and SMPC ram are retained after that this command is issued.*/
|
||||
memset(state->m_scu_regs ,0x00,0x000100);
|
||||
memset(state->m_scsp_regs,0x00,0x001000);
|
||||
memset(state->m_sound_ram,0x00,0x080000);
|
||||
memset(state->m_workram_h,0x00,0x100000);
|
||||
memset(state->m_workram_l,0x00,0x100000);
|
||||
memset(state->m_vdp2_regs,0x00,0x040000);
|
||||
memset(state->m_vdp2_vram,0x00,0x100000);
|
||||
memset(state->m_vdp2_cram,0x00,0x080000);
|
||||
memset(state->m_vdp1_vram,0x00,0x100000);
|
||||
memset(m_scu_regs ,0x00,0x000100);
|
||||
memset(m_scsp_regs,0x00,0x001000);
|
||||
memset(m_sound_ram,0x00,0x080000);
|
||||
memset(m_workram_h,0x00,0x100000);
|
||||
memset(m_workram_l,0x00,0x100000);
|
||||
memset(m_vdp2_regs,0x00,0x040000);
|
||||
memset(m_vdp2_vram,0x00,0x100000);
|
||||
memset(m_vdp2_cram,0x00,0x080000);
|
||||
memset(m_vdp1_vram,0x00,0x100000);
|
||||
//A-Bus
|
||||
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( smpc_change_clock )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
UINT32 xtal;
|
||||
|
||||
if(LOG_SMPC) printf ("Clock change execute at (%d %d)\n",machine.first_screen()->hpos(),machine.first_screen()->vpos());
|
||||
if(LOG_SMPC) printf ("Clock change execute at (%d %d)\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
|
||||
xtal = param ? MASTER_CLOCK_320 : MASTER_CLOCK_352;
|
||||
|
||||
machine.device("maincpu")->set_unscaled_clock(xtal/2);
|
||||
machine.device("slave")->set_unscaled_clock(xtal/2);
|
||||
machine().device("maincpu")->set_unscaled_clock(xtal/2);
|
||||
machine().device("slave")->set_unscaled_clock(xtal/2);
|
||||
|
||||
state->m_vdp2.dotsel = param ^ 1;
|
||||
state->stv_vdp2_dynamic_res_change();
|
||||
m_vdp2.dotsel = param ^ 1;
|
||||
stv_vdp2_dynamic_res_change();
|
||||
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
if(!state->m_NMI_reset)
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
state->m_slave->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
state->m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
state->m_audiocpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
if(!m_NMI_reset)
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
m_audiocpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
|
||||
/* put issued command in OREG31 */
|
||||
state->m_smpc.OREG[31] = 0x0e + param;
|
||||
m_smpc.OREG[31] = 0x0e + param;
|
||||
/* clear hand-shake flag */
|
||||
state->m_smpc.SF = 0x00;
|
||||
m_smpc.SF = 0x00;
|
||||
|
||||
/* TODO: VDP1 / VDP2 / SCU / SCSP default power ON values? */
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( stv_intback_peripheral )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
if (state->m_smpc.intback_stage == 2)
|
||||
if (m_smpc.intback_stage == 2)
|
||||
{
|
||||
state->m_smpc.SR = (0x80 | state->m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
|
||||
state->m_smpc.intback_stage = 0;
|
||||
m_smpc.SR = (0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
|
||||
m_smpc.intback_stage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->m_smpc.SR = (0xc0 | state->m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
|
||||
state->m_smpc.intback_stage ++;
|
||||
m_smpc.SR = (0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
|
||||
m_smpc.intback_stage ++;
|
||||
}
|
||||
|
||||
if(!(state->m_scu.ism & IRQ_SMPC))
|
||||
state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
state->m_scu.ist |= (IRQ_SMPC);
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
|
||||
state->m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
||||
state->m_smpc.SF = 0x00; /* clear hand-shake flag */
|
||||
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
||||
m_smpc.SF = 0x00; /* clear hand-shake flag */
|
||||
}
|
||||
|
||||
|
||||
static TIMER_CALLBACK( stv_smpc_intback )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
int i;
|
||||
|
||||
// printf("%02x %02x %02x\n",state->m_smpc.intback_buf[0],state->m_smpc.intback_buf[1],state->m_smpc.intback_buf[2]);
|
||||
// printf("%02x %02x %02x\n",m_smpc.intback_buf[0],m_smpc.intback_buf[1],m_smpc.intback_buf[2]);
|
||||
|
||||
if(state->m_smpc.intback_buf[0] != 0)
|
||||
if(m_smpc.intback_buf[0] != 0)
|
||||
{
|
||||
state->m_smpc.OREG[0] = (0x80) | ((state->m_NMI_reset & 1) << 6);
|
||||
m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6);
|
||||
|
||||
for(i=0;i<7;i++)
|
||||
state->m_smpc.OREG[1+i] = state->m_smpc.rtc_data[i];
|
||||
m_smpc.OREG[1+i] = m_smpc.rtc_data[i];
|
||||
|
||||
state->m_smpc.OREG[8]=0x00; // CTG0 / CTG1?
|
||||
m_smpc.OREG[8]=0x00; // CTG0 / CTG1?
|
||||
|
||||
state->m_smpc.OREG[9]=0x00; // TODO: system region on Saturn
|
||||
m_smpc.OREG[9]=0x00; // TODO: system region on Saturn
|
||||
|
||||
state->m_smpc.OREG[10]= 0 << 7 |
|
||||
state->m_vdp2.dotsel << 6 |
|
||||
m_smpc.OREG[10]= 0 << 7 |
|
||||
m_vdp2.dotsel << 6 |
|
||||
1 << 5 |
|
||||
1 << 4 |
|
||||
0 << 3 | //MSHNMI
|
||||
1 << 2 |
|
||||
0 << 1 | //SYSRES
|
||||
0 << 0; //SOUNDRES
|
||||
state->m_smpc.OREG[11]= 0 << 6; //CDRES
|
||||
m_smpc.OREG[11]= 0 << 6; //CDRES
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
state->m_smpc.OREG[12+i]=state->m_smpc.SMEM[i];
|
||||
m_smpc.OREG[12+i]=m_smpc.SMEM[i];
|
||||
|
||||
for(i=0;i<15;i++)
|
||||
state->m_smpc.OREG[16+i]=0xff; // undefined
|
||||
m_smpc.OREG[16+i]=0xff; // undefined
|
||||
|
||||
state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
state->m_smpc.SR = 0x40 | state->m_smpc.intback_stage << 5;
|
||||
state->m_smpc.pmode = state->m_smpc.intback_buf[0]>>4;
|
||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
m_smpc.SR = 0x40 | m_smpc.intback_stage << 5;
|
||||
m_smpc.pmode = m_smpc.intback_buf[0]>>4;
|
||||
|
||||
// /*This is for RTC,cartridge code and similar stuff...*/
|
||||
//if(LOG_SMPC) printf ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline);
|
||||
if(!(state->m_scu.ism & IRQ_SMPC))
|
||||
state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
state->m_scu.ist |= (IRQ_SMPC);
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
|
||||
/* put issued command in OREG31 */
|
||||
state->m_smpc.OREG[31] = 0x10; // TODO: doc says 0?
|
||||
m_smpc.OREG[31] = 0x10; // TODO: doc says 0?
|
||||
/* clear hand-shake flag */
|
||||
state->m_smpc.SF = 0x00;
|
||||
m_smpc.SF = 0x00;
|
||||
}
|
||||
else if(state->m_smpc.intback_buf[1] & 8)
|
||||
else if(m_smpc.intback_buf[1] & 8)
|
||||
{
|
||||
state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
state->m_smpc.SR = 0x40;
|
||||
state->m_smpc.OREG[31] = 0x10;
|
||||
machine.scheduler().timer_set(attotime::from_usec(0), FUNC(stv_intback_peripheral),0);
|
||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
m_smpc.SR = 0x40;
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shienryu calls this, it would be plainly illegal on Saturn, I'll just return the command and clear the hs flag for now. */
|
||||
state->m_smpc.OREG[31] = 0x10;
|
||||
state->m_smpc.SF = 0x00;
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
m_smpc.SF = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,65 +368,62 @@ static TIMER_CALLBACK( stv_smpc_intback )
|
||||
0x34 keyboard
|
||||
*/
|
||||
|
||||
static void smpc_digital_pad(running_machine &machine, UINT8 pad_num, UINT8 offset)
|
||||
void saturn_state::smpc_digital_pad(UINT8 pad_num, UINT8 offset)
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
static const char *const padnames[] = { "JOY1", "JOY2" };
|
||||
UINT16 pad_data;
|
||||
|
||||
pad_data = machine.root_device().ioport(padnames[pad_num])->read();
|
||||
state->m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
state->m_smpc.OREG[1+pad_num*offset] = 0x02;
|
||||
state->m_smpc.OREG[2+pad_num*offset] = pad_data>>8;
|
||||
state->m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff;
|
||||
pad_data = ioport(padnames[pad_num])->read();
|
||||
m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
m_smpc.OREG[1+pad_num*offset] = 0x02;
|
||||
m_smpc.OREG[2+pad_num*offset] = pad_data>>8;
|
||||
m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff;
|
||||
}
|
||||
|
||||
static void smpc_analog_pad(running_machine &machine, UINT8 pad_num, UINT8 offset, UINT8 id)
|
||||
void saturn_state::smpc_analog_pad( UINT8 pad_num, UINT8 offset, UINT8 id)
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
static const char *const padnames[] = { "AN_JOY1", "AN_JOY2" };
|
||||
static const char *const annames[2][3] = { { "AN_X1", "AN_Y1", "AN_Z1" },
|
||||
{ "AN_X2", "AN_Y2", "AN_Z2" }};
|
||||
UINT16 pad_data;
|
||||
|
||||
pad_data = machine.root_device().ioport(padnames[pad_num])->read();
|
||||
state->m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
state->m_smpc.OREG[1+pad_num*offset] = id;
|
||||
state->m_smpc.OREG[2+pad_num*offset] = pad_data>>8;
|
||||
state->m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff;
|
||||
state->m_smpc.OREG[4+pad_num*offset] = machine.root_device().ioport(annames[pad_num][0])->read();
|
||||
pad_data = ioport(padnames[pad_num])->read();
|
||||
m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
m_smpc.OREG[1+pad_num*offset] = id;
|
||||
m_smpc.OREG[2+pad_num*offset] = pad_data>>8;
|
||||
m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff;
|
||||
m_smpc.OREG[4+pad_num*offset] = ioport(annames[pad_num][0])->read();
|
||||
if(id == 0x15)
|
||||
{
|
||||
state->m_smpc.OREG[5+pad_num*offset] = machine.root_device().ioport(annames[pad_num][1])->read();
|
||||
state->m_smpc.OREG[6+pad_num*offset] = machine.root_device().ioport(annames[pad_num][2])->read();
|
||||
m_smpc.OREG[5+pad_num*offset] = ioport(annames[pad_num][1])->read();
|
||||
m_smpc.OREG[6+pad_num*offset] = ioport(annames[pad_num][2])->read();
|
||||
}
|
||||
}
|
||||
|
||||
static void smpc_keyboard(running_machine &machine, UINT8 pad_num, UINT8 offset)
|
||||
void saturn_state::smpc_keyboard(UINT8 pad_num, UINT8 offset)
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
UINT16 game_key;
|
||||
|
||||
game_key = 0xffff;
|
||||
|
||||
game_key ^= ((state->ioport("KEYS_1")->read() & 0x80) << 8); // right
|
||||
game_key ^= ((state->ioport("KEYS_1")->read() & 0x40) << 8); // left
|
||||
game_key ^= ((state->ioport("KEYS_1")->read() & 0x20) << 8); // down
|
||||
game_key ^= ((state->ioport("KEYS_1")->read() & 0x10) << 8); // up
|
||||
game_key ^= ((state->ioport("KEYF")->read() & 0x80) << 4); // ESC -> START
|
||||
game_key ^= ((state->ioport("KEY3")->read() & 0x04) << 8); // Z / A trigger
|
||||
game_key ^= ((state->ioport("KEY4")->read() & 0x02) << 8); // C / C trigger
|
||||
game_key ^= ((state->ioport("KEY6")->read() & 0x04) << 6); // X / B trigger
|
||||
game_key ^= ((state->ioport("KEY2")->read() & 0x20) << 2); // Q / R trigger
|
||||
game_key ^= ((state->ioport("KEY3")->read() & 0x10) << 2); // A / X trigger
|
||||
game_key ^= ((state->ioport("KEY3")->read() & 0x08) << 2); // S / Y trigger
|
||||
game_key ^= ((state->ioport("KEY4")->read() & 0x08) << 1); // D / Z trigger
|
||||
game_key ^= ((state->ioport("KEY4")->read() & 0x10) >> 1); // E / L trigger
|
||||
game_key ^= ((ioport("KEYS_1")->read() & 0x80) << 8); // right
|
||||
game_key ^= ((ioport("KEYS_1")->read() & 0x40) << 8); // left
|
||||
game_key ^= ((ioport("KEYS_1")->read() & 0x20) << 8); // down
|
||||
game_key ^= ((ioport("KEYS_1")->read() & 0x10) << 8); // up
|
||||
game_key ^= ((ioport("KEYF")->read() & 0x80) << 4); // ESC -> START
|
||||
game_key ^= ((ioport("KEY3")->read() & 0x04) << 8); // Z / A trigger
|
||||
game_key ^= ((ioport("KEY4")->read() & 0x02) << 8); // C / C trigger
|
||||
game_key ^= ((ioport("KEY6")->read() & 0x04) << 6); // X / B trigger
|
||||
game_key ^= ((ioport("KEY2")->read() & 0x20) << 2); // Q / R trigger
|
||||
game_key ^= ((ioport("KEY3")->read() & 0x10) << 2); // A / X trigger
|
||||
game_key ^= ((ioport("KEY3")->read() & 0x08) << 2); // S / Y trigger
|
||||
game_key ^= ((ioport("KEY4")->read() & 0x08) << 1); // D / Z trigger
|
||||
game_key ^= ((ioport("KEY4")->read() & 0x10) >> 1); // E / L trigger
|
||||
|
||||
state->m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
state->m_smpc.OREG[1+pad_num*offset] = 0x34;
|
||||
state->m_smpc.OREG[2+pad_num*offset] = game_key>>8; // game buttons, TODO
|
||||
state->m_smpc.OREG[3+pad_num*offset] = game_key & 0xff;
|
||||
m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
m_smpc.OREG[1+pad_num*offset] = 0x34;
|
||||
m_smpc.OREG[2+pad_num*offset] = game_key>>8; // game buttons, TODO
|
||||
m_smpc.OREG[3+pad_num*offset] = game_key & 0xff;
|
||||
/*
|
||||
x--- ---- 0
|
||||
-x-- ---- caps lock
|
||||
@ -452,21 +434,20 @@ static void smpc_keyboard(running_machine &machine, UINT8 pad_num, UINT8 offset)
|
||||
---- --x- 1
|
||||
---- ---x Break key
|
||||
*/
|
||||
state->m_smpc.OREG[4+pad_num*offset] = state->m_keyb.status | 6;
|
||||
state->m_smpc.OREG[5+pad_num*offset] = state->m_keyb.data;
|
||||
m_smpc.OREG[4+pad_num*offset] = m_keyb.status | 6;
|
||||
m_smpc.OREG[5+pad_num*offset] = m_keyb.data;
|
||||
}
|
||||
|
||||
static void smpc_mouse(running_machine &machine, UINT8 pad_num, UINT8 offset, UINT8 id)
|
||||
void saturn_state::smpc_mouse(UINT8 pad_num, UINT8 offset, UINT8 id)
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
static const char *const mousenames[2][3] = { { "MOUSEB1", "MOUSEX1", "MOUSEY1" },
|
||||
{ "MOUSEB2", "MOUSEX2", "MOUSEY2" }};
|
||||
UINT8 mouse_ctrl;
|
||||
INT16 mouse_x, mouse_y;
|
||||
|
||||
mouse_ctrl = machine.root_device().ioport(mousenames[pad_num][0])->read();
|
||||
mouse_x = machine.root_device().ioport(mousenames[pad_num][1])->read();
|
||||
mouse_y = machine.root_device().ioport(mousenames[pad_num][2])->read();
|
||||
mouse_ctrl = ioport(mousenames[pad_num][0])->read();
|
||||
mouse_x = ioport(mousenames[pad_num][1])->read();
|
||||
mouse_y = ioport(mousenames[pad_num][2])->read();
|
||||
|
||||
if(mouse_x < 0)
|
||||
mouse_ctrl |= 0x10;
|
||||
@ -480,38 +461,34 @@ static void smpc_mouse(running_machine &machine, UINT8 pad_num, UINT8 offset, UI
|
||||
if((mouse_y & 0xff00) != 0xff00 && (mouse_y & 0xff00) != 0x0000)
|
||||
mouse_ctrl |= 0x80;
|
||||
|
||||
state->m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
state->m_smpc.OREG[1+pad_num*offset] = id; // 0x23 / 0xe3
|
||||
state->m_smpc.OREG[2+pad_num*offset] = mouse_ctrl;
|
||||
state->m_smpc.OREG[3+pad_num*offset] = mouse_x & 0xff;
|
||||
state->m_smpc.OREG[4+pad_num*offset] = mouse_y & 0xff;
|
||||
m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
m_smpc.OREG[1+pad_num*offset] = id; // 0x23 / 0xe3
|
||||
m_smpc.OREG[2+pad_num*offset] = mouse_ctrl;
|
||||
m_smpc.OREG[3+pad_num*offset] = mouse_x & 0xff;
|
||||
m_smpc.OREG[4+pad_num*offset] = mouse_y & 0xff;
|
||||
}
|
||||
|
||||
/* TODO: is there ANY game on which the MD pad works? */
|
||||
static void smpc_md_pad(running_machine &machine, UINT8 pad_num, UINT8 offset, UINT8 id)
|
||||
void saturn_state::smpc_md_pad(UINT8 pad_num, UINT8 offset, UINT8 id)
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
static const char *const padnames[] = { "MD_JOY1", "MD_JOY2" };
|
||||
UINT16 pad_data;
|
||||
|
||||
pad_data = machine.root_device().ioport(padnames[pad_num])->read();
|
||||
state->m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
state->m_smpc.OREG[1+pad_num*offset] = id;
|
||||
state->m_smpc.OREG[2+pad_num*offset] = pad_data>>8;
|
||||
pad_data = ioport(padnames[pad_num])->read();
|
||||
m_smpc.OREG[0+pad_num*offset] = 0xf1;
|
||||
m_smpc.OREG[1+pad_num*offset] = id;
|
||||
m_smpc.OREG[2+pad_num*offset] = pad_data>>8;
|
||||
if(id == 0xe2) // MD 6 Button PAD
|
||||
state->m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff;
|
||||
m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff;
|
||||
}
|
||||
|
||||
static void smpc_unconnected(running_machine &machine, UINT8 pad_num, UINT8 offset)
|
||||
void saturn_state::smpc_unconnected(UINT8 pad_num, UINT8 offset)
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
state->m_smpc.OREG[0+pad_num*offset] = 0xf0;
|
||||
m_smpc.OREG[0+pad_num*offset] = 0xf0;
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( intback_peripheral )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
int pad_num;
|
||||
static const UINT8 peri_id[10] = { 0x02, 0x13, 0x15, 0x23, 0x23, 0x34, 0xe1, 0xe2, 0xe3, 0xff };
|
||||
UINT8 read_id[2];
|
||||
@ -519,13 +496,13 @@ static TIMER_CALLBACK( intback_peripheral )
|
||||
|
||||
// if (LOG_SMPC) logerror("SMPC: providing PAD data for intback, pad %d\n", intback_stage-2);
|
||||
|
||||
read_id[0] = (machine.root_device().ioport("INPUT_TYPE")->read()) & 0x0f;
|
||||
read_id[1] = (machine.root_device().ioport("INPUT_TYPE")->read()) >> 4;
|
||||
read_id[0] = (ioport("INPUT_TYPE")->read()) & 0x0f;
|
||||
read_id[1] = (ioport("INPUT_TYPE")->read()) >> 4;
|
||||
|
||||
/* doesn't work? */
|
||||
//pad_num = state->m_smpc.intback_stage - 1;
|
||||
//pad_num = m_smpc.intback_stage - 1;
|
||||
|
||||
if(LOG_PAD_CMD) printf("%d %d %d\n",state->m_smpc.intback_stage - 1,machine.first_screen()->vpos(),(int)machine.first_screen()->frame_number());
|
||||
if(LOG_PAD_CMD) printf("%d %d %d\n",m_smpc.intback_stage - 1,machine().first_screen()->vpos(),(int)machine().first_screen()->frame_number());
|
||||
|
||||
offset = 0;
|
||||
|
||||
@ -533,141 +510,134 @@ static TIMER_CALLBACK( intback_peripheral )
|
||||
{
|
||||
switch(read_id[pad_num])
|
||||
{
|
||||
case 0: smpc_digital_pad(machine,pad_num,offset); break;
|
||||
case 1: smpc_analog_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Steering Wheel */
|
||||
case 2: smpc_analog_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Analog Pad */
|
||||
case 4: smpc_mouse(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Pointing Device */
|
||||
case 5: smpc_keyboard(machine,pad_num,offset); break;
|
||||
case 6: smpc_md_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 3B PAD */
|
||||
case 7: smpc_md_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 6B PAD */
|
||||
case 8: smpc_mouse(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Saturn Mouse */
|
||||
case 9: smpc_unconnected(machine,pad_num,offset); break;
|
||||
case 0: smpc_digital_pad(pad_num,offset); break;
|
||||
case 1: smpc_analog_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Steering Wheel */
|
||||
case 2: smpc_analog_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Analog Pad */
|
||||
case 4: smpc_mouse(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Pointing Device */
|
||||
case 5: smpc_keyboard(pad_num,offset); break;
|
||||
case 6: smpc_md_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 3B PAD */
|
||||
case 7: smpc_md_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 6B PAD */
|
||||
case 8: smpc_mouse(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Saturn Mouse */
|
||||
case 9: smpc_unconnected(pad_num,offset); break;
|
||||
}
|
||||
|
||||
offset += (peri_id[read_id[pad_num]] & 0xf) + 2; /* offset for port 2 */
|
||||
}
|
||||
|
||||
if (state->m_smpc.intback_stage == 2)
|
||||
if (m_smpc.intback_stage == 2)
|
||||
{
|
||||
state->m_smpc.SR = (0x80 | state->m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
|
||||
state->m_smpc.intback_stage = 0;
|
||||
m_smpc.SR = (0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
|
||||
m_smpc.intback_stage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->m_smpc.SR = (0xc0 | state->m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
|
||||
state->m_smpc.intback_stage ++;
|
||||
m_smpc.SR = (0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
|
||||
m_smpc.intback_stage ++;
|
||||
}
|
||||
|
||||
if(!(state->m_scu.ism & IRQ_SMPC))
|
||||
state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
state->m_scu.ist |= (IRQ_SMPC);
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
|
||||
state->m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
||||
state->m_smpc.SF = 0x00; /* clear hand-shake flag */
|
||||
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
||||
m_smpc.SF = 0x00; /* clear hand-shake flag */
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( saturn_smpc_intback )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
if(state->m_smpc.intback_buf[0] != 0)
|
||||
if(m_smpc.intback_buf[0] != 0)
|
||||
{
|
||||
{
|
||||
int i;
|
||||
|
||||
state->m_smpc.OREG[0] = (0x80) | ((state->m_NMI_reset & 1) << 6); // bit 7: SETTIME (RTC isn't setted up properly)
|
||||
m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6); // bit 7: SETTIME (RTC isn't setted up properly)
|
||||
|
||||
for(i=0;i<7;i++)
|
||||
state->m_smpc.OREG[1+i] = state->m_smpc.rtc_data[i];
|
||||
m_smpc.OREG[1+i] = m_smpc.rtc_data[i];
|
||||
|
||||
state->m_smpc.OREG[8]=0x00; //Cartridge code?
|
||||
m_smpc.OREG[8]=0x00; //Cartridge code?
|
||||
|
||||
state->m_smpc.OREG[9] = state->m_saturn_region;
|
||||
m_smpc.OREG[9] = m_saturn_region;
|
||||
|
||||
state->m_smpc.OREG[10]= 0 << 7 |
|
||||
state->m_vdp2.dotsel << 6 |
|
||||
m_smpc.OREG[10]= 0 << 7 |
|
||||
m_vdp2.dotsel << 6 |
|
||||
1 << 5 |
|
||||
1 << 4 |
|
||||
0 << 3 | //MSHNMI
|
||||
1 << 2 |
|
||||
0 << 1 | //SYSRES
|
||||
0 << 0; //SOUNDRES
|
||||
state->m_smpc.OREG[11]= 0 << 6; //CDRES
|
||||
m_smpc.OREG[11]= 0 << 6; //CDRES
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
state->m_smpc.OREG[12+i]=state->m_smpc.SMEM[i];
|
||||
m_smpc.OREG[12+i]=m_smpc.SMEM[i];
|
||||
|
||||
for(i=0;i<15;i++)
|
||||
state->m_smpc.OREG[16+i]=0xff; // undefined
|
||||
m_smpc.OREG[16+i]=0xff; // undefined
|
||||
}
|
||||
|
||||
state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
state->m_smpc.SR = 0x40 | state->m_smpc.intback_stage << 5;
|
||||
state->m_smpc.pmode = state->m_smpc.intback_buf[0]>>4;
|
||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
m_smpc.SR = 0x40 | m_smpc.intback_stage << 5;
|
||||
m_smpc.pmode = m_smpc.intback_buf[0]>>4;
|
||||
|
||||
if(!(state->m_scu.ism & IRQ_SMPC))
|
||||
state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
state->m_scu.ist |= (IRQ_SMPC);
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
|
||||
/* put issued command in OREG31 */
|
||||
state->m_smpc.OREG[31] = 0x10;
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
/* clear hand-shake flag */
|
||||
state->m_smpc.SF = 0x00;
|
||||
m_smpc.SF = 0x00;
|
||||
}
|
||||
else if(state->m_smpc.intback_buf[1] & 8)
|
||||
else if(m_smpc.intback_buf[1] & 8)
|
||||
{
|
||||
state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
state->m_smpc.SR = 0x40;
|
||||
state->m_smpc.OREG[31] = 0x10;
|
||||
machine.scheduler().timer_set(attotime::from_usec(0), FUNC(intback_peripheral),0);
|
||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
m_smpc.SR = 0x40;
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("SMPC intback bogus behaviour called %02x %02x\n",state->m_smpc.IREG[0],state->m_smpc.IREG[1]);
|
||||
printf("SMPC intback bogus behaviour called %02x %02x\n",m_smpc.IREG[0],m_smpc.IREG[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void smpc_rtc_write(running_machine &machine)
|
||||
void saturn_state::smpc_rtc_write()
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
int i;
|
||||
|
||||
for(i=0;i<7;i++)
|
||||
state->m_smpc.rtc_data[i] = state->m_smpc.IREG[i];
|
||||
m_smpc.rtc_data[i] = m_smpc.IREG[i];
|
||||
}
|
||||
|
||||
static void smpc_memory_setting(running_machine &machine)
|
||||
void saturn_state::smpc_memory_setting()
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
int i;
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
state->m_smpc.SMEM[i] = state->m_smpc.IREG[i];
|
||||
m_smpc.SMEM[i] = m_smpc.IREG[i];
|
||||
}
|
||||
|
||||
static void smpc_nmi_req(running_machine &machine)
|
||||
void saturn_state::smpc_nmi_req()
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
|
||||
/*NMI is unconditionally requested */
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( smpc_nmi_set )
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_nmi_set )
|
||||
{
|
||||
saturn_state *state = machine.driver_data<saturn_state>();
|
||||
// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
|
||||
// printf("%d %d\n",machine.first_screen()->hpos(),machine.first_screen()->vpos());
|
||||
state->m_NMI_reset = param;
|
||||
m_NMI_reset = param;
|
||||
/* put issued command in OREG31 */
|
||||
state->m_smpc.OREG[31] = 0x19 + param;
|
||||
m_smpc.OREG[31] = 0x19 + param;
|
||||
/* clear hand-shake flag */
|
||||
state->m_smpc.SF = 0x00;
|
||||
m_smpc.SF = 0x00;
|
||||
|
||||
//state->m_smpc.OREG[0] = (0x80) | ((state->m_NMI_reset & 1) << 6);
|
||||
//m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6);
|
||||
}
|
||||
|
||||
|
||||
@ -682,42 +652,40 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_audio_reset_line_pulse )
|
||||
*
|
||||
*******************************************/
|
||||
|
||||
static void smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv)
|
||||
void saturn_state::smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv)
|
||||
{
|
||||
saturn_state *state = space.machine().driver_data<saturn_state>();
|
||||
|
||||
switch (data)
|
||||
{
|
||||
case 0x00:
|
||||
if(LOG_SMPC) printf ("SMPC: Master ON\n");
|
||||
smpc_master_on(space.machine());
|
||||
smpc_master_on();
|
||||
break;
|
||||
//case 0x01: Master OFF?
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
if(LOG_SMPC) printf ("SMPC: Slave %s %d %d\n",(data & 1) ? "off" : "on",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos());
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(15), FUNC(smpc_slave_enable),data & 1);
|
||||
if(LOG_SMPC) printf ("SMPC: Slave %s %d %d\n",(data & 1) ? "off" : "on",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
machine().scheduler().timer_set(attotime::from_usec(15), timer_expired_delegate(FUNC(saturn_state::smpc_slave_enable),this),data & 1);
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
if(LOG_SMPC) printf ("SMPC: Sound %s\n",(data & 1) ? "off" : "on");
|
||||
|
||||
if(!is_stv)
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(15), FUNC(smpc_sound_enable),data & 1);
|
||||
machine().scheduler().timer_set(attotime::from_usec(15), timer_expired_delegate(FUNC(saturn_state::smpc_sound_enable),this),data & 1);
|
||||
break;
|
||||
/*CD (SH-1) ON/OFF */
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
printf ("SMPC: CD %s\n",(data & 1) ? "off" : "on");
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(20), FUNC(smpc_cd_enable),data & 1);
|
||||
machine().scheduler().timer_set(attotime::from_usec(20), timer_expired_delegate(FUNC(saturn_state::smpc_cd_enable),this),data & 1);
|
||||
break;
|
||||
case 0x0d:
|
||||
if(LOG_SMPC) printf ("SMPC: System Reset\n");
|
||||
smpc_system_reset(space.machine());
|
||||
smpc_system_reset();
|
||||
break;
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
if(LOG_SMPC) printf ("SMPC: Change Clock to %s (%d %d)\n",data & 1 ? "320" : "352",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos());
|
||||
if(LOG_SMPC) printf ("SMPC: Change Clock to %s (%d %d)\n",data & 1 ? "320" : "352",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
|
||||
/* on ST-V timing of this is pretty fussy, you get 2 credits at start-up otherwise
|
||||
My current theory is that SMPC first stops all CPUs until it executes the whole snippet for this,
|
||||
@ -725,29 +693,28 @@ static void smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv)
|
||||
can do an usable mid-frame clock switching anyway.
|
||||
*/
|
||||
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
state->m_slave->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
state->m_audiocpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
m_audiocpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
|
||||
space.machine().scheduler().timer_set(space.machine().first_screen()->time_until_pos(state->get_vblank_start_position()*state->get_ystep_count(), 0), FUNC(smpc_change_clock),data & 1);
|
||||
machine().scheduler().timer_set(machine().first_screen()->time_until_pos(get_vblank_start_position()*get_ystep_count(), 0), timer_expired_delegate(FUNC(saturn_state::smpc_change_clock),this),data & 1);
|
||||
break;
|
||||
/*"Interrupt Back"*/
|
||||
case 0x10:
|
||||
if(0)
|
||||
{
|
||||
saturn_state *state = space.machine().driver_data<saturn_state>();
|
||||
printf ("SMPC: Status Acquire %02x %02x %02x %d\n",state->m_smpc.IREG[0],state->m_smpc.IREG[1],state->m_smpc.IREG[2],space.machine().first_screen()->vpos());
|
||||
printf ("SMPC: Status Acquire %02x %02x %02x %d\n",m_smpc.IREG[0],m_smpc.IREG[1],m_smpc.IREG[2],machine().first_screen()->vpos());
|
||||
}
|
||||
|
||||
int timing;
|
||||
|
||||
timing = 8;
|
||||
|
||||
if(state->m_smpc.IREG[0] != 0) // non-peripheral data
|
||||
if(m_smpc.IREG[0] != 0) // non-peripheral data
|
||||
timing += 8;
|
||||
|
||||
/* TODO: At vblank-out actually ... */
|
||||
if(state->m_smpc.IREG[1] & 8) // peripheral data
|
||||
if(m_smpc.IREG[1] & 8) // peripheral data
|
||||
timing += 700;
|
||||
|
||||
/* TODO: check if IREG[2] is setted to 0xf0 */
|
||||
@ -755,38 +722,38 @@ static void smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv)
|
||||
int i;
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
state->m_smpc.intback_buf[i] = state->m_smpc.IREG[i];
|
||||
m_smpc.intback_buf[i] = m_smpc.IREG[i];
|
||||
}
|
||||
|
||||
if(is_stv)
|
||||
{
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(timing), FUNC(stv_smpc_intback),0); //TODO: variable time
|
||||
machine().scheduler().timer_set(attotime::from_usec(timing), timer_expired_delegate(FUNC(saturn_state::stv_smpc_intback),this),0); //TODO: variable time
|
||||
}
|
||||
else
|
||||
{
|
||||
if(LOG_PAD_CMD) printf("INTBACK %02x %02x %d %d\n",state->m_smpc.IREG[0],state->m_smpc.IREG[1],space.machine().first_screen()->vpos(),(int)space.machine().first_screen()->frame_number());
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(timing), FUNC(saturn_smpc_intback),0); //TODO: is variable time correct?
|
||||
if(LOG_PAD_CMD) printf("INTBACK %02x %02x %d %d\n",m_smpc.IREG[0],m_smpc.IREG[1],machine().first_screen()->vpos(),(int)machine().first_screen()->frame_number());
|
||||
machine().scheduler().timer_set(attotime::from_usec(timing), timer_expired_delegate(FUNC(saturn_state::saturn_smpc_intback),this),0); //TODO: is variable time correct?
|
||||
}
|
||||
break;
|
||||
/* RTC write*/
|
||||
case 0x16:
|
||||
if(LOG_SMPC) printf("SMPC: RTC write\n");
|
||||
smpc_rtc_write(space.machine());
|
||||
smpc_rtc_write();
|
||||
break;
|
||||
/* SMPC memory setting*/
|
||||
case 0x17:
|
||||
if(LOG_SMPC) printf ("SMPC: memory setting\n");
|
||||
smpc_memory_setting(space.machine());
|
||||
smpc_memory_setting();
|
||||
break;
|
||||
case 0x18:
|
||||
if(LOG_SMPC) printf ("SMPC: NMI request\n");
|
||||
smpc_nmi_req(space.machine());
|
||||
smpc_nmi_req();
|
||||
break;
|
||||
case 0x19:
|
||||
case 0x1a:
|
||||
/* TODO: timing */
|
||||
if(LOG_SMPC) printf ("SMPC: NMI %sable %d %d\n",data & 1 ? "Dis" : "En",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos());
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(100), FUNC(smpc_nmi_set),data & 1);
|
||||
if(LOG_SMPC) printf ("SMPC: NMI %sable %d %d\n",data & 1 ? "Dis" : "En",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_nmi_set),this),data & 1);
|
||||
break;
|
||||
default:
|
||||
printf ("cpu '%s' (PC=%08X) SMPC: undocumented Command %02x\n", space.device().tag(), space.device().safe_pc(), data);
|
||||
@ -799,60 +766,57 @@ static void smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv)
|
||||
*
|
||||
*******************************************/
|
||||
|
||||
READ8_HANDLER( stv_SMPC_r )
|
||||
READ8_MEMBER( saturn_state::stv_SMPC_r )
|
||||
{
|
||||
saturn_state *state = space.machine().driver_data<saturn_state>();
|
||||
int return_data = 0;
|
||||
|
||||
if(!(offset & 1))
|
||||
return 0;
|
||||
|
||||
if(offset >= 0x21 && offset <= 0x5f)
|
||||
return_data = state->m_smpc.OREG[(offset-0x21) >> 1];
|
||||
return_data = m_smpc.OREG[(offset-0x21) >> 1];
|
||||
|
||||
if (offset == 0x61) // TODO: SR
|
||||
return_data = state->m_smpc.SR;
|
||||
return_data = m_smpc.SR;
|
||||
|
||||
if (offset == 0x63)
|
||||
return_data = state->m_smpc.SF;
|
||||
return_data = m_smpc.SF;
|
||||
|
||||
if (offset == 0x75)//PDR1 read
|
||||
return_data = state->ioport("DSW1")->read();
|
||||
return_data = ioport("DSW1")->read();
|
||||
|
||||
if (offset == 0x77)//PDR2 read
|
||||
return_data = (0xfe | state->m_eeprom->do_read());
|
||||
return_data = (0xfe | m_eeprom->do_read());
|
||||
|
||||
return return_data;
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( stv_SMPC_w )
|
||||
WRITE8_MEMBER( saturn_state::stv_SMPC_w )
|
||||
{
|
||||
saturn_state *state = space.machine().driver_data<saturn_state>();
|
||||
|
||||
if (!(offset & 1)) // avoid writing to even bytes
|
||||
return;
|
||||
|
||||
// if(LOG_SMPC) printf ("8-bit SMPC Write to Offset %02x with Data %02x\n", offset, data);
|
||||
|
||||
if(offset >= 1 && offset <= 0xd)
|
||||
state->m_smpc.IREG[offset >> 1] = data;
|
||||
m_smpc.IREG[offset >> 1] = data;
|
||||
|
||||
if(offset == 1) //IREG0, check if a BREAK / CONTINUE request for INTBACK command
|
||||
{
|
||||
if(state->m_smpc.intback_stage)
|
||||
if(m_smpc.intback_stage)
|
||||
{
|
||||
if(data & 0x40)
|
||||
{
|
||||
if(LOG_PAD_CMD) printf("SMPC: BREAK request\n");
|
||||
state->m_smpc.SR &= 0x0f;
|
||||
state->m_smpc.intback_stage = 0;
|
||||
m_smpc.SR &= 0x0f;
|
||||
m_smpc.intback_stage = 0;
|
||||
}
|
||||
else if(data & 0x80)
|
||||
{
|
||||
if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n");
|
||||
space.machine().scheduler().timer_set(attotime::from_usec(700), FUNC(stv_intback_peripheral),0); /* TODO: is timing correct? */
|
||||
state->m_smpc.OREG[31] = 0x10;
|
||||
state->m_smpc.SF = 0x01; //TODO: set hand-shake flag?
|
||||
machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0); /* TODO: is timing correct? */
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
m_smpc.SF = 0x01; //TODO: set hand-shake flag?
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -864,14 +828,14 @@ WRITE8_HANDLER( stv_SMPC_w )
|
||||
// we've processed the command, clear status flag
|
||||
if(data != 0x10 && data != 0x02 && data != 0x03 && data != 0x08 && data != 0x09 && data != 0xe && data != 0xf && data != 0x19 && data != 0x1a)
|
||||
{
|
||||
state->m_smpc.OREG[31] = data; //read-back command
|
||||
state->m_smpc.SF = 0x00;
|
||||
m_smpc.OREG[31] = data; //read-back command
|
||||
m_smpc.SF = 0x00;
|
||||
}
|
||||
/*TODO:emulate the timing of each command...*/
|
||||
}
|
||||
|
||||
if(offset == 0x63)
|
||||
state->m_smpc.SF = data & 1;
|
||||
m_smpc.SF = data & 1;
|
||||
|
||||
if(offset == 0x75)
|
||||
{
|
||||
@ -882,14 +846,14 @@ WRITE8_HANDLER( stv_SMPC_w )
|
||||
---- -x-- EEPROM CS line
|
||||
---- --xx A-Bus bank bits
|
||||
*/
|
||||
state->m_eeprom->clk_write((data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
|
||||
state->m_eeprom->di_write((data >> 4) & 1);
|
||||
state->m_eeprom->cs_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE);
|
||||
state->m_stv_multi_bank = data & 3;
|
||||
m_eeprom->clk_write((data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_eeprom->di_write((data >> 4) & 1);
|
||||
m_eeprom->cs_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_stv_multi_bank = data & 3;
|
||||
|
||||
stv_select_game(space.machine(), state->m_stv_multi_bank);
|
||||
stv_select_game(m_stv_multi_bank);
|
||||
|
||||
state->m_smpc.PDR1 = (data & 0x60);
|
||||
m_smpc.PDR1 = (data & 0x60);
|
||||
}
|
||||
|
||||
if(offset == 0x77)
|
||||
@ -898,15 +862,15 @@ WRITE8_HANDLER( stv_SMPC_w )
|
||||
-xx- ---- PDR2
|
||||
---x ---- Enable Sound System (ACTIVE LOW)
|
||||
*/
|
||||
//popmessage("PDR2 = %02x",state->m_smpc_ram[0x77]);
|
||||
//popmessage("PDR2 = %02x",m_smpc_ram[0x77]);
|
||||
|
||||
if(LOG_SMPC) printf("SMPC: M68k %s\n",(data & 0x10) ? "off" : "on");
|
||||
//space.machine().scheduler().timer_set(attotime::from_usec(100), FUNC(smpc_sound_enable),(state->m_smpc_ram[0x77] & 0x10) >> 4);
|
||||
state->m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
|
||||
state->m_en_68k = ((data & 0x10) >> 4) ^ 1;
|
||||
//machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_sound_enable),this),(m_smpc_ram[0x77] & 0x10) >> 4);
|
||||
m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_en_68k = ((data & 0x10) >> 4) ^ 1;
|
||||
|
||||
//if(LOG_SMPC) printf("SMPC: ram [0x77] = %02x\n",data);
|
||||
state->m_smpc.PDR2 = (data & 0x60);
|
||||
m_smpc.PDR2 = (data & 0x60);
|
||||
}
|
||||
|
||||
if(offset == 0x7d)
|
||||
@ -915,15 +879,15 @@ WRITE8_HANDLER( stv_SMPC_w )
|
||||
---- --x- IOSEL2 direct (1) / control mode (0) port select
|
||||
---- ---x IOSEL1 direct (1) / control mode (0) port select
|
||||
*/
|
||||
state->m_smpc.IOSEL1 = (data & 1) >> 0;
|
||||
state->m_smpc.IOSEL2 = (data & 2) >> 1;
|
||||
m_smpc.IOSEL1 = (data & 1) >> 0;
|
||||
m_smpc.IOSEL2 = (data & 2) >> 1;
|
||||
}
|
||||
|
||||
if(offset == 0x7f)
|
||||
{
|
||||
//enable PAD irq & VDP2 external latch for port 1/2
|
||||
state->m_smpc.EXLE1 = (data & 1) >> 0;
|
||||
state->m_smpc.EXLE2 = (data & 2) >> 1;
|
||||
m_smpc.EXLE1 = (data & 1) >> 0;
|
||||
m_smpc.EXLE2 = (data & 2) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1001,7 +965,7 @@ READ8_MEMBER( saturn_state::saturn_SMPC_r )
|
||||
|
||||
if (offset == 0x63)
|
||||
{
|
||||
//printf("SF %d %d\n",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos());
|
||||
//printf("SF %d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
return_data = m_smpc.SF;
|
||||
}
|
||||
|
||||
@ -1060,7 +1024,7 @@ WRITE8_MEMBER( saturn_state::saturn_SMPC_w )
|
||||
else if(data & 0x80)
|
||||
{
|
||||
if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n");
|
||||
machine().scheduler().timer_set(attotime::from_usec(700), FUNC(intback_peripheral),0); /* TODO: is timing correct? */
|
||||
machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0); /* TODO: is timing correct? */
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
m_smpc.SF = 0x01; //TODO: set hand-shake flag?
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
DECLARE_WRITE8_HANDLER( stv_SMPC_w );
|
||||
DECLARE_READ8_HANDLER( stv_SMPC_r );
|
||||
DECLARE_WRITE8_HANDLER( saturn_SMPC_w );
|
||||
DECLARE_READ8_HANDLER( saturn_SMPC_r );
|
||||
// TODO: make separate device when code is decoupled better
|
||||
//DECLARE_WRITE8_MEMBER( stv_SMPC_w );
|
||||
//DECLARE_READ8_MEMBER( stv_SMPC_r );
|
||||
//DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
|
||||
//DECLARE_READ8_MEMBER( saturn_SMPC_r );
|
||||
|
@ -429,12 +429,12 @@ READ32_MEMBER ( saturn_state::saturn_vdp1_framebuffer0_r )
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
WRITE32_HANDLER ( saturn_vdp1_framebuffer1_w )
|
||||
WRITE32_MEMBER ( saturn_state::saturn_vdp1_framebuffer1_w )
|
||||
{
|
||||
//popmessage ("STV VDP1 Framebuffer 1 WRITE offset %08x data %08x",offset, data);
|
||||
}
|
||||
|
||||
READ32_HANDLER ( saturn_vdp1_framebuffer1_r )
|
||||
READ32_MEMBER ( saturn_state::saturn_vdp1_framebuffer1_r )
|
||||
{
|
||||
//popmessage ("STV VDP1 Framebuffer 1 READ offset %08x",offset);
|
||||
return 0xffff;
|
||||
|
@ -927,7 +927,7 @@ static const sh2_cpu_core sh2_conf_slave = { 1, NULL };
|
||||
|
||||
static ADDRESS_MAP_START( stv_mem, AS_PROGRAM, 32, stv_state )
|
||||
AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios
|
||||
AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8_LEGACY(stv_SMPC_r, stv_SMPC_w,0xffffffff)
|
||||
AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(stv_SMPC_r, stv_SMPC_w,0xffffffff)
|
||||
AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r,saturn_backupram_w,0xffffffff) AM_SHARE("share1")
|
||||
AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("workram_l")
|
||||
// AM_RANGE(0x00400000, 0x0040001f) AM_READWRITE(stv_ioga_r32, stv_io_w32) AM_SHARE("ioga") AM_MIRROR(0x20) /* installed with per-game specific */
|
||||
|
@ -645,6 +645,34 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER(scudsp_end_w);
|
||||
DECLARE_READ16_MEMBER(scudsp_dma_r);
|
||||
DECLARE_WRITE16_MEMBER(scudsp_dma_w);
|
||||
|
||||
// FROM smpc.c
|
||||
TIMER_CALLBACK_MEMBER( stv_bankswitch_state );
|
||||
void stv_select_game(int gameno);
|
||||
void smpc_master_on();
|
||||
TIMER_CALLBACK_MEMBER( smpc_slave_enable );
|
||||
TIMER_CALLBACK_MEMBER( smpc_sound_enable );
|
||||
TIMER_CALLBACK_MEMBER( smpc_cd_enable );
|
||||
void smpc_system_reset();
|
||||
TIMER_CALLBACK_MEMBER( smpc_change_clock );
|
||||
TIMER_CALLBACK_MEMBER( stv_intback_peripheral );
|
||||
TIMER_CALLBACK_MEMBER( stv_smpc_intback );
|
||||
void smpc_digital_pad(UINT8 pad_num, UINT8 offset);
|
||||
void smpc_analog_pad(UINT8 pad_num, UINT8 offset, UINT8 id);
|
||||
void smpc_keyboard(UINT8 pad_num, UINT8 offset);
|
||||
void smpc_mouse(UINT8 pad_num, UINT8 offset, UINT8 id);
|
||||
void smpc_md_pad(UINT8 pad_num, UINT8 offset, UINT8 id);
|
||||
void smpc_unconnected(UINT8 pad_num, UINT8 offset);
|
||||
TIMER_CALLBACK_MEMBER( intback_peripheral );
|
||||
TIMER_CALLBACK_MEMBER( saturn_smpc_intback );
|
||||
void smpc_rtc_write();
|
||||
void smpc_memory_setting();
|
||||
void smpc_nmi_req();
|
||||
TIMER_CALLBACK_MEMBER( smpc_nmi_set );
|
||||
void smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv);
|
||||
DECLARE_READ8_MEMBER( stv_SMPC_r );
|
||||
DECLARE_WRITE8_MEMBER( stv_SMPC_w );
|
||||
|
||||
};
|
||||
|
||||
class stv_state : public saturn_state
|
||||
|
Loading…
Reference in New Issue
Block a user