smpc moved to state, need to be device-fied in future (nw)

This commit is contained in:
Miodrag Milanovic 2014-04-03 08:08:38 +00:00
parent 1b5f24add6
commit 5e99f6e4c8
5 changed files with 294 additions and 301 deletions

View File

@ -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?
}

View File

@ -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 );

View File

@ -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;

View File

@ -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 */

View File

@ -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