trunk/src/mess/machine/mpu401.c
| r24853 | r24854 | |
| 40 | 40 | |
| 41 | 41 | #define M6801_TAG "mpu6801" |
| 42 | 42 | #define ROM_TAG "mpurom" |
| 43 | #define MIDIIN_TAG "mdin" |
| 44 | #define MIDIOUT_TAG "mdout" |
| 43 | 45 | |
| 44 | 46 | #define P2_SYNC_OUT (0x01) |
| 45 | 47 | #define P2_SYNC_IN (0x02) |
| r24853 | r24854 | |
| 64 | 66 | AM_RANGE(M6801_PORT2, M6801_PORT2) AM_READWRITE(port2_r, port2_w) |
| 65 | 67 | ADDRESS_MAP_END |
| 66 | 68 | |
| 69 | static SLOT_INTERFACE_START(midiin_slot) |
| 70 | SLOT_INTERFACE("midiin", MIDIIN_PORT) |
| 71 | SLOT_INTERFACE_END |
| 72 | |
| 73 | static const serial_port_interface midiin_intf = |
| 74 | { |
| 75 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, mpu401_device, midi_rx_w) |
| 76 | }; |
| 77 | |
| 78 | static SLOT_INTERFACE_START(midiout_slot) |
| 79 | SLOT_INTERFACE("midiout", MIDIOUT_PORT) |
| 80 | SLOT_INTERFACE_END |
| 81 | |
| 82 | static const serial_port_interface midiout_intf = |
| 83 | { |
| 84 | DEVCB_NULL // midi out ports don't transmit inward |
| 85 | }; |
| 86 | |
| 67 | 87 | MACHINE_CONFIG_FRAGMENT( mpu401 ) |
| 68 | 88 | MCFG_CPU_ADD(M6801_TAG, M6801, 4000000) /* 4 MHz as per schematics */ |
| 69 | 89 | MCFG_CPU_PROGRAM_MAP(mpu401_map) |
| 70 | 90 | MCFG_CPU_IO_MAP(mpu401_io_map) |
| 91 | MCFG_M6801_SER_TX(WRITELINE(mpu401_device, mpu401_midi_tx)) |
| 92 | |
| 93 | MCFG_SERIAL_PORT_ADD(MIDIIN_TAG, midiin_intf, midiin_slot, "midiin") |
| 94 | MCFG_SERIAL_PORT_ADD(MIDIOUT_TAG, midiout_intf, midiout_slot, "midiout") |
| 71 | 95 | MACHINE_CONFIG_END |
| 72 | 96 | |
| 73 | 97 | ROM_START( mpu401 ) |
| r24853 | r24854 | |
| 109 | 133 | //------------------------------------------------- |
| 110 | 134 | |
| 111 | 135 | mpu401_device::mpu401_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 112 | | device_t(mconfig, MPU401, "Roland MPU-401", tag, owner, clock, "mpu401", __FILE__), |
| 136 | device_t(mconfig, MPU401, "Roland MPU-401 I/O box", tag, owner, clock, "mpu401", __FILE__), |
| 113 | 137 | m_ourcpu(*this, M6801_TAG), |
| 138 | m_mdout(*this, MIDIOUT_TAG), |
| 114 | 139 | write_irq(*this) |
| 115 | 140 | { |
| 116 | 141 | } |
| r24853 | r24854 | |
| 122 | 147 | void mpu401_device::device_start() |
| 123 | 148 | { |
| 124 | 149 | write_irq.resolve_safe(); |
| 150 | m_timer = timer_alloc(0, NULL); |
| 125 | 151 | } |
| 126 | 152 | |
| 127 | 153 | //------------------------------------------------- |
| r24853 | r24854 | |
| 130 | 156 | |
| 131 | 157 | void mpu401_device::device_reset() |
| 132 | 158 | { |
| 133 | | m_port2 = 0xff & ~P2_SRCK_OUT; |
| 159 | m_port2 = 0xff & ~(P2_SRCK_OUT | P2_MIDI_IN); // prevent spurious reception |
| 134 | 160 | m_command = 0; |
| 135 | 161 | m_mpudata = 0; |
| 136 | 162 | m_gatearrstat = 0; |
| 163 | |
| 164 | m_timer->adjust(attotime::zero, 0, attotime::from_hz(31250*8)); |
| 137 | 165 | } |
| 138 | 166 | |
| 167 | //------------------------------------------------- |
| 168 | // device_timer - called when our device timer expires |
| 169 | //------------------------------------------------- |
| 170 | |
| 171 | void mpu401_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) |
| 172 | { |
| 173 | m_ourcpu->m6801_clock_serial(); |
| 174 | } |
| 175 | |
| 139 | 176 | READ8_MEMBER(mpu401_device::regs_mode2_r) |
| 140 | 177 | { |
| 141 | 178 | switch (offset) |
| r24853 | r24854 | |
| 179 | 216 | |
| 180 | 217 | WRITE8_MEMBER(mpu401_device::port1_w) |
| 181 | 218 | { |
| 182 | | printf("port1_w: %02x met %x syncout %x DSRD %d DRRD %d\n", data, data & 3, (data>>3) & 3, (data>>6) & 1, (data>>7) & 1); |
| 219 | // printf("port1_w: %02x met %x syncout %x DSRD %d DRRD %d\n", data, data & 3, (data>>3) & 3, (data>>6) & 1, (data>>7) & 1); |
| 183 | 220 | } |
| 184 | 221 | |
| 185 | 222 | READ8_MEMBER(mpu401_device::port2_r) |
| 186 | 223 | { |
| 187 | | printf("Read P2 (PC=%x)\n", space.device().safe_pc()); |
| 224 | // printf("Read P2 (PC=%x)\n", space.device().safe_pc()); |
| 188 | 225 | return m_port2; |
| 189 | 226 | } |
| 190 | 227 | |
| 191 | 228 | WRITE8_MEMBER(mpu401_device::port2_w) |
| 192 | 229 | { |
| 193 | | printf("port2_w: %02x SYCOUT %d SYCIN %d SRCK %d MIDI OUT %d\n", data, (data & 1), (data>>1) & 1, (data>>2) & 1, (data>>4) & 1); |
| 230 | // printf("port2_w: %02x SYCOUT %d SYCIN %d SRCK %d MIDI OUT %d\n", data, (data & 1), (data>>1) & 1, (data>>2) & 1, (data>>4) & 1); |
| 194 | 231 | } |
| 195 | 232 | |
| 196 | 233 | READ8_MEMBER(mpu401_device::mpu_r) |
| r24853 | r24854 | |
| 219 | 256 | { |
| 220 | 257 | m_gatearrstat |= STAT_CMD_PORT; |
| 221 | 258 | } |
| 259 | else |
| 260 | { |
| 261 | m_gatearrstat &= ~STAT_CMD_PORT; |
| 262 | } |
| 222 | 263 | } |
| 223 | 264 | |
| 224 | 265 | READ8_MEMBER(mpu401_device::asic_r) |
| r24853 | r24854 | |
| 248 | 289 | } |
| 249 | 290 | } |
| 250 | 291 | |
| 292 | // MIDI receive |
| 293 | WRITE_LINE_MEMBER( mpu401_device::midi_rx_w ) |
| 294 | { |
| 295 | if (state == ASSERT_LINE) |
| 296 | { |
| 297 | m_port2 |= P2_MIDI_IN; |
| 298 | } |
| 299 | else |
| 300 | { |
| 301 | m_port2 &= ~P2_MIDI_IN; |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | // MIDI send |
| 306 | WRITE_LINE_MEMBER(mpu401_device::mpu401_midi_tx) |
| 307 | { |
| 308 | m_mdout->tx(state); |
| 309 | } |
| 310 | |
trunk/src/mess/machine/mpu401.h
| r24853 | r24854 | |
| 5 | 5 | |
| 6 | 6 | #include "emu.h" |
| 7 | 7 | #include "cpu/m6800/m6800.h" |
| 8 | #include "machine/serial.h" |
| 9 | #include "machine/midiinport.h" |
| 10 | #include "machine/midioutport.h" |
| 8 | 11 | |
| 9 | 12 | #define MCFG_MPU401_ADD(_tag, _irqf ) \ |
| 10 | 13 | MCFG_DEVICE_ADD(_tag, MPU401, 0) \ |
| r24853 | r24854 | |
| 27 | 30 | virtual machine_config_constructor device_mconfig_additions() const; |
| 28 | 31 | |
| 29 | 32 | required_device<m6801_cpu_device> m_ourcpu; |
| 33 | required_device<serial_port_device> m_mdout; |
| 30 | 34 | |
| 31 | 35 | template<class _write> void set_irqf(_write wr) |
| 32 | 36 | { |
| r24853 | r24854 | |
| 43 | 47 | DECLARE_WRITE8_MEMBER(port1_w); |
| 44 | 48 | DECLARE_READ8_MEMBER(port2_r); |
| 45 | 49 | DECLARE_WRITE8_MEMBER(port2_w); |
| 50 | DECLARE_WRITE_LINE_MEMBER(midi_rx_w); |
| 51 | DECLARE_WRITE_LINE_MEMBER(mpu401_midi_tx); |
| 46 | 52 | |
| 47 | 53 | // public API - call for reads/writes at I/O 330/331 on PC, C0n0/C0n1 on Apple II, etc. |
| 48 | 54 | DECLARE_READ8_MEMBER(mpu_r); |
| r24853 | r24854 | |
| 53 | 59 | virtual void device_start(); |
| 54 | 60 | virtual void device_reset(); |
| 55 | 61 | virtual const rom_entry *device_rom_region() const; |
| 62 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 56 | 63 | |
| 57 | 64 | private: |
| 58 | 65 | UINT8 m_port2; |
| 59 | 66 | UINT8 m_command; |
| 60 | 67 | UINT8 m_mpudata; |
| 61 | 68 | UINT8 m_gatearrstat; |
| 69 | emu_timer *m_timer; |
| 62 | 70 | }; |
| 63 | 71 | |
| 64 | 72 | // device type definition |