2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
17 #define SIG_Z80SIO_RECV_CH0 0
18 #define SIG_Z80SIO_RECV_CH1 1
19 #define SIG_Z80SIO_BREAK_CH0 2
20 #define SIG_Z80SIO_BREAK_CH1 3
21 #define SIG_Z80SIO_DCD_CH0 4
22 #define SIG_Z80SIO_DCD_CH1 5
23 #define SIG_Z80SIO_CTS_CH0 6
24 #define SIG_Z80SIO_CTS_CH1 7
25 #define SIG_Z80SIO_SYNC_CH0 8
26 #define SIG_Z80SIO_SYNC_CH1 9
27 #define SIG_Z80SIO_TX_CLK_CH0 10
28 #define SIG_Z80SIO_TX_CLK_CH1 11
29 #define SIG_Z80SIO_RX_CLK_CH0 12
30 #define SIG_Z80SIO_RX_CLK_CH1 13
31 // hack: clear recv buffer
32 #define SIG_Z80SIO_CLEAR_CH0 14
33 #define SIG_Z80SIO_CLEAR_CH1 15
37 class Z80SIO : public DEVICE
56 double tx_clock, tx_interval;
57 double rx_clock, rx_interval;
59 int tx_bits_x2, tx_bits_x2_remain;
60 int rx_bits_x2, rx_bits_x2_remain;
61 bool prev_tx_clock_signal;
62 bool prev_rx_clock_signal;
81 outputs_t outputs_rts;
82 outputs_t outputs_dtr;
83 outputs_t outputs_send;
84 outputs_t outputs_sync;
85 outputs_t outputs_break;
86 outputs_t outputs_txdone;
87 outputs_t outputs_rxdone;
90 void update_tx_timing(int ch);
91 void update_rx_timing(int ch);
94 DEVICE *d_cpu, *d_child;
103 Z80SIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
105 memset(port, 0, sizeof(port));
106 for(int i = 0; i < 2; i++) {
107 port[i].tx_data_bits = 5;
110 initialize_output_signals(&port[i].outputs_rts);
111 initialize_output_signals(&port[i].outputs_dtr);
112 initialize_output_signals(&port[i].outputs_send);
113 initialize_output_signals(&port[i].outputs_sync);
114 initialize_output_signals(&port[i].outputs_break);
115 initialize_output_signals(&port[i].outputs_txdone);
116 initialize_output_signals(&port[i].outputs_rxdone);
118 d_cpu = d_child = NULL;
119 __HAS_UPD7201 = false;
121 set_device_name(_T("Z80 SIO"));
129 void write_io8(uint32_t addr, uint32_t data);
130 uint32_t read_io8(uint32_t addr);
131 void write_signal(int id, uint32_t data, uint32_t mask);
132 void event_callback(int event_id, int err);
133 bool process_state(FILEIO* state_fio, bool loading);
134 // interrupt common functions
135 void set_context_intr(DEVICE* device, uint32_t bit)
140 void set_context_child(DEVICE* device)
144 void set_intr_iei(bool val);
145 uint32_t get_intr_ack();
146 void notify_intr_reti();
149 void set_context_rts(int ch, DEVICE* device, int id, uint32_t mask)
151 register_output_signal(&port[ch].outputs_rts, device, id, mask);
153 void set_context_dtr(int ch, DEVICE* device, int id, uint32_t mask)
155 register_output_signal(&port[ch].outputs_dtr, device, id, mask);
157 void set_context_send(int ch, DEVICE* device, int id)
159 register_output_signal(&port[ch].outputs_send, device, id, 0xff);
161 void set_context_sync(int ch, DEVICE* device, int id, uint32_t mask)
163 register_output_signal(&port[ch].outputs_sync, device, id, mask);
165 void set_context_break(int ch, DEVICE* device, int id, uint32_t mask)
167 register_output_signal(&port[ch].outputs_break, device, id, mask);
169 void set_context_rxdone(int ch, DEVICE* device, int id, uint32_t mask)
171 register_output_signal(&port[ch].outputs_rxdone, device, id, mask);
173 void set_context_txdone(int ch, DEVICE* device, int id, uint32_t mask)
175 register_output_signal(&port[ch].outputs_txdone, device, id, mask);
177 void set_tx_clock(int ch, double clock)
179 if(port[ch].tx_clock != clock) {
180 port[ch].tx_clock = clock;
181 update_tx_timing(ch);
184 void set_rx_clock(int ch, double clock)
186 if(port[ch].rx_clock != clock) {
187 port[ch].rx_clock = clock;
188 update_rx_timing(ch);