diff options
Diffstat (limited to 'src/devices/bus/sms_ctrl/graphic.cpp')
-rw-r--r-- | src/devices/bus/sms_ctrl/graphic.cpp | 161 |
1 files changed, 90 insertions, 71 deletions
diff --git a/src/devices/bus/sms_ctrl/graphic.cpp b/src/devices/bus/sms_ctrl/graphic.cpp index 1ada76748e7..fa46594ded7 100644 --- a/src/devices/bus/sms_ctrl/graphic.cpp +++ b/src/devices/bus/sms_ctrl/graphic.cpp @@ -36,55 +36,69 @@ Then 2 nibbles are read to form a byte containing the absolute Y coordiante. #include "graphic.h" - -//************************************************************************** -// DEVICE DEFINITIONS -//************************************************************************** - -DEFINE_DEVICE_TYPE(SMS_GRAPHIC, sms_graphic_device, "sms_graphic", "Sega SMS Graphic Board") - +namespace { static INPUT_PORTS_START( sms_graphic ) PORT_START("BUTTONS") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) // MENU PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) // DO PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) // PEN - PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // some kind of ready signal? + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_TOGGLE PORT_NAME("%p Pen") // pretend pen pressure is all-or-nothing PORT_START("X") - PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) + PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 254 / 268.0, 6 / 268.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_START("Y") - PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) + PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 255 / 224.0, -19 / 224.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) INPUT_PORTS_END -//------------------------------------------------- -// input_ports - device-specific input ports -//------------------------------------------------- - -ioport_constructor sms_graphic_device::device_input_ports() const -{ - return INPUT_PORTS_NAME( sms_graphic ); -} //************************************************************************** -// LIVE DEVICE +// TYPE DEFINITIONS //************************************************************************** +class sms_graphic_device : public device_t, public device_sms_control_interface +{ +public: + // construction/destruction + sms_graphic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // device_sms_control_interface implementation + virtual uint8_t in_r() override; + virtual void out_w(uint8_t data, uint8_t mem_mask) override; + +protected: + // device_t implementation + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(sms_graphic); } + virtual void device_start() override ATTR_COLD; + +private: + required_ioport m_buttons; + required_ioport m_x_axis; + required_ioport m_y_axis; + + uint8_t m_phase; + uint8_t m_select; + uint8_t m_data; +}; + + //------------------------------------------------- // sms_graphic_device - constructor //------------------------------------------------- -sms_graphic_device::sms_graphic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, SMS_GRAPHIC, tag, owner, clock) - , device_sms_control_port_interface(mconfig, *this) - , m_buttons(*this, "BUTTONS") - , m_x(*this, "X") - , m_y(*this, "Y") - , m_index(0) - , m_previous_write(0xff) - , m_pressure(0xfd) +sms_graphic_device::sms_graphic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, SMS_GRAPHIC, tag, owner, clock), + device_sms_control_interface(mconfig, *this), + m_buttons(*this, "BUTTONS"), + m_x_axis(*this, "X"), + m_y_axis(*this, "Y"), + m_phase(0), + m_select(0x7f), + m_data(0xff) { } @@ -95,8 +109,12 @@ sms_graphic_device::sms_graphic_device(const machine_config &mconfig, const char void sms_graphic_device::device_start() { - save_item(NAME(m_index)); - save_item(NAME(m_previous_write)); + m_phase = 0; + m_data = 0xff; + + save_item(NAME(m_phase)); + save_item(NAME(m_select)); + save_item(NAME(m_data)); } @@ -104,54 +122,55 @@ void sms_graphic_device::device_start() // sms_peripheral_r - joypad read //------------------------------------------------- -uint8_t sms_graphic_device::peripheral_r() +uint8_t sms_graphic_device::in_r() { - switch (m_index) - { - case 0: // Initial state / "I am a board" - // If any regular button is pressed raise/lower TL ? -// if ((m_buttons->read() & 0x07) != 0x07) -// return 0xf0; - return 0xd0; - - case 1: // Read buttons (active low) - return m_buttons->read(); - - case 2: // Some thing only FD, FE, and FF cause the other values to be read - return m_pressure >> 4; - - case 3: - return m_pressure & 0x0f; - - case 4: // High nibble X? - return m_x->read() >> 4; - - case 5: // Low nibble X? - return m_x->read() & 0x0f; - - case 6: // High nibble Y? - return m_y->read() >> 4; - - case 7: // Low Nibble Y? - return m_y->read() & 0x0f; - } - - return 0xff; + if (BIT(m_select, 5)) + return 0x20; // low four bits must be low to recognise Graphic Board, TL is a kind of active-low ready flag + else if (m_phase) + return BIT(m_data, BIT(m_select, 6) ? 0 : 4, 4) | 0x30; + else + return (m_buttons->read() & 0x1f) | 0x20; } -void sms_graphic_device::peripheral_w(uint8_t data) + +void sms_graphic_device::out_w(uint8_t data, uint8_t mem_mask) { - // Check for toggle on TH/TL - if ((data ^ m_previous_write) & 0xc0) + if (BIT(data, 5)) { - m_index++; + // TR high - deselected + m_phase = 0; } - - // If TR is high, restart - if (data & 0x80) + else if (!BIT(m_select, 5) && BIT(m_select, 6) && !BIT(data, 6)) { - m_index = 0; + // negative edge on TH seems to trigger acquisition + switch (m_phase) + { + case 0: + m_data = BIT(m_buttons->read(), 5) ? 0xfe : 0x00; // values made up to satisfy software + m_phase = 1; + break; + case 1: + m_data = m_x_axis->read(); + m_phase = 2; + break; + case 2: + m_data = m_y_axis->read(); + m_phase = 3; + break; + default: + break; // TODO: what actually happens if you keep clocking TH? + } } - m_previous_write = data; + m_select = data; } + +} // anonymous namespace + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(SMS_GRAPHIC, device_sms_control_interface, sms_graphic_device, "sms_graphic", "Sega Master System Graphic Board") |