diff options
Diffstat (limited to 'src/mame/machine/coco.cpp')
-rw-r--r-- | src/mame/machine/coco.cpp | 75 |
1 files changed, 34 insertions, 41 deletions
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 |