diff options
author | 2013-06-19 06:50:07 +0000 | |
---|---|---|
committer | 2013-06-19 06:50:07 +0000 | |
commit | d8bf9eaac5907e5eafd17217dcd90f07585323fc (patch) | |
tree | b5486ece6d48150e794abffb1f81cf5b31fba1fe /src/mess/machine/sms.c | |
parent | f9dbdf1920fc5890518bd6016e8be88a7aa1fc43 (diff) |
(MESS) sms: Converted SMS inputs to use slot devices. You now select
controllers in the Slot Devices menu of the internal UI, not in the Driver
Configurations anymore. [Enik]
Diffstat (limited to 'src/mess/machine/sms.c')
-rw-r--r-- | src/mess/machine/sms.c | 659 |
1 files changed, 136 insertions, 523 deletions
diff --git a/src/mess/machine/sms.c b/src/mess/machine/sms.c index c75f71794d3..98886294bb9 100644 --- a/src/mess/machine/sms.c +++ b/src/mess/machine/sms.c @@ -13,205 +13,6 @@ #define ENABLE_CART 3 #define ENABLE_BIOS 4 -#define LGUN_RADIUS 6 -#define LGUN_X_INTERVAL 4 - -void sms_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_RAPID_FIRE: - rapid_fire_callback(ptr, param); - break; - case TIMER_LIGHTGUN_TICK: - lightgun_tick(ptr, param); - break; - case TIMER_LPHASER_1: - lphaser_1_callback(ptr, param); - break; - case TIMER_LPHASER_2: - lphaser_2_callback(ptr, param); - break; - default: - assert_always(FALSE, "Unknown id in sms_state::device_timer"); - } -} - - -TIMER_CALLBACK_MEMBER(sms_state::rapid_fire_callback) -{ - m_rapid_fire_state_1 ^= 0xff; - m_rapid_fire_state_2 ^= 0xff; -} - - - -WRITE8_MEMBER(sms_state::sms_input_write) -{ - switch (offset) - { - case 0: - switch (m_port_ctrlsel->read_safe(0x00) & 0x0f) - { - case 0x04: /* Sports Pad */ - if (data != m_sports_pad_last_data_1) - { - UINT32 cpu_cycles = m_maincpu->total_cycles(); - - m_sports_pad_last_data_1 = data; - if (cpu_cycles - m_last_sports_pad_time_1 > 512) - { - m_sports_pad_state_1 = 3; - m_sports_pad_1_x = m_port_sport0->read(); - m_sports_pad_1_y = m_port_sport1->read(); - } - m_last_sports_pad_time_1 = cpu_cycles; - m_sports_pad_state_1 = (m_sports_pad_state_1 + 1) & 3; - } - break; - } - break; - - case 1: - switch (m_port_ctrlsel->read_safe(0x00) & 0xf0) - { - case 0x40: /* Sports Pad */ - if (data != m_sports_pad_last_data_2) - { - UINT32 cpu_cycles = m_maincpu->total_cycles(); - - m_sports_pad_last_data_2 = data; - if (cpu_cycles - m_last_sports_pad_time_2 > 2048) - { - m_sports_pad_state_2 = 3; - m_sports_pad_2_x = m_port_sport2->read(); - m_sports_pad_2_y = m_port_sport3->read(); - } - m_last_sports_pad_time_2 = cpu_cycles; - m_sports_pad_state_2 = (m_sports_pad_state_2 + 1) & 3; - } - break; - } - break; - } -} - - -/* - Light Phaser (light gun) emulation notes: - - The sensor is activated based on color brightness of some individual - pixels being drawn by the beam, at circular area where the gun is aiming. - - Currently, brightness is calculated based only on single pixels. - - In general, after the trigger is pressed, games draw the next frame using - a light color pattern, to make sure sensor will be activated. If emulation - skips that frame, sensor may stay deactivated. Frameskip set to 0 (no skip) is - recommended to avoid problems. - - When sensor switches from off to on, a value is latched for HCount register - and a flag is set. The emulation uses the flag to avoid sequential latches and - to signal that TH line is activated when the status of the input port is read. - When the status is read, the flag is cleared, or else it is cleared later when - the Pause status is read (end of a frame). This is necessary because the - "Color & Switch Test" ROM only reads the TH bit after the VINT line. - - The gun test of "Color & Switch Test" is an example that requires checks - of sensor status independent of other events, like trigger press or TH bit - reads. Another example is the title screen of "Hang-On & Safari Hunt", where - the game only reads HCount register in a loop, expecting a latch by the gun. - - 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. -*/ -int sms_state::lgun_bright_aim_area( emu_timer *timer, int lgun_x, int lgun_y ) -{ - const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; - const rectangle &visarea = m_main_scr->visible_area(); - int beam_x = m_main_scr->hpos(); - int beam_y = m_main_scr->vpos(); - int dx, dy; - int result = 0; - int pos_changed = 0; - double dx_radius; - - while (1) - { - /* If beam's y isn't at a line where the aim area is, change it - the next line it enters that area. */ - dy = abs(beam_y - lgun_y); - if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y) - { - beam_y = lgun_y - LGUN_RADIUS; - if (beam_y < visarea.min_y) - beam_y = visarea.min_y; - dy = abs(beam_y - lgun_y); - pos_changed = 1; - } - - /* Caculate distance in x of the radius, relative to beam's y distance. - First try some shortcuts. */ - switch (dy) - { - case LGUN_RADIUS: - dx_radius = 0; - break; - case 0: - dx_radius = LGUN_RADIUS; - break; - default: - /* step 1: r^2 = dx^2 + dy^2 */ - /* step 2: dx^2 = r^2 - dy^2 */ - /* step 3: dx = sqrt(r^2 - dy^2) */ - dx_radius = ceil((float) sqrt((float) (r_x_r - (dy * dy)))); - } - - /* If beam's x isn't in the circular aim area, change it - to the next point it enters that area. */ - dx = abs(beam_x - lgun_x); - if (dx > dx_radius || beam_x < visarea.min_x || beam_x > visarea.max_x) - { - /* If beam's x has passed the aim area, advance to - next line and recheck y/x coordinates. */ - if (beam_x > lgun_x) - { - beam_x = 0; - beam_y++; - continue; - } - beam_x = lgun_x - dx_radius; - if (beam_x < visarea.min_x) - beam_x = visarea.min_x; - pos_changed = 1; - } - - if (!pos_changed) - { - bitmap_rgb32 &bitmap = m_vdp->get_bitmap(); - - /* brightness of the lightgray color in the frame drawn by Light Phaser games */ - const UINT8 sensor_min_brightness = 0x7f; - - /* TODO: Check how Light Phaser behaves for border areas. For Gangster Town, should */ - /* a shot at right border (HC~=0x90) really appear at active scr, near to left border? */ - if (beam_x < SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH || beam_x >= SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256) - return 0; - - rgb_t color = bitmap.pix32(beam_y, beam_x); - - /* reference: http://www.w3.org/TR/AERT#color-contrast */ - UINT8 brightness = (RGB_RED(color) * 0.299) + (RGB_GREEN(color) * 0.587) + (RGB_BLUE(color) * 0.114); - //printf ("color brightness: %2X for x %d y %d\n", brightness, beam_x, beam_y); - - result = (brightness >= sensor_min_brightness) ? 1 : 0; - - /* next check at same line */ - beam_x += LGUN_X_INTERVAL; - pos_changed = 1; - } - else - break; - } - timer->adjust(m_main_scr->time_until_pos(beam_y, beam_x)); - - return result; -} - void sms_state::lphaser_hcount_latch( int hpos ) { @@ -221,258 +22,45 @@ void sms_state::lphaser_hcount_latch( int hpos ) } -UINT16 sms_state::screen_hpos_nonscaled(int scaled_hpos) -{ - const rectangle &visarea = m_main_scr->visible_area(); - int offset_x = (scaled_hpos * (visarea.max_x - visarea.min_x)) / 255; - return visarea.min_x + offset_x; -} - - -UINT16 sms_state::screen_vpos_nonscaled(int scaled_vpos) -{ - const rectangle &visarea = m_main_scr->visible_area(); - int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255; - return visarea.min_y + offset_y; -} - - -void sms_state::lphaser1_sensor_check() -{ - const int x = screen_hpos_nonscaled(m_port_lphas0->read()); - const int y = screen_vpos_nonscaled(m_port_lphas1->read()); - - if (lgun_bright_aim_area(m_lphaser_1_timer, x, y)) - { - if (m_lphaser_1_latch == 0) - { - m_lphaser_1_latch = 1; - lphaser_hcount_latch(x); - } - } -} - -void sms_state::lphaser2_sensor_check() +WRITE16_MEMBER(sms_state::sms_ctrl1_th_input) { - const int x = screen_hpos_nonscaled(m_port_lphas2->read()); - const int y = screen_vpos_nonscaled(m_port_lphas3->read()); - - if (lgun_bright_aim_area(m_lphaser_2_timer, x, y)) + if (m_ctrl1_th_latch == 0) { - if (m_lphaser_2_latch == 0) - { - m_lphaser_2_latch = 1; - lphaser_hcount_latch(x); - } + m_ctrl1_th_latch = 1; + lphaser_hcount_latch(data); } } -// at each input port read we check if lightguns are enabled in one of the ports: -// if so, we turn on crosshair and the lightgun timer -TIMER_CALLBACK_MEMBER(sms_state::lightgun_tick) +WRITE16_MEMBER(sms_state::sms_ctrl2_th_input) { - if ((m_port_ctrlsel->read_safe(0x00) & 0x0f) == 0x01) - { - /* enable crosshair */ - crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); - if (!m_lphaser_1_timer->enabled()) - lphaser1_sensor_check(); - } - else - { - /* disable crosshair */ - crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); - m_lphaser_1_timer->enable(0); - } - - if ((m_port_ctrlsel->read_safe(0x00) & 0xf0) == 0x10) + if (m_ctrl2_th_latch == 0) { - /* enable crosshair */ - crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); - if (!m_lphaser_2_timer->enabled()) - lphaser2_sensor_check(); + m_ctrl2_th_latch = 1; + lphaser_hcount_latch(data); } - else - { - /* disable crosshair */ - crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_NONE); - m_lphaser_2_timer->enable(0); - } -} - - -TIMER_CALLBACK_MEMBER(sms_state::lphaser_1_callback) -{ - lphaser1_sensor_check(); -} - - -TIMER_CALLBACK_MEMBER(sms_state::lphaser_2_callback) -{ - lphaser2_sensor_check(); -} - - -INPUT_CHANGED_MEMBER(sms_state::lgun1_changed) -{ - if (!m_lphaser_1_timer || - (m_port_ctrlsel->read_safe(0x00) & 0x0f) != 0x01) - return; - - if (newval != oldval) - lphaser1_sensor_check(); -} - -INPUT_CHANGED_MEMBER(sms_state::lgun2_changed) -{ - if (!m_lphaser_2_timer || - (m_port_ctrlsel->read_safe(0x00) & 0xf0) != 0x10) - return; - - if (newval != oldval) - lphaser2_sensor_check(); } void sms_state::sms_get_inputs( address_space &space ) { - UINT8 data = 0x00; - UINT32 cpu_cycles = m_maincpu->total_cycles(); - - m_input_port0 = 0xff; - m_input_port1 = 0xff; - - if (cpu_cycles - m_last_paddle_read_time > 256) - { - m_paddle_read_state ^= 0xff; - m_last_paddle_read_time = cpu_cycles; - } + UINT8 data; - /* Check if lightgun has been chosen as input: if so, enable crosshair */ - timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); + m_port_dc_reg = 0xff; + m_port_dd_reg = 0xff; - /* Player 1 */ - switch (m_port_ctrlsel->read_safe(0x00) & 0x0f) - { - case 0x00: /* Joystick */ - data = m_port_dc->read(); - /* Check Rapid Fire setting for Button A */ - if (!(data & 0x10) && (m_port_rfu->read() & 0x01)) - data |= m_rapid_fire_state_1 & 0x10; - - /* Check Rapid Fire setting for Button B */ - if (!(data & 0x20) && (m_port_rfu->read() & 0x02)) - data |= m_rapid_fire_state_1 & 0x20; - - m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f); - break; - - case 0x01: /* Light Phaser */ - data = (m_port_ctrlipt->read() & 0x01) << 4; - /* Check Rapid Fire setting for Trigger */ - if (!(data & 0x10) && (m_port_rfu->read() & 0x01)) - data |= m_rapid_fire_state_1 & 0x10; - - /* just consider the trigger (button) bit */ - data |= ~0x10; - - m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f); - break; - - case 0x02: /* Paddle Control */ - /* Get button A state */ - data = m_port_paddle0->read(); - - if (m_paddle_read_state) - data = data >> 4; - - m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x0f) | (m_paddle_read_state & 0x20) - | ((m_port_ctrlipt->read() & 0x02) << 3); - break; - - case 0x04: /* Sega Sports Pad */ - switch (m_sports_pad_state_1) - { - case 0: - data = (m_sports_pad_1_x >> 4) & 0x0f; - break; - case 1: - data = m_sports_pad_1_x & 0x0f; - break; - case 2: - data = (m_sports_pad_1_y >> 4) & 0x0f; - break; - case 3: - data = m_sports_pad_1_y & 0x0f; - break; - } - m_input_port0 = (m_input_port0 & 0xc0) | data | ((m_port_ctrlipt->read() & 0x0c) << 2); - break; - } + data = m_port_ctrl1->port_r(); + m_port_dc_reg &= ~0x0F | data; // Up, Down, Left, Right + m_port_dc_reg &= ~0x10 | (data >> 1); // TL (Button 1) + m_port_dc_reg &= ~0x20 | (data >> 2); // TR (Button 2) + m_port_dd_reg &= ~0x40 | data; // TH - /* Player 2 */ - switch (m_port_ctrlsel->read_safe(0x00) & 0xf0) - { - case 0x00: /* Joystick */ - data = m_port_dc->read(); - m_input_port0 = (m_input_port0 & 0x3f) | (data & 0xc0); - - data = m_port_dd->read(); - /* Check Rapid Fire setting for Button A */ - if (!(data & 0x04) && (m_port_rfu->read() & 0x04)) - data |= m_rapid_fire_state_2 & 0x04; - - /* Check Rapid Fire setting for Button B */ - if (!(data & 0x08) && (m_port_rfu->read() & 0x08)) - data |= m_rapid_fire_state_2 & 0x08; - - m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f); - break; - - case 0x10: /* Light Phaser */ - data = (m_port_ctrlipt->read() & 0x10) >> 2; - /* Check Rapid Fire setting for Trigger */ - if (!(data & 0x04) && (m_port_rfu->read() & 0x04)) - data |= m_rapid_fire_state_2 & 0x04; - - /* just consider the trigger (button) bit */ - data |= ~0x04; - - m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f); - break; - - case 0x20: /* Paddle Control */ - /* Get button A state */ - data = m_port_paddle1->read(); - if (m_paddle_read_state) - data = data >> 4; - - m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6); - m_input_port1 = (m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (m_paddle_read_state & 0x08) - | ((m_port_ctrlipt->read() & 0x20) >> 3); - break; - - case 0x40: /* Sega Sports Pad */ - switch (m_sports_pad_state_2) - { - case 0: - data = m_sports_pad_2_x & 0x0f; - break; - case 1: - data = (m_sports_pad_2_x >> 4) & 0x0f; - break; - case 2: - data = m_sports_pad_2_y & 0x0f; - break; - case 3: - data = (m_sports_pad_2_y >> 4) & 0x0f; - break; - } - m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6); - m_input_port1 = (m_input_port1 & 0xf0) | (data >> 2) | ((m_port_ctrlipt->read() & 0xc0) >> 4); - break; - } + data = m_port_ctrl2->port_r(); + m_port_dc_reg &= ~0xc0 | (data << 6); // Up, Down + m_port_dd_reg &= ~0x03 | (data >> 2); // Left, Right + m_port_dd_reg &= ~0x04 | (data >> 3); // TL (Button 1) + m_port_dd_reg &= ~0x08 | (data >> 4); // TR (Button 2) + m_port_dd_reg &= ~0x80 | (data << 1); // TH } @@ -498,40 +86,75 @@ READ8_MEMBER(sms_state::sms_fm_detect_r) else { sms_get_inputs(space); - return m_input_port0; + return m_port_dc_reg; } } } + WRITE8_MEMBER(sms_state::sms_io_control_w) { bool latch_hcount = false; + UINT8 ctrl1_port_data = 0xff; + UINT8 ctrl2_port_data = 0xff; - if (data & 0x08) + // Controller Port 1: + + // check if TR or TH are set to output (0). + if ((data & 0x03) != 0x03) { - /* check if TH pin level is high (1) and was low last time */ - if (data & 0x80 && !(m_ctrl_reg & 0x80)) + if (!(data & 0x01)) // TR set to output { - latch_hcount = true; + ctrl1_port_data &= ~0x80 | (data << 3); + } + if (!(data & 0x02)) // TH set to output + { + ctrl1_port_data &= ~0x40 | (data << 1); } - sms_input_write(space, 0, (data & 0x20) >> 5); + if (!m_is_gamegear) + m_port_ctrl1->port_w(ctrl1_port_data); } - + // check if TH is set to input (1). if (data & 0x02) { - if (data & 0x20 && !(m_ctrl_reg & 0x20)) - { + UINT8 th_level = (m_port_ctrl1->port_r() & 0x40) >> 1; + + // check if TH pin level is high (1) and was low (0) + if ((th_level & 0x20) && !(m_io_ctrl_reg & 0x20)) latch_hcount = true; + } + + // Controller Port 2: + + // check if TR or TH are set to output (0). + if ((data & 0x0c) != 0x0c) + { + if (!(data & 0x04)) // TR set to output + { + ctrl2_port_data &= ~0x80 | (data << 1); } - sms_input_write(space, 1, (data & 0x80) >> 7); + if (!(data & 0x08)) // TH set to output + { + ctrl2_port_data &= ~0x40 | (data >> 1); + } + if (!m_is_gamegear) + m_port_ctrl2->port_w(ctrl2_port_data); + } + // check if TH is set to input (1). + if (data & 0x08) + { + UINT8 th_level = (m_port_ctrl2->port_r() & 0x40) << 1; + + // check if TH pin level is high (1) and was low (0) + if ((th_level & 0x80) && !(m_io_ctrl_reg & 0x80)) + latch_hcount = true; } if (latch_hcount) { m_vdp->hcount_latch(); } - - m_ctrl_reg = data; + m_io_ctrl_reg = data; } @@ -563,12 +186,13 @@ WRITE_LINE_MEMBER(sms_state::sms_pause_callback) else m_paused = 0; - /* clear Light Phaser latch flags for next frame */ - m_lphaser_1_latch = 0; - m_lphaser_2_latch = 0; + // clear TH latch of the controller ports + m_ctrl1_th_latch = 0; + m_ctrl2_th_latch = 0; } -READ8_MEMBER(sms_state::sms_input_port_0_r) + +READ8_MEMBER(sms_state::sms_input_port_dc_r) { if (m_bios_port & IO_CHIP) { @@ -577,63 +201,82 @@ READ8_MEMBER(sms_state::sms_input_port_0_r) else { sms_get_inputs(space); - return m_input_port0; + + // Check if TR of controller port 1 is set to output (0) + if (!(m_io_ctrl_reg & 0x01)) + { + // Read TR state set through IO control port + m_port_dc_reg &= ~0x20 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x10) << 1); + } + + return m_port_dc_reg; } } -READ8_MEMBER(sms_state::sms_input_port_1_r) +READ8_MEMBER(sms_state::sms_input_port_dd_r) { if (m_bios_port & IO_CHIP) return 0xff; sms_get_inputs(space); - /* Reset Button */ - m_input_port1 = (m_input_port1 & 0xef) | (m_port_reset->read_safe(0x01) & 0x01) << 4; + // Reset Button + m_port_dd_reg &= ~0x10 | (m_port_reset->read_safe(0x01) & 0x01) << 4; - /* Do region detection if TH of ports A and B are set to output (0) */ - if (!(m_ctrl_reg & 0x0a)) + // Check if TR of controller port 2 is set to output (0) + if (!(m_io_ctrl_reg & 0x04)) { - /* Move bits 7,5 of IO control port into bits 7, 6 */ - m_input_port1 = (m_input_port1 & 0x3f) | (m_ctrl_reg & 0x80) | (m_ctrl_reg & 0x20) << 1; + // Read TR state set through IO control port + m_port_dd_reg &= ~0x08 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x40) >> 3); + } - /* Inverse region detect value for Japanese machines */ - if (m_is_region_japan) - m_input_port1 ^= 0xc0; + // Check if TH of controller port 1 is set to output (0) + if (!(m_io_ctrl_reg & 0x02)) + { + // Read TH state set through IO control port + m_port_dd_reg &= ~0x40 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x20) << 1); } - else + else // TH set to input (1) { - if (m_ctrl_reg & 0x02 && m_lphaser_1_latch) + if (m_ctrl1_th_latch) { - m_input_port1 &= ~0x40; - m_lphaser_1_latch = 0; + m_port_dd_reg &= ~0x40; + m_ctrl1_th_latch = 0; } + } - if (m_ctrl_reg & 0x08 && m_lphaser_2_latch) + // Check if TH of controller port 2 is set to output (0) + if (!(m_io_ctrl_reg & 0x08)) + { + // Read TH state set through IO control port + m_port_dd_reg &= ~0x80 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x80)); + } + else // TH set to input (1) + { + if (m_ctrl2_th_latch) { - m_input_port1 &= ~0x80; - m_lphaser_2_latch = 0; + m_port_dd_reg &= ~0x80; + m_ctrl2_th_latch = 0; } } - return m_input_port1; + return m_port_dd_reg; } - -WRITE8_MEMBER(sms_state::sms_ym2413_register_port_0_w) +WRITE8_MEMBER(sms_state::sms_ym2413_register_port_w) { if (m_has_fm) m_ym->write(space, 0, (data & 0x3f)); } -WRITE8_MEMBER(sms_state::sms_ym2413_data_port_0_w) +WRITE8_MEMBER(sms_state::sms_ym2413_data_port_w) { if (m_has_fm) { - logerror("data_port_0_w %x %x\n", offset, data); + logerror("data_port_w %x %x\n", offset, data); m_ym->write(space, 1, data); } } @@ -1056,19 +699,10 @@ MACHINE_START_MEMBER(sms_state,sms) { char str[7]; - m_rapid_fire_timer = timer_alloc(TIMER_RAPID_FIRE); - m_rapid_fire_timer->adjust(attotime::from_hz(10), 0, attotime::from_hz(10)); - - m_lphaser_1_timer = timer_alloc(TIMER_LPHASER_1); - m_lphaser_2_timer = timer_alloc(TIMER_LPHASER_2); - m_left_lcd = machine().device("left_lcd"); m_right_lcd = machine().device("right_lcd"); m_space = &m_maincpu->space(AS_PROGRAM); - /* Check if lightgun has been chosen as input: if so, enable crosshair */ - timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); - // alibaba and blockhol are ports of games for the MSX system. The // MSX bios usually initializes callback "vectors" at the top of RAM. // The code in alibaba does not do this so the IRQ vector only contains @@ -1083,32 +717,18 @@ MACHINE_START_MEMBER(sms_state,sms) } save_item(NAME(m_fm_detect)); - save_item(NAME(m_ctrl_reg)); + save_item(NAME(m_io_ctrl_reg)); save_item(NAME(m_paused)); save_item(NAME(m_bios_port)); save_item(NAME(m_mapper)); - save_item(NAME(m_input_port0)); - save_item(NAME(m_input_port1)); + save_item(NAME(m_port_dc_reg)); + save_item(NAME(m_port_dd_reg)); save_item(NAME(m_gg_sio)); save_item(NAME(m_bank_enabled)); save_item(NAME(m_bios_page)); - save_item(NAME(m_rapid_fire_state_1)); - save_item(NAME(m_rapid_fire_state_2)); - save_item(NAME(m_last_paddle_read_time)); - save_item(NAME(m_paddle_read_state)); - save_item(NAME(m_last_sports_pad_time_1)); - save_item(NAME(m_last_sports_pad_time_2)); - save_item(NAME(m_sports_pad_state_1)); - save_item(NAME(m_sports_pad_state_2)); - save_item(NAME(m_sports_pad_last_data_1)); - save_item(NAME(m_sports_pad_last_data_2)); - save_item(NAME(m_sports_pad_1_x)); - save_item(NAME(m_sports_pad_1_y)); - save_item(NAME(m_sports_pad_2_x)); - save_item(NAME(m_sports_pad_2_y)); - save_item(NAME(m_lphaser_1_latch)); - save_item(NAME(m_lphaser_2_latch)); + save_item(NAME(m_ctrl1_th_latch)); + save_item(NAME(m_ctrl2_th_latch)); save_item(NAME(m_sscope_state)); save_item(NAME(m_frame_sscope_state)); @@ -1142,7 +762,7 @@ MACHINE_START_MEMBER(sms_state,sms) MACHINE_RESET_MEMBER(sms_state,sms) { - m_ctrl_reg = 0xff; + m_io_ctrl_reg = 0xff; if (m_has_fm) m_fm_detect = 0x01; @@ -1168,25 +788,8 @@ MACHINE_RESET_MEMBER(sms_state,sms) setup_rom(); - m_rapid_fire_state_1 = 0; - m_rapid_fire_state_2 = 0; - - m_last_paddle_read_time = 0; - m_paddle_read_state = 0; - - m_last_sports_pad_time_1 = 0; - m_last_sports_pad_time_2 = 0; - m_sports_pad_state_1 = 0; - m_sports_pad_state_2 = 0; - m_sports_pad_last_data_1 = 0; - m_sports_pad_last_data_2 = 0; - m_sports_pad_1_x = 0; - m_sports_pad_1_y = 0; - m_sports_pad_2_x = 0; - m_sports_pad_2_y = 0; - - m_lphaser_1_latch = 0; - m_lphaser_2_latch = 0; + m_ctrl1_th_latch = 0; + m_ctrl2_th_latch = 0; m_lphaser_x_offs = (m_cartslot->m_cart) ? m_cartslot->m_cart->get_lphaser_xoffs() : 51; m_sscope_state = 0; @@ -1206,8 +809,8 @@ WRITE8_MEMBER(smssdisp_state::sms_store_cart_select_w) logerror("switching in part of %s slot #%d\n", slottype ? "card" : "cartridge", slot ); /* cartridge? slot #0 */ -// if (slottype == 0) -// m_current_cartridge = slot; + //if (slottype == 0) + // m_current_cartridge = slot; setup_rom(); } @@ -1336,6 +939,16 @@ VIDEO_START_MEMBER(sms_state,sms1) } +READ32_MEMBER(sms_state::sms_pixel_color) +{ + bitmap_rgb32 &vdp_bitmap = m_vdp->get_bitmap(); + int beam_x = m_main_scr->hpos(); + int beam_y = m_main_scr->vpos(); + + return vdp_bitmap.pix32(beam_y, beam_x); +} + + void sms_state::screen_vblank_sms1(screen_device &screen, bool state) { // on falling edge |