4
Written by Mariusz Wojcieszek
5
Updated by Jonathan Gevaryahu AKA Lord Nightmare
12
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
14
static const char *const duart68681_reg_read_names[0x10] =
16
"MRA", "SRA", "BRG Test", "RHRA", "IPCR", "ISR", "CTU", "CTL", "MRB", "SRB", "1X/16X Test", "RHRB", "IVR", "Input Ports", "Start Counter", "Stop Counter"
19
static const char *const duart68681_reg_write_names[0x10] =
21
"MRA", "CSRA", "CRA", "THRA", "ACR", "IMR", "CRUR", "CTLR", "MRB", "CSRB", "CRB", "THRB", "IVR", "OPCR", "Set OP Bits", "Reset OP Bits"
24
#define INT_INPUT_PORT_CHANGE 0x80
25
#define INT_DELTA_BREAK_B 0x40
26
#define INT_RXRDY_FFULLB 0x20
27
#define INT_TXRDYB 0x10
28
#define INT_COUNTER_READY 0x08
29
#define INT_DELTA_BREAK_A 0x04
30
#define INT_RXRDY_FFULLA 0x02
31
#define INT_TXRDYA 0x01
33
#define STATUS_RECEIVED_BREAK 0x80
34
#define STATUS_FRAMING_ERROR 0x40
35
#define STATUS_PARITY_ERROR 0x20
36
#define STATUS_OVERRUN_ERROR 0x10
37
#define STATUS_TRANSMITTER_EMPTY 0x08
38
#define STATUS_TRANSMITTER_READY 0x04
39
#define STATUS_FIFO_FULL 0x02
40
#define STATUS_RECEIVER_READY 0x01
42
#define MODE_RX_INT_SELECT_BIT 0x40
44
#define RX_FIFO_SIZE 3
49
UINT8 CR; /* Command register */
50
UINT8 CSR; /* Clock select register */
51
UINT8 MR1; /* Mode register 1 */
52
UINT8 MR2; /* Mode register 2 */
53
UINT8 MR_ptr; /* Mode register pointer */
54
UINT8 SR; /* Status register */
61
UINT8 rx_fifo[RX_FIFO_SIZE];
63
int rx_fifo_write_ptr;
80
const duart68681_config *duart_config;
83
UINT8 ACR; /* Auxiliary Control Register */
84
UINT8 IMR; /* Interrupt Mask Register */
85
UINT8 ISR; /* Interrupt Status Register */
86
UINT8 IVR; /* Interrupt Vector Register */
87
UINT8 OPCR; /* Output Port Conf. Register */
88
UINT8 OPR; /* Output Port Register */
89
PAIR CTR; /* Counter/Timer Preset Value */
92
UINT8 IP_last_state; /* last state of IP bits */
95
emu_timer *duart_timer;
98
DUART68681_CHANNEL channel[2];
102
INLINE duart68681_state *get_safe_token(device_t *device)
104
assert(device != NULL);
105
assert(device->type() == DUART68681);
107
return (duart68681_state *)downcast<legacy_device_base *>(device)->token();
110
static void duart68681_update_interrupts(duart68681_state *duart68681)
112
/* update SR state and update interrupt ISR state for the following bits:
113
SRn: bits 7-4: handled elsewhere.
114
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)
115
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)
116
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.)
117
SRn: bit 0 (RxRDYn) (this bit we also emulate; the bit is always asserted if the receive fifo is not empty)
118
ISR: bit 7: Input Port change; this should be handled elsewhere, on the input port handler
119
ISR: bit 6: Delta Break B; this should be handled elsewhere, on the data receive handler
120
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
121
ISR: bit 4: TxRDYB: this is handled here; it mirrors SRB bit 2
122
ISR: bit 3: Counter ready; this should be handled by the timer generator
123
ISR: bit 2: Delta Break A; this should be handled elsewhere, on the data receive handler
124
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
125
ISR: bit 0: TxRDYA: this is handled here; it mirrors SRA bit 2
128
//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);
129
for (ch = 0; ch < 2; ch++)
131
//if ( duart68681->channel[ch].rx_enabled )
133
if ( duart68681->channel[ch].rx_fifo_num > 0 )
135
duart68681->channel[ch].SR |= STATUS_RECEIVER_READY;
139
duart68681->channel[ch].SR &= ~STATUS_RECEIVER_READY;
141
if ( duart68681->channel[ch].rx_fifo_num == RX_FIFO_SIZE )
143
duart68681->channel[ch].SR |= STATUS_FIFO_FULL;
147
duart68681->channel[ch].SR &= ~STATUS_FIFO_FULL;
152
//duart68681->channel[ch].SR &= ~STATUS_RECEIVER_READY;
153
//duart68681->channel[ch].SR &= ~STATUS_FIFO_FULL;
155
// Handle the TxEMT and TxRDY bits based on mode
156
switch( duart68681->channel[ch].MR2&0xC0) // what mode are we in?
158
case 0x00: // normal mode
159
if ( duart68681->channel[ch].tx_enabled )
161
duart68681->channel[ch].SR |= STATUS_TRANSMITTER_EMPTY;
165
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
168
case 0x40: // automatic echo mode
169
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
170
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
172
case 0x80: // local loopback mode
173
if ( duart68681->channel[ch].tx_enabled )
175
duart68681->channel[ch].SR |= STATUS_TRANSMITTER_EMPTY;
179
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
182
case 0xC0: // remote loopback mode
183
// write me, what the txrdy/txemt regs do for remote loopback mode is undocumented afaik, for now just clear both
184
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_EMPTY;
185
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
188
// now handle the ISR bits
189
if ( duart68681->channel[ch].SR & STATUS_TRANSMITTER_READY )
192
duart68681->ISR |= INT_TXRDYA;
194
duart68681->ISR |= INT_TXRDYB;
199
duart68681->ISR &= ~INT_TXRDYA;
201
duart68681->ISR &= ~INT_TXRDYB;
203
//logerror("DEBUG: 68681 int check: before receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR);
204
if ( duart68681->channel[ch].MR1 & MODE_RX_INT_SELECT_BIT )
206
if ( duart68681->channel[ch].SR & STATUS_FIFO_FULL )
208
duart68681->ISR |= ((ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB);
212
duart68681->ISR &= ((ch == 0) ? ~INT_RXRDY_FFULLA : ~INT_RXRDY_FFULLB);
217
if ( duart68681->channel[ch].SR & STATUS_RECEIVER_READY )
219
duart68681->ISR |= ((ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB);
223
duart68681->ISR &= ((ch == 0) ? ~INT_RXRDY_FFULLA : ~INT_RXRDY_FFULLB);
226
//logerror("DEBUG: 68681 int check: after receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR);
228
if ( (duart68681->ISR & duart68681->IMR) != 0 )
230
if ( duart68681->duart_config->irq_handler )
232
LOG(( "68681: Interrupt line active (IMR & ISR = %02X)\n", (duart68681->ISR & duart68681->IMR) ));
233
duart68681->duart_config->irq_handler( duart68681->device, duart68681->IVR );
238
static TIMER_CALLBACK( duart_timer_callback )
240
device_t *device = (device_t *)ptr;
241
duart68681_state *duart68681 = get_safe_token(device);
243
duart68681->ISR |= INT_COUNTER_READY;
244
duart68681_update_interrupts(duart68681);
246
// if ((duart68681->OPCR & 0x0c)== 0x04) {
247
// duart68681->OPR ^= 0x08;
248
// if (duart68681->duart_config->output_port_write)
249
// duart68681->duart_config->output_port_write(duart68681->device, duart68681->OPR ^ 0xff);
254
static void duart68681_write_MR(duart68681_state *duart68681, int ch, UINT8 data)
256
if ( duart68681->channel[ch].MR_ptr == 0 )
258
duart68681->channel[ch].MR1 = data;
259
duart68681->channel[ch].MR_ptr = 1;
263
duart68681->channel[ch].MR2 = data;
265
duart68681_update_interrupts(duart68681);
268
static void duart68681_write_CSR(duart68681_state *duart68681, int ch, UINT8 data, UINT8 ACR)
270
static const int baud_rate_ACR_0[] = { 50, 110, 134, 200, 300, 600, 1200, 1050, 2400, 4800, 7200, 9600, 38400, 0, 0, 0 };
271
static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000, 2400, 4800, 1800, 9600, 19200, 0, 0, 0 };
273
duart68681->channel[ch].CSR = data;
275
if ( BIT(ACR,7) == 0 )
277
duart68681->channel[ch].baud_rate = baud_rate_ACR_0[data & 0x0f];
281
if ((data & 0xf) == 0xe)
283
duart68681->channel[ch].baud_rate = duart68681->duart_config->ip3clk/16;
285
else if ((data & 0xf) == 0xf)
287
duart68681->channel[ch].baud_rate = duart68681->duart_config->ip3clk;
292
if ((data & 0xf) == 0xe)
294
duart68681->channel[ch].baud_rate = duart68681->duart_config->ip5clk/16;
296
else if ((data & 0xf) == 0xf)
298
duart68681->channel[ch].baud_rate = duart68681->duart_config->ip5clk;
304
duart68681->channel[ch].baud_rate = baud_rate_ACR_1[data & 0x0f];
306
if ( duart68681->channel[ch].baud_rate == 0 )
308
LOG(( "Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data ));
312
static void duart68681_write_CR(duart68681_state *duart68681, int ch, UINT8 data)
314
duart68681->channel[ch].CR = data;
316
switch( (data >> 4) & 0x07 )
318
case 0: /* No command */
320
case 1: /* Reset MR pointer. Causes the Channel A MR pointer to point to MR1 */
321
duart68681->channel[ch].MR_ptr = 0;
323
case 2: /* Reset channel A receiver (disable receiver and flush fifo) */
324
duart68681->channel[ch].rx_enabled = 0;
325
duart68681->channel[ch].SR &= ~STATUS_RECEIVER_READY;
326
duart68681->channel[ch].SR &= ~STATUS_OVERRUN_ERROR; // is this correct?
327
duart68681->channel[ch].rx_fifo_read_ptr = 0;
328
duart68681->channel[ch].rx_fifo_write_ptr = 0;
329
duart68681->channel[ch].rx_fifo_num = 0;
331
case 3: /* Reset channel A transmitter */
332
duart68681->channel[ch].tx_enabled = 0;
333
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
335
duart68681->ISR &= ~INT_TXRDYA;
337
duart68681->ISR &= ~INT_TXRDYB;
338
duart68681->channel[ch].tx_timer->adjust(attotime::never, ch);
340
case 4: /* Reset Error Status */
341
duart68681->channel[ch].SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR | STATUS_OVERRUN_ERROR);
343
case 5: /* Reset Channel break change interrupt */
346
duart68681->ISR &= ~INT_DELTA_BREAK_A;
350
duart68681->ISR &= ~INT_DELTA_BREAK_B;
353
/* 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 */
355
LOG(( "68681: Unhandled command (%x) in CR%d\n", (data >> 4) & 0x07, ch ));
358
duart68681_update_interrupts(duart68681);
361
duart68681->channel[ch].rx_enabled = 1;
364
duart68681->channel[ch].rx_enabled = 0;
365
duart68681->channel[ch].SR &= ~STATUS_RECEIVER_READY;
369
duart68681->channel[ch].tx_enabled = 1;
370
duart68681->channel[ch].tx_ready = 1;
371
duart68681->channel[ch].SR |= STATUS_TRANSMITTER_READY;
373
duart68681->ISR |= INT_TXRDYA;
375
duart68681->ISR |= INT_TXRDYB;
378
duart68681->channel[ch].tx_enabled = 0;
379
duart68681->channel[ch].tx_ready = 0;
380
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
382
duart68681->ISR &= ~INT_TXRDYA;
384
duart68681->ISR &= ~INT_TXRDYB;
389
static UINT8 duart68681_read_rx_fifo(duart68681_state *duart68681, int ch)
393
if ( duart68681->channel[ch].rx_fifo_num == 0 )
395
LOG(( "68681: rx fifo underflow\n" ));
399
r = duart68681->channel[ch].rx_fifo[duart68681->channel[ch].rx_fifo_read_ptr++];
400
if ( duart68681->channel[ch].rx_fifo_read_ptr == RX_FIFO_SIZE )
402
duart68681->channel[ch].rx_fifo_read_ptr = 0;
405
duart68681->channel[ch].rx_fifo_num--;
406
duart68681_update_interrupts(duart68681);
411
static TIMER_CALLBACK( tx_timer_callback )
413
device_t *device = (device_t *)ptr;
414
duart68681_state *duart68681 = get_safe_token(device);
417
// send the byte unless we're in loopback mode;
418
// in loopback mode do NOT 'actually' send the byte: the TXn pin is held high when loopback mode is on.
419
if ((duart68681->duart_config->tx_callback) && ((duart68681->channel[ch].MR2&0xC0) != 0x80))
420
duart68681->duart_config->tx_callback(device, ch, duart68681->channel[ch].tx_data);
422
// if local loopback is on, write the transmitted data as if a byte had been received
423
if ((duart68681->channel[ch].MR2 & 0xC0) == 0x80)
425
if (duart68681->channel[ch].rx_fifo_num >= RX_FIFO_SIZE)
427
LOG(( "68681: FIFO overflow\n" ));
428
duart68681->channel[ch].SR |= STATUS_OVERRUN_ERROR;
432
duart68681->channel[ch].rx_fifo[duart68681->channel[ch].rx_fifo_write_ptr++]
433
= duart68681->channel[ch].tx_data;
434
if (duart68681->channel[ch].rx_fifo_write_ptr == RX_FIFO_SIZE)
436
duart68681->channel[ch].rx_fifo_write_ptr = 0;
438
duart68681->channel[ch].rx_fifo_num++;
442
duart68681->channel[ch].tx_ready = 1;
443
duart68681->channel[ch].SR |= STATUS_TRANSMITTER_READY;
446
duart68681->ISR |= INT_TXRDYA;
448
duart68681->ISR |= INT_TXRDYB;
450
duart68681_update_interrupts(duart68681);
451
duart68681->channel[ch].tx_timer->adjust(attotime::never, ch);
454
static void duart68681_write_TX(duart68681_state* duart68681, int ch, UINT8 data)
458
duart68681->channel[ch].tx_data = data;
460
duart68681->channel[ch].tx_ready = 0;
461
duart68681->channel[ch].SR &= ~STATUS_TRANSMITTER_READY;
464
duart68681->ISR &= ~INT_TXRDYA;
466
duart68681->ISR &= ~INT_TXRDYB;
468
duart68681_update_interrupts(duart68681);
470
period = attotime::from_hz(duart68681->channel[ch].baud_rate / 10 );
471
duart68681->channel[ch].tx_timer->adjust(period, ch);
475
READ8_DEVICE_HANDLER(duart68681_r)
477
duart68681_state* duart68681 = get_safe_token(device);
482
LOG(( "Reading 68681 (%s) reg %x (%s) ", device->tag(), offset, duart68681_reg_read_names[offset] ));
486
case 0x00: /* MR1A/MR2A */
487
if ( duart68681->channel[0].MR_ptr == 0 )
489
r = duart68681->channel[0].MR1;
490
duart68681->channel[0].MR_ptr = 1;
494
r = duart68681->channel[0].MR2;
498
r = duart68681->channel[0].SR;
500
case 0x03: /* Rx Holding Register A */
501
r = duart68681_read_rx_fifo(duart68681, 0);
503
case 0x04: /* IPCR */
506
if ( duart68681->duart_config->input_port_read != NULL )
507
IP = duart68681->duart_config->input_port_read(duart68681->device);
511
r = (((duart68681->IP_last_state ^ IP) & 0x0f) << 4) | (IP & 0x0f);
512
duart68681->IP_last_state = IP;
513
duart68681->ISR &= ~INT_INPUT_PORT_CHANGE;
514
duart68681_update_interrupts(duart68681);
520
case 0x08: /* MR1B/MR2B */
521
if ( duart68681->channel[1].MR_ptr == 0 )
523
r = duart68681->channel[1].MR1;
524
duart68681->channel[1].MR_ptr = 1;
528
r = duart68681->channel[1].MR2;
532
r = duart68681->channel[1].SR;
534
case 0x0b: /* RHRB */
535
r = duart68681_read_rx_fifo(duart68681, 1);
538
if ( duart68681->duart_config->input_port_read != NULL )
539
r = duart68681->duart_config->input_port_read(duart68681->device);
544
if (device->machine().input().code_pressed(KEYCODE_1)) r ^= 0x0001;
545
if (device->machine().input().code_pressed(KEYCODE_2)) r ^= 0x0002;
546
if (device->machine().input().code_pressed(KEYCODE_3)) r ^= 0x0004;
547
if (device->machine().input().code_pressed(KEYCODE_4)) r ^= 0x0008;
548
if (device->machine().input().code_pressed(KEYCODE_5)) r ^= 0x0010;
549
if (device->machine().input().code_pressed(KEYCODE_6)) r ^= 0x0020;
550
if (device->machine().input().code_pressed(KEYCODE_7)) r ^= 0x0040;
551
if (device->machine().input().code_pressed(KEYCODE_8)) r ^= 0x0080;
555
case 0x0e: /* Start counter command */
556
switch( (duart68681->ACR >> 4) & 0x07 )
558
/* TODO: implement modes 0,1,2,4,5 */
559
case 0x03: /* Counter, CLK/16 */
561
attotime rate = attotime::from_hz(2*device->clock()/(2*16*16*duart68681->CTR.w.l));
562
duart68681->duart_timer->adjust(rate, 0, rate);
565
case 0x06: /* Timer, CLK/1 */
567
attotime rate = attotime::from_hz(2*device->clock()/(2*16*duart68681->CTR.w.l));
568
duart68681->duart_timer->adjust(rate, 0, rate);
571
case 0x07: /* Timer, CLK/16 */
574
//attotime rate = attotime::from_hz(duart68681->clock) * (16*duart68681->CTR.w.l);
575
attotime rate = attotime::from_hz(2*device->clock()/(2*16*16*duart68681->CTR.w.l));
576
//hz = ATTOSECONDS_TO_HZ(rate.attoseconds);
577
duart68681->duart_timer->adjust(rate, 0, rate);
582
case 0x0f: /* Stop counter command */
583
duart68681->ISR &= ~INT_COUNTER_READY;
584
if (((duart68681->ACR >>4)& 0x07) < 4) // if in counter mode...
585
duart68681->duart_timer->adjust(attotime::never); // shut down timer
586
duart68681_update_interrupts(duart68681);
589
LOG(( "Reading unhandled 68681 reg %x\n", offset ));
592
LOG(("returned %02x\n", r));
597
WRITE8_DEVICE_HANDLER(duart68681_w)
599
duart68681_state* duart68681 = get_safe_token(device);
602
LOG(( "Writing 68681 (%s) reg %x (%s) with %04x\n", device->tag(), offset, duart68681_reg_write_names[offset], data ));
607
duart68681_write_MR(duart68681, 0, data);
609
case 0x01: /* CSRA */
610
duart68681_write_CSR(duart68681, 0, data, duart68681->ACR);
613
duart68681_write_CR(duart68681, 0, data);
615
case 0x03: /* THRA */
616
duart68681_write_TX(duart68681, 0, data);
619
duart68681->ACR = data;
620
// bits 6-4: Counter/Timer Mode And Clock Source Select
621
// bits 3-0: IP3-0 Change-Of-State Interrupt Enable
622
switch ((data >> 4) & 0x07)
624
case 0: case 1: case 2: case 4: case 5: // TODO: handle these cases!
625
logerror( "68681 (%s): Unhandled timer/counter mode %d\n", device->tag(), (data >> 4) & 0x07);
627
case 3: case 6: case 7:
630
duart68681_write_CSR(duart68681, 0, duart68681->channel[0].CSR, data);
631
duart68681_write_CSR(duart68681, 1, duart68681->channel[1].CSR, data);
632
duart68681_update_interrupts(duart68681); // need to add ACR checking for IP delta ints
635
duart68681->IMR = data;
636
duart68681_update_interrupts(duart68681);
638
case 0x06: /* CTUR */
639
duart68681->CTR.b.h = data;
641
case 0x07: /* CTLR */
642
duart68681->CTR.b.l = data;
645
duart68681_write_MR(duart68681, 1, data);
647
case 0x09: /* CSRB */
648
duart68681_write_CSR(duart68681, 1, data, duart68681->ACR);
651
duart68681_write_CR(duart68681, 1, data);
653
case 0x0b: /* THRB */
654
duart68681_write_TX(duart68681, 1, data);
657
duart68681->IVR = data;
659
case 0x0d: /* OPCR */
661
logerror( "68681 (%s): Unhandled OPCR value: %02x\n", device->tag(), data);
662
duart68681->OPCR = data;
664
case 0x0e: /* Set Output Port Bits */
665
duart68681->OPR |= data;
666
if (duart68681->duart_config->output_port_write)
667
duart68681->duart_config->output_port_write(duart68681->device, duart68681->OPR ^ 0xff);
669
case 0x0f: /* Reset Output Port Bits */
670
duart68681->OPR &= ~data;
671
if (duart68681->duart_config->output_port_write)
672
duart68681->duart_config->output_port_write(duart68681->device, duart68681->OPR ^ 0xff);
677
void duart68681_rx_data( device_t* device, int ch, UINT8 data )
679
duart68681_state *duart68681 = get_safe_token(device);
681
if ( duart68681->channel[ch].rx_enabled )
683
if ( duart68681->channel[ch].rx_fifo_num >= RX_FIFO_SIZE )
685
LOG(( "68681: FIFO overflow\n" ));
686
duart68681->channel[ch].SR |= STATUS_OVERRUN_ERROR;
689
duart68681->channel[ch].rx_fifo[duart68681->channel[ch].rx_fifo_write_ptr++] = data;
690
if ( duart68681->channel[ch].rx_fifo_write_ptr == RX_FIFO_SIZE )
692
duart68681->channel[ch].rx_fifo_write_ptr = 0;
694
duart68681->channel[ch].rx_fifo_num++;
695
duart68681_update_interrupts(duart68681);
699
/*-------------------------------------------------
700
device start callback
701
-------------------------------------------------*/
703
static DEVICE_START(duart68681)
705
duart68681_state *duart68681 = get_safe_token(device);
707
/* validate arguments */
708
assert(device != NULL);
710
duart68681->duart_config = (const duart68681_config *)device->static_config();
711
duart68681->device = device;
713
duart68681->channel[0].tx_timer = device->machine().scheduler().timer_alloc(FUNC(tx_timer_callback), (void*)device);
714
duart68681->channel[1].tx_timer = device->machine().scheduler().timer_alloc(FUNC(tx_timer_callback), (void*)device);
715
duart68681->duart_timer = device->machine().scheduler().timer_alloc(FUNC(duart_timer_callback), (void*)device);
717
device->save_item(NAME(duart68681->ACR));
718
device->save_item(NAME(duart68681->IMR));
719
device->save_item(NAME(duart68681->ISR));
720
device->save_item(NAME(duart68681->IVR));
721
device->save_item(NAME(duart68681->OPCR));
722
device->save_item(NAME(duart68681->CTR));
723
device->save_item(NAME(duart68681->IP_last_state));
725
device->save_item(NAME(duart68681->channel[0].CR));
726
device->save_item(NAME(duart68681->channel[0].CSR));
727
device->save_item(NAME(duart68681->channel[0].MR1));
728
device->save_item(NAME(duart68681->channel[0].MR2));
729
device->save_item(NAME(duart68681->channel[0].MR_ptr));
730
device->save_item(NAME(duart68681->channel[0].SR));
731
device->save_item(NAME(duart68681->channel[0].baud_rate));
732
device->save_item(NAME(duart68681->channel[0].rx_enabled));
733
device->save_item(NAME(duart68681->channel[0].rx_fifo));
734
device->save_item(NAME(duart68681->channel[0].rx_fifo_read_ptr));
735
device->save_item(NAME(duart68681->channel[0].rx_fifo_write_ptr));
736
device->save_item(NAME(duart68681->channel[0].rx_fifo_num));
737
device->save_item(NAME(duart68681->channel[0].tx_enabled));
738
device->save_item(NAME(duart68681->channel[0].tx_data));
739
device->save_item(NAME(duart68681->channel[0].tx_ready));
741
device->save_item(NAME(duart68681->channel[1].CR));
742
device->save_item(NAME(duart68681->channel[1].CSR));
743
device->save_item(NAME(duart68681->channel[1].MR1));
744
device->save_item(NAME(duart68681->channel[1].MR2));
745
device->save_item(NAME(duart68681->channel[1].MR_ptr));
746
device->save_item(NAME(duart68681->channel[1].SR));
747
device->save_item(NAME(duart68681->channel[1].baud_rate));
748
device->save_item(NAME(duart68681->channel[1].rx_enabled));
749
device->save_item(NAME(duart68681->channel[1].rx_fifo));
750
device->save_item(NAME(duart68681->channel[1].rx_fifo_read_ptr));
751
device->save_item(NAME(duart68681->channel[1].rx_fifo_write_ptr));
752
device->save_item(NAME(duart68681->channel[1].rx_fifo_num));
753
device->save_item(NAME(duart68681->channel[1].tx_enabled));
754
device->save_item(NAME(duart68681->channel[1].tx_data));
755
device->save_item(NAME(duart68681->channel[1].tx_ready));
758
/*-------------------------------------------------
759
device reset callback
760
-------------------------------------------------*/
762
static DEVICE_RESET(duart68681)
764
duart68681_state *duart68681 = get_safe_token(device);
765
emu_timer *save0, *save1;
767
duart68681->ACR = 0; /* Interrupt Vector Register */
768
duart68681->IVR = 0x0f; /* Interrupt Vector Register */
769
duart68681->IMR = 0; /* Interrupt Mask Register */
770
duart68681->ISR = 0; /* Interrupt Status Register */
771
duart68681->OPCR = 0; /* Output Port Conf. Register */
772
duart68681->OPR = 0; /* Output Port Register */
773
duart68681->CTR.d = 0; /* Counter/Timer Preset Value */
774
duart68681->IP_last_state = 0; /* last state of IP bits */
775
// "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"
776
save0 = duart68681->channel[0].tx_timer;
777
save1 = duart68681->channel[1].tx_timer;
778
memset(duart68681->channel, 0, sizeof(duart68681->channel));
779
duart68681->channel[0].tx_timer = save0;
780
duart68681->channel[1].tx_timer = save1;
782
if (duart68681->duart_config->output_port_write)
783
duart68681->duart_config->output_port_write(duart68681->device, duart68681->OPR ^ 0xff);
786
duart68681->channel[0].tx_timer->adjust(attotime::never);
787
duart68681->channel[1].tx_timer->adjust(attotime::never, 1);
790
/*-------------------------------------------------
791
device get info callback
792
-------------------------------------------------*/
794
DEVICE_GET_INFO(duart68681)
798
/* --- the following bits of info are returned as 64-bit signed integers --- */
799
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(duart68681_state); break;
800
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(duart68681_config); break;
802
/* --- the following bits of info are returned as pointers to data or functions --- */
803
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(duart68681); break;
804
case DEVINFO_FCT_STOP: /* nothing */ break;
805
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(duart68681);break;
807
/* --- the following bits of info are returned as NULL-terminated strings --- */
808
case DEVINFO_STR_NAME: strcpy(info->s, "DUART 68681"); break;
809
case DEVINFO_STR_FAMILY: strcpy(info->s, "DUART"); break;
810
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
811
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
812
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
816
DEFINE_LEGACY_DEVICE(DUART68681, duart68681);