2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
18 #define MONOSYNC(ch) ((port[ch].wr[4] & 0x3c) == 0x00)
19 #define BISYNC(ch) ((port[ch].wr[4] & 0x3c) == 0x10)
20 //#define SDLC(ch) ((port[ch].wr[4] & 0x3c) == 0x20)
21 //#define EXTSYNC(ch) ((port[ch].wr[4] & 0x3c) == 0x30)
22 #define SYNC_MODE(ch) (MONOSYNC(ch) || BISYNC(ch))
27 #define REGISTER_FIRST_SEND_EVENT(ch) { \
28 if(port[ch].tx_clock != 0) { \
29 if(port[ch].send_id == -1) { \
30 register_event(this, EVENT_SEND + ch, 1000000.0 / port[ch].tx_clock / 2.0, false, &port[ch].send_id); \
33 if(port[ch].tx_bits_x2_remain == 0) { \
34 port[ch].tx_bits_x2_remain = 1; \
39 #define REGISTER_SEND_EVENT(ch) { \
40 if(port[ch].tx_clock != 0) { \
41 if(port[ch].send_id == -1) { \
42 register_event(this, EVENT_SEND + ch, port[ch].tx_interval, false, &port[ch].send_id); \
45 if(port[ch].tx_bits_x2_remain == 0) { \
46 port[ch].tx_bits_x2_remain = port[ch].tx_bits_x2; \
51 #define CANCEL_SEND_EVENT(ch) { \
52 if(port[ch].tx_clock != 0) { \
53 if(port[ch].send_id != -1) { \
54 cancel_event(this, port[ch].send_id); \
55 port[ch].send_id = -1; \
58 port[ch].tx_bits_x2_remain = 0; \
62 #define REGISTER_RECV_EVENT(ch) { \
63 if(port[ch].rx_clock != 0) { \
64 if(port[ch].recv_id == -1) { \
65 register_event(this, EVENT_RECV + ch, port[ch].rx_interval, false, &port[ch].recv_id); \
68 if(port[ch].rx_bits_x2_remain == 0) { \
69 port[ch].rx_bits_x2_remain = port[ch].rx_bits_x2; \
74 #define CANCEL_RECV_EVENT(ch) { \
75 if(port[ch].rx_clock != 0) { \
76 if(port[ch].recv_id != -1) { \
77 cancel_event(this, port[ch].recv_id); \
78 port[ch].recv_id = -1; \
81 port[ch].rx_bits_x2_remain = 0; \
85 void Z80SIO::initialize()
88 __HAS_UPD7201 = osd->check_feature(_T("HAS_UPD7201"));
89 __SIO_DEBUG = osd->check_feature(_T("SIO_DEBUG"));
91 for(int ch = 0; ch < 2; ch++) {
94 port[ch].send = new FIFO(16);
95 port[ch].recv = new FIFO(16);
96 port[ch].rtmp = new FIFO(16);
99 port[ch].send = new FIFO(1);
100 port[ch].recv = new FIFO(4);
101 port[ch].rtmp = new FIFO(8);
102 port[ch].tx_count_hi = 0;
108 port[ch].sync = true;
109 port[ch].sync_bit = 0;
115 for(int ch = 0; ch < 2; ch++) {
116 port[ch].pointer = 0;
117 port[ch].nextrecv_intr = false;
118 port[ch].first_data = false;
119 port[ch].over_flow = false;
120 port[ch].under_run = false;
121 port[ch].abort = false;
123 port[ch].tx_count = 0;
125 port[ch].send->clear();
126 port[ch].recv->clear();
127 port[ch].rtmp->clear();
128 port[ch].shift_reg = -1;
129 port[ch].send_id = -1;
130 port[ch].recv_id = -1;
131 memset(port[ch].wr, 0, sizeof(port[ch].wr));
133 port[ch].err_intr = false;
134 port[ch].recv_intr = 0;
135 port[ch].stat_intr = false;
136 port[ch].send_intr = false;
137 port[ch].req_intr = false;
138 port[ch].in_service = false;
143 void Z80SIO::release()
145 for(int ch = 0; ch < 2; ch++) {
147 port[ch].send->release();
148 delete port[ch].send;
151 port[ch].recv->release();
152 delete port[ch].recv;
155 port[ch].rtmp->release();
156 delete port[ch].rtmp;
168 void Z80SIO::write_io8(uint32_t addr, uint32_t data)
170 int ch = (addr >> 1) & 1;
171 bool update_intr_required = false;
172 bool update_tx_timing_required = false;
173 bool update_rx_timing_required = false;
179 if(port[ch].send_intr) {
180 port[ch].send_intr = false;
183 // register next event
184 if(port[ch].wr[5] & 8) {
185 int tx_data_bits = 5;
186 if((data & 0xe0) == 0x00) {
188 } else if((data & 0xf0) == 0x80) {
190 } else if((data & 0xf8) == 0xc0) {
192 } else if((data & 0xfc) == 0xe0) {
194 } else if((data & 0xfe) == 0xf0) {
197 if(port[ch].tx_data_bits != tx_data_bits) {
198 port[ch].tx_data_bits = tx_data_bits;
199 update_tx_timing(ch);
201 if((port[ch].wr[4] & 0x0c) != 0 && port[ch].shift_reg == -1 && port[ch].send->empty()) {
202 // this is the first data
203 CANCEL_SEND_EVENT(ch);
204 REGISTER_FIRST_SEND_EVENT(ch);
206 REGISTER_SEND_EVENT(ch);
209 CANCEL_SEND_EVENT(ch);
211 //#ifndef HAS_UPD7201
212 if(!__HAS_UPD7201) port[ch].send->clear();
214 port[ch].send->write(data);
216 if(__HAS_UPD7201) port[ch].tx_count++;
223 // if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d WR[%d]=%2x\n"), ch, port[ch].pointer, data);
225 switch(port[ch].pointer) {
227 switch(data & 0x38) {
229 if(port[ch].stat_intr) {
230 port[ch].stat_intr = false;
231 update_intr_required = true;
236 CANCEL_SEND_EVENT(ch);
237 CANCEL_RECV_EVENT(ch);
238 port[ch].nextrecv_intr = false;
239 port[ch].first_data = false;
240 port[ch].over_flow = false;
242 if(__HAS_UPD7201) port[ch].tx_count = 0; // is this correct ???
244 port[ch].send->clear();
245 port[ch].recv->clear();
246 port[ch].rtmp->clear();
247 port[ch].shift_reg = -1;
248 memset(port[ch].wr, 0, sizeof(port[ch].wr));
250 if(port[ch].err_intr) {
251 port[ch].err_intr = false;
252 update_intr_required = true;
254 if(port[ch].recv_intr) {
255 port[ch].recv_intr = 0;
256 update_intr_required = true;
258 if(port[ch].stat_intr) {
259 port[ch].stat_intr = false;
260 update_intr_required = true;
262 if(port[ch].send_intr) {
263 port[ch].send_intr = false;
264 update_intr_required = true;
266 port[ch].req_intr = false;
269 port[ch].nextrecv_intr = true;
272 if(port[ch].send_intr) {
273 port[ch].send_intr = false;
274 update_intr_required = true;
278 port[ch].over_flow = false;
279 if(port[ch].err_intr) {
280 port[ch].err_intr = false;
281 update_intr_required = true;
287 for(int c = 0; c < 2; c++) {
288 if(port[c].in_service) {
289 port[c].in_service = false;
290 update_intr_required = true;
297 switch(data & 0xc0) {
299 // reset receive crc checker
302 // reset transmit crc generator
305 // reset transmit underrun
306 if(port[ch].under_run) {
307 port[ch].under_run = false;
308 if(port[ch].stat_intr) {
309 port[ch].stat_intr = false;
310 update_intr_required = true;
318 if(port[ch].wr[port[ch].pointer] != data) {
319 update_intr_required = true;
323 if((data & 0x11) == 0x11) {
324 // enter hunt/sync phase
327 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (monosync)\n"), ch);
329 port[ch].sync_bit = BIT_SYNC1;
330 } else if(BISYNC(ch)) {
332 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (bisync)\n"), ch);
334 port[ch].sync_bit = BIT_SYNC1 | BIT_SYNC2;
336 port[ch].sync = false;
337 write_signals(&port[ch].outputs_sync, 0xffffffff);
339 if((port[ch].wr[3] & 0xc0) != (data & 0xc0)) {
340 update_rx_timing_required = true;
344 if((port[ch].wr[4] & 0xcd) != (data & 0xcd)) {
345 update_tx_timing_required = update_rx_timing_required = true;
349 if((uint32_t)(port[ch].wr[5] & 2) != (data & 2)) {
351 write_signals(&port[ch].outputs_rts, (data & 2) ? 0 : 0xffffffff);
353 if((uint32_t)(port[ch].wr[5] & 0x80) != (data & 0x80)) {
355 write_signals(&port[ch].outputs_dtr, (data & 0x80) ? 0 : 0xffffffff);
358 if((port[ch].wr[4] & 0x0c) != 0 && port[ch].shift_reg == -1 && !port[ch].send->empty()) {
359 // CANCEL_SEND_EVENT(ch);
360 REGISTER_FIRST_SEND_EVENT(ch);
362 REGISTER_SEND_EVENT(ch);
365 CANCEL_SEND_EVENT(ch);
369 write_signals(&port[ch].outputs_break, 0xffffffff);
371 if((port[ch].wr[5] & 0x60) != (data & 0x60)) {
372 update_tx_timing_required = true;
376 port[ch].wr[port[ch].pointer] = data;
377 if(update_intr_required) {
380 if(update_tx_timing_required) {
381 update_tx_timing(ch);
383 if(update_rx_timing_required) {
384 update_rx_timing(ch);
386 port[ch].pointer = (port[ch].pointer == 0) ? (data & 7) : 0;
391 uint32_t Z80SIO::read_io8(uint32_t addr)
393 int ch = (addr >> 1) & 1;
400 if(port[ch].recv_intr) {
401 // cancel pending interrupt
402 if(--port[ch].recv_intr == 0) {
406 // for polling case (thanks YAT)
408 if(port[ch].recv->empty()) {
409 int data = port[ch].rtmp->read();
410 port[ch].recv->write(data);
413 return port[ch].recv->read();
416 if(port[ch].pointer == 0) {
417 if(!port[ch].recv->empty()) {
420 if(ch == 0 && (port[0].req_intr || port[1].req_intr)) {
423 if(!port[ch].send->full()) {
435 if(port[ch].under_run) {
441 } else if(port[ch].pointer == 1) {
443 if(port[ch].send->empty()) {
446 if(port[ch].over_flow) {
449 } else if(port[ch].pointer == 2) {
450 val = port[ch].vector;
452 } else if(port[ch].pointer == 3) {
454 val = port[ch].tx_count & 0xff;
455 port[ch].tx_count_hi = port[ch].tx_count >> 8;
457 } else if(port[ch].pointer == 4) {
459 // val = (port[ch].tx_count >> 8) & 0xff;
460 val = port[ch].tx_count_hi;
464 port[ch].pointer = 0;
470 void Z80SIO::write_signal(int id, uint32_t data, uint32_t mask)
474 bool signal = ((data & mask) != 0);
477 case SIG_Z80SIO_RECV_CH0:
478 case SIG_Z80SIO_RECV_CH1:
480 REGISTER_RECV_EVENT(ch);
481 if(port[ch].rtmp->empty()) {
482 port[ch].first_data = true;
484 port[ch].rtmp->write(data & mask);
486 case SIG_Z80SIO_BREAK_CH0:
487 case SIG_Z80SIO_BREAK_CH1:
489 if((data & mask) && !port[ch].abort) {
490 port[ch].abort = true;
491 if(!port[ch].stat_intr) {
492 port[ch].stat_intr = true;
497 case SIG_Z80SIO_DCD_CH0:
498 case SIG_Z80SIO_DCD_CH1:
499 if(port[ch].dcd != signal) {
500 port[ch].dcd = signal;
501 if(!signal && (port[ch].wr[3] & 0x20)) {
505 if(!port[ch].stat_intr) {
506 port[ch].stat_intr = true;
511 case SIG_Z80SIO_CTS_CH0:
512 case SIG_Z80SIO_CTS_CH1:
513 if(port[ch].cts != signal) {
514 port[ch].cts = signal;
515 if(!signal && (port[ch].wr[3] & 0x20)) {
517 if((port[ch].wr[4] & 0x0c) != 0 && port[ch].shift_reg == -1 && !port[ch].send->empty()) {
518 // CANCEL_SEND_EVENT(ch);
519 REGISTER_FIRST_SEND_EVENT(ch);
521 REGISTER_SEND_EVENT(ch);
525 if(!port[ch].stat_intr) {
526 port[ch].stat_intr = true;
530 case SIG_Z80SIO_SYNC_CH0:
531 case SIG_Z80SIO_SYNC_CH1:
532 if(port[ch].sync != signal) {
533 port[ch].sync = signal;
534 if(!port[ch].stat_intr) {
535 port[ch].stat_intr = true;
540 case SIG_Z80SIO_TX_CLK_CH0:
541 case SIG_Z80SIO_TX_CLK_CH1:
542 if(port[ch].prev_tx_clock_signal != signal) {
543 if(port[ch].tx_bits_x2_remain > 0 && --port[ch].tx_bits_x2_remain == 0) {
544 event_callback(EVENT_SEND + ch, 0);
546 port[ch].prev_tx_clock_signal = signal;
549 case SIG_Z80SIO_RX_CLK_CH0:
550 case SIG_Z80SIO_RX_CLK_CH1:
551 if(port[ch].prev_rx_clock_signal != signal) {
552 if(port[ch].rx_bits_x2_remain > 0 && --port[ch].rx_bits_x2_remain == 0) {
553 event_callback(EVENT_RECV + ch, 0);
555 port[ch].prev_rx_clock_signal = signal;
558 case SIG_Z80SIO_CLEAR_CH0:
559 case SIG_Z80SIO_CLEAR_CH1:
560 // hack: clear recv buffer
562 CANCEL_RECV_EVENT(ch);
563 port[ch].rtmp->clear();
564 port[ch].recv->clear();
565 if(port[ch].recv_intr) {
566 port[ch].recv_intr = 0;
574 void Z80SIO::event_callback(int event_id, int err)
576 int ch = event_id & 1;
578 if(event_id & EVENT_SEND) {
580 port[ch].send_id = -1;
581 port[ch].tx_bits_x2_remain = 0;
583 bool under_run = true;
585 if(port[ch].shift_reg != -1) {
586 // send data in shift register
587 write_signals(&port[ch].outputs_send, port[ch].shift_reg);
588 port[ch].shift_reg = -1;
591 if(!port[ch].send->empty()) {
592 // load data in send buffer to shift register
593 port[ch].shift_reg = port[ch].send->read();
597 // underrun interrupt
598 if(!port[ch].under_run) {
599 port[ch].under_run = true;
600 if(!port[ch].stat_intr) {
601 port[ch].stat_intr = true;
606 if(port[ch].send->empty()) {
607 // transmitter interrupt
608 if(!port[ch].send_intr) {
609 port[ch].send_intr = true;
612 write_signals(&port[ch].outputs_txdone, 0xffffffff);
614 REGISTER_SEND_EVENT(ch);
615 } else if(event_id & EVENT_RECV) {
617 port[ch].recv_id = -1;
618 port[ch].rx_bits_x2_remain = 0;
620 if(!(port[ch].wr[3] & 1)) {
621 REGISTER_RECV_EVENT(ch);
624 bool update_intr_required = false;
626 if(port[ch].recv->full()) {
628 if(!port[ch].over_flow) {
629 port[ch].over_flow = true;
630 if(!port[ch].err_intr) {
631 port[ch].err_intr = true;
632 update_intr_required = true;
637 int data = port[ch].rtmp->read();
639 if(SYNC_MODE(ch) && port[ch].sync_bit != 0) {
640 // receive sync data in monosync/bisync mode ?
641 if(port[ch].sync_bit & BIT_SYNC1) {
642 if(data != port[ch].wr[6]) {
643 goto request_next_data;
646 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d recv sync1\n"), ch);
648 port[ch].sync_bit &= ~BIT_SYNC1;
649 } else if(port[ch].sync_bit & BIT_SYNC2) {
650 if(data != port[ch].wr[7]) {
651 port[ch].sync_bit |= BIT_SYNC1;
652 goto request_next_data;
655 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d recv sync2\n"), ch);
657 port[ch].sync_bit &= ~BIT_SYNC2;
659 if(port[ch].sync_bit == 0) {
661 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d leave hunt/sync phase\n"), ch);
663 if(!port[ch].stat_intr) {
664 port[ch].stat_intr = true;
665 update_intr_required = true;
667 port[ch].sync = true;
668 write_signals(&port[ch].outputs_sync, 0);
670 if(port[ch].wr[3] & 2) {
671 // sync char is not loaded into buffer
672 goto request_next_data;
675 // load received data into buffer
677 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d recv %2x\n"), ch, data);
679 port[ch].recv->write(data);
683 port[ch].abort = false;
684 if(!port[ch].stat_intr) {
685 port[ch].stat_intr = true;
686 update_intr_required = true;
690 // check receive interrupt
692 if((port[ch].wr[1] & 0x18) == 8 && (port[ch].first_data || port[ch].nextrecv_intr)) {
694 } else if(port[ch].wr[1] & 0x10) {
698 if(port[ch].recv_intr++ == 0) {
699 update_intr_required = true;
702 port[ch].first_data = port[ch].nextrecv_intr = false;
705 bool first_data = port[ch].first_data;
706 if(port[ch].rtmp->empty()) {
707 // request data in this message
708 write_signals(&port[ch].outputs_rxdone, 0xffffffff);
710 if(port[ch].rtmp->empty()) {
713 if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d end of block\n"), ch);
715 port[ch].recv_id = -1;
717 REGISTER_RECV_EVENT(ch);
718 port[ch].first_data = first_data;
720 if(update_intr_required) {
726 void Z80SIO::update_tx_timing(int ch)
728 port[ch].tx_bits_x2 = (port[ch].wr[4] & 1) * 2;
729 switch(port[ch].wr[5] & 0x60) {
730 case 0x00: port[ch].tx_bits_x2 += 2 * port[ch].tx_data_bits; break;
731 case 0x20: port[ch].tx_bits_x2 += 2 * 7; break;
732 case 0x40: port[ch].tx_bits_x2 += 2 * 6; break;
733 case 0x60: port[ch].tx_bits_x2 += 2 * 8; break;
735 switch(port[ch].wr[4] & 0x0c) {
736 case 0x00: port[ch].tx_bits_x2 += 0; break; // sync mode
737 case 0x04: port[ch].tx_bits_x2 += 4; break; // 2 * (1 + 1)
738 case 0x08: port[ch].tx_bits_x2 += 5; break; // 2 * (1 + 1.5)
739 case 0x0c: port[ch].tx_bits_x2 += 6; break; // 2 * (1 + 2)
741 switch(port[ch].wr[4] & 0xc0) {
742 case 0x40: port[ch].tx_bits_x2 *= 16; break;
743 case 0x80: port[ch].tx_bits_x2 *= 32; break;
744 case 0xc0: port[ch].tx_bits_x2 *= 64; break;
746 if(port[ch].tx_clock != 0) {
747 port[ch].tx_interval = 1000000.0 / port[ch].tx_clock * (double)port[ch].tx_bits_x2 / 2.0;
751 void Z80SIO::update_rx_timing(int ch)
753 port[ch].rx_bits_x2 = (port[ch].wr[4] & 1) * 2;
754 switch(port[ch].wr[3] & 0xc0) {
755 case 0x00: port[ch].rx_bits_x2 += 2 * 5; break;
756 case 0x40: port[ch].rx_bits_x2 += 2 * 7; break;
757 case 0x80: port[ch].rx_bits_x2 += 2 * 6; break;
758 case 0xc0: port[ch].rx_bits_x2 += 2 * 8; break;
760 switch(port[ch].wr[4] & 0x0c) {
761 case 0x00: port[ch].rx_bits_x2 += 0; break; // sync mode
762 case 0x04: port[ch].rx_bits_x2 += 4; break; // 2 * (1 + 1)
763 case 0x08: port[ch].rx_bits_x2 += 5; break; // 2 * (1 + 1.5)
764 case 0x0c: port[ch].rx_bits_x2 += 6; break; // 2 * (1 + 2)
766 switch(port[ch].wr[4] & 0xc0) {
767 case 0x40: port[ch].rx_bits_x2 *= 16; break;
768 case 0x80: port[ch].rx_bits_x2 *= 32; break;
769 case 0xc0: port[ch].rx_bits_x2 *= 64; break;
771 if(port[ch].rx_clock != 0) {
772 port[ch].rx_interval = 1000000.0 / port[ch].rx_clock * (double)port[ch].rx_bits_x2 / 2.0;
776 void Z80SIO::set_intr_iei(bool val)
784 #define set_intr_oei(val) { \
788 d_child->set_intr_iei(oei); \
793 void Z80SIO::update_intr()
798 if((next = iei) == true) {
799 for(int ch = 0; ch < 2; ch++) {
800 if(port[ch].in_service) {
808 // check interrupt status
809 for(int ch = 0; ch < 2; ch++) {
810 if(port[ch].err_intr) {
811 port[ch].req_intr = true;
812 port[ch].affect = (ch ? 0 : 4) | 3;
813 } else if(port[ch].recv_intr && (port[ch].wr[1] & 0x18)) {
814 port[ch].req_intr = true;
815 port[ch].affect = (ch ? 0 : 4) | 2;
816 } else if(port[ch].stat_intr && (port[ch].wr[1] & 1)) {
817 port[ch].req_intr = true;
818 port[ch].affect = (ch ? 0 : 4) | 1;
819 } else if(port[ch].send_intr && (port[ch].wr[1] & 2)) {
820 port[ch].req_intr = true;
821 port[ch].affect = (ch ? 0 : 4) | 0;
823 port[ch].req_intr = false;
828 if(port[1].wr[1] & 4) {
831 uint8_t affect = 7; // no interrupt pending
832 for(int ch = 0; ch < 2; ch++) {
833 if(port[ch].in_service) {
836 if(port[ch].req_intr) {
837 affect = port[ch].affect;
841 uint8_t mode = port[0].wr[2] & 0x38;
842 if(mode == 0 || mode == 8 || mode == 0x20 || mode == 0x28 || mode == 0x38) {
843 port[1].vector = (port[1].wr[2] & 0xe3) | (affect << 2); // 8085
845 port[1].vector = (port[1].wr[2] & 0xf8) | (affect << 0); // 8086
849 uint8_t affect = 3; // no interrupt pending
850 for(int ch = 0; ch < 2; ch++) {
851 if(port[ch].in_service) {
854 if(port[ch].req_intr) {
855 affect = port[ch].affect;
859 port[1].vector = (port[1].wr[2] & 0xf1) | (affect << 1);
863 port[1].vector = port[1].wr[2];
867 if((next = iei) == true) {
869 for(int ch = 0; ch < 2; ch++) {
870 if(port[ch].in_service) {
873 if(port[ch].req_intr) {
880 d_cpu->set_intr_line(next, true, intr_bit);
884 uint32_t Z80SIO::get_intr_ack()
887 for(int ch = 0; ch < 2; ch++) {
888 if(port[ch].in_service) {
889 // invalid interrupt status
892 // priority is error > receive > status > send ???
893 if(port[ch].err_intr) {
894 port[ch].err_intr = false;
895 port[ch].in_service = true;
896 } else if(port[ch].recv_intr && (port[ch].wr[1] & 0x18)) {
897 // port[ch].recv_intr = 0; // thanks YAT
898 port[ch].in_service = true;
899 } else if(port[ch].stat_intr && (port[ch].wr[1] & 1)) {
900 port[ch].stat_intr = false;
901 port[ch].in_service = true;
902 } else if(port[ch].send_intr && (port[ch].wr[1] & 2)) {
903 port[ch].send_intr = false;
904 port[ch].in_service = true;
906 if(port[ch].in_service) {
907 uint8_t vector = port[1].vector;
913 return d_child->get_intr_ack();
918 void Z80SIO::notify_intr_reti()
921 for(int ch = 0; ch < 2; ch++) {
922 if(port[ch].in_service) {
923 port[ch].in_service = false;
929 d_child->notify_intr_reti();
933 #define STATE_VERSION 3
935 bool Z80SIO::process_state(FILEIO* state_fio, bool loading)
937 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
940 if(!state_fio->StateCheckInt32(this_device_id)) {
943 for(int i = 0; i < 2; i++) {
944 state_fio->StateValue(port[i].pointer);
945 state_fio->StateArray(port[i].wr, sizeof(port[i].wr), 1);
946 state_fio->StateValue(port[i].vector);
947 state_fio->StateValue(port[i].affect);
948 state_fio->StateValue(port[i].nextrecv_intr);
949 state_fio->StateValue(port[i].first_data);
950 state_fio->StateValue(port[i].over_flow);
951 state_fio->StateValue(port[i].under_run);
952 state_fio->StateValue(port[i].abort);
953 state_fio->StateValue(port[i].sync);
954 state_fio->StateValue(port[i].sync_bit);
956 state_fio->StateValue(port[i].tx_count);
957 state_fio->StateValue(port[i].tx_count_hi);
959 state_fio->StateValue(port[i].tx_clock);
960 state_fio->StateValue(port[i].tx_interval);
961 state_fio->StateValue(port[i].rx_clock);
962 state_fio->StateValue(port[i].rx_interval);
963 state_fio->StateValue(port[i].tx_data_bits);
964 state_fio->StateValue(port[i].tx_bits_x2);
965 state_fio->StateValue(port[i].tx_bits_x2_remain);
966 state_fio->StateValue(port[i].rx_bits_x2);
967 state_fio->StateValue(port[i].rx_bits_x2_remain);
968 state_fio->StateValue(port[i].prev_tx_clock_signal);
969 state_fio->StateValue(port[i].prev_rx_clock_signal);
970 if(!port[i].send->process_state((void *)state_fio, loading)) {
973 if(!port[i].recv->process_state((void *)state_fio, loading)) {
976 if(!port[i].rtmp->process_state((void *)state_fio, loading)) {
979 state_fio->StateValue(port[i].shift_reg);
980 state_fio->StateValue(port[i].send_id);
981 state_fio->StateValue(port[i].recv_id);
982 state_fio->StateValue(port[i].err_intr);
983 state_fio->StateValue(port[i].recv_intr);
984 state_fio->StateValue(port[i].stat_intr);
985 state_fio->StateValue(port[i].send_intr);
986 state_fio->StateValue(port[i].req_intr);
987 state_fio->StateValue(port[i].in_service);
988 state_fio->StateValue(port[i].dcd);
989 state_fio->StateValue(port[i].cts);
991 state_fio->StateValue(iei);
992 state_fio->StateValue(oei);
993 state_fio->StateValue(intr_bit);