/* Ensoniq panel/display device */ #include "emu.h" #include "esqpanel.h" //************************************************************************** // MACROS / CONSTANTS //************************************************************************** //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** const device_type ESQPANEL1x22 = &device_creator; const device_type ESQPANEL2x40 = &device_creator; const device_type ESQPANEL2x40_SQ1 = &device_creator; //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // esqpanel_device - constructor //------------------------------------------------- esqpanel_device::esqpanel_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : device_t(mconfig, type, name, tag, owner, clock, shortname, source), device_serial_interface(mconfig, *this), m_write_tx(*this), m_write_analog(*this) { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void esqpanel_device::device_start() { m_write_tx.resolve_safe(); m_write_analog.resolve_safe(); } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void esqpanel_device::device_reset() { // panel comms is at 62500 baud (double the MIDI rate), 8N2 set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2); set_rcv_rate(62500); set_tra_rate(62500); m_tx_busy = false; m_xmit_read = m_xmit_write = 0; m_bCalibSecondByte = false; m_bButtonLightSecondByte = false; } void esqpanel_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { device_serial_interface::device_timer(timer, id, param, ptr); } void esqpanel_device::rcv_complete() // Rx completed receiving byte { receive_register_extract(); UINT8 data = get_received_char(); // if (data >= 0xe0) printf("Got %02x from motherboard (second %s)\n", data, m_bCalibSecondByte ? "yes" : "no"); send_to_display(data); if (m_bCalibSecondByte) { // printf("second byte is %02x\n", data); if (data == 0xfd) // calibration request { // printf("let's send reply!\n"); xmit_char(0xff); // this is the correct response for "calibration OK" } m_bCalibSecondByte = false; } else if (m_bButtonLightSecondByte) { // Lights on the Buttons, on the VFX-SD: // Number Button // 0 1-6 // 1 8 // 2 6 // 3 4 // 4 2 // 5 Compare // 6 1 // 7 Presets // 8 7-12 // 9 9 // a 7 // b 5 // c 3 // d Sounds // e 0 // f Cart // int lightNumber = data & 0x3f; // Light states: // 0 = Off // 2 = On // 3 = Blinking // int lightState = (data & 0xc0) >> 6; // TODO: do something with the button information! // printf("Setting light %d to %s\n", lightNumber, lightState == 3 ? "Blink" : lightState == 2 ? "On" : "Off"); m_bButtonLightSecondByte = false; } else if (data == 0xfb) // request calibration { m_bCalibSecondByte = true; } else if (data == 0xff) // button light state command { m_bButtonLightSecondByte = true; } else { // EPS wants a throwaway reply byte for each byte sent to the KPC // VFX-SD and SD-1 definitely don't :) if (m_eps_mode) { if (data == 0xe7) { xmit_char(0x00); // actual value of response is never checked } else if (data == 0x71) { xmit_char(0x00); // actual value of response is never checked } else { xmit_char(data); // actual value of response is never checked } } } } void esqpanel_device::tra_complete() // Tx completed sending byte { // printf("panel Tx complete\n"); // is there more waiting to send? if (m_xmit_read != m_xmit_write) { transmit_register_setup(m_xmitring[m_xmit_read++]); if (m_xmit_read >= XMIT_RING_SIZE) { m_xmit_read = 0; } } else { m_tx_busy = false; } } void esqpanel_device::tra_callback() // Tx send bit { m_write_tx(transmit_register_get_data_bit()); } void esqpanel_device::xmit_char(UINT8 data) { // printf("Panel: xmit %02x\n", data); // if tx is busy it'll pick this up automatically when it completes if (!m_tx_busy) { m_tx_busy = true; transmit_register_setup(data); } else { // tx is busy, it'll pick this up next time m_xmitring[m_xmit_write++] = data; if (m_xmit_write >= XMIT_RING_SIZE) { m_xmit_write = 0; } } } void esqpanel_device::set_analog_value(offs_t offset, UINT16 value) { m_write_analog(offset, value); } /* panel with 1x22 VFD display used in the EPS-16 and EPS-16 Plus */ static MACHINE_CONFIG_FRAGMENT(esqpanel1x22) MCFG_ESQ1x22_ADD("vfd") MACHINE_CONFIG_END machine_config_constructor esqpanel1x22_device::device_mconfig_additions() const { return MACHINE_CONFIG_NAME( esqpanel1x22 ); } esqpanel1x22_device::esqpanel1x22_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : esqpanel_device(mconfig, ESQPANEL1x22, "Ensoniq front panel with 1x22 VFD", tag, owner, clock, "esqpanel122", __FILE__), m_vfd(*this, "vfd") { m_eps_mode = true; } /* panel with 2x40 VFD display used in the ESQ-1, VFX-SD, SD-1, and others */ static MACHINE_CONFIG_FRAGMENT(esqpanel2x40) MCFG_ESQ2x40_ADD("vfd") MACHINE_CONFIG_END machine_config_constructor esqpanel2x40_device::device_mconfig_additions() const { return MACHINE_CONFIG_NAME( esqpanel2x40 ); } esqpanel2x40_device::esqpanel2x40_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : esqpanel_device(mconfig, ESQPANEL2x40, "Ensoniq front panel with 2x40 VFD", tag, owner, clock, "esqpanel240", __FILE__), m_vfd(*this, "vfd") { m_eps_mode = false; } /* panel with 2x16? LCD display used in the SQ and MR series, plus probably more */ static MACHINE_CONFIG_FRAGMENT(esqpanel2x40_sq1) MCFG_ESQ2x40_SQ1_ADD("vfd") MACHINE_CONFIG_END machine_config_constructor esqpanel2x40_sq1_device::device_mconfig_additions() const { return MACHINE_CONFIG_NAME( esqpanel2x40_sq1 ); } esqpanel2x40_sq1_device::esqpanel2x40_sq1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : esqpanel_device(mconfig, ESQPANEL2x40, "Ensoniq front panel with 2x16 LCD", tag, owner, clock, "esqpanel240_sq1", __FILE__), m_vfd(*this, "vfd") { m_eps_mode = false; }