OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[csp-qt/common_source_project-fm7.git] / source / src / vm / z80sio.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2006.12.31 -
6
7         [ Z80SIO ]
8 */
9
10 #include "z80sio.h"
11 #include "../fifo.h"
12
13 #define EVENT_SEND      2
14 #define EVENT_RECV      4
15
16 //#define SIO_DEBUG
17
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))
23
24 #define BIT_SYNC1       1
25 #define BIT_SYNC2       2
26
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); \
31                 } \
32         } else { \
33                 if(port[ch].tx_bits_x2_remain == 0) { \
34                         port[ch].tx_bits_x2_remain = 1; \
35                 } \
36         } \
37 }
38
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); \
43                 } \
44         } else { \
45                 if(port[ch].tx_bits_x2_remain == 0) { \
46                         port[ch].tx_bits_x2_remain = port[ch].tx_bits_x2; \
47                 } \
48         } \
49 }
50
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; \
56                 } \
57         } else { \
58                 port[ch].tx_bits_x2_remain = 0; \
59         } \
60 }
61
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); \
66                 } \
67         } else { \
68                 if(port[ch].rx_bits_x2_remain == 0) { \
69                         port[ch].rx_bits_x2_remain = port[ch].rx_bits_x2; \
70                 } \
71         } \
72 }
73
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; \
79                 } \
80         } else { \
81                 port[ch].rx_bits_x2_remain = 0; \
82         } \
83 }
84
85 void Z80SIO::initialize()
86 {
87         DEVICE::initialize();
88         __HAS_UPD7201 = osd->check_feature(_T("HAS_UPD7201"));
89         __SIO_DEBUG   = osd->check_feature(_T("SIO_DEBUG"));
90         
91         for(int ch = 0; ch < 2; ch++) {
92 //#ifdef HAS_UPD7201
93                 if(__HAS_UPD7201) {
94                         port[ch].send = new FIFO(16);
95                         port[ch].recv = new FIFO(16);
96                         port[ch].rtmp = new FIFO(16);
97                 } else {
98 //#else
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;
103                 }
104 //#endif
105                 // input signals
106                 port[ch].dcd = true;
107                 port[ch].cts = true;
108                 port[ch].sync = true;
109                 port[ch].sync_bit = 0;
110         }
111 }
112
113 void Z80SIO::reset()
114 {
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;
122 //#ifdef HAS_UPD7201
123                 port[ch].tx_count = 0;
124 //#endif
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));
132                 // interrupt
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;
139         }
140         iei = oei = true;
141 }
142
143 void Z80SIO::release()
144 {
145         for(int ch = 0; ch < 2; ch++) {
146                 if(port[ch].send) {
147                         port[ch].send->release();
148                         delete port[ch].send;
149                 }
150                 if(port[ch].recv) {
151                         port[ch].recv->release();
152                         delete port[ch].recv;
153                 }
154                 if(port[ch].rtmp) {
155                         port[ch].rtmp->release();
156                         delete port[ch].rtmp;
157                 }
158         }
159 }
160
161 /*
162         0       ch.a data
163         1       ch.a control
164         2       ch.b data
165         3       ch.b control
166 */
167
168 void Z80SIO::write_io8(uint32_t addr, uint32_t data)
169 {
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;
174         
175         switch(addr & 3) {
176         case 0:
177         case 2:
178                 // send data
179                 if(port[ch].send_intr) {
180                         port[ch].send_intr = false;
181                         update_intr();
182                 }
183                 // register next event
184                 if(port[ch].wr[5] & 8) {
185                         int tx_data_bits = 5;
186                         if((data & 0xe0) == 0x00) {
187                                 tx_data_bits = 5;
188                         } else if((data & 0xf0) == 0x80) {
189                                 tx_data_bits = 4;
190                         } else if((data & 0xf8) == 0xc0) {
191                                 tx_data_bits = 3;
192                         } else if((data & 0xfc) == 0xe0) {
193                                 tx_data_bits = 2;
194                         } else if((data & 0xfe) == 0xf0) {
195                                 tx_data_bits = 1;
196                         }
197                         if(port[ch].tx_data_bits != tx_data_bits) {
198                                 port[ch].tx_data_bits = tx_data_bits;
199                                 update_tx_timing(ch);
200                         }
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);
205                         } else {
206                                 REGISTER_SEND_EVENT(ch);
207                         }
208                 } else {
209                         CANCEL_SEND_EVENT(ch);
210                 }
211 //#ifndef HAS_UPD7201
212                 if(!__HAS_UPD7201) port[ch].send->clear();
213 //#endif
214                 port[ch].send->write(data);
215 //#ifdef HAS_UPD7201
216                 if(__HAS_UPD7201) port[ch].tx_count++;
217 //#endif
218                 break;
219         case 1:
220         case 3:
221                 // control
222 //#ifdef SIO_DEBUG
223 //              if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d WR[%d]=%2x\n"), ch, port[ch].pointer, data);
224 //#endif
225                 switch(port[ch].pointer) {
226                 case 0:
227                         switch(data & 0x38) {
228                         case 0x10:
229                                 if(port[ch].stat_intr) {
230                                         port[ch].stat_intr = false;
231                                         update_intr_required = true;
232                                 }
233                                 break;
234                         case 0x18:
235                                 // channel reset
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;
241 //#ifdef HAS_UPD7201
242                                 if(__HAS_UPD7201) port[ch].tx_count = 0;        // is this correct ???
243 //#endif
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));
249                                 // interrupt
250                                 if(port[ch].err_intr) {
251                                         port[ch].err_intr = false;
252                                         update_intr_required = true;
253                                 }
254                                 if(port[ch].recv_intr) {
255                                         port[ch].recv_intr = 0;
256                                         update_intr_required = true;
257                                 }
258                                 if(port[ch].stat_intr) {
259                                         port[ch].stat_intr = false;
260                                         update_intr_required = true;
261                                 }
262                                 if(port[ch].send_intr) {
263                                         port[ch].send_intr = false;
264                                         update_intr_required = true;
265                                 }
266                                 port[ch].req_intr = false;
267                                 break;
268                         case 0x20:
269                                 port[ch].nextrecv_intr = true;
270                                 break;
271                         case 0x28:
272                                 if(port[ch].send_intr) {
273                                         port[ch].send_intr = false;
274                                         update_intr_required = true;
275                                 }
276                                 break;
277                         case 0x30:
278                                 port[ch].over_flow = false;
279                                 if(port[ch].err_intr) {
280                                         port[ch].err_intr = false;
281                                         update_intr_required = true;
282                                 }
283                                 break;
284                         case 0x38:
285                                 // end of interrupt
286                                 if(ch == 0) {
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;
291                                                         break;
292                                                 }
293                                         }
294                                 }
295                                 break;
296                         }
297                         switch(data & 0xc0) {
298                         case 0x40:
299                                 // reset receive crc checker
300                                 break;
301                         case 0x80:
302                                 // reset transmit crc generator
303                                 break;
304                         case 0xc0:
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;
311                                         }
312                                 }
313                                 break;
314                         }
315                         break;
316                 case 1:
317                 case 2:
318                         if(port[ch].wr[port[ch].pointer] != data) {
319                                 update_intr_required = true;
320                         }
321                         break;
322                 case 3:
323                         if((data & 0x11) == 0x11) {
324                                 // enter hunt/sync phase
325                                 if(MONOSYNC(ch)) {
326 //#ifdef SIO_DEBUG
327                                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (monosync)\n"), ch);
328 //#endif
329                                         port[ch].sync_bit = BIT_SYNC1;
330                                 } else if(BISYNC(ch)) {
331 //#ifdef SIO_DEBUG
332                                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d enter hunt/sync phase (bisync)\n"), ch);
333 //#endif
334                                         port[ch].sync_bit = BIT_SYNC1 | BIT_SYNC2;
335                                 }
336                                 port[ch].sync = false;
337                                 write_signals(&port[ch].outputs_sync, 0xffffffff);
338                         }
339                         if((port[ch].wr[3] & 0xc0) != (data & 0xc0)) {
340                                 update_rx_timing_required = true;
341                         }
342                         break;
343                 case 4:
344                         if((port[ch].wr[4] & 0xcd) != (data & 0xcd)) {
345                                 update_tx_timing_required = update_rx_timing_required = true;
346                         }
347                         break;
348                 case 5:
349                         if((uint32_t)(port[ch].wr[5] & 2) != (data & 2)) {
350                                 // rts
351                                 write_signals(&port[ch].outputs_rts, (data & 2) ? 0 : 0xffffffff);
352                         }
353                         if((uint32_t)(port[ch].wr[5] & 0x80) != (data & 0x80)) {
354                                 // dtr
355                                 write_signals(&port[ch].outputs_dtr, (data & 0x80) ? 0 : 0xffffffff);
356                         }
357                         if(data & 8) {
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);
361                                 } else {
362                                         REGISTER_SEND_EVENT(ch);
363                                 }
364                         } else {
365                                 CANCEL_SEND_EVENT(ch);
366                         }
367                         if(data & 0x10) {
368                                 // send break
369                                 write_signals(&port[ch].outputs_break, 0xffffffff);
370                         }
371                         if((port[ch].wr[5] & 0x60) != (data & 0x60)) {
372                                 update_tx_timing_required = true;
373                         }
374                         break;
375                 }
376                 port[ch].wr[port[ch].pointer] = data;
377                 if(update_intr_required) {
378                         update_intr();
379                 }
380                 if(update_tx_timing_required) {
381                         update_tx_timing(ch);
382                 }
383                 if(update_rx_timing_required) {
384                         update_rx_timing(ch);
385                 }
386                 port[ch].pointer = (port[ch].pointer == 0) ? (data & 7) : 0;
387                 break;
388         }
389 }
390
391 uint32_t Z80SIO::read_io8(uint32_t addr)
392 {
393         int ch = (addr >> 1) & 1;
394         uint32_t val = 0;
395         
396         switch(addr & 3) {
397         case 0:
398         case 2:
399                 // recv data;
400                 if(port[ch].recv_intr) {
401                         // cancel pending interrupt
402                         if(--port[ch].recv_intr == 0) {
403                                 update_intr();
404                         }
405                 }
406                 // for polling case (thanks YAT)
407                 if(!SYNC_MODE(ch)) {
408                         if(port[ch].recv->empty()) {
409                                 int data = port[ch].rtmp->read();
410                                 port[ch].recv->write(data);
411                         }
412                 }
413                 return port[ch].recv->read();
414         case 1:
415         case 3:
416                 if(port[ch].pointer == 0) {
417                         if(!port[ch].recv->empty()) {
418                                 val |= 1;
419                         }
420                         if(ch == 0 && (port[0].req_intr || port[1].req_intr)) {
421                                 val |= 2;
422                         }
423                         if(!port[ch].send->full()) {
424                                 val |= 4;       // ???
425                         }
426                         if(!port[ch].dcd) {
427                                 val |= 8;
428                         }
429                         if(!port[ch].sync) {
430                                 val |= 0x10;
431                         }
432                         if(!port[ch].cts) {
433                                 val |= 0x20;
434                         }
435                         if(port[ch].under_run) {
436                                 val |= 0x40;
437                         }
438                         if(port[ch].abort) {
439                                 val |= 0x80;
440                         }
441                 } else if(port[ch].pointer == 1) {
442                         val = 0x8e;     // TODO
443                         if(port[ch].send->empty()) {
444                                 val |= 1;
445                         }
446                         if(port[ch].over_flow) {
447                                 val |= 0x20;
448                         }
449                 } else if(port[ch].pointer == 2) {
450                         val = port[ch].vector;
451 //#ifdef HAS_UPD7201
452                 } else if(port[ch].pointer == 3) {
453                         if(__HAS_UPD7201) {
454                                 val = port[ch].tx_count & 0xff;
455                                 port[ch].tx_count_hi = port[ch].tx_count >> 8;
456                         }
457                 } else if(port[ch].pointer == 4) {
458                         if(__HAS_UPD7201) {
459 //                      val = (port[ch].tx_count >> 8) & 0xff;
460                                 val = port[ch].tx_count_hi;
461                         }
462 //#endif
463                 }
464                 port[ch].pointer = 0;
465                 return val;
466         }
467         return 0xff;
468 }
469
470 void Z80SIO::write_signal(int id, uint32_t data, uint32_t mask)
471 {
472         // recv data
473         int ch = id & 1;
474         bool signal = ((data & mask) != 0);
475         
476         switch(id) {
477         case SIG_Z80SIO_RECV_CH0:
478         case SIG_Z80SIO_RECV_CH1:
479                 // recv data
480                 REGISTER_RECV_EVENT(ch);
481                 if(port[ch].rtmp->empty()) {
482                         port[ch].first_data = true;
483                 }
484                 port[ch].rtmp->write(data & mask);
485                 break;
486         case SIG_Z80SIO_BREAK_CH0:
487         case SIG_Z80SIO_BREAK_CH1:
488                 // recv break
489                 if((data & mask) && !port[ch].abort) {
490                         port[ch].abort = true;
491                         if(!port[ch].stat_intr) {
492                                 port[ch].stat_intr = true;
493                                 update_intr();
494                         }
495                 }
496                 break;
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)) {
502                                 // auto enables
503                                 port[ch].wr[3] |= 1;
504                         }
505                         if(!port[ch].stat_intr) {
506                                 port[ch].stat_intr = true;
507                                 update_intr();
508                         }
509                 }
510                 break;
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)) {
516                                 // auto enables
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);
520                                 } else {
521                                         REGISTER_SEND_EVENT(ch);
522                                 }
523                                 port[ch].wr[5] |= 8;
524                         }
525                         if(!port[ch].stat_intr) {
526                                 port[ch].stat_intr = true;
527                                 update_intr();
528                         }
529                 }
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;
536                                 update_intr();
537                         }
538                 }
539                 break;
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);
545                         }
546                         port[ch].prev_tx_clock_signal = signal;
547                 }
548                 break;
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);
554                         }
555                         port[ch].prev_rx_clock_signal = signal;
556                 }
557                 break;
558         case SIG_Z80SIO_CLEAR_CH0:
559         case SIG_Z80SIO_CLEAR_CH1:
560                 // hack: clear recv buffer
561                 if(data & mask) {
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;
567                                 update_intr();
568                         }
569                 }
570                 break;
571         }
572 }
573
574 void Z80SIO::event_callback(int event_id, int err)
575 {
576         int ch = event_id & 1;
577         
578         if(event_id & EVENT_SEND) {
579                 // send
580                 port[ch].send_id = -1;
581                 port[ch].tx_bits_x2_remain = 0;
582                 
583                 bool under_run = true;
584                 
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;
589                         under_run = false;
590                 }
591                 if(!port[ch].send->empty()) {
592                         // load data in send buffer to shift register
593                         port[ch].shift_reg = port[ch].send->read();
594                         under_run = false;
595                 }
596                 if(under_run) {
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;
602                                         update_intr();
603                                 }
604                         }
605                 }
606                 if(port[ch].send->empty()) {
607                         // transmitter interrupt
608                         if(!port[ch].send_intr) {
609                                 port[ch].send_intr = true;
610                                 update_intr();
611                         }
612                         write_signals(&port[ch].outputs_txdone, 0xffffffff);
613                 }
614                 REGISTER_SEND_EVENT(ch);
615         } else if(event_id & EVENT_RECV) {
616                 // recv
617                 port[ch].recv_id = -1;
618                 port[ch].rx_bits_x2_remain = 0;
619                 
620                 if(!(port[ch].wr[3] & 1)) {
621                         REGISTER_RECV_EVENT(ch);
622                         return;
623                 }
624                 bool update_intr_required = false;
625                 
626                 if(port[ch].recv->full()) {
627                         // overflow
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;
633                                 }
634                         }
635                 } else {
636                         // no error
637                         int data = port[ch].rtmp->read();
638                         
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;
644                                         }
645 //#ifdef SIO_DEBUG
646                                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d recv sync1\n"), ch);
647 //#endif
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;
653                                         }
654 //#ifdef SIO_DEBUG
655                                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d recv sync2\n"), ch);
656 //#endif
657                                         port[ch].sync_bit &= ~BIT_SYNC2;
658                                 }
659                                 if(port[ch].sync_bit == 0) {
660 //#ifdef SIO_DEBUG
661                                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d leave hunt/sync phase\n"), ch);
662 //#endif
663                                         if(!port[ch].stat_intr) {
664                                                 port[ch].stat_intr = true;
665                                                 update_intr_required = true;
666                                         }
667                                         port[ch].sync = true;
668                                         write_signals(&port[ch].outputs_sync, 0);
669                                 }
670                                 if(port[ch].wr[3] & 2) {
671                                         // sync char is not loaded into buffer
672                                         goto request_next_data;
673                                 }
674                         }
675                         // load received data into buffer
676 //#ifdef SIO_DEBUG
677                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d recv %2x\n"), ch, data);
678 //#endif
679                         port[ch].recv->write(data);
680                         
681                         // quit abort
682                         if(port[ch].abort) {
683                                 port[ch].abort = false;
684                                 if(!port[ch].stat_intr) {
685                                         port[ch].stat_intr = true;
686                                         update_intr_required = true;
687                                 }
688                         }
689                         
690                         // check receive interrupt
691                         bool req = false;
692                         if((port[ch].wr[1] & 0x18) == 8 && (port[ch].first_data || port[ch].nextrecv_intr)) {
693                                 req = true;
694                         } else if(port[ch].wr[1] & 0x10) {
695                                 req = true;
696                         }
697                         if(req) {
698                                 if(port[ch].recv_intr++ == 0) {
699                                         update_intr_required = true;
700                                 }
701                         }
702                         port[ch].first_data = port[ch].nextrecv_intr = false;
703                 }
704 request_next_data:
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);
709                 }
710                 if(port[ch].rtmp->empty()) {
711                         // no data received
712 //#ifdef SIO_DEBUG
713                         if(__SIO_DEBUG) this->out_debug_log(_T("Z80SIO: ch=%d end of block\n"), ch);
714 //#endif
715                         port[ch].recv_id = -1;
716                 } else {
717                         REGISTER_RECV_EVENT(ch);
718                         port[ch].first_data = first_data;
719                 }
720                 if(update_intr_required) {
721                         update_intr();
722                 }
723         }
724 }
725
726 void Z80SIO::update_tx_timing(int ch)
727 {
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;
734         }
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)
740         }
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;
745         }
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;
748         }
749 }
750
751 void Z80SIO::update_rx_timing(int ch)
752 {
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;
759         }
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)
765         }
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;
770         }
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;
773         }
774 }
775
776 void Z80SIO::set_intr_iei(bool val)
777 {
778         if(iei != val) {
779                 iei = val;
780                 update_intr();
781         }
782 }
783
784 #define set_intr_oei(val) { \
785         if(oei != val) { \
786                 oei = val; \
787                 if(d_child) { \
788                         d_child->set_intr_iei(oei); \
789                 } \
790         } \
791 }
792
793 void Z80SIO::update_intr()
794 {
795         bool next;
796         
797         // set oei signal
798         if((next = iei) == true) {
799                 for(int ch = 0; ch < 2; ch++) {
800                         if(port[ch].in_service) {
801                                 next = false;
802                                 break;
803                         }
804                 }
805         }
806         set_intr_oei(next);
807         
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;
822                 } else {
823                         port[ch].req_intr = false;
824                 }
825         }
826         
827         // create vector
828         if(port[1].wr[1] & 4) {
829 //#ifdef HAS_UPD7201
830                 if(__HAS_UPD7201) {
831                         uint8_t affect = 7;     // no interrupt pending
832                         for(int ch = 0; ch < 2; ch++) {
833                                 if(port[ch].in_service) {
834                                         break;
835                                 }
836                                 if(port[ch].req_intr) {
837                                         affect = port[ch].affect;
838                                         break;
839                                 }
840                         }
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
844                         } else {
845                                 port[1].vector = (port[1].wr[2] & 0xf8) | (affect << 0);        // 8086
846                         }
847                 } else {
848 //#else
849                         uint8_t affect = 3;     // no interrupt pending
850                         for(int ch = 0; ch < 2; ch++) {
851                                 if(port[ch].in_service) {
852                                         break;
853                                 }
854                                 if(port[ch].req_intr) {
855                                         affect = port[ch].affect;
856                                         break;
857                                 }
858                         }
859                         port[1].vector = (port[1].wr[2] & 0xf1) | (affect << 1);
860                 }
861 //#endif
862         } else {
863                 port[1].vector = port[1].wr[2];
864         }
865         
866         // set int signal
867         if((next = iei) == true) {
868                 next = false;
869                 for(int ch = 0; ch < 2; ch++) {
870                         if(port[ch].in_service) {
871                                 break;
872                         }
873                         if(port[ch].req_intr) {
874                                 next = true;
875                                 break;
876                         }
877                 }
878         }
879         if(d_cpu) {
880                 d_cpu->set_intr_line(next, true, intr_bit);
881         }
882 }
883
884 uint32_t Z80SIO::get_intr_ack()
885 {
886         // ack (M1=IORQ=L)
887         for(int ch = 0; ch < 2; ch++) {
888                 if(port[ch].in_service) {
889                         // invalid interrupt status
890                         return 0xff;
891                 }
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;
905                 }
906                 if(port[ch].in_service) {
907                         uint8_t vector = port[1].vector;
908                         update_intr();
909                         return vector;
910                 }
911         }
912         if(d_child) {
913                 return d_child->get_intr_ack();
914         }
915         return 0xff;
916 }
917
918 void Z80SIO::notify_intr_reti()
919 {
920         // detect RETI
921         for(int ch = 0; ch < 2; ch++) {
922                 if(port[ch].in_service) {
923                         port[ch].in_service = false;
924                         update_intr();
925                         return;
926                 }
927         }
928         if(d_child) {
929                 d_child->notify_intr_reti();
930         }
931 }
932
933 #define STATE_VERSION   3
934
935 bool Z80SIO::process_state(FILEIO* state_fio, bool loading)
936 {
937         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
938                 return false;
939         }
940         if(!state_fio->StateCheckInt32(this_device_id)) {
941                 return false;
942         }
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);
955                 if(__HAS_UPD7201) {
956                 state_fio->StateValue(port[i].tx_count);
957                 state_fio->StateValue(port[i].tx_count_hi);
958                 }
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)) {
971                         return false;
972                 }
973                 if(!port[i].recv->process_state((void *)state_fio, loading)) {
974                         return false;
975                 }
976                 if(!port[i].rtmp->process_state((void *)state_fio, loading)) {
977                         return false;
978                 }
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);
990         }
991         state_fio->StateValue(iei);
992         state_fio->StateValue(oei);
993         state_fio->StateValue(intr_bit);
994         return true;
995 }
996
997