trunk/src/emu/bus/nes_ctrl/miracle.c
| r243186 | r243187 | |
| 11 | 11 | **********************************************************************/ |
| 12 | 12 | |
| 13 | 13 | #include "miracle.h" |
| 14 | | #include "bus/midi/midi.h" |
| 15 | 14 | |
| 16 | 15 | #define MIRACLE_MIDI_WAITING 0 |
| 17 | | #define MIRACLE_MIDI_RECEIVE 1 |
| 18 | | #define MIRACLE_MIDI_SEND 2 |
| 16 | #define MIRACLE_MIDI_RECEIVE 1 // receive byte from piano |
| 17 | #define MIRACLE_MIDI_SEND 2 // send byte to piano |
| 19 | 18 | |
| 20 | 19 | //************************************************************************** |
| 21 | 20 | // DEVICE DEFINITIONS |
| r243186 | r243187 | |
| 25 | 24 | |
| 26 | 25 | |
| 27 | 26 | MACHINE_CONFIG_FRAGMENT( nes_miracle ) |
| 28 | | // MCFG_CPU_ADD("piano_cpu", I8051, XTAL_11_0592MHz) // xtal to be verified |
| 29 | | |
| 30 | 27 | MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin") |
| 31 | 28 | MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout") |
| 32 | 29 | MACHINE_CONFIG_END |
| r243186 | r243187 | |
| 58 | 55 | //------------------------------------------------- |
| 59 | 56 | |
| 60 | 57 | nes_miracle_device::nes_miracle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 61 | | device_t(mconfig, NES_MIRACLE, "Miracle Piano Controller", tag, owner, clock, "nes_miracle", __FILE__) |
| 62 | | , device_nes_control_port_interface(mconfig, *this) |
| 63 | | // , m_cpu(*this, "piano_cpu") |
| 58 | device_t(mconfig, NES_MIRACLE, "Miracle Piano Controller", tag, owner, clock, "nes_miracle", __FILE__), |
| 59 | device_serial_interface(mconfig, *this), |
| 60 | device_nes_control_port_interface(mconfig, *this), |
| 61 | m_midiin(*this, "mdin"), |
| 62 | m_midiout(*this, "mdout") |
| 64 | 63 | { |
| 65 | 64 | } |
| 66 | 65 | |
| r243186 | r243187 | |
| 90 | 89 | m_sent_bits = 0; |
| 91 | 90 | m_strobe_clock = 0; |
| 92 | 91 | m_midi_mode = MIRACLE_MIDI_WAITING; |
| 92 | |
| 93 | // set standard MIDI parameters |
| 94 | set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); |
| 95 | set_rcv_rate(31250); |
| 96 | set_tra_rate(31250); |
| 97 | |
| 98 | m_xmit_read = m_xmit_write = 0; |
| 99 | m_tx_busy = false; |
| 93 | 100 | } |
| 94 | 101 | |
| 95 | 102 | |
| r243186 | r243187 | |
| 102 | 109 | UINT8 nes_miracle_device::read_bit0() |
| 103 | 110 | { |
| 104 | 111 | UINT8 ret = 0; |
| 105 | | if (m_strobe_clock >= 66) |
| 106 | | { |
| 107 | | // more than 66 clocks since strobe on write means send mode |
| 108 | | m_midi_mode = MIRACLE_MIDI_SEND; |
| 109 | | strobe_timer->reset(); |
| 110 | | m_strobe_on = 0; |
| 111 | | m_strobe_clock = 0; |
| 112 | | // printf("send start\n"); |
| 113 | | } |
| 114 | 112 | |
| 115 | | if (m_midi_mode == MIRACLE_MIDI_SEND) |
| 113 | if (m_midi_mode == MIRACLE_MIDI_RECEIVE) |
| 116 | 114 | { |
| 117 | 115 | //NES reads from Miracle Piano! |
| 118 | 116 | // ret |= ... |
| r243186 | r243187 | |
| 126 | 124 | //------------------------------------------------- |
| 127 | 125 | |
| 128 | 126 | // TODO: here, writes to serial midi in bit0, when in MIDI_RECEIVE mode |
| 127 | // c4fc = start of recv routine |
| 128 | // c53a = start of send routine |
| 129 | 129 | |
| 130 | 130 | void nes_miracle_device::write(UINT8 data) |
| 131 | 131 | { |
| 132 | // printf("write: %d (%d %02x %d)\n", data & 1, m_sent_bits, m_data_sent, m_midi_mode); |
| 133 | |
| 134 | if (m_midi_mode == MIRACLE_MIDI_SEND) |
| 135 | { |
| 136 | //NES writes (data & 1) to Miracle Piano! |
| 137 | // 1st write is data present flag (1=data present) |
| 138 | // next 8 writes are actual data bits (with ^1) |
| 139 | m_sent_bits++; |
| 140 | m_data_sent <<= 1; |
| 141 | m_data_sent |= (data & 1); |
| 142 | // then we go back to waiting |
| 143 | if (m_sent_bits == 8) |
| 144 | { |
| 145 | // printf("xmit MIDI byte %02x\n", m_data_sent); |
| 146 | xmit_char(m_data_sent); |
| 147 | m_midi_mode = MIRACLE_MIDI_WAITING; |
| 148 | m_sent_bits = 0; |
| 149 | } |
| 150 | |
| 151 | return; |
| 152 | } |
| 153 | |
| 132 | 154 | if (data == 1 && !m_strobe_on) |
| 133 | 155 | { |
| 134 | 156 | strobe_timer->adjust(attotime::zero, 0, machine().device<cpu_device>("maincpu")->cycles_to_attotime(1)); |
| r243186 | r243187 | |
| 141 | 163 | // was timer running? |
| 142 | 164 | if (m_strobe_clock > 0) |
| 143 | 165 | { |
| 166 | // printf("got strobe at %d clocks\n", m_strobe_clock); |
| 167 | |
| 144 | 168 | if (m_strobe_clock < 66 && data == 0) |
| 145 | 169 | { |
| 146 | | // less than 66 clocks before new write means receive mode |
| 170 | // short delay is recieve mode |
| 147 | 171 | m_midi_mode = MIRACLE_MIDI_RECEIVE; |
| 148 | | // printf("receive start\n"); |
| 149 | 172 | strobe_timer->reset(); |
| 150 | 173 | m_strobe_on = 0; |
| 151 | 174 | m_strobe_clock = 0; |
| 152 | 175 | return; |
| 153 | 176 | } |
| 177 | else if (m_strobe_clock >= 66) |
| 178 | { |
| 179 | // more than 66 clocks since strobe on write means send mode |
| 180 | m_midi_mode = MIRACLE_MIDI_SEND; |
| 181 | strobe_timer->reset(); |
| 182 | m_strobe_on = 0; |
| 183 | m_strobe_clock = 0; |
| 184 | m_sent_bits = 1; |
| 185 | m_data_sent <<= 1; |
| 186 | m_data_sent |= (data & 1); |
| 187 | return; |
| 188 | } |
| 154 | 189 | } |
| 155 | 190 | |
| 156 | 191 | if (m_midi_mode == MIRACLE_MIDI_SEND && data == 0) |
| 157 | 192 | { |
| 158 | 193 | // strobe off after the end of a byte |
| 159 | 194 | m_midi_mode = MIRACLE_MIDI_WAITING; |
| 160 | | // printf("send end\n"); |
| 161 | 195 | } |
| 162 | 196 | } |
| 197 | } |
| 163 | 198 | |
| 164 | | if (m_midi_mode == MIRACLE_MIDI_RECEIVE) |
| 199 | void nes_miracle_device::rcv_complete() // Rx completed receiving byte |
| 200 | { |
| 201 | receive_register_extract(); |
| 202 | // UINT8 rcv = get_received_char(); |
| 203 | } |
| 204 | |
| 205 | void nes_miracle_device::tra_complete() // Tx completed sending byte |
| 206 | { |
| 207 | // printf("Tx complete\n"); |
| 208 | // is there more waiting to send? |
| 209 | if (m_xmit_read != m_xmit_write) |
| 165 | 210 | { |
| 166 | | //NES writes (data & 1) to Miracle Piano! |
| 167 | | // 1st write is data present flag (1=data present) |
| 168 | | // next 8 writes are actual data bits (with ^1) |
| 169 | | m_sent_bits++; |
| 170 | | // then we go back to waiting |
| 171 | | if (m_sent_bits == 9) |
| 211 | transmit_register_setup(m_xmitring[m_xmit_read++]); |
| 212 | if (m_xmit_read >= XMIT_RING_SIZE) |
| 172 | 213 | { |
| 173 | | // printf("receive end\n"); |
| 174 | | m_midi_mode = MIRACLE_MIDI_WAITING; |
| 175 | | m_sent_bits = 0; |
| 214 | m_xmit_read = 0; |
| 176 | 215 | } |
| 177 | 216 | } |
| 217 | else |
| 218 | { |
| 219 | m_tx_busy = false; |
| 220 | } |
| 178 | 221 | } |
| 222 | |
| 223 | void nes_miracle_device::tra_callback() // Tx send bit |
| 224 | { |
| 225 | // send this to midi out |
| 226 | m_midiout->write_txd(transmit_register_get_data_bit()); |
| 227 | } |
| 228 | |
| 229 | void nes_miracle_device::xmit_char(UINT8 data) |
| 230 | { |
| 231 | // printf("xmit %02x\n", data); |
| 232 | |
| 233 | // if tx is busy it'll pick this up automatically when it completes |
| 234 | // if not, send now! |
| 235 | if (!m_tx_busy) |
| 236 | { |
| 237 | m_tx_busy = true; |
| 238 | transmit_register_setup(data); |
| 239 | } |
| 240 | else |
| 241 | { |
| 242 | // tx is busy, it'll pick this up next time |
| 243 | m_xmitring[m_xmit_write++] = data; |
| 244 | if (m_xmit_write >= XMIT_RING_SIZE) |
| 245 | { |
| 246 | m_xmit_write = 0; |
| 247 | } |
| 248 | } |
| 249 | } |
| 250 | |
trunk/src/emu/bus/nes_ctrl/miracle.h
| r243186 | r243187 | |
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | 17 | #include "ctrl.h" |
| 18 | | //#include "cpu/mcs51/mcs51.h" |
| 18 | #include "bus/midi/midi.h" |
| 19 | 19 | |
| 20 | 20 | //************************************************************************** |
| 21 | 21 | // TYPE DEFINITIONS |
| r243186 | r243187 | |
| 24 | 24 | // ======================> nes_miracle_device |
| 25 | 25 | |
| 26 | 26 | class nes_miracle_device : public device_t, |
| 27 | public device_serial_interface, |
| 27 | 28 | public device_nes_control_port_interface |
| 28 | 29 | { |
| 29 | 30 | public: |
| 31 | static const int XMIT_RING_SIZE = 16; |
| 32 | |
| 30 | 33 | // construction/destruction |
| 31 | 34 | nes_miracle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 32 | 35 | |
| 33 | 36 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 34 | 37 | virtual machine_config_constructor device_mconfig_additions() const; |
| 35 | 38 | |
| 39 | // serial overrides |
| 40 | virtual void rcv_complete(); // Rx completed receiving byte |
| 41 | virtual void tra_complete(); // Tx completed sending byte |
| 42 | virtual void tra_callback(); // Tx send bit |
| 43 | |
| 44 | void xmit_char(UINT8 data); |
| 45 | |
| 46 | required_device<midi_port_device> m_midiin, m_midiout; |
| 47 | |
| 36 | 48 | protected: |
| 37 | 49 | // device-level overrides |
| 38 | 50 | virtual void device_start(); |
| r243186 | r243187 | |
| 44 | 56 | static const device_timer_id TIMER_STROBE_ON = 0; |
| 45 | 57 | emu_timer *strobe_timer; |
| 46 | 58 | |
| 47 | | //required_device<i8051_device> m_cpu; |
| 48 | 59 | int m_strobe_on, m_midi_mode, m_sent_bits; |
| 49 | 60 | UINT32 m_strobe_clock; |
| 61 | UINT8 m_data_sent; |
| 62 | UINT8 m_xmitring[XMIT_RING_SIZE]; |
| 63 | int m_xmit_read, m_xmit_write; |
| 64 | bool m_tx_busy; |
| 50 | 65 | }; |
| 51 | 66 | |
| 52 | 67 | // device type definition |