Previous 199869 Revisions Next

r20071 Saturday 5th January, 2013 at 05:03:38 UTC by R. Belmont
Checkpoint of "n68681" modernized, diserial-ized 68681 device (nw)

This covers the modernization aspect; the diserial-ization comes next.  Do not convert other drivers to use this yet.
[src/emu]emu.mak
[src/emu/machine]n68681.c* n68681.h*
[src/mess/drivers]esq5505.c

trunk/src/emu/emu.mak
r20070r20071
152152   $(EMUMACHINE)/6840ptm.o      \
153153   $(EMUMACHINE)/6850acia.o   \
154154   $(EMUMACHINE)/68681.o      \
155   $(EMUMACHINE)/n68681.o      \
155156   $(EMUMACHINE)/74123.o      \
156157   $(EMUMACHINE)/74148.o      \
157158   $(EMUMACHINE)/74153.o      \
trunk/src/emu/machine/n68681.c
r0r20071
1/*
2    68681 DUART
3
4    Written by Mariusz Wojcieszek
5    Updated by Jonathan Gevaryahu AKA Lord Nightmare
6    Improved interrupt handling by R. Belmont
7    Rewrite and modernization in progress by R. Belmont
8*/
9
10#include "emu.h"
11#include "n68681.h"
12
13#define VERBOSE 0
14#define LOG(x)   do { if (VERBOSE) logerror x; } while (0)
15
16static const char *const duart68681_reg_read_names[0x10] =
17{
18   "MRA", "SRA", "BRG Test", "RHRA", "IPCR", "ISR", "CTU", "CTL", "MRB", "SRB", "1X/16X Test", "RHRB", "IVR", "Input Ports", "Start Counter", "Stop Counter"
19};
20
21static const char *const duart68681_reg_write_names[0x10] =
22{
23   "MRA", "CSRA", "CRA", "THRA", "ACR", "IMR", "CRUR", "CTLR", "MRB", "CSRB", "CRB", "THRB", "IVR", "OPCR", "Set OP Bits", "Reset OP Bits"
24};
25
26#define INT_INPUT_PORT_CHANGE      0x80
27#define INT_DELTA_BREAK_B         0x40
28#define INT_RXRDY_FFULLB         0x20
29#define INT_TXRDYB               0x10
30#define INT_COUNTER_READY         0x08
31#define INT_DELTA_BREAK_A         0x04
32#define INT_RXRDY_FFULLA         0x02
33#define INT_TXRDYA               0x01
34
35#define STATUS_RECEIVED_BREAK      0x80
36#define STATUS_FRAMING_ERROR      0x40
37#define STATUS_PARITY_ERROR         0x20
38#define STATUS_OVERRUN_ERROR      0x10
39#define STATUS_TRANSMITTER_EMPTY   0x08
40#define STATUS_TRANSMITTER_READY   0x04
41#define STATUS_FIFO_FULL         0x02
42#define STATUS_RECEIVER_READY      0x01
43
44#define MODE_RX_INT_SELECT_BIT      0x40
45
46// device type definition
47const device_type DUARTN68681 = &device_creator<duartn68681_device>;
48
49//**************************************************************************
50//  LIVE DEVICE
51//**************************************************************************
52
53duartn68681_device::duartn68681_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
54   : device_t(mconfig, DUARTN68681, "DUART 68681 (new)", tag, owner, clock),
55   device_serial_interface(mconfig, *this)
56{
57}
58
59/*-------------------------------------------------
60    device start callback
61-------------------------------------------------*/
62
63void duartn68681_device::device_start()
64{
65   m_out_irq_func.resolve(m_out_irq_cb, *this);
66   m_out_a_tx_func.resolve(m_out_a_tx_cb, *this);
67   m_out_b_tx_func.resolve(m_out_b_tx_cb, *this);
68   m_in_port_func.resolve(m_in_port_cb, *this);
69   m_out_port_func.resolve(m_out_port_cb, *this);
70
71   channel[0].tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(duartn68681_device::tx_timer_callback),this), NULL);
72   channel[1].tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(duartn68681_device::tx_timer_callback),this), NULL);
73   duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(duartn68681_device::duart_timer_callback),this), NULL);
74
75   save_item(NAME(ACR));
76   save_item(NAME(IMR));
77   save_item(NAME(ISR));
78   save_item(NAME(IVR));
79   save_item(NAME(OPCR));
80   save_item(NAME(CTR));
81   save_item(NAME(IP_last_state));
82   save_item(NAME(half_period));
83
84   save_item(NAME(channel[0].CR));
85   save_item(NAME(channel[0].CSR));
86   save_item(NAME(channel[0].MR1));
87   save_item(NAME(channel[0].MR2));
88   save_item(NAME(channel[0].MR_ptr));
89   save_item(NAME(channel[0].SR));
90   save_item(NAME(channel[0].baud_rate));
91   save_item(NAME(channel[0].rx_enabled));
92   save_item(NAME(channel[0].rx_fifo));
93   save_item(NAME(channel[0].rx_fifo_read_ptr));
94   save_item(NAME(channel[0].rx_fifo_write_ptr));
95   save_item(NAME(channel[0].rx_fifo_num));
96   save_item(NAME(channel[0].tx_enabled));
97   save_item(NAME(channel[0].tx_data));
98   save_item(NAME(channel[0].tx_ready));
99
100   save_item(NAME(channel[1].CR));
101   save_item(NAME(channel[1].CSR));
102   save_item(NAME(channel[1].MR1));
103   save_item(NAME(channel[1].MR2));
104   save_item(NAME(channel[1].MR_ptr));
105   save_item(NAME(channel[1].SR));
106   save_item(NAME(channel[1].baud_rate));
107   save_item(NAME(channel[1].rx_enabled));
108   save_item(NAME(channel[1].rx_fifo));
109   save_item(NAME(channel[1].rx_fifo_read_ptr));
110   save_item(NAME(channel[1].rx_fifo_write_ptr));
111   save_item(NAME(channel[1].rx_fifo_num));
112   save_item(NAME(channel[1].tx_enabled));
113   save_item(NAME(channel[1].tx_data));
114   save_item(NAME(channel[1].tx_ready));
115}
116
117/*-------------------------------------------------
118    device reset callback
119-------------------------------------------------*/
120
121void duartn68681_device::device_reset()
122{
123   emu_timer *save0, *save1;
124
125   ACR = 0;  /* Interrupt Vector Register */
126   IVR = 0x0f;  /* Interrupt Vector Register */
127   IMR = 0;  /* Interrupt Mask Register */
128   ISR = 0;  /* Interrupt Status Register */
129   OPCR = 0; /* Output Port Conf. Register */
130   OPR = 0;  /* Output Port Register */
131   CTR.d = 0;  /* Counter/Timer Preset Value */
132   IP_last_state = 0;  /* last state of IP bits */
133   // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state"
134   save0 = channel[0].tx_timer;
135   save1 = channel[1].tx_timer;
136   memset(channel, 0, sizeof(channel));
137   channel[0].tx_timer = save0;
138   channel[1].tx_timer = save1;
139
140   m_out_port_func(0, OPR ^ 0xff);
141
142   // reset timers
143   channel[0].tx_timer->adjust(attotime::never);
144   channel[1].tx_timer->adjust(attotime::never, 1);
145}
146
147//-------------------------------------------------
148//  device_config_complete - perform any
149//  operations now that the configuration is
150//  complete
151//-------------------------------------------------
152
153void duartn68681_device::device_config_complete()
154{
155   m_shortname = "dun68681";
156
157   // inherit a copy of the static data
158   const duartn68681_config *intf = reinterpret_cast<const duartn68681_config *>(static_config());
159   if (intf != NULL)
160   {
161      *static_cast<duartn68681_config *>(this) = *intf;
162   }
163   // or initialize to defaults if none provided
164   else
165   {
166      memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb));
167      memset(&m_out_a_tx_cb, 0, sizeof(m_out_a_tx_cb));
168      memset(&m_out_b_tx_cb, 0, sizeof(m_out_b_tx_cb));
169      memset(&m_in_port_cb, 0, sizeof(m_in_port_cb));
170      memset(&m_out_port_cb, 0, sizeof(m_out_port_cb));
171   }
172}
173
174void duartn68681_device::update_interrupts()
175{
176   /* update SR state and update interrupt ISR state for the following bits:
177    SRn: bits 7-4: handled elsewhere.
178    SRn: bit 3 (TxEMTn) (we can assume since we're not actually emulating the delay/timing of sending bits, that as long as TxRDYn is set, TxEMTn is also set since the transmit byte has 'already happened', therefore TxEMTn is always 1 assuming tx is enabled on channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined)
179    SRn: bit 2 (TxRDYn) (we COULD assume since we're not emulating delay and timing output, that as long as tx is enabled on channel n, TxRDY is 1 for channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined; however, tx_ready is already nicely handled for us elsewhere, so we can use that instead for now, though we may need to retool that code as well)
180    SRn: bit 1 (FFULLn) (this bit we actually emulate; if the receive fifo for channel n is full, this bit is 1, otherwise it is 0. the receive fifo should be three words long.)
181    SRn: bit 0 (RxRDYn) (this bit we also emulate; the bit is always asserted if the receive fifo is not empty)
182    ISR: bit 7: Input Port change; this should be handled elsewhere, on the input port handler
183    ISR: bit 6: Delta Break B; this should be handled elsewhere, on the data receive handler
184    ISR: bit 5: RxRDYB/FFULLB: this is handled here; depending on whether MSR1B bit 6 is 0 or 1, this bit holds the state of SRB bit 0 or bit 1 respectively
185    ISR: bit 4: TxRDYB: this is handled here; it mirrors SRB bit 2
186    ISR: bit 3: Counter ready; this should be handled by the timer generator
187    ISR: bit 2: Delta Break A; this should be handled elsewhere, on the data receive handler
188    ISR: bit 1: RxRDYA/FFULLA: this is handled here; depending on whether MSR1A bit 6 is 0 or 1, this bit holds the state of SRA bit 0 or bit 1 respectively
189    ISR: bit 0: TxRDYA: this is handled here; it mirrors SRA bit 2
190    */
191   UINT8 ch = 0;
192   //logerror("DEBUG: 68681 int check: upon func call, SRA is %02X, SRB is %02X, ISR is %02X\n", duart68681->channel[0].SR, duart68681->channel[1].SR, duart68681->ISR);
193   for (ch = 0; ch < 2; ch++)
194   {
195      //if ( duart68681->channel[ch].rx_enabled )
196      //{
197         if ( channel[ch].rx_fifo_num > 0 )
198         {
199            channel[ch].SR |= STATUS_RECEIVER_READY;
200         }
201         else
202         {
203            channel[ch].SR &= ~STATUS_RECEIVER_READY;
204         }
205         if ( channel[ch].rx_fifo_num == MC68681_RX_FIFO_SIZE )
206         {
207            channel[ch].SR |= STATUS_FIFO_FULL;
208         }
209         else
210         {
211            channel[ch].SR &= ~STATUS_FIFO_FULL;
212         }
213      //}
214      //else
215      //{
216      //duart68681->channel[ch].SR &= ~STATUS_RECEIVER_READY;
217      //duart68681->channel[ch].SR &= ~STATUS_FIFO_FULL;
218      //}
219      // Handle the TxEMT and TxRDY bits based on mode
220      switch( channel[ch].MR2&0xC0) // what mode are we in?
221         {
222         case 0x00: // normal mode
223            if ( channel[ch].tx_enabled )
224            {
225               channel[ch].SR |= STATUS_TRANSMITTER_EMPTY;
226            }
227            else
228            {
229               channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
230            }
231         break;
232         case 0x40: // automatic echo mode
233            channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
234            channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
235         break;
236         case 0x80: // local loopback mode
237            if ( channel[ch].tx_enabled )
238            {
239               channel[ch].SR |= STATUS_TRANSMITTER_EMPTY;
240            }
241            else
242            {
243               channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
244            }
245         break;
246         case 0xC0: // remote loopback mode
247            // write me, what the txrdy/txemt regs do for remote loopback mode is undocumented afaik, for now just clear both
248            channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
249            channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
250         break;
251         }
252      // now handle the ISR bits
253      if ( channel[ch].SR & STATUS_TRANSMITTER_READY )
254      {
255         if (ch == 0)
256            ISR |= INT_TXRDYA;
257         else
258            ISR |= INT_TXRDYB;
259      }
260      else
261      {
262         if (ch == 0)
263            ISR &= ~INT_TXRDYA;
264         else
265            ISR &= ~INT_TXRDYB;
266      }
267      //logerror("DEBUG: 68681 int check: before receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR);
268      if ( channel[ch].MR1 & MODE_RX_INT_SELECT_BIT )
269      {
270         if ( channel[ch].SR & STATUS_FIFO_FULL )
271         {
272            ISR |= ((ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB);
273         }
274         else
275         {
276            ISR &= ((ch == 0) ? ~INT_RXRDY_FFULLA : ~INT_RXRDY_FFULLB);
277         }
278      }
279      else
280      {
281         if ( channel[ch].SR & STATUS_RECEIVER_READY )
282         {
283            ISR |= ((ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB);
284         }
285         else
286         {
287            ISR &= ((ch == 0) ? ~INT_RXRDY_FFULLA : ~INT_RXRDY_FFULLB);
288         }
289      }
290      //logerror("DEBUG: 68681 int check: after receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR);
291   }
292   if ( (ISR & IMR) != 0 )
293   {
294      LOG(( "68681: Interrupt line active (IMR & ISR = %02X)\n", (ISR & IMR) ));
295      m_out_irq_func(ASSERT_LINE);
296   }
297    else
298    {
299      LOG(( "68681: Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR));
300      m_out_irq_func(CLEAR_LINE);
301    }
302};
303
304double duartn68681_device::duart68681_get_ct_rate()
305{
306   double rate = 0.0f;
307
308   if (ACR & 0x40)
309   {
310      // Timer mode
311      switch ((ACR >> 4) & 3)
312      {
313         case 0: // IP2
314         case 1: // IP2 / 16
315            //logerror( "68681 (%s): Unhandled timer/counter mode %d\n", duart68681->tag(), (duart68681->ACR >> 4) & 3);
316            rate = clock();
317            break;
318         case 2: // X1/CLK
319            rate = clock();
320            break;
321         case 3: // X1/CLK / 16
322            rate = clock() / 16;
323            break;
324      }
325   }
326   else
327   {
328      // Counter mode
329      switch ((ACR >> 4) & 3)
330      {
331         case 0: // IP2
332         case 1: // TxCA
333         case 2: // TxCB
334            //logerror( "68681 (%s): Unhandled timer/counter mode %d\n", device->tag(), (duart68681->ACR >> 4) & 3);
335            rate = clock();
336            break;
337         case 3: // X1/CLK / 16
338            rate = clock() / 16;
339            break;
340      }
341   }
342
343   return rate;
344}
345
346UINT16 duartn68681_device::duart68681_get_ct_count()
347{
348   double clock = duart68681_get_ct_rate();
349   return (duart_timer->remaining() * clock).as_double();
350}
351
352void duartn68681_device::duart68681_start_ct(int count)
353{
354   double clock = duart68681_get_ct_rate();
355   duart_timer->adjust(attotime::from_hz(clock) * count, 0);
356}
357
358TIMER_CALLBACK_MEMBER( duartn68681_device::duart_timer_callback )
359{
360   if (ACR & 0x40)
361   {
362      // Timer mode
363      half_period ^= 1;
364
365      // TODO: Set OP3
366
367      if (!half_period)
368      {
369         ISR |= INT_COUNTER_READY;
370         update_interrupts();
371      }
372
373      int count = MAX(CTR.w.l, 1);
374      duart68681_start_ct(count);
375   }
376   else
377   {
378      // Counter mode
379      ISR |= INT_COUNTER_READY;
380      update_interrupts();
381      duart68681_start_ct(0xffff);
382   }
383
384};
385
386void duartn68681_device::duart68681_write_MR(int ch, UINT8 data)
387{
388   if ( channel[ch].MR_ptr == 0 )
389   {
390      channel[ch].MR1 = data;
391      channel[ch].MR_ptr = 1;
392   }
393   else
394   {
395      channel[ch].MR2 = data;
396   }
397   update_interrupts();
398};
399
400void duartn68681_device::duart68681_write_CSR(int ch, UINT8 data, UINT8 inACR)
401{
402   static const int baud_rate_ACR_0[] = { 50, 110, 134, 200, 300, 600, 1200, 1050, 2400, 4800, 7200, 9600, 38400, 0, 0, 0 };
403   static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000, 2400, 4800, 1800, 9600, 19200, 0, 0, 0 };
404
405   channel[ch].CSR = data;
406
407   if ( BIT(inACR,7) == 0 )
408   {
409      channel[ch].baud_rate = baud_rate_ACR_0[data & 0x0f];
410
411      if (ch == 0)
412      {
413         if ((data & 0xf) == 0xe)
414         {
415            channel[ch].baud_rate = ip3clk/16;
416         }
417         else if ((data & 0xf) == 0xf)
418         {
419            channel[ch].baud_rate = ip3clk;
420         }
421      }
422      else if (ch == 1)
423      {
424         if ((data & 0xf) == 0xe)
425         {
426            channel[ch].baud_rate = ip5clk/16;
427         }
428         else if ((data & 0xf) == 0xf)
429         {
430            channel[ch].baud_rate = ip5clk;
431         }
432      }
433   }
434   else
435   {
436      channel[ch].baud_rate = baud_rate_ACR_1[data & 0x0f];
437   }
438   if ( channel[ch].baud_rate == 0 )
439   {
440      LOG(( "Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data ));
441   }
442};
443
444void duartn68681_device::duart68681_write_CR(int ch, UINT8 data)
445{
446   channel[ch].CR = data;
447
448   switch( (data >> 4) & 0x07 )
449   {
450      case 0: /* No command */
451         break;
452      case 1: /* Reset MR pointer. Causes the Channel A MR pointer to point to MR1 */
453         channel[ch].MR_ptr = 0;
454         break;
455      case 2: /* Reset channel A receiver (disable receiver and flush fifo) */
456         channel[ch].rx_enabled = 0;
457         channel[ch].SR &= ~STATUS_RECEIVER_READY;
458         channel[ch].SR &= ~STATUS_OVERRUN_ERROR; // is this correct?
459         channel[ch].rx_fifo_read_ptr = 0;
460         channel[ch].rx_fifo_write_ptr = 0;
461         channel[ch].rx_fifo_num = 0;
462         break;
463      case 3: /* Reset channel A transmitter */
464         channel[ch].tx_enabled = 0;
465         channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
466         if (ch == 0)
467            ISR &= ~INT_TXRDYA;
468         else
469            ISR &= ~INT_TXRDYB;
470         channel[ch].tx_timer->adjust(attotime::never, ch);
471            break;
472      case 4: /* Reset Error Status */
473         channel[ch].SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR | STATUS_OVERRUN_ERROR);
474         break;
475      case 5: /* Reset Channel break change interrupt */
476         if ( ch == 0 )
477         {
478            ISR &= ~INT_DELTA_BREAK_A;
479         }
480         else
481         {
482            ISR &= ~INT_DELTA_BREAK_B;
483         }
484         break;
485      /* TODO: case 6 and case 7 are start break and stop break respectively, which start or stop holding the TxDA or TxDB line low (space) after whatever data is in the buffer finishes transmitting (following the stop bit?), or after two bit-times if no data is being transmitted  */
486      default:
487         LOG(( "68681: Unhandled command (%x) in CR%d\n", (data >> 4) & 0x07, ch ));
488         break;
489   }
490
491   if (BIT(data, 0)) {
492      channel[ch].rx_enabled = 1;
493   }
494   if (BIT(data, 1)) {
495      channel[ch].rx_enabled = 0;
496      channel[ch].SR &= ~STATUS_RECEIVER_READY;
497   }
498
499   if (BIT(data, 2)) {
500      channel[ch].tx_enabled = 1;
501      channel[ch].tx_ready = 1;
502      channel[ch].SR |= STATUS_TRANSMITTER_READY;
503      if (ch == 0)
504         ISR |= INT_TXRDYA;
505      else
506         ISR |= INT_TXRDYB;
507   }
508   if (BIT(data, 3)) {
509      channel[ch].tx_enabled = 0;
510      channel[ch].tx_ready = 0;
511      channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
512      if (ch == 0)
513         ISR &= ~INT_TXRDYA;
514      else
515         ISR &= ~INT_TXRDYB;
516   }
517
518    update_interrupts();
519};
520
521UINT8 duartn68681_device::duart68681_read_rx_fifo(int ch)
522{
523   UINT8 r;
524
525   if ( channel[ch].rx_fifo_num == 0 )
526   {
527      LOG(( "68681: rx fifo underflow\n" ));
528      return 0x0;
529   }
530
531   r = channel[ch].rx_fifo[channel[ch].rx_fifo_read_ptr++];
532   if ( channel[ch].rx_fifo_read_ptr == MC68681_RX_FIFO_SIZE )
533   {
534      channel[ch].rx_fifo_read_ptr = 0;
535   }
536
537   channel[ch].rx_fifo_num--;
538   update_interrupts();
539
540   return r;
541};
542
543TIMER_CALLBACK_MEMBER( duartn68681_device::tx_timer_callback )
544{
545   int ch = param & 1;
546
547   // send the byte unless we're in loopback mode;
548   // in loopback mode do NOT 'actually' send the byte: the TXn pin is held high when loopback mode is on.
549   if ((channel[ch].MR2&0xC0) != 0x80)
550   {
551      if (ch == 0)
552      {
553         m_out_a_tx_func(0, channel[0].tx_data);
554      }
555      else if (ch == 1)
556      {
557         m_out_b_tx_func(0, channel[1].tx_data);
558      }
559   }
560
561   // if local loopback is on, write the transmitted data as if a byte had been received
562   if ((channel[ch].MR2 & 0xC0) == 0x80)
563   {
564      if (channel[ch].rx_fifo_num >= MC68681_RX_FIFO_SIZE)
565      {
566         LOG(( "68681: FIFO overflow\n" ));
567         channel[ch].SR |= STATUS_OVERRUN_ERROR;
568      }
569      else
570      {
571         channel[ch].rx_fifo[channel[ch].rx_fifo_write_ptr++]
572               = channel[ch].tx_data;
573         if (channel[ch].rx_fifo_write_ptr == MC68681_RX_FIFO_SIZE)
574         {
575            channel[ch].rx_fifo_write_ptr = 0;
576         }
577         channel[ch].rx_fifo_num++;
578      }
579   }
580
581   channel[ch].tx_ready = 1;
582   channel[ch].SR |= STATUS_TRANSMITTER_READY;
583
584   if (ch == 0)
585      ISR |= INT_TXRDYA;
586   else
587      ISR |= INT_TXRDYB;
588
589   update_interrupts();
590   channel[ch].tx_timer->adjust(attotime::never, ch);
591};
592
593void duartn68681_device::duart68681_write_TX(int ch, UINT8 data)
594{
595   attotime period;
596
597   channel[ch].tx_data = data;
598
599   channel[ch].tx_ready = 0;
600   channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
601
602   if (ch == 0)
603      ISR &= ~INT_TXRDYA;
604   else
605      ISR &= ~INT_TXRDYB;
606
607   update_interrupts();
608
609   period = attotime::from_hz(channel[ch].baud_rate / 10 );
610   channel[ch].tx_timer->adjust(period, ch);
611};
612
613READ8_MEMBER( duartn68681_device::read )
614{
615   UINT8 r = 0xff;
616
617   offset &= 0xf;
618
619   LOG(( "Reading 68681 (%s) reg %x (%s) ", tag(), offset, duart68681_reg_read_names[offset] ));
620
621   switch (offset)
622   {
623      case 0x00: /* MR1A/MR2A */
624         if ( channel[0].MR_ptr == 0 )
625         {
626            r = channel[0].MR1;
627            channel[0].MR_ptr = 1;
628         }
629         else
630         {
631            r = channel[0].MR2;
632         }
633         break;
634
635      case 0x01: /* SRA */
636         r = channel[0].SR;
637         break;
638
639      case 0x03: /* Rx Holding Register A */
640         r = duart68681_read_rx_fifo(0);
641         break;
642
643      case 0x04: /* IPCR */
644      {
645         UINT8 IP = m_in_port_func(0);
646
647         r = (((IP_last_state ^ IP) & 0x0f) << 4) | (IP & 0x0f);
648         IP_last_state = IP;
649         ISR &= ~INT_INPUT_PORT_CHANGE;
650         update_interrupts();
651      }
652      break;
653
654      case 0x05: /* ISR */
655         r = ISR;
656         break;
657
658      case 0x06: /* CUR */
659         r = duart68681_get_ct_count() >> 8;
660         break;
661
662      case 0x07: /* CLR */
663         r = duart68681_get_ct_count() & 0xff;
664         break;
665
666      case 0x08: /* MR1B/MR2B */
667         if ( channel[1].MR_ptr == 0 )
668         {
669            r = channel[1].MR1;
670            channel[1].MR_ptr = 1;
671         }
672         else
673         {
674            r = channel[1].MR2;
675         }
676         break;
677
678      case 0x09: /* SRB */
679         r = channel[1].SR;
680         break;
681
682      case 0x0b: /* RHRB */
683         r = duart68681_read_rx_fifo(1);
684         break;
685
686      case 0x0d: /* IP */
687         r = m_in_port_func(0);
688         break;
689
690      case 0x0e: /* Start counter command */
691      {
692         if (ACR & 0x40)
693         {
694            // Reset the timer
695            half_period = 0;
696            // TODO: Set OP3 to 1
697         }
698
699         int count = MAX(CTR.w.l, 1);
700         duart68681_start_ct(count);
701         break;
702      }
703
704      case 0x0f: /* Stop counter command */
705         ISR &= ~INT_COUNTER_READY;
706
707         // Stop the counter only
708         if (!(ACR & 0x40))
709            duart_timer->adjust(attotime::never);
710
711         update_interrupts();
712         break;
713
714      default:
715         LOG(( "Reading unhandled 68681 reg %x\n", offset ));
716         break;
717   }
718   LOG(("returned %02x\n", r));
719
720   return r;
721}
722
723WRITE8_MEMBER( duartn68681_device::write )
724{
725   offset &= 0x0f;
726   LOG(( "Writing 68681 (%s) reg %x (%s) with %04x\n", tag(), offset, duart68681_reg_write_names[offset], data ));
727   switch(offset)
728   {
729      case 0x00: /* MRA */
730         duart68681_write_MR(0, data);
731         break;
732
733      case 0x01: /* CSRA */
734         duart68681_write_CSR(0, data, ACR);
735         break;
736
737      case 0x02: /* CRA */
738         duart68681_write_CR(0, data);
739         break;
740
741      case 0x03: /* THRA */
742         duart68681_write_TX(0, data);
743         break;
744
745      case 0x04: /* ACR */
746      {
747         UINT8 old_acr = ACR;
748         ACR = data;
749
750         //       bits 6-4: Counter/Timer Mode And Clock Source Select
751         //       bits 3-0: IP3-0 Change-Of-State Interrupt Enable
752         if ((old_acr ^ data) & 0x40)
753         {
754            if (data & 0x40)
755            {
756               // Entering timer mode
757               UINT16 count = MAX(CTR.w.l, 1);
758               half_period = 0;
759
760               // TODO: Set OP3
761               duart68681_start_ct(count);
762            }
763            else
764            {
765               // Leaving timer mode (TODO: is this correct?)
766               duart_timer->adjust(attotime::never);
767            }
768         }
769
770         duart68681_write_CSR(0, channel[0].CSR, data);
771         duart68681_write_CSR(1, channel[1].CSR, data);
772         update_interrupts(); // need to add ACR checking for IP delta ints
773         break;
774      }
775      case 0x05: /* IMR */
776         IMR = data;
777         update_interrupts();
778         break;
779
780      case 0x06: /* CTUR */
781         CTR.b.h = data;
782         break;
783
784      case 0x07: /* CTLR */
785         CTR.b.l = data;
786         break;
787
788      case 0x08: /* MRB */
789         duart68681_write_MR(1, data);
790         break;
791
792      case 0x09: /* CSRB */
793         duart68681_write_CSR(1, data, ACR);
794         break;
795
796      case 0x0a: /* CRB */
797         duart68681_write_CR(1, data);
798         break;
799
800      case 0x0b: /* THRB */
801         duart68681_write_TX(1, data);
802         break;
803
804      case 0x0c: /* IVR */
805         IVR = data;
806         break;
807
808      case 0x0d: /* OPCR */
809         if (data != 0x00)
810            logerror( "68681 (%s): Unhandled OPCR value: %02x\n", tag(), data);
811         OPCR = data;
812         break;
813
814      case 0x0e: /* Set Output Port Bits */
815         OPR |= data;
816         m_out_port_func(0, OPR ^ 0xff);
817         break;
818
819      case 0x0f: /* Reset Output Port Bits */
820         OPR &= ~data;
821         m_out_port_func(0, OPR ^ 0xff);
822         break;
823   }
824}
825
826void duartn68681_device::duart68681_rx_data(int ch, UINT8 data)
827{
828   if ( channel[ch].rx_enabled )
829   {
830      if ( channel[ch].rx_fifo_num >= MC68681_RX_FIFO_SIZE )
831      {
832         LOG(( "68681: FIFO overflow\n" ));
833         channel[ch].SR |= STATUS_OVERRUN_ERROR;
834         return;
835      }
836      channel[ch].rx_fifo[channel[ch].rx_fifo_write_ptr++] = data;
837      if ( channel[ch].rx_fifo_write_ptr == MC68681_RX_FIFO_SIZE )
838      {
839         channel[ch].rx_fifo_write_ptr = 0;
840      }
841      channel[ch].rx_fifo_num++;
842      update_interrupts();
843   }
844};
845
846// serial device virtual overrides
847void duartn68681_device::rcv_complete()
848{
849}
850
851void duartn68681_device::tra_complete()
852{
853}
854
855void duartn68681_device::tra_callback()
856{
857}
858
859void duartn68681_device::input_callback(UINT8 state)
860{
861}
862
trunk/src/emu/machine/n68681.h
r0r20071
1#ifndef _N68681_H
2#define _N68681_H
3
4#include "diserial.h"
5
6// forward declaration
7class duartn68681_device;
8
9struct duartn68681_config
10{
11   devcb_write_line   m_out_irq_cb;
12   devcb_write8      m_out_a_tx_cb;
13   devcb_write8      m_out_b_tx_cb;
14   devcb_read8         m_in_port_cb;
15   devcb_write8      m_out_port_cb;
16
17   /* clocks for external baud rates */
18   INT32 ip3clk, ip4clk, ip5clk, ip6clk;
19};
20
21#define MC68681_RX_FIFO_SIZE            3
22
23struct DUART68681_CHANNEL
24{
25   /* Registers */
26   UINT8 CR;  /* Command register */
27   UINT8 CSR; /* Clock select register */
28   UINT8 MR1; /* Mode register 1 */
29   UINT8 MR2; /* Mode register 2 */
30   UINT8 MR_ptr; /* Mode register pointer */
31   UINT8 SR;  /* Status register */
32
33   /* State */
34   int   baud_rate;
35
36   /* Receiver */
37   UINT8 rx_enabled;
38   UINT8 rx_fifo[MC68681_RX_FIFO_SIZE];
39   int   rx_fifo_read_ptr;
40   int   rx_fifo_write_ptr;
41   int   rx_fifo_num;
42
43   /* Transmitter */
44   UINT8 tx_enabled;
45   UINT8 tx_data;
46   UINT8 tx_ready;
47   emu_timer *tx_timer;
48};
49
50class duartn68681_device : public device_t, public device_serial_interface, public duartn68681_config
51{
52public:
53   duartn68681_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
54
55   DECLARE_READ8_HANDLER(read);
56   DECLARE_WRITE8_HANDLER(write);
57
58   void duart68681_rx_data(int ch, UINT8 data);
59
60   TIMER_CALLBACK_MEMBER( tx_timer_callback );
61   TIMER_CALLBACK_MEMBER( duart_timer_callback );
62
63   UINT8 get_irq_vector() { return IVR; }
64
65protected:
66   // device-level overrides
67   virtual void device_config_complete();
68   virtual void device_start();
69   virtual void device_reset();
70
71   // device_serial overrides
72   virtual void rcv_complete();   // Rx complete
73   virtual void tra_complete();   // Tx complete
74   virtual void tra_callback();   // Tx bit ready
75   void input_callback(UINT8 state);
76
77private:
78   /* registers */
79   UINT8 ACR;  /* Auxiliary Control Register */
80   UINT8 IMR;  /* Interrupt Mask Register */
81   UINT8 ISR;  /* Interrupt Status Register */
82   UINT8 IVR;  /* Interrupt Vector Register */
83   UINT8 OPCR; /* Output Port Conf. Register */
84   UINT8 OPR;  /* Output Port Register */
85   PAIR  CTR;  /* Counter/Timer Preset Value */
86
87   /* state */
88   UINT8 IP_last_state; /* last state of IP bits */
89
90   /* timer */
91   UINT8 half_period;
92   emu_timer *duart_timer;
93
94   /* UART channels */
95   DUART68681_CHANNEL channel[2];
96
97   void update_interrupts();
98   double duart68681_get_ct_rate();
99   UINT16 duart68681_get_ct_count();
100   void duart68681_start_ct(int count);
101   void duart68681_write_MR(int ch, UINT8 data);
102   void duart68681_write_CSR(int ch, UINT8 data, UINT8 ACR);
103   void duart68681_write_CR(int ch, UINT8 data);
104   UINT8 duart68681_read_rx_fifo(int ch);
105   void duart68681_write_TX(int ch, UINT8 data);
106
107   devcb_resolved_write_line   m_out_irq_func;
108    devcb_resolved_write8      m_out_a_tx_func;
109    devcb_resolved_write8      m_out_b_tx_func;
110   devcb_resolved_read8      m_in_port_func;
111    devcb_resolved_write8      m_out_port_func;
112
113};
114
115#define MCFG_DUARTN68681_ADD(_tag, _clock, _config) \
116   MCFG_DEVICE_ADD(_tag, DUARTN68681, _clock) \
117   MCFG_DEVICE_CONFIG(_config)
118
119extern const device_type DUARTN68681;
120
121#endif //_N68681_H
122
trunk/src/mess/drivers/esq5505.c
r20070r20071
102102#include "emu.h"
103103#include "cpu/m68000/m68000.h"
104104#include "sound/es5506.h"
105#include "machine/68681.h"
105#include "machine/n68681.h"
106106#include "machine/wd_fdc.h"
107107#include "machine/hd63450.h"    // compatible with MC68450, which is what these really have
108108#include "formats/esq16_dsk.h"
r20070r20071
139139    { }
140140
141141    required_device<m68000_device> m_maincpu;
142    required_device<duart68681_device> m_duart;
142    required_device<duartn68681_device> m_duart;
143143    optional_device<wd1772_t> m_fdc;
144144    optional_device<esq1x22_t> m_epsvfd;
145145    optional_device<esq2x40_sq1_t> m_sq1vfd;
r20070r20071
155155    DECLARE_READ16_MEMBER(lower_r);
156156    DECLARE_WRITE16_MEMBER(lower_w);
157157
158   DECLARE_WRITE_LINE_MEMBER(duart_irq_handler);
159   DECLARE_WRITE8_MEMBER(duart_tx_a);
160   DECLARE_WRITE8_MEMBER(duart_tx_b);
161   DECLARE_READ8_MEMBER(duart_input);
162   DECLARE_WRITE8_MEMBER(duart_output);
163
158164    int m_system_type;
159165    UINT8 m_duart_io;
160166    bool  m_bCalibSecondByte;
r20070r20071
341347   AM_RANGE(0x000000, 0x007fff) AM_READWRITE(lower_r, lower_w)
342348   AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w)
343349   AM_RANGE(0x260000, 0x2601ff) AM_READWRITE(es5510_dsp_r, es5510_dsp_w)
344    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8_LEGACY("duart", duart68681_r, duart68681_w, 0x00ff)
350    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff)
345351    AM_RANGE(0xc00000, 0xc1ffff) AM_ROM AM_REGION("osrom", 0)
346352    AM_RANGE(0xff0000, 0xffffff) AM_RAM AM_SHARE("osram")
347353ADDRESS_MAP_END
r20070r20071
350356   AM_RANGE(0x000000, 0x007fff) AM_READWRITE(lower_r, lower_w)
351357   AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w)
352358   AM_RANGE(0x260000, 0x2601ff) AM_READWRITE(es5510_dsp_r, es5510_dsp_w)
353    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8_LEGACY("duart", duart68681_r, duart68681_w, 0x00ff)
359    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff)
354360    AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff)
355361    AM_RANGE(0x330000, 0x3bffff) AM_RAM // sequencer memory?
356362    AM_RANGE(0xc00000, 0xc3ffff) AM_ROM AM_REGION("osrom", 0)
r20070r20071
361367   AM_RANGE(0x000000, 0x007fff) AM_READWRITE(lower_r, lower_w)
362368   AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w)
363369    AM_RANGE(0x240000, 0x2400ff) AM_DEVREADWRITE_LEGACY("mc68450", hd63450_r, hd63450_w)
364    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8_LEGACY("duart", duart68681_r, duart68681_w, 0x00ff)
370    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff)
365371    AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff)
366372    AM_RANGE(0x580000, 0x7fffff) AM_RAM         // sample RAM?
367373    AM_RANGE(0xc00000, 0xc0ffff) AM_ROM AM_REGION("osrom", 0)
r20070r20071
372378   AM_RANGE(0x000000, 0x03ffff) AM_READWRITE(lower_r, lower_w)
373379   AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w)
374380   AM_RANGE(0x260000, 0x2601ff) AM_READWRITE(es5510_dsp_r, es5510_dsp_w)
375    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8_LEGACY("duart", duart68681_r, duart68681_w, 0x00ff)
381    AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff)
376382    AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff)
377383    AM_RANGE(0x330000, 0x3bffff) AM_RAM // sequencer memory?
378384    AM_RANGE(0xc00000, 0xc3ffff) AM_ROM AM_REGION("osrom", 0)
r20070r20071
435441    }
436442}
437443
438static void duart_irq_handler(device_t *device, int state, UINT8 vector)
444WRITE_LINE_MEMBER(esq5505_state::duart_irq_handler)
439445{
440    esq5505_state *esq5505 = device->machine().driver_data<esq5505_state>();
441
442446//    printf("\nDUART IRQ: state %d vector %d\n", state, vector);
443447    if (state == ASSERT_LINE)
444448    {
445        esq5505->m_maincpu->set_input_line_vector(M68K_IRQ_3, vector);
446        esq5505->m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE);
449        m_maincpu->set_input_line_vector(M68K_IRQ_3, m_duart->get_irq_vector());
450        m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE);
447451    }
448452    else
449453    {
450        esq5505->m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
454        m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
451455    }
452456};
453457
454static UINT8 duart_input(device_t *device)
458READ8_MEMBER(esq5505_state::duart_input)
455459{
456   floppy_connector *con = device->machine().device<floppy_connector>("wd1772:0");
460   floppy_connector *con = machine().device<floppy_connector>("wd1772:0");
457461   floppy_image_device *floppy = con ? con->get_device() : 0;
458462   UINT8 result = 0;   // DUART input lines are separate from the output lines
459463
460464   // on VFX, bit 0 is 1 for 'cartridge present'.
461465   // on VFX-SD and later, bit 0 is 1 for floppy present, bit 1 is 1 for cartridge present
462   if (mame_stricmp(device->machine().system().name, "vfx") == 0)
466   if (mame_stricmp(machine().system().name, "vfx") == 0)
463467   {
464468      // todo: handle VFX cart-in when we support cartridges
465469   }
r20070r20071
478482    return result;
479483}
480484
481static void duart_output(device_t *device, UINT8 data)
485WRITE8_MEMBER(esq5505_state::duart_output)
482486{
483    esq5505_state *state = device->machine().driver_data<esq5505_state>();
484   floppy_connector *con = device->machine().device<floppy_connector>("wd1772:0");
487   floppy_connector *con = machine().device<floppy_connector>("wd1772:0");
485488   floppy_image_device *floppy = con ? con->get_device() : 0;
486489
487    state->m_duart_io = data;
490    m_duart_io = data;
488491
489492   /*
490493        EPS:
r20070r20071
505508
506509    if (floppy)
507510    {
508      if (state->m_system_type == EPS)
511      if (m_system_type == EPS)
509512      {
510513         floppy->ss_w((data & 2)>>1);
511514      }
r20070r20071
515518      }
516519    }
517520
518//    printf("DUART output: %02x (PC=%x)\n", data, state->m_maincpu->pc());
521//    printf("DUART output: %02x (PC=%x)\n", data, m_maincpu->pc());
519522}
520523
521static void duart_tx(device_t *device, int channel, UINT8 data)
524// MIDI send, we don't care yet
525WRITE8_MEMBER(esq5505_state::duart_tx_a)
522526{
523    esq5505_state *state = device->machine().driver_data<esq5505_state>();
527}
524528
525    if (channel == 1)
526    {
527        printf("ch %d: [%02x] (PC=%x)\n", channel, data, state->m_maincpu->pc());
529WRITE8_MEMBER(esq5505_state::duart_tx_b)
530{
531/*   if (data >= 'A' && data <= 'z')
532   {
533      printf("ch 1: [%02x](%c) (PC=%x)\n", data, data, m_maincpu->pc());
534   }
535   else
536   {
537      printf("ch 1: [%02x] (PC=%x)\n", data, m_maincpu->pc());
538   }*/
528539
529        switch (state->m_system_type)
530        {
531            case GENERIC:
532                state->m_vfd->write_char(data);
533                break;
540   switch (m_system_type)
541   {
542      case GENERIC:
543         m_vfd->write_char(data);
544         break;
534545
535            case EPS:
536                state->m_epsvfd->write_char(data);
537                break;
546      case EPS:
547         m_epsvfd->write_char(data);
548         break;
538549
539            case SQ1:
540                state->m_sq1vfd->write_char(data);
541                break;
542        }
550      case SQ1:
551         m_sq1vfd->write_char(data);
552         break;
553   }
543554
544      if (state->m_bCalibSecondByte)
545        {
546            if (data == 0xfd)   // calibration request
547            {
548                duart68681_rx_data(state->m_duart, 1, (UINT8)(FPTR)0xff);   // this is the correct response for "calibration OK"
549            }
550            state->m_bCalibSecondByte = false;
551        }
552        else if (data == 0xfb)   // request calibration
553        {
554            state->m_bCalibSecondByte = true;
555        }
556        else
557        {
558            // EPS wants a throwaway reply byte for each byte sent to the KPC
559            // VFX-SD and SD-1 definitely don't :)
560            if (state->m_system_type == EPS)
561            {
562            if (data == 0xe7)
563            {
564               duart68681_rx_data(state->m_duart, 1, (UINT8)(FPTR)0x00);   // actual value of response is never checked
565            }
566            else if (data == 0x71)
567            {
568               duart68681_rx_data(state->m_duart, 1, (UINT8)(FPTR)0x00);   // actual value of response is never checked
569            }
570            else
571            {
572               duart68681_rx_data(state->m_duart, 1, data);   // actual value of response is never checked
573            }
574            }
575        }
576    }
555   if (m_bCalibSecondByte)
556   {
557      if (data == 0xfd)   // calibration request
558      {
559         m_duart->duart68681_rx_data(1, (UINT8)(FPTR)0xff);   // this is the correct response for "calibration OK"
560      }
561      m_bCalibSecondByte = false;
562   }
563   else if (data == 0xfb)   // request calibration
564   {         
565      m_bCalibSecondByte = true;
566   }
567   else
568   {
569      // EPS wants a throwaway reply byte for each byte sent to the KPC
570      // VFX-SD and SD-1 definitely don't :)
571      if (m_system_type == EPS)
572      {
573         if (data == 0xe7)
574         {
575            m_duart->duart68681_rx_data(1, (UINT8)(FPTR)0x00);   // actual value of response is never checked
576         }
577         else if (data == 0x71)
578         {
579            m_duart->duart68681_rx_data(1, (UINT8)(FPTR)0x00);   // actual value of response is never checked
580         }
581         else
582         {
583            m_duart->duart68681_rx_data(1, data);   // actual value of response is never checked
584         }
585      }
586   }
577587}
578588
579static const duart68681_config duart_config =
589static const duartn68681_config duart_config =
580590{
581   duart_irq_handler,
582   duart_tx,
583   duart_input,
584   duart_output,
591   DEVCB_DRIVER_LINE_MEMBER(esq5505_state, duart_irq_handler),
592   DEVCB_DRIVER_MEMBER(esq5505_state, duart_tx_a),
593   DEVCB_DRIVER_MEMBER(esq5505_state, duart_tx_b),
594   DEVCB_DRIVER_MEMBER(esq5505_state, duart_input),
595   DEVCB_DRIVER_MEMBER(esq5505_state, duart_output),
585596
586   1000000, 500000,   // IP3, IP4
587   500000, 1000000, // IP5, IP6
597   500000, 500000,   // IP3, IP4
598   1000000, 1000000, // IP5, IP6
588599};
589600
590601static void esq_dma_end(running_machine &machine, int channel, int irq)
r20070r20071
649660                printf("program to %d\n", program);
650661            }
651662
652            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)0xc0); // program change
653            duart68681_rx_data(m_duart, 0, program); // program
663         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)0xc0); // program change
664         m_duart->duart68681_rx_data(0, program); // program
654665        }
655666        else
656667        {
657            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)0x90); // note on
658            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)param);
659            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)0x7f);
668         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)0x90); // note on
669         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)param);
670         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)0x7f);
660671        }
661672    }
662673    else if (oldval == 1 && newval == 0)
663674    {
664675        if ((UINT8)(FPTR)param != 0x40)
665676        {
666            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)0x80); // note off
667            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)param);
668            duart68681_rx_data(m_duart, 0, (UINT8)(FPTR)0x7f);
677         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)0x80); // note off
678         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)param);
679         m_duart->duart68681_rx_data(0, (UINT8)(FPTR)0x7f);
669680        }
670681    }
671682    #else
r20070r20071
693704      if (oldval == 0 && newval == 1)
694705      {
695706         printf("key pressed %d\n", val&0x7f);
696         duart68681_rx_data(m_duart, 1, val);
697         duart68681_rx_data(m_duart, 1, 0x00);
707         m_duart->duart68681_rx_data(1, val);
708         m_duart->duart68681_rx_data(1, 0x00);
698709      }
699710      else if (oldval == 1 && newval == 0)
700711      {
701712   //        printf("key off %x\n", (UINT8)(FPTR)param);
702         duart68681_rx_data(m_duart, 1, val&0x7f);
703         duart68681_rx_data(m_duart, 1, 0x00);
713         m_duart->duart68681_rx_data(1, val&0x7f);
714         m_duart->duart68681_rx_data(1, 0x00);
704715      }
705716   }
706717    #endif
r20070r20071
732743
733744    MCFG_ESQ2x40_ADD("vfd")
734745
735   MCFG_DUART68681_ADD("duart", 4000000, duart_config)
746   MCFG_DUARTN68681_ADD("duart", 4000000, duart_config)
736747
737748   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
738749   MCFG_SOUND_ADD("ensoniq", ES5505, XTAL_10MHz)
r20070r20071
769780
770781    MCFG_ESQ2x40_ADD("vfd")
771782
772   MCFG_DUART68681_ADD("duart", 4000000, duart_config)
783   MCFG_DUARTN68681_ADD("duart", 4000000, duart_config)
773784
774785   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
775786   MCFG_SOUND_ADD("ensoniq", ES5505, XTAL_30_4761MHz / 2)
r20070r20071
10071018CONS( 1989, vfxsd, 0, 0,   vfxsd, vfx, esq5505_state, denib,  "Ensoniq", "VFX-SD", GAME_NOT_WORKING )    // 2x40 VFD
10081019CONS( 1990, sd1,   0, 0,   vfxsd, vfx, esq5505_state, denib,  "Ensoniq", "SD-1", GAME_NOT_WORKING )      // 2x40 VFD
10091020CONS( 1990, sd132, sd1, 0, vfx32, vfx, esq5505_state, denib,  "Ensoniq", "SD-1 32", GAME_NOT_WORKING )   // 2x40 VFD
1010CONS( 1990, sq1,   0, 0,   sq1,   vfx, esq5505_state, sq1,    "Ensoniq", "SQ-1", GAME_NOT_WORKING )      // LCD of some sort
1011CONS( 1990, sqrack,sq1, 0, sq1,   vfx, esq5505_state, sq1,    "Ensoniq", "SQ-Rack", GAME_NOT_WORKING )   // LCD of some sort
1021CONS( 1990, sq1,   0, 0,   sq1,   vfx, esq5505_state, sq1,    "Ensoniq", "SQ-1", GAME_NOT_WORKING )      // 2x16 LCD
1022CONS( 1990, sqrack,sq1, 0, sq1,   vfx, esq5505_state, sq1,    "Ensoniq", "SQ-Rack", GAME_NOT_WORKING )   // 2x16 LCD                     
1023

Previous 199869 Revisions Next


© 1997-2024 The MAME Team