(MESS)sms.c: Getting rid of some static functions (nw)

This commit is contained in:
Wilbert Pol 2013-01-20 20:35:40 +00:00
parent 18a0b2a85a
commit e0b0d2cf8b
2 changed files with 214 additions and 233 deletions

View File

@ -27,17 +27,28 @@ public:
public: public:
sms_state(const machine_config &mconfig, device_type type, const char *tag) sms_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) : driver_device(mconfig, type, tag)
, m_main_cpu(*this, "maincpu")
, m_control_cpu(*this, "control")
, m_vdp(*this, "sms_vdp")
, m_main_scr(*this, "screen")
, m_is_gamegear(0)
, m_is_region_japan(0)
, m_has_bios_0400(0)
, m_has_bios_2000(0)
, m_has_bios_full(0)
, m_has_bios(0)
, m_has_fm(0)
, m_mainram(*this, "mainram") , m_mainram(*this, "mainram")
{ {
} }
// device_ts // device_ts
device_t *m_main_cpu; required_device<cpu_device> m_main_cpu;
device_t *m_control_cpu; optional_device<cpu_device> m_control_cpu;
sega315_5124_device *m_vdp; required_device<sega315_5124_device> m_vdp;
eeprom_device *m_eeprom; eeprom_device *m_eeprom;
device_t *m_ym; device_t *m_ym;
device_t *m_main_scr; required_device<screen_device> m_main_scr;
device_t *m_left_lcd; device_t *m_left_lcd;
device_t *m_right_lcd; device_t *m_right_lcd;
address_space *m_space; address_space *m_space;
@ -200,6 +211,19 @@ public:
protected: protected:
required_shared_ptr<UINT8> m_mainram; required_shared_ptr<UINT8> m_mainram;
void setup_rom();
void vdp_hcount_lphaser(int hpos);
void lphaser1_sensor_check();
void lphaser2_sensor_check();
UINT16 screen_hpos_nonscaled(int scaled_hpos);
UINT16 screen_vpos_nonscaled(int scaled_vpos);
int lgun_bright_aim_area(emu_timer *timer, int lgun_x, int lgun_y);
void sms_vdp_hcount_latch(address_space &space);
UINT8 sms_vdp_hcount();
void setup_cart_banks();
void setup_banks();
void sms_get_inputs(address_space &space);
}; };

View File

