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()
87 for(int ch = 0; ch < 2; ch++) {
89 port[ch].send = new FIFO(16);
90 port[ch].recv = new FIFO(16);
91 port[ch].rtmp = new FIFO(16);
93 port[ch].send = new FIFO(1);
94 port[ch].recv = new FIFO(4);
95 port[ch].rtmp = new FIFO(8);
100 port[ch].sync = true;
101 port[ch].sync_bit = 0;
107 for(int ch = 0; ch < 2; ch++) {
108 port[ch].pointer = 0;
109 port[ch].nextrecv_intr = false;
110 port[ch].first_data = false;
111 port[ch].over_flow = false;
112 port[ch].under_run = false;
113 port[ch].abort = false;
115 port[ch].tx_count = 0;
117 port[ch].send->clear();
118 port[ch].recv->clear();
119 port[ch].rtmp->clear();
120 port[ch].shift_reg = -1;
121 port[ch].send_id = -1;
122 port[ch].recv_id = -1;
123 memset(port[ch].wr, 0, sizeof(port[ch].wr));
125 port[ch].err_intr = false;
126 port[ch].recv_intr = 0;
127 port[ch].stat_intr = false;
128 port[ch].send_intr = false;
129 port[ch].req_intr = false;
130 port[ch].in_service = false;
135 void Z80SIO::release()
137 for(int ch = 0; ch < 2; ch++) {
139 port[ch].send->release();
140 delete port[ch].send;
143 port[ch].recv->release();
144 delete port[ch].recv;
147 port[ch].rtmp->release();
148 delete port[ch].rtmp;
160 void Z80SIO::write_io8(uint32 addr, uint32 data)
162 int ch = (addr >> 1) & 1;
163 bool update_intr_required = false;
164 bool update_tx_timing_required = false;
165 bool update_rx_timing_required = false;
171 if(port[ch].send_intr) {
172 port[ch].send_intr = false;
175 // register next event
176 if(port[ch].wr[5] & 8) {
177 int tx_data_bits = 5;
178 if((data & 0xe0) == 0x00) {
180 } else if((data & 0xf0) == 0x80) {
182 } else if((data & 0xf8) == 0xc0) {
184 } else if((data & 0xfc) == 0xe0) {
186 } else if((data & 0xfe) == 0xf0) {
189 if(port[ch].tx_data_bits != tx_data_bits) {
190 port[ch].tx_data_bits = tx_data_bits;
191 update_tx_timing(ch);
193 if((port[ch].wr[4] & 0x0c) != 0 && port[ch].shift_reg == -1 && port[ch].send->empty()) {
194 // this is the first data
195 CANCEL_SEND_EVENT(ch);
196 REGISTER_FIRST_SEND_EVENT(ch);
198 REGISTER_SEND_EVENT(ch);
201 CANCEL_SEND_EVENT(ch);
204 port[ch].send->clear();
206 port[ch].send->write(data);
215 // emu->out_debug_log(_T("Z80SIO: ch=%d WR[%d]=%2x\n"), ch, port[ch].pointer, data);
217 switch(port[ch].pointer) {
219 switch(data & 0x38) {
221 if(port[ch].stat_intr) {
222 port[ch].stat_intr = false;
223 update_intr_required = true;
228 CANCEL_SEND_EVENT(ch);
229 CANCEL_RECV_EVENT(ch);
230 port[ch].nextrecv_intr = false;
231 port[ch].first_data = false;
232 port[ch].over_flow = false;
234 port[ch].tx_count = 0; // is this correct ???
236 port[ch].send->clear();
237 port[ch].recv->clear();
238 port[ch].rtmp->clear();
239 port[ch].shift_reg = -1;
240 memset(port[ch].wr, 0, sizeof(port[ch].wr));
242 if(port[ch].err_intr) {
243 port[ch].err_intr = false;
244 update_intr_required = true;
246 if(port[ch].recv_intr) {
247 port[ch].recv_intr = 0;
248 update_intr_required = true;
250 if(port[ch].stat_intr) {
251 port[ch].stat_intr = false;
252 update_intr_required = true;
254 if(port[ch].send_intr) {
255 port[ch].send_intr = false;
256 update_intr_required = true;
258 port[ch].req_intr = false;
261 port[ch].nextrecv_intr = true;
264 if(port[ch].send_intr) {
265 port[ch].send_intr = false;
266 update_intr_required = true;
270 port[ch].over_flow = false;
271 if(port[ch].err_intr) {
272 port[ch].err_intr = false;
273 update_intr_required = true;
279 for(int c = 0; c < 2; c++) {
280 if(port[c].in_service) {
281 port[c].in_service = false;
282 update_intr_required = true;
289 switch(data & 0xc0) {
291 // reset receive crc checker
294 // reset transmit crc generator
297 // reset transmit underrun
298 if(port[ch].under_run) {
299 port[ch].under_run = false;
300 if(port[ch].stat_intr) {
301 port[ch].stat_intr = false;
302 update_intr_required = true;
310 if(port[ch].wr[port[ch].pointer] != data) {
311 update_intr_required = true;
315 if((data & 0x11) == 0x11) {
316 // enter hunt/sync phase
319 emu->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (monosync)\n"), ch);
321 port[ch].sync_bit = BIT_SYNC1;
322 } else if(BISYNC(ch)) {
324 emu->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (bisync)\n"), ch);
326 port[ch].sync_bit = BIT_SYNC1 | BIT_SYNC2;
328 port[ch].sync = false;
329 write_signals(&port[ch].outputs_sync, 0xffffffff);
331 if((port[ch].wr[3] & 0xc0) != (data & 0xc0)) {
332 update_rx_timing_required = true;
336 if((port[ch].wr[4] & 0xcd) != (data & 0xcd)) {
337 update_tx_timing_required = update_rx_timing_required = true;
341 if((uint32)(port[ch].wr[5] & 2) != (data & 2)) {
343 write_signals(&port[ch].outputs_rts, (data & 2) ? 0 : 0xffffffff);
345 if((uint32)(port[ch].wr[5] & 0x80) != (data & 0x80)) {
347 write_signals(&port[ch].outputs_dtr, (data & 0x80) ? 0 : 0xffffffff);
350 if((port[ch].wr[4] & 0x0c) != 0 && port[ch].shift_reg == -1 && !port[ch].send->empty()) {
351 // CANCEL_SEND_EVENT(ch);
352 REGISTER_FIRST_SEND_EVENT(ch);
354 REGISTER_SEND_EVENT(ch);
357 CANCEL_SEND_EVENT(ch);
361 write_signals(&port[ch].outputs_break, 0xffffffff);
363 if((port[ch].wr[5] & 0x60) != (data & 0x60)) {
364 update_tx_timing_required = true;
368 port[ch].wr[port[ch].pointer] = data;
369 if(update_intr_required) {
372 if(update_tx_timing_required) {
373 update_tx_timing(ch);
375 if(update_rx_timing_required) {
376 update_rx_timing(ch);
378 port[ch].pointer = (port[ch].pointer == 0) ? (data & 7) : 0;
383 uint32 Z80SIO::read_io8(uint32 addr)
385 int ch = (addr >> 1) & 1;
392 if(port[ch].recv_intr) {
393 // cancel pending interrupt
394 if(--port[ch].recv_intr == 0) {
398 return port[ch].recv->read();
401 if(port[ch].pointer == 0) {
402 if(!port[ch].recv->empty()) {
405 if(ch == 0 && (port[0].req_intr || port[1].req_intr)) {
408 if(!port[ch].send->full()) {
420 if(port[ch].under_run) {
426 } else if(port[ch].pointer == 1) {
428 if(port[ch].send->empty()) {
431 if(port[ch].over_flow) {
434 } else if(port[ch].pointer == 2) {
435 val = port[ch].vector;
437 } else if(port[ch].pointer == 3) {
438 val = port[ch].tx_count & 0xff;
439 port[ch].tx_count_hi = port[ch].tx_count >> 8;
440 } else if(port[ch].pointer == 4) {
441 // val = (port[ch].tx_count >> 8) & 0xff;
442 val = port[ch].tx_count_hi;
445 port[ch].pointer = 0;
451 void Z80SIO::write_signal(int id, uint32 data, uint32 mask)
455 bool signal = ((data & mask) != 0);
458 case SIG_Z80SIO_RECV_CH0:
459 case SIG_Z80SIO_RECV_CH1:
461 REGISTER_RECV_EVENT(ch);
462 if(port[ch].rtmp->empty()) {
463 port[ch].first_data = true;
465 port[ch].rtmp->write(data & mask);
467 case SIG_Z80SIO_BREAK_CH0:
468 case SIG_Z80SIO_BREAK_CH1:
470 if((data & mask) && !port[ch].abort) {
471 port[ch].abort = true;
472 if(!port[ch].stat_intr) {
473 port[ch].stat_intr = true;
478 case SIG_Z80SIO_DCD_CH0:
479 case SIG_Z80SIO_DCD_CH1:
480 if(port[ch].dcd != signal) {
481 port[ch].dcd = signal;
482 if(!signal && (port[ch].wr[3] & 0x20)) {
486 if(!port[ch].stat_intr) {
487 port[ch].stat_intr = true;
492 case SIG_Z80SIO_CTS_CH0:
493 case SIG_Z80SIO_CTS_CH1:
494 if(port[ch].cts != signal) {
495 port[ch].cts = signal;
496 if(!signal && (port[ch].wr[3] & 0x20)) {
498 if((port[ch].wr[4] & 0x0c) != 0 && port[ch].shift_reg == -1 && !port[ch].send->empty()) {
499 // CANCEL_SEND_EVENT(ch);
500 REGISTER_FIRST_SEND_EVENT(ch);
502 REGISTER_SEND_EVENT(ch);
506 if(!port[ch].stat_intr) {
507 port[ch].stat_intr = true;
511 case SIG_Z80SIO_SYNC_CH0:
512 case SIG_Z80SIO_SYNC_CH1:
513 if(port[ch].sync != signal) {
514 port[ch].sync = signal;
515 if(!port[ch].stat_intr) {
516 port[ch].stat_intr = true;
521 case SIG_Z80SIO_TX_CLK_CH0:
522 case SIG_Z80SIO_TX_CLK_CH1:
523 if(port[ch].prev_tx_clock_signal != signal) {
524 if(port[ch].tx_bits_x2_remain > 0 && --port[ch].tx_bits_x2_remain == 0) {
525 event_callback(EVENT_SEND + ch, 0);
527 port[ch].prev_tx_clock_signal = signal;
530 case SIG_Z80SIO_RX_CLK_CH0:
531 case SIG_Z80SIO_RX_CLK_CH1:
532 if(port[ch].prev_rx_clock_signal != signal) {
533 if(port[ch].rx_bits_x2_remain > 0 && --port[ch].rx_bits_x2_remain == 0) {
534 event_callback(EVENT_RECV + ch, 0);
536 port[ch].prev_rx_clock_signal = signal;
539 case SIG_Z80SIO_CLEAR_CH0:
540 case SIG_Z80SIO_CLEAR_CH1:
541 // hack: clear recv buffer
543 CANCEL_RECV_EVENT(ch);
544 port[ch].rtmp->clear();
545 port[ch].recv->clear();
546 if(port[ch].recv_intr) {
547 port[ch].recv_intr = 0;
555 void Z80SIO::event_callback(int event_id, int err)
557 int ch = event_id & 1;
559 if(event_id & EVENT_SEND) {
561 port[ch].send_id = -1;
562 port[ch].tx_bits_x2_remain = 0;
564 bool under_run = true;
566 if(port[ch].shift_reg != -1) {
567 // send data in shift register
568 write_signals(&port[ch].outputs_send, port[ch].shift_reg);
569 port[ch].shift_reg = -1;
572 if(!port[ch].send->empty()) {
573 // load data in send buffer to shift register
574 port[ch].shift_reg = port[ch].send->read();
578 // underrun interrupt
579 if(!port[ch].under_run) {
580 port[ch].under_run = true;
581 if(!port[ch].stat_intr) {
582 port[ch].stat_intr = true;
587 if(port[ch].send->empty()) {
588 // transmitter interrupt
589 if(!port[ch].send_intr) {
590 port[ch].send_intr = true;
593 write_signals(&port[ch].outputs_txdone, 0xffffffff);
595 REGISTER_SEND_EVENT(ch);
596 } else if(event_id & EVENT_RECV) {
598 port[ch].recv_id = -1;
599 port[ch].rx_bits_x2_remain = 0;
601 if(!(port[ch].wr[3] & 1)) {
602 REGISTER_RECV_EVENT(ch);
605 bool update_intr_required = false;
607 if(port[ch].recv->full()) {
609 if(!port[ch].over_flow) {
610 port[ch].over_flow = true;
611 if(!port[ch].err_intr) {
612 port[ch].err_intr = true;
613 update_intr_required = true;
618 int data = port[ch].rtmp->read();
620 if(SYNC_MODE(ch) && port[ch].sync_bit != 0) {
621 // receive sync data in monosync/bisync mode ?
622 if(port[ch].sync_bit & BIT_SYNC1) {
623 if(data != port[ch].wr[6]) {
624 goto request_next_data;
627 emu->out_debug_log(_T("Z80SIO: ch=%d recv sync1\n"), ch);
629 port[ch].sync_bit &= ~BIT_SYNC1;
630 } else if(port[ch].sync_bit & BIT_SYNC2) {
631 if(data != port[ch].wr[7]) {
632 port[ch].sync_bit |= BIT_SYNC1;
633 goto request_next_data;
636 emu->out_debug_log(_T("Z80SIO: ch=%d recv sync2\n"), ch);
638 port[ch].sync_bit &= ~BIT_SYNC2;
640 if(port[ch].sync_bit == 0) {
642 emu->out_debug_log(_T("Z80SIO: ch=%d leave hunt/sync phase\n"), ch);
644 if(!port[ch].stat_intr) {
645 port[ch].stat_intr = true;
646 update_intr_required = true;
648 port[ch].sync = true;
649 write_signals(&port[ch].outputs_sync, 0);
651 if(port[ch].wr[3] & 2) {
652 // sync char is not loaded into buffer
653 goto request_next_data;
656 // load received data into buffer
658 emu->out_debug_log(_T("Z80SIO: ch=%d recv %2x\n"), ch, data);
660 port[ch].recv->write(data);
664 port[ch].abort = false;
665 if(!port[ch].stat_intr) {
666 port[ch].stat_intr = true;
667 update_intr_required = true;
671 // check receive interrupt
673 if((port[ch].wr[1] & 0x18) == 8 && (port[ch].first_data || port[ch].nextrecv_intr)) {
675 } else if(port[ch].wr[1] & 0x10) {
679 if(port[ch].recv_intr++ == 0) {
680 update_intr_required = true;
683 port[ch].first_data = port[ch].nextrecv_intr = false;
686 bool first_data = port[ch].first_data;
687 if(port[ch].rtmp->empty()) {
688 // request data in this message
689 write_signals(&port[ch].outputs_rxdone, 0xffffffff);
691 if(port[ch].rtmp->empty()) {
694 emu->out_debug_log(_T("Z80SIO: ch=%d end of block\n"), ch);
696 port[ch].recv_id = -1;
698 REGISTER_RECV_EVENT(ch);
699 port[ch].first_data = first_data;
701 if(update_intr_required) {
707 void Z80SIO::update_tx_timing(int ch)
709 port[ch].tx_bits_x2 = (port[ch].wr[4] & 1) * 2;
710 switch(port[ch].wr[5] & 0x60) {
711 case 0x00: port[ch].tx_bits_x2 += 2 * port[ch].tx_data_bits; break;
712 case 0x20: port[ch].tx_bits_x2 += 2 * 7; break;
713 case 0x40: port[ch].tx_bits_x2 += 2 * 6; break;
714 case 0x60: port[ch].tx_bits_x2 += 2 * 8; break;
716 switch(port[ch].wr[4] & 0x0c) {
717 case 0x00: port[ch].tx_bits_x2 += 0; break; // sync mode
718 case 0x04: port[ch].tx_bits_x2 += 4; break; // 2 * (1 + 1)
719 case 0x08: port[ch].tx_bits_x2 += 5; break; // 2 * (1 + 1.5)
720 case 0x0c: port[ch].tx_bits_x2 += 6; break; // 2 * (1 + 2)
722 switch(port[ch].wr[4] & 0xc0) {
723 case 0x40: port[ch].tx_bits_x2 *= 16; break;
724 case 0x80: port[ch].tx_bits_x2 *= 32; break;
725 case 0xc0: port[ch].tx_bits_x2 *= 64; break;
727 if(port[ch].tx_clock != 0) {
728 port[ch].tx_interval = 1000000.0 / port[ch].tx_clock * (double)port[ch].tx_bits_x2 / 2.0;
732 void Z80SIO::update_rx_timing(int ch)
734 port[ch].rx_bits_x2 = (port[ch].wr[4] & 1) * 2;
735 switch(port[ch].wr[3] & 0xc0) {
736 case 0x00: port[ch].rx_bits_x2 += 2 * 5; break;
737 case 0x40: port[ch].rx_bits_x2 += 2 * 7; break;
738 case 0x80: port[ch].rx_bits_x2 += 2 * 6; break;
739 case 0xc0: port[ch].rx_bits_x2 += 2 * 8; break;
741 switch(port[ch].wr[4] & 0x0c) {
742 case 0x00: port[ch].rx_bits_x2 += 0; break; // sync mode
743 case 0x04: port[ch].rx_bits_x2 += 4; break; // 2 * (1 + 1)
744 case 0x08: port[ch].rx_bits_x2 += 5; break; // 2 * (1 + 1.5)
745 case 0x0c: port[ch].rx_bits_x2 += 6; break; // 2 * (1 + 2)
747 switch(port[ch].wr[4] & 0xc0) {
748 case 0x40: port[ch].rx_bits_x2 *= 16; break;
749 case 0x80: port[ch].rx_bits_x2 *= 32; break;
750 case 0xc0: port[ch].rx_bits_x2 *= 64; break;
752 if(port[ch].rx_clock != 0) {
753 port[ch].rx_interval = 1000000.0 / port[ch].rx_clock * (double)port[ch].rx_bits_x2 / 2.0;
757 void Z80SIO::set_intr_iei(bool val)
765 #define set_intr_oei(val) { \
769 d_child->set_intr_iei(oei); \
774 void Z80SIO::update_intr()
779 if((next = iei) == true) {
780 for(int ch = 0; ch < 2; ch++) {
781 if(port[ch].in_service) {
789 // check interrupt status
790 for(int ch = 0; ch < 2; ch++) {
791 if(port[ch].err_intr) {
792 port[ch].req_intr = true;
793 port[ch].affect = (ch ? 0 : 4) | 3;
794 } else if(port[ch].recv_intr && (port[ch].wr[1] & 0x18)) {
795 port[ch].req_intr = true;
796 port[ch].affect = (ch ? 0 : 4) | 2;
797 } else if(port[ch].stat_intr && (port[ch].wr[1] & 1)) {
798 port[ch].req_intr = true;
799 port[ch].affect = (ch ? 0 : 4) | 1;
800 } else if(port[ch].send_intr && (port[ch].wr[1] & 2)) {
801 port[ch].req_intr = true;
802 port[ch].affect = (ch ? 0 : 4) | 0;
804 port[ch].req_intr = false;
809 if(port[1].wr[1] & 4) {
811 uint8 affect = 7; // no interrupt pending
812 for(int ch = 0; ch < 2; ch++) {
813 if(port[ch].in_service) {
816 if(port[ch].req_intr) {
817 affect = port[ch].affect;
821 uint8 mode = port[0].wr[2] & 0x38;
822 if(mode == 0 || mode == 8 || mode == 0x20 || mode == 0x28 || mode == 0x38) {
823 port[1].vector = (port[1].wr[2] & 0xe3) | (affect << 2); // 8085
825 port[1].vector = (port[1].wr[2] & 0xf8) | (affect << 0); // 8086
828 uint8 affect = 3; // no interrupt pending
829 for(int ch = 0; ch < 2; ch++) {
830 if(port[ch].in_service) {
833 if(port[ch].req_intr) {
834 affect = port[ch].affect;
838 port[1].vector = (port[1].wr[2] & 0xf1) | (affect << 1);
841 port[1].vector = port[1].wr[2];
845 if((next = iei) == true) {
847 for(int ch = 0; ch < 2; ch++) {
848 if(port[ch].in_service) {
851 if(port[ch].req_intr) {
858 d_cpu->set_intr_line(next, true, intr_bit);
862 uint32 Z80SIO::intr_ack()
865 for(int ch = 0; ch < 2; ch++) {
866 if(port[ch].in_service) {
867 // invalid interrupt status
870 // priority is error > receive > status > send ???
871 if(port[ch].err_intr) {
872 port[ch].err_intr = false;
873 port[ch].in_service = true;
874 } else if(port[ch].recv_intr && (port[ch].wr[1] & 0x18)) {
875 port[ch].recv_intr = 0;
876 port[ch].in_service = true;
877 } else if(port[ch].stat_intr && (port[ch].wr[1] & 1)) {
878 port[ch].stat_intr = false;
879 port[ch].in_service = true;
880 } else if(port[ch].send_intr && (port[ch].wr[1] & 2)) {
881 port[ch].send_intr = false;
882 port[ch].in_service = true;
884 if(port[ch].in_service) {
885 uint8 vector = port[1].vector;
891 return d_child->intr_ack();
896 void Z80SIO::intr_reti()
899 for(int ch = 0; ch < 2; ch++) {
900 if(port[ch].in_service) {
901 port[ch].in_service = false;
907 d_child->intr_reti();
911 #define STATE_VERSION 3
913 void Z80SIO::save_state(FILEIO* state_fio)
915 state_fio->FputUint32(STATE_VERSION);
916 state_fio->FputInt32(this_device_id);
918 for(int i = 0; i < 2; i++) {
919 state_fio->FputInt32(port[i].pointer);
920 state_fio->Fwrite(port[i].wr, sizeof(port[i].wr), 1);
921 state_fio->FputUint8(port[i].vector);
922 state_fio->FputUint8(port[i].affect);
923 state_fio->FputBool(port[i].nextrecv_intr);
924 state_fio->FputBool(port[i].first_data);
925 state_fio->FputBool(port[i].over_flow);
926 state_fio->FputBool(port[i].under_run);
927 state_fio->FputBool(port[i].abort);
928 state_fio->FputBool(port[i].sync);
929 state_fio->FputUint8(port[i].sync_bit);
931 state_fio->FputUint16(port[i].tx_count);
932 state_fio->FputUint8(port[i].tx_count_hi);
934 state_fio->FputDouble(port[i].tx_clock);
935 state_fio->FputDouble(port[i].tx_interval);
936 state_fio->FputDouble(port[i].rx_clock);
937 state_fio->FputDouble(port[i].rx_interval);
938 state_fio->FputInt32(port[i].tx_data_bits);
939 state_fio->FputInt32(port[i].tx_bits_x2);
940 state_fio->FputInt32(port[i].tx_bits_x2_remain);
941 state_fio->FputInt32(port[i].rx_bits_x2);
942 state_fio->FputInt32(port[i].rx_bits_x2_remain);
943 state_fio->FputBool(port[i].prev_tx_clock_signal);
944 state_fio->FputBool(port[i].prev_rx_clock_signal);
945 port[i].send->save_state((void *)state_fio);
946 port[i].recv->save_state((void *)state_fio);
947 port[i].rtmp->save_state((void *)state_fio);
948 state_fio->FputInt32(port[i].shift_reg);
949 state_fio->FputInt32(port[i].send_id);
950 state_fio->FputInt32(port[i].recv_id);
951 state_fio->FputBool(port[i].err_intr);
952 state_fio->FputInt32(port[i].recv_intr);
953 state_fio->FputBool(port[i].stat_intr);
954 state_fio->FputBool(port[i].send_intr);
955 state_fio->FputBool(port[i].req_intr);
956 state_fio->FputBool(port[i].in_service);
957 state_fio->FputBool(port[i].dcd);
958 state_fio->FputBool(port[i].cts);
960 state_fio->FputBool(iei);
961 state_fio->FputBool(oei);
962 state_fio->FputUint32(intr_bit);
965 bool Z80SIO::load_state(FILEIO* state_fio)
967 if(state_fio->FgetUint32() != STATE_VERSION) {
970 if(state_fio->FgetInt32() != this_device_id) {
973 for(int i = 0; i < 2; i++) {
974 port[i].pointer = state_fio->FgetInt32();
975 state_fio->Fread(port[i].wr, sizeof(port[i].wr), 1);
976 port[i].vector = state_fio->FgetUint8();
977 port[i].affect = state_fio->FgetUint8();
978 port[i].nextrecv_intr = state_fio->FgetBool();
979 port[i].first_data = state_fio->FgetBool();
980 port[i].over_flow = state_fio->FgetBool();
981 port[i].under_run = state_fio->FgetBool();
982 port[i].abort = state_fio->FgetBool();
983 port[i].sync = state_fio->FgetBool();
984 port[i].sync_bit = state_fio->FgetUint8();
986 port[i].tx_count = state_fio->FgetUint16();
987 port[i].tx_count_hi = state_fio->FgetUint8();
989 port[i].tx_clock = state_fio->FgetDouble();
990 port[i].tx_interval = state_fio->FgetDouble();
991 port[i].rx_clock = state_fio->FgetDouble();
992 port[i].rx_interval = state_fio->FgetDouble();
993 port[i].tx_data_bits = state_fio->FgetInt32();
994 port[i].tx_bits_x2 = state_fio->FgetInt32();
995 port[i].tx_bits_x2_remain = state_fio->FgetInt32();
996 port[i].rx_bits_x2 = state_fio->FgetInt32();
997 port[i].rx_bits_x2_remain = state_fio->FgetInt32();
998 port[i].prev_tx_clock_signal = state_fio->FgetBool();
999 port[i].prev_rx_clock_signal = state_fio->FgetBool();
1000 if(!port[i].send->load_state((void *)state_fio)) {
1003 if(!port[i].recv->load_state((void *)state_fio)) {
1006 if(!port[i].rtmp->load_state((void *)state_fio)) {
1009 port[i].shift_reg = state_fio->FgetInt32();
1010 port[i].send_id = state_fio->FgetInt32();
1011 port[i].recv_id = state_fio->FgetInt32();
1012 port[i].err_intr = state_fio->FgetBool();
1013 port[i].recv_intr = state_fio->FgetInt32();
1014 port[i].stat_intr = state_fio->FgetBool();
1015 port[i].send_intr = state_fio->FgetBool();
1016 port[i].req_intr = state_fio->FgetBool();
1017 port[i].in_service = state_fio->FgetBool();
1018 port[i].dcd = state_fio->FgetBool();
1019 port[i].cts = state_fio->FgetBool();
1021 iei = state_fio->FgetBool();
1022 oei = state_fio->FgetBool();
1023 intr_bit = state_fio->FgetUint32();