Previous 199869 Revisions Next

r34803 Sunday 1st February, 2015 at 21:11:53 UTC by Fabio Priuli
serve an assist to Arbee for SNES Miracle Piano. nw.
[src/emu/bus]bus.mak
[src/emu/bus/snes_ctrl]ctrl.c miracle.c* miracle.h*

trunk/src/emu/bus/bus.mak
r243314r243315
11421142BUSOBJS += $(BUSOBJ)/snes_ctrl/ctrl.o
11431143BUSOBJS += $(BUSOBJ)/snes_ctrl/bcbattle.o
11441144BUSOBJS += $(BUSOBJ)/snes_ctrl/joypad.o
1145BUSOBJS += $(BUSOBJ)/snes_ctrl/miracle.o
11451146BUSOBJS += $(BUSOBJ)/snes_ctrl/mouse.o
11461147BUSOBJS += $(BUSOBJ)/snes_ctrl/multitap.o
11471148BUSOBJS += $(BUSOBJ)/snes_ctrl/pachinko.o
trunk/src/emu/bus/snes_ctrl/ctrl.c
r243314r243315
1111// slot devices
1212#include "bcbattle.h"
1313#include "joypad.h"
14#include "miracle.h"
1415#include "mouse.h"
1516#include "multitap.h"
1617#include "pachinko.h"
r243314r243315
132133   SLOT_INTERFACE("sscope", SNES_SUPERSCOPE)
133134   SLOT_INTERFACE("twintap", SNES_TWINTAP)
134135   SLOT_INTERFACE("barcode_battler", SNES_BARCODE_BATTLER)
136   SLOT_INTERFACE("miracle_piano", SNES_MIRACLE)
135137SLOT_INTERFACE_END
trunk/src/emu/bus/snes_ctrl/miracle.c
r0r243315
1/**********************************************************************
2
3    Nintendo SNES - Miracle Piano Keyboard
4
5    TODO: ???
6
7    Copyright MESS Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10**********************************************************************/
11
12#include "miracle.h"
13
14#define MIRACLE_MIDI_WAITING 0
15#define MIRACLE_MIDI_RECEIVE 1      // receive byte from piano
16#define MIRACLE_MIDI_SEND 2         // send byte to piano
17
18//**************************************************************************
19//  DEVICE DEFINITIONS
20//**************************************************************************
21
22const device_type SNES_MIRACLE = &device_creator<snes_miracle_device>;
23
24
25MACHINE_CONFIG_FRAGMENT( snes_miracle )
26   MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin")
27   MCFG_MIDI_RX_HANDLER(WRITELINE(snes_miracle_device, rx_w))
28
29   MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout")
30MACHINE_CONFIG_END
31
32machine_config_constructor snes_miracle_device::device_mconfig_additions() const
33{
34   return MACHINE_CONFIG_NAME( snes_miracle );
35}
36
37
38//-------------------------------------------------
39//  device_timer - handler timer events
40//-------------------------------------------------
41
42void snes_miracle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
43{
44   if (id == TIMER_STROBE_ON)
45   {
46      m_strobe_clock++;
47   }
48   else
49   {
50      device_serial_interface::device_timer(timer, id, param, ptr);
51   }
52}
53
54//**************************************************************************
55//  LIVE DEVICE
56//**************************************************************************
57
58//-------------------------------------------------
59//  snes_miracle_device - constructor
60//-------------------------------------------------
61
62snes_miracle_device::snes_miracle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
63               device_t(mconfig, SNES_MIRACLE, "Miracle Piano Controller (SNES)", tag, owner, clock, "snes_miracle", __FILE__),
64               device_serial_interface(mconfig, *this),
65               device_snes_control_port_interface(mconfig, *this),
66               m_midiin(*this, "mdin"),
67               m_midiout(*this, "mdout")
68{
69}
70
71
72//-------------------------------------------------
73//  device_start
74//-------------------------------------------------
75
76void snes_miracle_device::device_start()
77{
78   strobe_timer = timer_alloc(TIMER_STROBE_ON);
79   strobe_timer->adjust(attotime::never);
80   save_item(NAME(m_strobe_on));
81   save_item(NAME(m_sent_bits));
82   save_item(NAME(m_strobe_clock));
83   save_item(NAME(m_midi_mode));
84}
85
86
87//-------------------------------------------------
88//  device_reset
89//-------------------------------------------------
90
91void snes_miracle_device::device_reset()
92{
93   m_strobe_on = 0;
94   m_sent_bits = 0;
95   m_strobe_clock = 0;
96   m_midi_mode = MIRACLE_MIDI_WAITING;
97
98   // set standard MIDI parameters
99   set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
100   set_rcv_rate(31250);
101   set_tra_rate(31250);
102
103   m_xmit_read = m_xmit_write = 0;
104   m_recv_read = m_recv_write = 0;
105   m_read_status = m_status_bit = false;
106   m_tx_busy = false;
107}
108
109
110//-------------------------------------------------
111//  read
112//-------------------------------------------------
113
114UINT8 snes_miracle_device::read_pin4()
115{
116   UINT8 ret = 0;
117
118   if (m_midi_mode == MIRACLE_MIDI_RECEIVE)
119   {
120      if (m_status_bit)
121      {
122         m_status_bit = false;
123         ret = (m_read_status) ? 1 : 0;
124      }
125      else
126      {
127         ret = (m_data_sent & 0x80) ? 0 : 1;
128         m_data_sent <<= 1;
129      }
130   }
131
132   return ret;
133}
134
135//-------------------------------------------------
136//  write
137//-------------------------------------------------
138
139// c4fc = start of recv routine
140// c53a = start of send routine
141
142void snes_miracle_device::write_strobe(UINT8 data)
143{
144//   printf("write: %d (%d %02x %d)\n", data & 1, m_sent_bits, m_data_sent, m_midi_mode);
145
146   if (m_midi_mode == MIRACLE_MIDI_SEND)
147   {
148      //SNES writes (data & 1) to Miracle Piano!
149      // 1st write is data present flag (1=data present)
150      // next 8 writes are actual data bits (with ^1)
151      m_sent_bits++;
152      m_data_sent <<= 1;
153      m_data_sent |= (data & 1);
154      // then we go back to waiting
155      if (m_sent_bits == 8)
156      {
157//         printf("xmit MIDI byte %02x\n", m_data_sent);
158         xmit_char(m_data_sent);
159         m_midi_mode = MIRACLE_MIDI_WAITING;
160         m_sent_bits = 0;
161      }
162
163      return;
164   }
165
166   if (data == 1 && !m_strobe_on)
167   {
168      strobe_timer->adjust(attotime::zero, 0, machine().device<cpu_device>("maincpu")->cycles_to_attotime(1));
169      m_strobe_on = 1;
170      return;
171   }
172
173   if (m_strobe_on)
174   {
175      // was timer running?
176      if (m_strobe_clock > 0)
177      {
178//         printf("got strobe at %d clocks\n", m_strobe_clock);
179
180         if (m_strobe_clock < 528 && data == 0)
181         {
182            // short delay is recieve mode
183            m_midi_mode = MIRACLE_MIDI_RECEIVE;
184            strobe_timer->reset();
185            m_strobe_on = 0;
186            m_strobe_clock = 0;
187
188            m_status_bit = true;
189            if (m_recv_read != m_recv_write)
190            {
191//               printf("Getting %02x from Miracle[%d]\n", m_recvring[m_recv_read], m_recv_read);
192               m_data_sent = m_recvring[m_recv_read++];
193               if (m_recv_read >= RECV_RING_SIZE)
194               {
195                  m_recv_read = 0;
196               }
197               m_read_status = true;
198            }
199            else
200            {
201               m_read_status = false;
202//               printf("Miracle has no data\n");
203            }
204            return;
205         }
206         else if (m_strobe_clock >= 528)
207         {
208            // more than 528 clocks since strobe on write means send mode
209            m_midi_mode = MIRACLE_MIDI_SEND;
210            strobe_timer->reset();
211            m_strobe_on = 0;
212            m_strobe_clock = 0;
213            m_sent_bits = 1;
214            m_data_sent <<= 1;
215            m_data_sent |= (data & 1);
216            return;
217         }
218      }
219
220      if (m_midi_mode == MIRACLE_MIDI_SEND &&  data == 0)
221      {
222         // strobe off after the end of a byte
223         m_midi_mode = MIRACLE_MIDI_WAITING;
224      }
225   }
226}
227
228void snes_miracle_device::rcv_complete()    // Rx completed receiving byte
229{
230   receive_register_extract();
231   UINT8 rcv = get_received_char();
232
233//   printf("Got %02x -> [%d]\n", rcv, m_recv_write);
234   m_recvring[m_recv_write++] = rcv;
235   if (m_recv_write >= RECV_RING_SIZE)
236   {
237      m_recv_write = 0;
238   }
239}
240
241void snes_miracle_device::tra_complete()    // Tx completed sending byte
242{
243   // is there more waiting to send?
244   if (m_xmit_read != m_xmit_write)
245   {
246      transmit_register_setup(m_xmitring[m_xmit_read++]);
247      if (m_xmit_read >= XMIT_RING_SIZE)
248      {
249         m_xmit_read = 0;
250      }
251   }
252   else
253   {
254      m_tx_busy = false;
255   }
256}
257
258void snes_miracle_device::tra_callback()    // Tx send bit
259{
260   UINT8 bit = transmit_register_get_data_bit();
261
262   // send this to midi out
263   m_midiout->write_txd(bit);
264}
265
266void snes_miracle_device::xmit_char(UINT8 data)
267{
268   // if tx is busy it'll pick this up automatically when it completes
269   // if not, send now!
270   if (!m_tx_busy)
271   {
272      m_tx_busy = true;
273      transmit_register_setup(data);
274   }
275   else
276   {
277      // tx is busy, it'll pick this up next time
278      m_xmitring[m_xmit_write++] = data;
279      if (m_xmit_write >= XMIT_RING_SIZE)
280      {
281         m_xmit_write = 0;
282      }
283   }
284}
285
trunk/src/emu/bus/snes_ctrl/miracle.h
r0r243315
1/**********************************************************************
2
3    Nintendo Entertainment System - Miracle Piano Keyboard
4
5    Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
7
8**********************************************************************/
9
10#pragma once
11
12#ifndef __SNES_MIRACLE__
13#define __SNES_MIRACLE__
14
15
16#include "emu.h"
17#include "ctrl.h"
18#include "bus/midi/midi.h"
19
20//**************************************************************************
21//  TYPE DEFINITIONS
22//**************************************************************************
23
24// ======================> snes_miracle_device
25
26class snes_miracle_device : public device_t,
27                     public device_serial_interface,
28                     public device_snes_control_port_interface
29{
30public:
31   static const int XMIT_RING_SIZE = 64;
32   static const int RECV_RING_SIZE = 64;
33
34   // construction/destruction
35   snes_miracle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
36
37   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
38   virtual machine_config_constructor device_mconfig_additions() const;
39
40   // serial overrides
41   virtual void rcv_complete();    // Rx completed receiving byte
42   virtual void tra_complete();    // Tx completed sending byte
43   virtual void tra_callback();    // Tx send bit
44
45   void xmit_char(UINT8 data);
46
47   required_device<midi_port_device> m_midiin, m_midiout;
48
49protected:
50   // device-level overrides
51   virtual void device_start();
52   virtual void device_reset();
53
54   virtual UINT8 read_pin4();
55   virtual void write_strobe(UINT8 data);
56
57   static const device_timer_id TIMER_STROBE_ON = 0;
58   emu_timer *strobe_timer;
59
60   int m_strobe_on, m_midi_mode, m_sent_bits;
61   UINT32 m_strobe_clock;
62   UINT8 m_data_sent;
63   UINT8 m_xmitring[XMIT_RING_SIZE], m_recvring[RECV_RING_SIZE];
64   int m_xmit_read, m_xmit_write;
65   int m_recv_read, m_recv_write;
66   bool m_tx_busy, m_read_status, m_status_bit;
67};
68
69// device type definition
70extern const device_type SNES_MIRACLE;
71
72#endif


Previous 199869 Revisions Next


© 1997-2024 The MAME Team