@ -27,9 +27,6 @@
#define LGUN_X_INTERVAL 4 #define LGUN_X_INTERVAL 4
static void setup_rom(address_space &space);
TIMER_CALLBACK_MEMBER(sms_state::rapid_fire_callback) TIMER_CALLBACK_MEMBER(sms_state::rapid_fire_callback)
{ {
m_rapid_fire_state_1 ^= 0xff; m_rapid_fire_state_1 ^= 0xff;
@ -285,14 +282,13 @@ WRITE8_MEMBER(sms_state::sms_input_write)
/* FIXME: this function is a hack for Light Phaser emulation. Theoretically /* FIXME: this function is a hack for Light Phaser emulation. Theoretically
sms_vdp_hcount_latch() should be used instead, but it returns incorrect sms_vdp_hcount_latch() should be used instead, but it returns incorrect
position for unknown reason (timing?) */ position for unknown reason (timing?) */
static void sms_vdp_hcount_lphaser( running_machine &machine, int hpos ) void sms_state::vdp_hcount_lphaser( int hpos )
{ {
sms_state *state = machine.driver_data<sms_state>(); int hpos_tmp = hpos + m_lphaser_x_offs;
int hpos_tmp = hpos + state->m_lphaser_x_offs;
UINT8 tmp = ((hpos_tmp - 46) >> 1) & 0xff; UINT8 tmp = ((hpos_tmp - 46) >> 1) & 0xff;
//printf ("sms_vdp_hcount_lphaser: hpos %3d hpos_tmp %3d => hcount %2X\n", hpos, hpos_tmp, tmp); //printf ("sms_vdp_hcount_lphaser: hpos %3d hpos_tmp %3d => hcount %2X\n", hpos, hpos_tmp, tmp);
state->m_vdp->hcount_latch_write(*state->m_space, 0, tmp); m_vdp->hcount_latch_write(*m_space, 0, tmp);
} }
@ -318,14 +314,12 @@ static void sms_vdp_hcount_lphaser( running_machine &machine, int hpos )
- The whole procedure is managed by a timer callback, that always reschedule - The whole procedure is managed by a timer callback, that always reschedule
itself to run in some intervals when the beam is at the circular area. itself to run in some intervals when the beam is at the circular area.
*/ */
static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int lgun_x, int lgun_y ) int sms_state::lgun_bright_aim_area( emu_timer *timer, int lgun_x, int lgun_y )
{ {
sms_state *state = machine.driver_data<sms_state>();
const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; const int r_x_r = LGUN_RADIUS * LGUN_RADIUS;
screen_device *screen = machine.first_screen(); const rectangle &visarea = m_main_scr->visible_area();
const rectangle &visarea = screen->visible_area(); int beam_x = m_main_scr->hpos();
int beam_x = screen->hpos(); int beam_y = m_main_scr->vpos();
int beam_y = screen->vpos();
int dx, dy; int dx, dy;
int result = 0; int result = 0;
int pos_changed = 0; int pos_changed = 0;
@ -365,7 +359,7 @@ static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int
if (!pos_changed) if (!pos_changed)
{ {
bitmap_rgb32 &bitmap = state->m_vdp->get_bitmap(); bitmap_rgb32 &bitmap = m_vdp->get_bitmap();
/* brightness of the lightgray color in the frame drawn by Light Phaser games */ /* brightness of the lightgray color in the frame drawn by Light Phaser games */
const UINT8 sensor_min_brightness = 0x7f; const UINT8 sensor_min_brightness = 0x7f;
@ -390,16 +384,15 @@ static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int
else else
break; break;
} }
timer->adjust(machine.first_screen()->time_until_pos(beam_y, beam_x)); timer->adjust(m_main_scr->time_until_pos(beam_y, beam_x));
return result; return result;
} }
static UINT8 sms_vdp_hcount( running_machine &machine ) UINT8 sms_state::sms_vdp_hcount()
{ {
UINT8 tmp; UINT8 tmp;
screen_device *screen = machine.first_screen(); int hpos = m_main_scr->hpos();
int hpos = screen->hpos();
/* alternative method: pass HCounter test, but some others fail */ /* alternative method: pass HCounter test, but some others fail */
//int hpos_tmp = hpos; //int hpos_tmp = hpos;
@ -408,14 +401,14 @@ static UINT8 sms_vdp_hcount( running_machine &machine )
UINT64 calc_cycles; UINT64 calc_cycles;
attotime time_end; attotime time_end;
int vpos = screen->vpos(); int vpos = m_main_scr->vpos();
int max_hpos = screen->width() - 1; int max_hpos = m_main_scr->width() - 1;
if (hpos == max_hpos) if (hpos == max_hpos)
time_end = attotime::zero; time_end = attotime::zero;
else else
time_end = screen->time_until_pos(vpos, max_hpos); time_end = m_main_scr->time_until_pos(vpos, max_hpos);
calc_cycles = machine.device<cpu_device>("maincpu")->attotime_to_clocks(time_end); calc_cycles = m_main_cpu->attotime_to_clocks(time_end);
/* equation got from SMSPower forum, posted by Flubba. */ /* equation got from SMSPower forum, posted by Flubba. */
tmp = ((590 - (calc_cycles * 3)) / 4) & 0xff; tmp = ((590 - (calc_cycles * 3)) / 4) & 0xff;
@ -425,59 +418,56 @@ static UINT8 sms_vdp_hcount( running_machine &machine )
} }
static void sms_vdp_hcount_latch( address_space &space ) void sms_state::sms_vdp_hcount_latch( address_space &space )
{ {
sms_state *state = space.machine().driver_data<sms_state>(); UINT8 value = sms_vdp_hcount();
UINT8 value = sms_vdp_hcount(space.machine());
state->m_vdp->hcount_latch_write(space, 0, value); m_vdp->hcount_latch_write(space, 0, value);
} }
static UINT16 screen_hpos_nonscaled( screen_device &screen, int scaled_hpos ) UINT16 sms_state::screen_hpos_nonscaled(int scaled_hpos)
{ {
const rectangle &visarea = screen.visible_area(); const rectangle &visarea = m_main_scr->visible_area();
int offset_x = (scaled_hpos * visarea.width()) / 255; int offset_x = (scaled_hpos * visarea.width()) / 255;
return visarea.min_x + offset_x; return visarea.min_x + offset_x;
} }
static UINT16 screen_vpos_nonscaled( screen_device &screen, int scaled_vpos ) UINT16 sms_state::screen_vpos_nonscaled(int scaled_vpos)
{ {
const rectangle &visarea = screen.visible_area(); const rectangle &visarea = m_main_scr->visible_area();
int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255; int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255;
return visarea.min_y + offset_y; return visarea.min_y + offset_y;
} }
static void lphaser1_sensor_check( running_machine &machine ) void sms_state::lphaser1_sensor_check()
{ {
sms_state *state = machine.driver_data<sms_state>(); const int x = screen_hpos_nonscaled( ioport("LPHASER0")->read() );
const int x = screen_hpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER0")->read()); const int y = screen_vpos_nonscaled( ioport("LPHASER1")->read() );
const int y = screen_vpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER1")->read());
if (lgun_bright_aim_area(machine, state->m_lphaser_1_timer, x, y)) if (lgun_bright_aim_area(m_lphaser_1_timer, x, y))
{ {
if (state->m_lphaser_1_latch == 0) if (m_lphaser_1_latch == 0)
{ {
state->m_lphaser_1_latch = 1; m_lphaser_1_latch = 1;
sms_vdp_hcount_lphaser(machine, x); vdp_hcount_lphaser(x);
} }
} }
} }
static void lphaser2_sensor_check( running_machine &machine ) void sms_state::lphaser2_sensor_check()
{ {
sms_state *state = machine.driver_data<sms_state>(); const int x = screen_hpos_nonscaled( ioport("LPHASER2")->read() );
const int x = screen_hpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER2")->read()); const int y = screen_vpos_nonscaled( ioport("LPHASER3")->read() );
const int y = screen_vpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER3")->read());
if (lgun_bright_aim_area(machine, state->m_lphaser_2_timer, x, y)) if (lgun_bright_aim_area(m_lphaser_2_timer, x, y))
{ {
if (state->m_lphaser_2_latch == 0) if (m_lphaser_2_latch == 0)
{ {
state->m_lphaser_2_latch = 1; m_lphaser_2_latch = 1;
sms_vdp_hcount_lphaser(machine, x); vdp_hcount_lphaser(x);
} }
} }
} }
@ -492,7 +482,7 @@ TIMER_CALLBACK_MEMBER(sms_state::lightgun_tick)
/* enable crosshair */ /* enable crosshair */
crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL);
if (!m_lphaser_1_timer->enabled()) if (!m_lphaser_1_timer->enabled())
lphaser1_sensor_check(machine()); lphaser1_sensor_check();
} }
else else
{ {
@ -506,7 +496,7 @@ TIMER_CALLBACK_MEMBER(sms_state::lightgun_tick)
/* enable crosshair */ /* enable crosshair */
crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL);
if (!m_lphaser_2_timer->enabled()) if (!m_lphaser_2_timer->enabled())
lphaser2_sensor_check(machine()); lphaser2_sensor_check();
} }
else else
{ {
@ -519,175 +509,173 @@ TIMER_CALLBACK_MEMBER(sms_state::lightgun_tick)
TIMER_CALLBACK_MEMBER(sms_state::lphaser_1_callback) TIMER_CALLBACK_MEMBER(sms_state::lphaser_1_callback)
{ {
lphaser1_sensor_check(machine()); lphaser1_sensor_check();
} }
TIMER_CALLBACK_MEMBER(sms_state::lphaser_2_callback) TIMER_CALLBACK_MEMBER(sms_state::lphaser_2_callback)
{ {
lphaser2_sensor_check(machine()); lphaser2_sensor_check();
} }
INPUT_CHANGED_MEMBER(sms_state::lgun1_changed) INPUT_CHANGED_MEMBER(sms_state::lgun1_changed)
{ {
if (!m_lphaser_1_timer || if (!m_lphaser_1_timer ||
(machine().root_device().ioport("CTRLSEL")->read_safe(0x00) & 0x0f) != 0x01) (ioport("CTRLSEL")->read_safe(0x00) & 0x0f) != 0x01)
return; return;
if (newval != oldval) if (newval != oldval)
lphaser1_sensor_check(machine()); lphaser1_sensor_check();
} }
INPUT_CHANGED_MEMBER(sms_state::lgun2_changed) INPUT_CHANGED_MEMBER(sms_state::lgun2_changed)
{ {
if (!m_lphaser_2_timer || if (!m_lphaser_2_timer ||
(machine().root_device().ioport("CTRLSEL")->read_safe(0x00) & 0xf0) != 0x10) (ioport("CTRLSEL")->read_safe(0x00) & 0xf0) != 0x10)
return; return;
if (newval != oldval) if (newval != oldval)
lphaser2_sensor_check(machine()); lphaser2_sensor_check();
} }
static void sms_get_inputs( address_space &space ) void sms_state::sms_get_inputs( address_space &space )
{ {
sms_state *state = space.machine().driver_data<sms_state>();
UINT8 data = 0x00; UINT8 data = 0x00;
UINT32 cpu_cycles = downcast<cpu_device *>(&space.device())->total_cycles(); UINT32 cpu_cycles = m_main_cpu->total_cycles();
running_machine &machine = space.machine();
state->m_input_port0 = 0xff; m_input_port0 = 0xff;
state->m_input_port1 = 0xff; m_input_port1 = 0xff;
if (cpu_cycles - state->m_last_paddle_read_time > 256) if (cpu_cycles - m_last_paddle_read_time > 256)
{ {
state->m_paddle_read_state ^= 0xff; m_paddle_read_state ^= 0xff;
state->m_last_paddle_read_time = cpu_cycles; m_last_paddle_read_time = cpu_cycles;
} }
/* Check if lightgun has been chosen as input: if so, enable crosshair */ /* Check if lightgun has been chosen as input: if so, enable crosshair */
machine.scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sms_state::lightgun_tick),state)); machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sms_state::lightgun_tick),this));
/* Player 1 */ /* Player 1 */
switch (machine.root_device().ioport("CTRLSEL")->read_safe(0x00) & 0x0f) switch (ioport("CTRLSEL")->read_safe(0x00) & 0x0f)
{ {
case 0x00: /* Joystick */ case 0x00: /* Joystick */
data = machine.root_device().ioport("PORT_DC")->read(); data = ioport("PORT_DC")->read();
/* Check Rapid Fire setting for Button A */ /* Check Rapid Fire setting for Button A */
if (!(data & 0x10) && (machine.root_device().ioport("RFU")->read() & 0x01)) if (!(data & 0x10) && (ioport("RFU")->read() & 0x01))
data |= state->m_rapid_fire_state_1 & 0x10; data |= m_rapid_fire_state_1 & 0x10;
/* Check Rapid Fire setting for Button B */ /* Check Rapid Fire setting for Button B */
if (!(data & 0x20) && (machine.root_device().ioport("RFU")->read() & 0x02)) if (!(data & 0x20) && (ioport("RFU")->read() & 0x02))
data |= state->m_rapid_fire_state_1 & 0x20; data |= m_rapid_fire_state_1 & 0x20;
state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f); m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f);
break; break;
case 0x01: /* Light Phaser */ case 0x01: /* Light Phaser */
data = (machine.root_device().ioport("CTRLIPT")->read() & 0x01) << 4; data = (ioport("CTRLIPT")->read() & 0x01) << 4;
if (!(data & 0x10)) if (!(data & 0x10))
{ {
if (machine.root_device().ioport("RFU")->read() & 0x01) if (ioport("RFU")->read() & 0x01)
data |= state->m_rapid_fire_state_1 & 0x10; data |= m_rapid_fire_state_1 & 0x10;
} }
/* just consider the button (trigger) bit */ /* just consider the button (trigger) bit */
data |= ~0x10; data |= ~0x10;
state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f); m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f);
break; break;
case 0x02: /* Paddle Control */ case 0x02: /* Paddle Control */
/* Get button A state */ /* Get button A state */
data = machine.root_device().ioport("PADDLE0")->read(); data = ioport("PADDLE0")->read();
if (state->m_paddle_read_state) if (m_paddle_read_state)
data = data >> 4; data = data >> 4;
state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x0f) | (state->m_paddle_read_state & 0x20) m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x0f) | (m_paddle_read_state & 0x20)
| ((machine.root_device().ioport("CTRLIPT")->read() & 0x02) << 3); | ((ioport("CTRLIPT")->read() & 0x02) << 3);
break; break;
case 0x04: /* Sega Sports Pad */ case 0x04: /* Sega Sports Pad */
switch (state->m_sports_pad_state_1) switch (m_sports_pad_state_1)
{ {
case 0: case 0:
data = (state->m_sports_pad_1_x >> 4) & 0x0f; data = (m_sports_pad_1_x >> 4) & 0x0f;
break; break;
case 1: case 1:
data = state->m_sports_pad_1_x & 0x0f; data = m_sports_pad_1_x & 0x0f;
break; break;
case 2: case 2:
data = (state->m_sports_pad_1_y >> 4) & 0x0f; data = (m_sports_pad_1_y >> 4) & 0x0f;
break; break;
case 3: case 3:
data = state->m_sports_pad_1_y & 0x0f; data = m_sports_pad_1_y & 0x0f;
break; break;
} }
state->m_input_port0 = (state->m_input_port0 & 0xc0) | data | ((machine.root_device().ioport("CTRLIPT")->read() & 0x0c) << 2); m_input_port0 = (m_input_port0 & 0xc0) | data | ((ioport("CTRLIPT")->read() & 0x0c) << 2);
break; break;
} }
/* Player 2 */ /* Player 2 */
switch (machine.root_device().ioport("CTRLSEL")->read_safe(0x00) & 0xf0) switch (ioport("CTRLSEL")->read_safe(0x00) & 0xf0)
{ {
case 0x00: /* Joystick */ case 0x00: /* Joystick */
data = machine.root_device().ioport("PORT_DC")->read(); data = ioport("PORT_DC")->read();
state->m_input_port0 = (state->m_input_port0 & 0x3f) | (data & 0xc0); m_input_port0 = (m_input_port0 & 0x3f) | (data & 0xc0);
data = machine.root_device().ioport("PORT_DD")->read(); data = ioport("PORT_DD")->read();
/* Check Rapid Fire setting for Button A */ /* Check Rapid Fire setting for Button A */
if (!(data & 0x04) && (machine.root_device().ioport("RFU")->read() & 0x04)) if (!(data & 0x04) && (ioport("RFU")->read() & 0x04))
data |= state->m_rapid_fire_state_2 & 0x04; data |= m_rapid_fire_state_2 & 0x04;
/* Check Rapid Fire setting for Button B */ /* Check Rapid Fire setting for Button B */
if (!(data & 0x08) && (machine.root_device().ioport("RFU")->read() & 0x08)) if (!(data & 0x08) && (ioport("RFU")->read() & 0x08))
data |= state->m_rapid_fire_state_2 & 0x08; data |= m_rapid_fire_state_2 & 0x08;
state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f); m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f);
break; break;
case 0x10: /* Light Phaser */ case 0x10: /* Light Phaser */
data = (machine.root_device().ioport("CTRLIPT")->read() & 0x10) >> 2; data = (ioport("CTRLIPT")->read() & 0x10) >> 2;
if (!(data & 0x04)) if (!(data & 0x04))
{ {
if (machine.root_device().ioport("RFU")->read() & 0x04) if (ioport("RFU")->read() & 0x04)
data |= state->m_rapid_fire_state_2 & 0x04; data |= m_rapid_fire_state_2 & 0x04;
} }
/* just consider the button (trigger) bit */ /* just consider the button (trigger) bit */
data |= ~0x04; data |= ~0x04;
state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f); m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f);
break; break;
case 0x20: /* Paddle Control */ case 0x20: /* Paddle Control */
/* Get button A state */ /* Get button A state */
data = machine.root_device().ioport("PADDLE1")->read(); data = ioport("PADDLE1")->read();
if (state->m_paddle_read_state) if (m_paddle_read_state)
data = data >> 4; data = data >> 4;
state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6); m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6);
state->m_input_port1 = (state->m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (state->m_paddle_read_state & 0x08) m_input_port1 = (m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (m_paddle_read_state & 0x08)
| ((machine.root_device().ioport("CTRLIPT")->read() & 0x20) >> 3); | ((ioport("CTRLIPT")->read() & 0x20) >> 3);
break; break;
case 0x40: /* Sega Sports Pad */ case 0x40: /* Sega Sports Pad */
switch (state->m_sports_pad_state_2) switch (m_sports_pad_state_2)
{ {
case 0: case 0:
data = state->m_sports_pad_2_x & 0x0f; data = m_sports_pad_2_x & 0x0f;
break; break;
case 1: case 1:
data = (state->m_sports_pad_2_x >> 4) & 0x0f; data = (m_sports_pad_2_x >> 4) & 0x0f;
break; break;
case 2: case 2:
data = state->m_sports_pad_2_y & 0x0f; data = m_sports_pad_2_y & 0x0f;
break; break;
case 3: case 3:
data = (state->m_sports_pad_2_y >> 4) & 0x0f; data = (m_sports_pad_2_y >> 4) & 0x0f;
break; break;
} }
state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6); m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6);
state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data >> 2) | ((machine.root_device().ioport("CTRLIPT")->read() & 0xc0) >> 4); m_input_port1 = (m_input_port1 & 0xf0) | (data >> 2) | ((ioport("CTRLIPT")->read() & 0xc0) >> 4);
break; break;
} }
} }
@ -774,7 +762,7 @@ WRITE_LINE_MEMBER(sms_state::sms_pause_callback)
{ {
if (!m_paused) if (!m_paused)
{ {
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); m_main_cpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
} }
m_paused = 1; m_paused = 1;
} }
@ -889,8 +877,6 @@ WRITE8_MEMBER(sms_state::sms_sscope_w)
if ( sscope ) if ( sscope )
{ {
// Scope is attached // Scope is attached
screen_device *screen = machine().first_screen();
m_sscope_state = data; m_sscope_state = data;
// There are occurrences when Sega Scope's state changes after VBLANK, or at // There are occurrences when Sega Scope's state changes after VBLANK, or at
@ -898,7 +884,7 @@ WRITE8_MEMBER(sms_state::sms_sscope_w)
// one exception is the first frame of Zaxxon 3-D's title screen. In that // one exception is the first frame of Zaxxon 3-D's title screen. In that
// case, this method is enough for setting the intended state for the frame. // case, this method is enough for setting the intended state for the frame.
// No information found about a minimum time need for switch open/closed lens. // No information found about a minimum time need for switch open/closed lens.
if (screen->vpos() < (screen->height() >> 1)) if (m_main_scr->vpos() < (m_main_scr->height() >> 1))
{ {
m_frame_sscope_state = m_sscope_state; m_frame_sscope_state = m_sscope_state;
} }
@ -1229,7 +1215,7 @@ WRITE8_MEMBER(sms_state::sms_bios_w)
logerror("bios write %02x, pc: %04x\n", data, space.device().safe_pc()); logerror("bios write %02x, pc: %04x\n", data, space.device().safe_pc());
setup_rom(space); setup_rom();
} }
@ -1363,28 +1349,26 @@ static void sms_machine_stop( running_machine &machine )
} }
static void setup_rom( address_space &space ) void sms_state::setup_rom()
{ {
sms_state *state = space.machine().driver_data<sms_state>();
/* 1. set up bank pointers to point to nothing */ /* 1. set up bank pointers to point to nothing */
state->membank("bank1")->set_base(state->m_banking_none); membank("bank1")->set_base(m_banking_none);
state->membank("bank2")->set_base(state->m_banking_none); membank("bank2")->set_base(m_banking_none);
state->membank("bank7")->set_base(state->m_banking_none); membank("bank7")->set_base(m_banking_none);
state->membank("bank3")->set_base(state->m_banking_none); membank("bank3")->set_base(m_banking_none);
state->membank("bank4")->set_base(state->m_banking_none); membank("bank4")->set_base(m_banking_none);
state->membank("bank5")->set_base(state->m_banking_none); membank("bank5")->set_base(m_banking_none);
state->membank("bank6")->set_base(state->m_banking_none); membank("bank6")->set_base(m_banking_none);
/* 2. check and set up expansion port */ /* 2. check and set up expansion port */
if (!(state->m_bios_port & IO_EXPANSION) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_CARD)) if (!(m_bios_port & IO_EXPANSION) && (m_bios_port & IO_CARTRIDGE) && (m_bios_port & IO_CARD))
{ {
/* TODO: Implement me */ /* TODO: Implement me */
logerror("Switching to unsupported expansion port.\n"); logerror("Switching to unsupported expansion port.\n");
} }
/* 3. check and set up card rom */ /* 3. check and set up card rom */
if (!(state->m_bios_port & IO_CARD) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_EXPANSION)) if (!(m_bios_port & IO_CARD) && (m_bios_port & IO_CARTRIDGE) && (m_bios_port & IO_EXPANSION))
{ {
/* TODO: Implement me */ /* TODO: Implement me */
logerror("Switching to unsupported card rom port.\n"); logerror("Switching to unsupported card rom port.\n");
@ -1393,51 +1377,51 @@ static void setup_rom( address_space &space )
/* 4. check and set up cartridge rom */ /* 4. check and set up cartridge rom */
/* if ((!(bios_port & IO_CARTRIDGE) && (bios_port & IO_EXPANSION) && (bios_port & IO_CARD)) || state->m_is_gamegear) { */ /* if ((!(bios_port & IO_CARTRIDGE) && (bios_port & IO_EXPANSION) && (bios_port & IO_CARD)) || state->m_is_gamegear) { */
/* Out Run Europa initially writes a value to port 3E where IO_CARTRIDGE, IO_EXPANSION and IO_CARD are reset */ /* Out Run Europa initially writes a value to port 3E where IO_CARTRIDGE, IO_EXPANSION and IO_CARD are reset */
if ((!(state->m_bios_port & IO_CARTRIDGE)) || state->m_is_gamegear) if ((!(m_bios_port & IO_CARTRIDGE)) || m_is_gamegear)
{ {
state->membank("bank1")->set_base(state->m_banking_cart[1]); membank("bank1")->set_base(m_banking_cart[1]);
state->membank("bank2")->set_base(state->m_banking_cart[2]); membank("bank2")->set_base(m_banking_cart[2]);
state->membank("bank7")->set_base(state->m_banking_cart[7]); membank("bank7")->set_base(m_banking_cart[7]);
state->membank("bank3")->set_base(state->m_banking_cart[3]); membank("bank3")->set_base(m_banking_cart[3]);
state->membank("bank4")->set_base(state->m_banking_cart[3] + 0x2000); membank("bank4")->set_base(m_banking_cart[3] + 0x2000);
state->membank("bank5")->set_base(state->m_banking_cart[5]); membank("bank5")->set_base(m_banking_cart[5]);
state->membank("bank6")->set_base(state->m_banking_cart[5] + 0x2000); membank("bank6")->set_base(m_banking_cart[5] + 0x2000);
logerror("Switched in cartridge rom.\n"); logerror("Switched in cartridge rom.\n");
} }
/* 5. check and set up bios rom */ /* 5. check and set up bios rom */
if (!(state->m_bios_port & IO_BIOS_ROM)) if (!(m_bios_port & IO_BIOS_ROM))
{ {
/* 0x0400 bioses */ /* 0x0400 bioses */
if (state->m_has_bios_0400) if (m_has_bios_0400)
{ {
state->membank("bank1")->set_base(state->m_banking_bios[1]); membank("bank1")->set_base(m_banking_bios[1]);
logerror("Switched in 0x0400 bios.\n"); logerror("Switched in 0x0400 bios.\n");
} }
/* 0x2000 bioses */ /* 0x2000 bioses */
if (state->m_has_bios_2000) if (m_has_bios_2000)
{ {
state->membank("bank1")->set_base(state->m_banking_bios[1]); membank("bank1")->set_base(m_banking_bios[1]);
state->membank("bank2")->set_base(state->m_banking_bios[2]); membank("bank2")->set_base(m_banking_bios[2]);
logerror("Switched in 0x2000 bios.\n"); logerror("Switched in 0x2000 bios.\n");
} }
if (state->m_has_bios_full) if (m_has_bios_full)
{ {
state->membank("bank1")->set_base(state->m_banking_bios[1]); membank("bank1")->set_base(m_banking_bios[1]);
state->membank("bank2")->set_base(state->m_banking_bios[2]); membank("bank2")->set_base(m_banking_bios[2]);
state->membank("bank7")->set_base(state->m_banking_bios[7]); membank("bank7")->set_base(m_banking_bios[7]);
state->membank("bank3")->set_base(state->m_banking_bios[3]); membank("bank3")->set_base(m_banking_bios[3]);
state->membank("bank4")->set_base(state->m_banking_bios[3] + 0x2000); membank("bank4")->set_base(m_banking_bios[3] + 0x2000);
state->membank("bank5")->set_base(state->m_banking_bios[5]); membank("bank5")->set_base(m_banking_bios[5]);
state->membank("bank6")->set_base(state->m_banking_bios[5] + 0x2000); membank("bank6")->set_base(m_banking_bios[5] + 0x2000);
logerror("Switched in full bios.\n"); logerror("Switched in full bios.\n");
} }
} }
if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM) if (m_cartridge[m_current_cartridge].features & CF_ONCART_RAM)
{ {
state->membank("bank5")->set_base(state->m_cartridge[state->m_current_cartridge].cartRAM); membank("bank5")->set_base(m_cartridge[m_current_cartridge].cartRAM);
state->membank("bank6")->set_base(state->m_cartridge[state->m_current_cartridge].cartRAM); membank("bank6")->set_base(m_cartridge[m_current_cartridge].cartRAM);
} }
} }
@ -1854,73 +1838,71 @@ DEVICE_IMAGE_LOAD( sms_cart )
} }
static void setup_cart_banks( running_machine &machine ) void sms_state::setup_cart_banks()
{ {
sms_state *state = machine.driver_data<sms_state>(); if (m_cartridge[m_current_cartridge].ROM)
if (state->m_cartridge[state->m_current_cartridge].ROM)
{ {
UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; UINT8 rom_page_count = m_cartridge[m_current_cartridge].size / 0x4000;
state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM; m_banking_cart[1] = m_cartridge[m_current_cartridge].ROM;
state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + 0x0400; m_banking_cart[2] = m_cartridge[m_current_cartridge].ROM + 0x0400;
state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0); m_banking_cart[3] = m_cartridge[m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0);
state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0); m_banking_cart[5] = m_cartridge[m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0);
state->m_banking_cart[7] = state->m_cartridge[state->m_current_cartridge].ROM + 0x2000; m_banking_cart[7] = m_cartridge[m_current_cartridge].ROM + 0x2000;
/* Codemasters mapper points to bank 0 for page 2 */ /* Codemasters mapper points to bank 0 for page 2 */
if ( state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER ) if ( m_cartridge[m_current_cartridge].features & CF_CODEMASTERS_MAPPER )
{ {
state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM; m_banking_cart[5] = m_cartridge[m_current_cartridge].ROM;
} }
/* Nemesis starts with last 8kb bank in page 0 */ /* Nemesis starts with last 8kb bank in page 0 */
if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_NEMESIS ) if (m_cartridge[m_current_cartridge].features & CF_KOREAN_ZEMINA_NEMESIS )
{ {
state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000; m_banking_cart[1] = m_cartridge[m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000;
state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000 + 0x400; m_banking_cart[2] = m_cartridge[m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000 + 0x400;
} }
} }
else else
{ {
state->m_banking_cart[1] = state->m_banking_none; m_banking_cart[1] = m_banking_none;
state->m_banking_cart[2] = state->m_banking_none; m_banking_cart[2] = m_banking_none;
state->m_banking_cart[3] = state->m_banking_none; m_banking_cart[3] = m_banking_none;
state->m_banking_cart[5] = state->m_banking_none; m_banking_cart[5] = m_banking_none;
} }
} }
static void setup_banks( running_machine &machine ) void sms_state::setup_banks()
{ {
sms_state *state = machine.driver_data<sms_state>(); UINT8 *mem = memregion("maincpu")->base();
UINT8 *mem = machine.root_device().memregion("maincpu")->base(); m_banking_none = mem;
state->m_banking_none = mem; m_banking_bios[1] = m_banking_cart[1] = mem;
state->m_banking_bios[1] = state->m_banking_cart[1] = mem; m_banking_bios[2] = m_banking_cart[2] = mem;
state->m_banking_bios[2] = state->m_banking_cart[2] = mem; m_banking_bios[3] = m_banking_cart[3] = mem;
state->m_banking_bios[3] = state->m_banking_cart[3] = mem; m_banking_bios[4] = m_banking_cart[4] = mem;
state->m_banking_bios[4] = state->m_banking_cart[4] = mem; m_banking_bios[5] = m_banking_cart[5] = mem;
state->m_banking_bios[5] = state->m_banking_cart[5] = mem; m_banking_bios[6] = m_banking_cart[6] = mem;
state->m_banking_bios[6] = state->m_banking_cart[6] = mem; m_banking_bios[7] = m_banking_cart[7] = mem;
state->m_banking_bios[7] = state->m_banking_cart[7] = mem;
state->m_BIOS = machine.root_device().memregion("user1")->base(); m_BIOS = memregion("user1")->base();
state->m_bios_page_count = (state->m_BIOS ? state->memregion("user1")->bytes() / 0x4000 : 0); m_bios_page_count = (m_BIOS ? memregion("user1")->bytes() / 0x4000 : 0);
setup_cart_banks(machine); setup_cart_banks();
if (state->m_BIOS == NULL || state->m_BIOS[0] == 0x00) if (m_BIOS == NULL || m_BIOS[0] == 0x00)
{ {
state->m_BIOS = NULL; m_BIOS = NULL;
state->m_bios_port |= IO_BIOS_ROM; m_bios_port |= IO_BIOS_ROM;
state->m_has_bios_0400 = 0; m_has_bios_0400 = 0;
state->m_has_bios_2000 = 0; m_has_bios_2000 = 0;
state->m_has_bios_full = 0; m_has_bios_full = 0;
state->m_has_bios = 0; m_has_bios = 0;
} }
if (state->m_BIOS) if (m_BIOS)
{ {
state->m_banking_bios[1] = state->m_BIOS; m_banking_bios[1] = m_BIOS;
state->m_banking_bios[2] = state->m_BIOS + 0x0400; m_banking_bios[2] = m_BIOS + 0x0400;
state->m_banking_bios[3] = state->m_BIOS + ((1 < state->m_bios_page_count) ? 0x4000 : 0); m_banking_bios[3] = m_BIOS + ((1 < m_bios_page_count) ? 0x4000 : 0);
state->m_banking_bios[5] = state->m_BIOS + ((2 < state->m_bios_page_count) ? 0x8000 : 0); m_banking_bios[5] = m_BIOS + ((2 < m_bios_page_count) ? 0x8000 : 0);
} }
} }
@ -1933,12 +1915,8 @@ MACHINE_START_MEMBER(sms_state,sms)
m_lphaser_1_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_1_callback),this)); m_lphaser_1_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_1_callback),this));
m_lphaser_2_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_2_callback),this)); m_lphaser_2_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_2_callback),this));
m_main_cpu = machine().device("maincpu");
m_control_cpu = machine().device("control");
m_vdp = machine().device<sega315_5124_device>("sms_vdp");
m_eeprom = machine().device<eeprom_device>("eeprom"); m_eeprom = machine().device<eeprom_device>("eeprom");
m_ym = machine().device("ym2413"); m_ym = machine().device("ym2413");
m_main_scr = machine().device("screen");
m_left_lcd = machine().device("left_lcd"); m_left_lcd = machine().device("left_lcd");
m_right_lcd = machine().device("right_lcd"); m_right_lcd = machine().device("right_lcd");
m_space = &machine().device("maincpu")->memory().space(AS_PROGRAM); m_space = &machine().device("maincpu")->memory().space(AS_PROGRAM);
@ -1965,7 +1943,7 @@ MACHINE_START_MEMBER(sms_state,sms)
MACHINE_RESET_MEMBER(sms_state,sms) MACHINE_RESET_MEMBER(sms_state,sms)
{ {
address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); address_space &space = m_main_cpu->space(AS_PROGRAM);
m_ctrl_reg = 0xff; m_ctrl_reg = 0xff;
if (m_has_fm) if (m_has_fm)
@ -2029,9 +2007,9 @@ MACHINE_RESET_MEMBER(sms_state,sms)
m_store_control = 0; m_store_control = 0;
setup_banks(machine()); setup_banks();
setup_rom(space); setup_rom();
m_rapid_fire_state_1 = 0; m_rapid_fire_state_1 = 0;
m_rapid_fire_state_2 = 0; m_rapid_fire_state_2 = 0;
@ -2073,9 +2051,9 @@ WRITE8_MEMBER(sms_state::sms_store_cart_select_w)
if (slottype == 0) if (slottype == 0)
m_current_cartridge = slot; m_current_cartridge = slot;
setup_cart_banks(machine()); setup_cart_banks();
membank("bank10")->set_base(m_banking_cart[3] + 0x2000); membank("bank10")->set_base(m_banking_cart[3] + 0x2000);
setup_rom(space); setup_rom();
} }
@ -2115,25 +2093,12 @@ WRITE8_MEMBER(sms_state::sms_store_control_w)
WRITE_LINE_MEMBER(sms_state::sms_store_int_callback) WRITE_LINE_MEMBER(sms_state::sms_store_int_callback)
{ {
(m_store_control & 0x01 ? m_control_cpu : m_main_cpu)->execute().set_input_line(0, state); (m_store_control & 0x01 ? m_control_cpu : m_main_cpu)->set_input_line(0, state);
} }
static void sms_set_zero_flag( running_machine &machine )
{
sms_state *state = machine.driver_data<sms_state>();
state->m_is_gamegear = 0;
state->m_is_region_japan = 0;
state->m_has_bios_0400 = 0;
state->m_has_bios_2000 = 0;
state->m_has_bios_full = 0;
state->m_has_bios = 0;
state->m_has_fm = 0;
}
DRIVER_INIT_MEMBER(sms_state,sg1000m3) DRIVER_INIT_MEMBER(sms_state,sg1000m3)
{ {
sms_set_zero_flag(machine());
m_is_region_japan = 1; m_is_region_japan = 1;
m_has_fm = 1; m_has_fm = 1;
} }
@ -2141,14 +2106,12 @@ DRIVER_INIT_MEMBER(sms_state,sg1000m3)
DRIVER_INIT_MEMBER(sms_state,sms1) DRIVER_INIT_MEMBER(sms_state,sms1)
{ {
sms_set_zero_flag(machine());
m_has_bios_full = 1; m_has_bios_full = 1;
} }
DRIVER_INIT_MEMBER(sms_state,smsj) DRIVER_INIT_MEMBER(sms_state,smsj)
{ {
sms_set_zero_flag(machine());
m_is_region_japan = 1; m_is_region_japan = 1;
m_has_bios_2000 = 1; m_has_bios_2000 = 1;
m_has_fm = 1; m_has_fm = 1;
@ -2157,7 +2120,6 @@ DRIVER_INIT_MEMBER(sms_state,smsj)
DRIVER_INIT_MEMBER(sms_state,sms2kr) DRIVER_INIT_MEMBER(sms_state,sms2kr)
{ {
sms_set_zero_flag(machine());
m_is_region_japan = 1; m_is_region_japan = 1;
m_has_bios_full = 1; m_has_bios_full = 1;
m_has_fm = 1; m_has_fm = 1;
@ -2166,13 +2128,11 @@ DRIVER_INIT_MEMBER(sms_state,sms2kr)
DRIVER_INIT_MEMBER(sms_state,smssdisp) DRIVER_INIT_MEMBER(sms_state,smssdisp)
{ {
sms_set_zero_flag(machine());
} }
DRIVER_INIT_MEMBER(sms_state,gamegear) DRIVER_INIT_MEMBER(sms_state,gamegear)
{ {
sms_set_zero_flag(machine());
m_is_gamegear = 1; m_is_gamegear = 1;
m_has_bios_0400 = 1; m_has_bios_0400 = 1;
} }
@ -2180,7 +2140,6 @@ DRIVER_INIT_MEMBER(sms_state,gamegear)
DRIVER_INIT_MEMBER(sms_state,gamegeaj) DRIVER_INIT_MEMBER(sms_state,gamegeaj)
{ {
sms_set_zero_flag(machine());
m_is_region_japan = 1; m_is_region_japan = 1;
m_is_gamegear = 1; m_is_gamegear = 1;
m_has_bios_0400 = 1; m_has_bios_0400 = 1;
@ -2189,10 +2148,8 @@ DRIVER_INIT_MEMBER(sms_state,gamegeaj)
VIDEO_START_MEMBER(sms_state,sms1) VIDEO_START_MEMBER(sms_state,sms1)
{ {
screen_device *screen = machine().first_screen(); m_main_scr->register_screen_bitmap(m_prevleft_bitmap);
m_main_scr->register_screen_bitmap(m_prevright_bitmap);
screen->register_screen_bitmap(m_prevleft_bitmap);
screen->register_screen_bitmap(m_prevright_bitmap);
save_item(NAME(m_prevleft_bitmap)); save_item(NAME(m_prevleft_bitmap));
save_item(NAME(m_prevright_bitmap)); save_item(NAME(m_prevright_bitmap));
} }