2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 #include "../fileio.h"
20 #define MONOSYNC(ch) ((port[ch].wr[4] & 0x3c) == 0x00)
21 #define BISYNC(ch) ((port[ch].wr[4] & 0x3c) == 0x10)
22 //#define SDLC(ch) ((port[ch].wr[4] & 0x3c) == 0x20)
23 //#define EXTSYNC(ch) ((port[ch].wr[4] & 0x3c) == 0x30)
24 #define SYNC_MODE(ch) (MONOSYNC(ch) || BISYNC(ch))
29 #define REGISTER_SEND_EVENT(ch) { \
30 if(port[ch].tx_clock != 0) { \
31 if(port[ch].send_id == -1) { \
32 register_event(this, EVENT_SEND + ch, port[ch].tx_interval, false, &port[ch].send_id); \
35 if(port[ch].tx_bits_x2_remain == 0) { \
36 port[ch].tx_bits_x2_remain = port[ch].tx_bits_x2; \
41 #define CANCEL_SEND_EVENT(ch) { \
42 if(port[ch].tx_clock != 0) { \
43 if(port[ch].send_id != -1) { \
44 cancel_event(this, port[ch].send_id); \
45 port[ch].send_id = -1; \
48 port[ch].tx_bits_x2_remain = 0; \
52 #define REGISTER_RECV_EVENT(ch) { \
53 if(port[ch].rx_clock != 0) { \
54 if(port[ch].recv_id == -1) { \
55 register_event(this, EVENT_RECV + ch, port[ch].rx_interval, false, &port[ch].recv_id); \
58 if(port[ch].rx_bits_x2_remain == 0) { \
59 port[ch].rx_bits_x2_remain = port[ch].rx_bits_x2; \
64 #define CANCEL_RECV_EVENT(ch) { \
65 if(port[ch].rx_clock != 0) { \
66 if(port[ch].recv_id != -1) { \
67 cancel_event(this, port[ch].recv_id); \
68 port[ch].recv_id = -1; \
71 port[ch].rx_bits_x2_remain = 0; \
75 void Z80SIO::initialize()
77 for(int ch = 0; ch < 2; ch++) {
79 port[ch].send = new FIFO(16);
80 port[ch].recv = new FIFO(16);
81 port[ch].rtmp = new FIFO(16);
83 port[ch].send = new FIFO(2);
84 port[ch].recv = new FIFO(4);
85 port[ch].rtmp = new FIFO(8);
91 port[ch].sync_bit = 0;
97 for(int ch = 0; ch < 2; ch++) {
99 port[ch].nextrecv_intr = false;
100 port[ch].first_data = false;
101 port[ch].over_flow = false;
102 port[ch].under_run = false;
103 port[ch].abort = false;
105 port[ch].tx_count = 0;
107 port[ch].send_id = -1;
108 port[ch].recv_id = -1;
109 port[ch].send->clear();
110 port[ch].recv->clear();
111 port[ch].rtmp->clear();
112 memset(port[ch].wr, 0, sizeof(port[ch].wr));
114 port[ch].err_intr = false;
115 port[ch].recv_intr = 0;
116 port[ch].stat_intr = false;
117 port[ch].send_intr = false;
118 port[ch].req_intr = false;
119 port[ch].in_service = false;
124 void Z80SIO::release()
126 for(int ch = 0; ch < 2; ch++) {
128 port[ch].send->release();
129 delete port[ch].send;
132 port[ch].recv->release();
133 delete port[ch].recv;
136 port[ch].rtmp->release();
137 delete port[ch].rtmp;
149 void Z80SIO::write_io8(uint32 addr, uint32 data)
151 int ch = (addr >> 1) & 1;
152 bool update_intr_required = false;
153 bool update_tx_timing_required = false;
154 bool update_rx_timing_required = false;
160 port[ch].send->write(data);
164 if(port[ch].send_intr) {
165 port[ch].send_intr = false;
168 // register next event
169 CANCEL_SEND_EVENT(ch);
170 if(port[ch].wr[5] & 8) {
171 int tx_data_bits = 5;
172 if((data & 0xe0) == 0x00) {
174 } else if((data & 0xf0) == 0x80) {
176 } else if((data & 0xf8) == 0xc0) {
178 } else if((data & 0xfc) == 0xe0) {
180 } else if((data & 0xfe) == 0xf0) {
183 if(port[ch].tx_data_bits != tx_data_bits) {
184 port[ch].tx_data_bits = tx_data_bits;
185 update_tx_timing(ch);
187 REGISTER_SEND_EVENT(ch);
194 // emu->out_debug_log(_T("Z80SIO: ch=%d WR[%d]=%2x\n"), ch, port[ch].pointer, data);
196 switch(port[ch].pointer) {
198 switch(data & 0x38) {
200 if(port[ch].stat_intr) {
201 port[ch].stat_intr = false;
202 update_intr_required = true;
206 CANCEL_SEND_EVENT(ch);
207 CANCEL_RECV_EVENT(ch);
208 port[ch].nextrecv_intr = false;
209 port[ch].first_data = false;
210 port[ch].over_flow = false;
212 port[ch].tx_count = 0; // is this correct ???
214 port[ch].send->clear();
215 port[ch].recv->clear();
216 port[ch].rtmp->clear();
217 memset(port[ch].wr, 0, sizeof(port[ch].wr));
219 if(port[ch].err_intr) {
220 port[ch].err_intr = false;
221 update_intr_required = true;
223 if(port[ch].recv_intr) {
224 port[ch].recv_intr = 0;
225 update_intr_required = true;
227 if(port[ch].stat_intr) {
228 port[ch].stat_intr = false;
229 update_intr_required = true;
231 if(port[ch].send_intr) {
232 port[ch].send_intr = false;
233 update_intr_required = true;
235 port[ch].req_intr = false;
238 port[ch].nextrecv_intr = true;
241 if(port[ch].send_intr) {
242 port[ch].send_intr = false;
243 update_intr_required = true;
247 port[ch].over_flow = false;
248 if(port[ch].err_intr) {
249 port[ch].err_intr = false;
250 update_intr_required = true;
256 for(int c = 0; c < 2; c++) {
257 if(port[c].in_service) {
258 port[c].in_service = false;
259 update_intr_required = true;
266 switch(data & 0xc0) {
268 // reset receive crc checker
271 // reset transmit crc generator
274 // reset transmit underrun
275 if(port[ch].under_run) {
276 port[ch].under_run = false;
277 if(port[ch].stat_intr) {
278 port[ch].stat_intr = false;
279 update_intr_required = true;
287 if(port[ch].wr[port[ch].pointer] != data) {
288 update_intr_required = true;
292 if((data & 0x11) == 0x11) {
293 // enter hunt/sync phase
296 emu->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (monosync)\n"), ch);
298 port[ch].sync_bit = BIT_SYNC1;
299 } else if(BISYNC(ch)) {
301 emu->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (bisync)\n"), ch);
303 port[ch].sync_bit = BIT_SYNC1 | BIT_SYNC2;
305 port[ch].sync = false;
306 write_signals(&port[ch].outputs_sync, 0xffffffff);
308 if((port[ch].wr[3] & 0xc0) != (data & 0xc0)) {
309 update_rx_timing_required = true;
313 if((port[ch].wr[4] & 0xcd) != (data & 0xcd)) {
314 update_tx_timing_required = update_rx_timing_required = true;
318 if((uint32)(port[ch].wr[5] & 2) != (data & 2)) {
320 write_signals(&port[ch].outputs_rts, (data & 2) ? 0 : 0xffffffff);
322 if((uint32)(port[ch].wr[5] & 0x80) != (data & 0x80)) {
324 write_signals(&port[ch].outputs_dtr, (data & 0x80) ? 0 : 0xffffffff);
327 REGISTER_SEND_EVENT(ch);
329 CANCEL_SEND_EVENT(ch);
333 write_signals(&port[ch].outputs_break, 0xffffffff);
335 if((port[ch].wr[5] & 0x60) != (data & 0x60)) {
336 update_tx_timing_required = true;
340 port[ch].wr[port[ch].pointer] = data;
341 if(update_intr_required) {
344 if(update_tx_timing_required) {
345 update_tx_timing(ch);
347 if(update_rx_timing_required) {
348 update_rx_timing(ch);
350 port[ch].pointer = (port[ch].pointer == 0) ? (data & 7) : 0;
355 uint32 Z80SIO::read_io8(uint32 addr)
357 int ch = (addr >> 1) & 1;
364 if(port[ch].recv_intr) {
365 // cancel pending interrupt
366 if(--port[ch].recv_intr == 0) {
370 return port[ch].recv->read();
373 if(port[ch].pointer == 0) {
374 if(!port[ch].recv->empty()) {
377 if(ch == 0 && (port[0].req_intr || port[1].req_intr)) {
380 if(!port[ch].send->full()) {
392 if(port[ch].under_run) {
398 } else if(port[ch].pointer == 1) {
400 if(port[ch].send->empty()) {
403 if(port[ch].over_flow) {
406 } else if(port[ch].pointer == 2) {
407 val = port[ch].vector;
409 } else if(port[ch].pointer == 3) {
410 val = port[ch].tx_count & 0xff;
411 } else if(port[ch].pointer == 4) {
412 val = (port[ch].tx_count >> 8) & 0xff;
415 port[ch].pointer = 0;
421 void Z80SIO::write_signal(int id, uint32 data, uint32 mask)
425 bool signal = ((data & mask) != 0);
428 case SIG_Z80SIO_RECV_CH0:
429 case SIG_Z80SIO_RECV_CH1:
431 REGISTER_RECV_EVENT(ch);
432 if(port[ch].rtmp->empty()) {
433 port[ch].first_data = true;
435 port[ch].rtmp->write(data & mask);
437 case SIG_Z80SIO_BREAK_CH0:
438 case SIG_Z80SIO_BREAK_CH1:
440 if((data & mask) && !port[ch].abort) {
441 port[ch].abort = true;
442 if(!port[ch].stat_intr) {
443 port[ch].stat_intr = true;
448 case SIG_Z80SIO_DCD_CH0:
449 case SIG_Z80SIO_DCD_CH1:
450 if(port[ch].dcd != signal) {
451 port[ch].dcd = signal;
452 if(!signal && (port[ch].wr[3] & 0x20)) {
456 if(!port[ch].stat_intr) {
457 port[ch].stat_intr = true;
462 case SIG_Z80SIO_CTS_CH0:
463 case SIG_Z80SIO_CTS_CH1:
464 if(port[ch].cts != signal) {
465 port[ch].cts = signal;
466 if(!signal && (port[ch].wr[3] & 0x20)) {
468 REGISTER_SEND_EVENT(ch);
471 if(!port[ch].stat_intr) {
472 port[ch].stat_intr = true;
476 case SIG_Z80SIO_SYNC_CH0:
477 case SIG_Z80SIO_SYNC_CH1:
478 if(port[ch].sync != signal) {
479 port[ch].sync = signal;
480 if(!port[ch].stat_intr) {
481 port[ch].stat_intr = true;
486 case SIG_Z80SIO_TX_CLK_CH0:
487 case SIG_Z80SIO_TX_CLK_CH1:
488 if(port[ch].prev_tx_clock_signal != signal) {
489 if(port[ch].tx_bits_x2_remain > 0 && --port[ch].tx_bits_x2_remain == 0) {
490 event_callback(EVENT_SEND + ch, 0);
492 port[ch].prev_tx_clock_signal = signal;
495 case SIG_Z80SIO_RX_CLK_CH0:
496 case SIG_Z80SIO_RX_CLK_CH1:
497 if(port[ch].prev_rx_clock_signal != signal) {
498 if(port[ch].rx_bits_x2_remain > 0 && --port[ch].rx_bits_x2_remain == 0) {
499 event_callback(EVENT_RECV + ch, 0);
501 port[ch].prev_rx_clock_signal = signal;
504 case SIG_Z80SIO_CLEAR_CH0:
505 case SIG_Z80SIO_CLEAR_CH1:
506 // hack: clear recv buffer
508 CANCEL_RECV_EVENT(ch);
509 port[ch].rtmp->clear();
510 port[ch].recv->clear();
511 if(port[ch].recv_intr) {
512 port[ch].recv_intr = 0;
520 void Z80SIO::event_callback(int event_id, int err)
522 int ch = event_id & 1;
524 if(event_id & EVENT_SEND) {
526 port[ch].send_id = -1;
527 port[ch].tx_bits_x2_remain = 0;
529 if(port[ch].send->empty()) {
530 // underrun interrupt
531 if(!port[ch].under_run) {
532 port[ch].under_run = true;
533 if(!port[ch].stat_intr) {
534 port[ch].stat_intr = true;
539 uint32 data = port[ch].send->read();
540 write_signals(&port[ch].outputs_send, data);
542 if(port[ch].send->empty()) {
543 // transmitter interrupt
544 if(!port[ch].send_intr) {
545 port[ch].send_intr = true;
548 write_signals(&port[ch].outputs_txdone, 0xffffffff);
550 // register next event
551 REGISTER_SEND_EVENT(ch);
552 } else if(event_id & EVENT_RECV) {
554 port[ch].recv_id = -1;
555 port[ch].rx_bits_x2_remain = 0;
557 if(!(port[ch].wr[3] & 1)) {
558 REGISTER_RECV_EVENT(ch);
561 bool update_intr_required = false;
563 if(port[ch].recv->full()) {
565 if(!port[ch].over_flow) {
566 port[ch].over_flow = true;
567 if(!port[ch].err_intr) {
568 port[ch].err_intr = true;
569 update_intr_required = true;
574 int data = port[ch].rtmp->read();
576 if(SYNC_MODE(ch) && port[ch].sync_bit != 0) {
577 // receive sync data in monosync/bisync mode ?
578 if(port[ch].sync_bit & BIT_SYNC1) {
579 if(data != port[ch].wr[6]) {
580 goto request_next_data;
583 emu->out_debug_log(_T("Z80SIO: ch=%d recv sync1\n"), ch);
585 port[ch].sync_bit &= ~BIT_SYNC1;
586 } else if(port[ch].sync_bit & BIT_SYNC2) {
587 if(data != port[ch].wr[7]) {
588 port[ch].sync_bit |= BIT_SYNC1;
589 goto request_next_data;
592 emu->out_debug_log(_T("Z80SIO: ch=%d recv sync2\n"), ch);
594 port[ch].sync_bit &= ~BIT_SYNC2;
596 if(port[ch].sync_bit == 0) {
598 emu->out_debug_log(_T("Z80SIO: ch=%d leave hunt/sync phase\n"), ch);
600 if(!port[ch].stat_intr) {
601 port[ch].stat_intr = true;
602 update_intr_required = true;
604 port[ch].sync = true;
605 write_signals(&port[ch].outputs_sync, 0);
607 if(port[ch].wr[3] & 2) {
608 // sync char is not loaded into buffer
609 goto request_next_data;
612 // load received data into buffer
614 emu->out_debug_log(_T("Z80SIO: ch=%d recv %2x\n"), ch, data);
616 port[ch].recv->write(data);
620 port[ch].abort = false;
621 if(!port[ch].stat_intr) {
622 port[ch].stat_intr = true;
623 update_intr_required = true;
627 // check receive interrupt
629 if((port[ch].wr[1] & 0x18) == 8 && (port[ch].first_data || port[ch].nextrecv_intr)) {
631 } else if(port[ch].wr[1] & 0x10) {
635 if(port[ch].recv_intr++ == 0) {
636 update_intr_required = true;
639 port[ch].first_data = port[ch].nextrecv_intr = false;
642 bool first_data = port[ch].first_data;
643 if(port[ch].rtmp->empty()) {
644 // request data in this message
645 write_signals(&port[ch].outputs_rxdone, 0xffffffff);
647 if(port[ch].rtmp->empty()) {
650 emu->out_debug_log(_T("Z80SIO: ch=%d end of block\n"), ch);
652 port[ch].recv_id = -1;
654 REGISTER_RECV_EVENT(ch);
655 port[ch].first_data = first_data;
657 if(update_intr_required) {
663 void Z80SIO::update_tx_timing(int ch)
665 port[ch].tx_bits_x2 = (port[ch].wr[4] & 1) * 2;
666 switch(port[ch].wr[5] & 0x60) {
667 case 0x00: port[ch].tx_bits_x2 += 2 * port[ch].tx_data_bits; break;
668 case 0x20: port[ch].tx_bits_x2 += 2 * 7; break;
669 case 0x40: port[ch].tx_bits_x2 += 2 * 6; break;
670 case 0x60: port[ch].tx_bits_x2 += 2 * 8; break;
672 switch(port[ch].wr[4] & 0x0c) {
673 case 0x00: port[ch].tx_bits_x2 += 0; break; // sync mode
674 case 0x04: port[ch].tx_bits_x2 += 4; break; // 2 * (1 + 1)
675 case 0x08: port[ch].tx_bits_x2 += 5; break; // 2 * (1 + 1.5)
676 case 0x0c: port[ch].tx_bits_x2 += 6; break; // 2 * (1 + 2)
678 switch(port[ch].wr[4] & 0xc0) {
679 case 0x40: port[ch].tx_bits_x2 *= 16; break;
680 case 0x80: port[ch].tx_bits_x2 *= 32; break;
681 case 0xc0: port[ch].tx_bits_x2 *= 64; break;
683 if(port[ch].tx_clock != 0) {
684 port[ch].tx_interval = 1000000.0 / port[ch].tx_clock * (double)port[ch].tx_bits_x2 / 2.0;
688 void Z80SIO::update_rx_timing(int ch)
690 port[ch].rx_bits_x2 = (port[ch].wr[4] & 1) * 2;
691 switch(port[ch].wr[3] & 0xc0) {
692 case 0x00: port[ch].rx_bits_x2 += 2 * 5; break;
693 case 0x40: port[ch].rx_bits_x2 += 2 * 7; break;
694 case 0x80: port[ch].rx_bits_x2 += 2 * 6; break;
695 case 0xc0: port[ch].rx_bits_x2 += 2 * 8; break;
697 switch(port[ch].wr[4] & 0x0c) {
698 case 0x00: port[ch].rx_bits_x2 += 0; break; // sync mode
699 case 0x04: port[ch].rx_bits_x2 += 4; break; // 2 * (1 + 1)
700 case 0x08: port[ch].rx_bits_x2 += 5; break; // 2 * (1 + 1.5)
701 case 0x0c: port[ch].rx_bits_x2 += 6; break; // 2 * (1 + 2)
703 switch(port[ch].wr[4] & 0xc0) {
704 case 0x40: port[ch].rx_bits_x2 *= 16; break;
705 case 0x80: port[ch].rx_bits_x2 *= 32; break;
706 case 0xc0: port[ch].rx_bits_x2 *= 64; break;
708 if(port[ch].rx_clock != 0) {
709 port[ch].rx_interval = 1000000.0 / port[ch].rx_clock * (double)port[ch].rx_bits_x2 / 2.0;
713 void Z80SIO::set_intr_iei(bool val)
721 #define set_intr_oei(val) { \
725 d_child->set_intr_iei(oei); \
730 void Z80SIO::update_intr()
735 if((next = iei) == true) {
736 for(int ch = 0; ch < 2; ch++) {
737 if(port[ch].in_service) {
745 // check interrupt status
746 for(int ch = 0; ch < 2; ch++) {
747 if(port[ch].err_intr) {
748 port[ch].req_intr = true;
749 port[ch].affect = (ch ? 0 : 4) | 3;
750 } else if(port[ch].recv_intr && (port[ch].wr[1] & 0x18)) {
751 port[ch].req_intr = true;
752 port[ch].affect = (ch ? 0 : 4) | 2;
753 } else if(port[ch].stat_intr && (port[ch].wr[1] & 1)) {
754 port[ch].req_intr = true;
755 port[ch].affect = (ch ? 0 : 4) | 1;
756 } else if(port[ch].send_intr && (port[ch].wr[1] & 2)) {
757 port[ch].req_intr = true;
758 port[ch].affect = (ch ? 0 : 4) | 0;
760 port[ch].req_intr = false;
765 if(port[1].wr[1] & 4) {
767 uint8 affect = 7; // no interrupt pending
768 for(int ch = 0; ch < 2; ch++) {
769 if(port[ch].in_service) {
772 if(port[ch].req_intr) {
773 affect = port[ch].affect;
777 uint8 mode = port[0].wr[2] & 0x38;
778 if(mode == 0 || mode == 8 || mode == 0x20 || mode == 0x28 || mode == 0x38) {
779 port[1].vector = (port[1].wr[2] & 0xe3) | (affect << 2); // 8085
781 port[1].vector = (port[1].wr[2] & 0xf8) | (affect << 0); // 8086
784 uint8 affect = 3; // no interrupt pending
785 for(int ch = 0; ch < 2; ch++) {
786 if(port[ch].in_service) {
789 if(port[ch].req_intr) {
790 affect = port[ch].affect;
794 port[1].vector = (port[1].wr[2] & 0xf1) | (affect << 1);
797 port[1].vector = port[1].wr[2];
801 if((next = iei) == true) {
803 for(int ch = 0; ch < 2; ch++) {
804 if(port[ch].in_service) {
807 if(port[ch].req_intr) {
814 d_cpu->set_intr_line(next, true, intr_bit);
818 uint32 Z80SIO::intr_ack()
821 for(int ch = 0; ch < 2; ch++) {
822 if(port[ch].in_service) {
823 // invalid interrupt status
826 // priority is error > receive > status > send ???
827 if(port[ch].err_intr) {
828 port[ch].err_intr = false;
829 port[ch].in_service = true;
830 } else if(port[ch].recv_intr && (port[ch].wr[1] & 0x18)) {
831 port[ch].recv_intr = 0;
832 port[ch].in_service = true;
833 } else if(port[ch].stat_intr && (port[ch].wr[1] & 1)) {
834 port[ch].stat_intr = false;
835 port[ch].in_service = true;
836 } else if(port[ch].send_intr && (port[ch].wr[1] & 2)) {
837 port[ch].send_intr = false;
838 port[ch].in_service = true;
840 if(port[ch].in_service) {
841 uint8 vector = port[1].vector;
847 return d_child->intr_ack();
852 void Z80SIO::intr_reti()
855 for(int ch = 0; ch < 2; ch++) {
856 if(port[ch].in_service) {
857 port[ch].in_service = false;
863 d_child->intr_reti();
867 #define STATE_VERSION 2
869 void Z80SIO::save_state(FILEIO* state_fio)
871 state_fio->FputUint32(STATE_VERSION);
872 state_fio->FputInt32(this_device_id);
874 for(int i = 0; i < 2; i++) {
875 state_fio->FputInt32(port[i].pointer);
876 state_fio->Fwrite(port[i].wr, sizeof(port[i].wr), 1);
877 state_fio->FputUint8(port[i].vector);
878 state_fio->FputUint8(port[i].affect);
879 state_fio->FputBool(port[i].nextrecv_intr);
880 state_fio->FputBool(port[i].first_data);
881 state_fio->FputBool(port[i].over_flow);
882 state_fio->FputBool(port[i].under_run);
883 state_fio->FputBool(port[i].abort);
884 state_fio->FputBool(port[i].sync);
885 state_fio->FputUint8(port[i].sync_bit);
887 state_fio->FputUint16(port[i].tx_count);
889 state_fio->FputDouble(port[i].tx_clock);
890 state_fio->FputDouble(port[i].tx_interval);
891 state_fio->FputDouble(port[i].rx_clock);
892 state_fio->FputDouble(port[i].rx_interval);
893 state_fio->FputInt32(port[i].tx_data_bits);
894 state_fio->FputInt32(port[i].tx_bits_x2);
895 state_fio->FputInt32(port[i].tx_bits_x2_remain);
896 state_fio->FputInt32(port[i].rx_bits_x2);
897 state_fio->FputInt32(port[i].rx_bits_x2_remain);
898 state_fio->FputBool(port[i].prev_tx_clock_signal);
899 state_fio->FputBool(port[i].prev_rx_clock_signal);
900 port[i].send->save_state((void *)state_fio);
901 port[i].recv->save_state((void *)state_fio);
902 port[i].rtmp->save_state((void *)state_fio);
903 state_fio->FputInt32(port[i].send_id);
904 state_fio->FputInt32(port[i].recv_id);
905 state_fio->FputBool(port[i].err_intr);
906 state_fio->FputInt32(port[i].recv_intr);
907 state_fio->FputBool(port[i].stat_intr);
908 state_fio->FputBool(port[i].send_intr);
909 state_fio->FputBool(port[i].req_intr);
910 state_fio->FputBool(port[i].in_service);
911 state_fio->FputBool(port[i].dcd);
912 state_fio->FputBool(port[i].cts);
914 state_fio->FputBool(iei);
915 state_fio->FputBool(oei);
916 state_fio->FputUint32(intr_bit);
919 bool Z80SIO::load_state(FILEIO* state_fio)
921 if(state_fio->FgetUint32() != STATE_VERSION) {
924 if(state_fio->FgetInt32() != this_device_id) {
927 for(int i = 0; i < 2; i++) {
928 port[i].pointer = state_fio->FgetInt32();
929 state_fio->Fread(port[i].wr, sizeof(port[i].wr), 1);
930 port[i].vector = state_fio->FgetUint8();
931 port[i].affect = state_fio->FgetUint8();
932 port[i].nextrecv_intr = state_fio->FgetBool();
933 port[i].first_data = state_fio->FgetBool();
934 port[i].over_flow = state_fio->FgetBool();
935 port[i].under_run = state_fio->FgetBool();
936 port[i].abort = state_fio->FgetBool();
937 port[i].sync = state_fio->FgetBool();
938 port[i].sync_bit = state_fio->FgetUint8();
940 port[i].tx_count = state_fio->FgetUint16();
942 port[i].tx_clock = state_fio->FgetDouble();
943 port[i].tx_interval = state_fio->FgetDouble();
944 port[i].rx_clock = state_fio->FgetDouble();
945 port[i].rx_interval = state_fio->FgetDouble();
946 port[i].tx_data_bits = state_fio->FgetInt32();
947 port[i].tx_bits_x2 = state_fio->FgetInt32();
948 port[i].tx_bits_x2_remain = state_fio->FgetInt32();
949 port[i].rx_bits_x2 = state_fio->FgetInt32();
950 port[i].rx_bits_x2_remain = state_fio->FgetInt32();
951 port[i].prev_tx_clock_signal = state_fio->FgetBool();
952 port[i].prev_rx_clock_signal = state_fio->FgetBool();
953 if(!port[i].send->load_state((void *)state_fio)) {
956 if(!port[i].recv->load_state((void *)state_fio)) {
959 if(!port[i].rtmp->load_state((void *)state_fio)) {
962 port[i].send_id = state_fio->FgetInt32();
963 port[i].recv_id = state_fio->FgetInt32();
964 port[i].err_intr = state_fio->FgetBool();
965 port[i].recv_intr = state_fio->FgetInt32();
966 port[i].stat_intr = state_fio->FgetBool();
967 port[i].send_intr = state_fio->FgetBool();
968 port[i].req_intr = state_fio->FgetBool();
969 port[i].in_service = state_fio->FgetBool();
970 port[i].dcd = state_fio->FgetBool();
971 port[i].cts = state_fio->FgetBool();
973 iei = state_fio->FgetBool();
974 oei = state_fio->FgetBool();
975 intr_bit = state_fio->FgetUint32();