diff options
author | tim lindner <tlindner@macmess.org> | 2021-05-22 05:02:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-22 08:02:29 -0400 |
commit | 599218b1f3f59f28b8871776e39ec14d6fe4d7e7 (patch) | |
tree | ef2fd9bbd34930b8aa6834316f498c131f2dc0c7 | |
parent | ae08a2f65d6cd0beae0633e31f973dc6e736367b (diff) |
coco3: fix diecom light gun. (#8075)
-rw-r--r-- | src/mame/drivers/coco3.cpp | 13 | ||||
-rw-r--r-- | src/mame/includes/coco.h | 4 | ||||
-rw-r--r-- | src/mame/machine/coco.cpp | 75 |
3 files changed, 41 insertions, 51 deletions
diff --git a/src/mame/drivers/coco3.cpp b/src/mame/drivers/coco3.cpp index 0a5d14a8e7b..026080ae9c5 100644 --- a/src/mame/drivers/coco3.cpp +++ b/src/mame/drivers/coco3.cpp @@ -200,11 +200,11 @@ INPUT_PORTS_END static INPUT_PORTS_START( coco_lightgun ) PORT_START(DIECOM_LIGHTGUN_RX_TAG) - PORT_BIT( 0x1ff, 266, IPT_LIGHTGUN_X ) PORT_NAME("Lightgun X (Right Port)") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(116,416) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CONDITION(CTRL_SEL_TAG, 0x0f, EQUALS, 0x03) + PORT_BIT( 0xfff, 266, IPT_LIGHTGUN_X ) PORT_NAME("Lightgun X (Right Port)") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(105,420) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CONDITION(CTRL_SEL_TAG, 0x0f, EQUALS, 0x03) PORT_START(DIECOM_LIGHTGUN_RY_TAG) PORT_BIT( 0xff, 121, IPT_LIGHTGUN_Y ) PORT_NAME("Lightgun Y (Right Port)") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0,242) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CONDITION(CTRL_SEL_TAG, 0x0f, EQUALS, 0x03) PORT_START(DIECOM_LIGHTGUN_LX_TAG) - PORT_BIT( 0x1ff, 266, IPT_LIGHTGUN_X ) PORT_NAME("Lightgun X (Left Port)") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(116,416) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CONDITION(CTRL_SEL_TAG, 0xf0, EQUALS, 0x30) + PORT_BIT( 0xfff, 266, IPT_LIGHTGUN_X ) PORT_NAME("Lightgun X (Left Port)") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(105,420) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CONDITION(CTRL_SEL_TAG, 0xf0, EQUALS, 0x30) PORT_START(DIECOM_LIGHTGUN_LY_TAG) PORT_BIT( 0xff, 121, IPT_LIGHTGUN_Y ) PORT_NAME("Lightgun Y (Left Port)") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0,242) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CONDITION(CTRL_SEL_TAG, 0xf0, EQUALS, 0x30) PORT_START(DIECOM_LIGHTGUN_BUTTONS_TAG) @@ -323,12 +323,9 @@ void coco3_state::coco3(machine_config &config) m_gime->floating_bus_rd_callback().set(FUNC(coco3_state::floating_bus_r)); // monitor - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_screen_update(FUNC(coco3_state::screen_update)); - screen.set_size(640, 243); - screen.set_visarea(0, 640-1, 1, 241-1); - screen.set_vblank_time(0); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(28.636363_MHz_XTAL/2, 912, 0, 640-1, 263, 1, 241-1); + m_screen->set_screen_update(FUNC(coco3_state::screen_update)); // internal ram RAM(config, RAM_TAG).set_default_size("512K").set_extra_options("128K,2M,8M"); diff --git a/src/mame/includes/coco.h b/src/mame/includes/coco.h index 9b01c681a9d..adb82421ac1 100644 --- a/src/mame/includes/coco.h +++ b/src/mame/includes/coco.h @@ -259,8 +259,8 @@ protected: bool m_dclg_previous_bit; uint8_t m_dclg_output_h; uint8_t m_dclg_output_v; - uint8_t m_dclg_state; - uint16_t m_dclg_timer; + uint32_t m_dclg_state; + uint32_t m_dclg_timer; // VHD selection uint8_t m_vhd_select; diff --git a/src/mame/machine/coco.cpp b/src/mame/machine/coco.cpp index 665d60c3a9f..3a3c51879c4 100644 --- a/src/mame/machine/coco.cpp +++ b/src/mame/machine/coco.cpp @@ -51,10 +51,6 @@ research that for you if you want an exact number for scanlines before the screen starts and the scanline that the v-interrupt triggers..etc. -Added bi-directional bitbanger support. Also fixed reading PIA 1, port A. The -DAC and bitbanger values written should be reflected in the read. - tim lindner, October 2010 - ***************************************************************************/ #include "emu.h" @@ -197,9 +193,11 @@ void coco_state::device_timer(emu_timer &timer, device_timer_id id, int param, v { switch(id) { + case TIMER_DIECOM_LIGHTGUN: + m_dclg_output_h |= 0x02; + [[fallthrough]]; case TIMER_HIRES_JOYSTICK_X: case TIMER_HIRES_JOYSTICK_Y: - case TIMER_DIECOM_LIGHTGUN: poll_keyboard(); break; } @@ -677,7 +675,6 @@ void coco_state::poll_joystick(bool *joyin, uint8_t *buttons) const analog_input_t *analog; bool joyin_value; uint32_t joyval; - int dclg_vpos; switch(joystick_type(joystick)) { case JOYSTICK_NORMAL: @@ -706,25 +703,7 @@ void coco_state::poll_joystick(bool *joyin, uint8_t *buttons) case JOYSTICK_DIECOM_LIGHT_GUN: analog = &m_diecom_lightgun; - - /* get the vertical position of the lightgun */ - dclg_vpos = analog->input(joystick, 1); - - if (m_screen->vpos() == dclg_vpos) - { - /* if gun is pointing at the current scan line, set hit bit and cache horizontal timer value */ - m_dclg_output_h |= 0x02; - m_dclg_timer = analog->input(joystick, 0) << 1; - } - joyin_value = (dac_output() <= dclg_table[(joystick_axis ? m_dclg_output_h : m_dclg_output_v) & 0x03]); - - if (m_dclg_state == 7) - { - /* while in state 7, prepare to check next video frame for a hit */ - attotime dclg_time = m_screen->time_until_pos(dclg_vpos, 0); - m_diecom_lightgun_timer->adjust(dclg_time); - } break; default: /* None */ @@ -803,41 +782,54 @@ void coco_state::update_cassout(int cassout) //------------------------------------------------- -// diecom_lightgun_clock - called the diecom -// lightgun undergoes a high to low transition +// diecom_lightgun_clock - called when the diecom +// lightgun undergoes a clock transition //------------------------------------------------- void coco_state::diecom_lightgun_clock(void) { - /* clock Diecom Light gun interface on a high to low transistion */ m_dclg_state++; - m_dclg_state &= 0x0f; + m_dclg_state &= 0x1f; + int half_state = m_dclg_state >> 1; /* clear hit bit for every transistion */ m_dclg_output_h &= ~0x02; + m_dclg_output_v = 0; - if (m_dclg_state > 7) + if (half_state > 7) { - /* Bit shift timer data on state 8 thru 15 */ - if (((m_dclg_timer >> (m_dclg_state - 8 + 1)) & 0x01) == 1) + /* bit shift timer data on half states 8 thru 15 */ + if (m_dclg_timer & (1 << (half_state - 7))) + { m_dclg_output_v |= 0x01; - else - m_dclg_output_v &= ~0x01; + } - /* Bit 9 of timer is only available if state == 8*/ - if (m_dclg_state == 8 && (((m_dclg_timer >> 9) & 0x01) == 1)) + /* bit 9 of timer is only available if half state == 8 */ + if (half_state == 8 && (m_dclg_timer & (1 << 8))) m_dclg_output_v |= 0x02; - else - m_dclg_output_v &= ~0x02; } - /* During state 15, this bit is high. */ - if (m_dclg_state == 15) + /* during half state 15, this bit is high. */ + /* it is used to sync the state of the converter box with the computer */ + if (half_state == 15) m_dclg_output_h |= 0x01; else m_dclg_output_h &= ~0x01; -} + /* while in full state 15, prepare to check next video frame for a hit */ + if (m_dclg_state == 15) + { + int dclg_vpos = m_diecom_lightgun.input(sel2() ? 1 : 0, 1) - 12; + m_dclg_timer = m_diecom_lightgun.input(sel2() ? 1 : 0, 0); + int horizontal_pixel = ((m_dclg_timer - 105.) / (420. - 110.0)) * (639.0 - 0.0) + 0.0; + attotime dclg_time = m_screen->time_until_pos(dclg_vpos, horizontal_pixel); + m_diecom_lightgun_timer->adjust(dclg_time); + } + else + { + m_diecom_lightgun_timer->adjust(attotime::never); + } +} //------------------------------------------------- @@ -849,10 +841,11 @@ void coco_state::update_prinout(bool prinout) if ((joystick_type(0) == JOYSTICK_DIECOM_LIGHT_GUN) || (joystick_type(1) == JOYSTICK_DIECOM_LIGHT_GUN)) { /* printer port is connected to diecom light gun */ - if (m_dclg_previous_bit && !prinout) + if (m_dclg_previous_bit != prinout) { diecom_lightgun_clock(); } + m_dclg_previous_bit = prinout; } else |