1 /**************************************************************************************\
2 * *
3 * The Lisa Emulator Project V1.2.6 DEV 2007.12.04 *
4 * http://lisaem.sunder.net *
5 * *
6 * Copyright (C) 1998, 2007 Ray A. Arachelian *
7 * All Rights Reserved *
8 * *
9 * This program is free software; you can redistribute it and/or *
10 * modify it under the terms of the GNU General Public License *
11 * as published by the Free Software Foundation; either version 2 *
12 * of the License, or (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place #330, Boston, MA 02111-1307, USA. *
22 * *
23 * or visit: http://www.gnu.org/licenses/gpl.html *
24 * *
25 * *
26 * *
27 * Z8530 SCC Functions for *
28 * Lisa serial ports *
29 \**************************************************************************************/
30
31 /*
32 * only basic functionality exists here because this is a very complex chip.
33 *
34 * Only async serial is used, most things are virtualized and won't necessarily behave
35 * as a real serial port. Sync-serial, SDLC options, ESCC support, not enabled.
36 *
37 */
38
39 #define LISAEMSCCZ8530 1
40 #include "vars.h"
41 #include "z8530_structs.h"
42
43 #ifndef __MSVCRT__
44 #include <sys/socket.h>
45 #include <arpa/inet.h>
46 #include <poll.h>
47 #include <sys/poll.h>
48 #include <netinet/in.h>
49
50 #ifndef sun
51 #include <err.h>
52 #endif
53
54 #endif
55
56 #include <unistd.h>
57
58
59
60 sccfunc_t scc_fn[2];
61
62
63 static int scc_fifos_allocated=0;
64
65 uint8 scc_bits_per_char_mask[2];
66 FLIFLO_QUEUE_t SCC_READ[2], SCC_WRITE[2];
67
68
69 int scc_interrupts_enabled=0;
70
71 int irq_on_next_rx_char[2];
72
73
74
75 // Defines for the above -- hmmm, not really using these...
76
77 #define CH_B_XMIT_BUFF_EMPTY 0
78 #define CH_B_EXT_STAT_CHANGE 1
79 #define CH_B_RECEIVE_CHAR_AVAILABLE 2
80 #define CH_B_SPECIAL_RECEIVE_COND 3
81
82 #define CH_A_XMIT_BUFF_EMPTY 4
83 #define CH_A_EXT_STAT_CHANGE 5
84 #define CH_A_RECEIVE_CHAR_AVAILABLE 6
85 #define CH_A_SPECIAL_RECEIVE_COND 7
86
87
88 #define RR3_IP_B_STAT 0x01 // Ext/status int pending, chan B
89 #define RR3_IP_B_TX 0x02 // Transmit int pending, chan B
90 #define RR3_IP_B_RX 0x04 // Receive int pending, chan B
91
92 #define RR3_IP_A_STAT 0x08 // Ditto for channel A
93 #define RR3_IP_A_TX 0x10
94 #define RR3_IP_A_RX 0x20
95
96 //128 is an unused bit, it's used to signify that an IRQ has occured since the result
97 //is zero.
98
99
100
101
102 #define TX_BUFF_EMPTY(port) { if (scc_w[port].s.wr1.r.txintenable) \
103 { \
104 if (port) {scc_r[0].r[3] = (scc_r[0].r[3]&0xf0) | RR3_IP_B_TX; z8530_last_irq_status_bits=8;} \
105 else {scc_r[0].r[3] = (scc_r[0].r[3]&0x0f) | RR3_IP_A_TX; z8530_last_irq_status_bits=128;}\
106 \
107 } \
108 }
109
110 #define EXT_STATUS_CHANGE(port) { if (scc_w[port].s.wr1.r.extintenable) \
111 { \
112 if (port) {scc_r[0].r[3] = (scc_r[0].r[3]&0xf0) | RR3_IP_B_STAT; z8530_last_irq_status_bits=10;} \
113 else {scc_r[0].r[3] = (scc_r[0].r[3]&0x0f) | RR3_IP_A_STAT; z8530_last_irq_status_bits=2;} \
114 } \
115 }
116
117 #define RX_CHAR_AVAILABLE(port) {if (scc_w[port].s.wr1.r.rxintmode && scc_w[port].s.wr1.r.rxintmode!=3) \
118 { \
119 if (port) {scc_r[0].r[3] = (scc_r[0].r[3]&0xf0) | RR3_IP_B_RX; z8530_last_irq_status_bits=12;} \
120 else {scc_r[0].r[3] = (scc_r[0].r[3]&0x0f) | RR3_IP_A_RX; z8530_last_irq_status_bits=4;} \
121 } \
122 }
123
124 #define SPECIAL_RECV_COND(port) {if (scc_w[port].s.wr1.r.rxintmode==3) \
125 { \
126 if (port) {scc_r[0].r[3] = (scc_r[0].r[3]&0xf0) | RR3_IP_B_STAT; z8530_last_irq_status_bits=14;} \
127 else {scc_r[0].r[3] = (scc_r[0].r[3]&0x0f) | RR3_IP_A_STAT; z8530_last_irq_status_bits=6;} \
128 } \
129 }
130
131 // Protos for link to host devices - or emulation of ports
132
133 int get_scc_pending_irq(void);
134 void send_break(uint8 port);
135 void set_dtr(uint8 port, uint8 value);
136 void set_rts(uint8 port, uint8 value);
137 void set_dtr_loopbackplug(uint8 port, uint8 value);
138 void set_rts_loopbackplug(uint8 port, uint8 value);
139 int get_dcd(uint8 port);
140 int get_cts(uint8 port);
141 int get_break(uint8 port);
142 void signal_parity_error(uint8 port);
143 void signal_crc_error(uint8 port);
144 void set_even_parity(uint8 port);
145 void set_odd_parity(uint8 port);
146 void set_no_parity(uint8 port);
147 void set_bits_per_char(uint8 port, uint8 bitsperchar);
148 void set_stop_bits(uint8 port,uint8 stopbits);
149 char read_serial_port(int8 port);
150 void write_serial_port(int8 port, char data);
151 void scc_hardware_reset_port(int8 port);
152 void scc_channel_reset_port(int8 port);
153 void initialize_scc(void);
154 void lisa_wb_Oxd200_sccz8530(uint32 address,uint8 data);
155 uint8 lisa_rb_Oxd200_sccz8530(uint32 address);
156 void scc_control_loop(void);
157 void dump_scc(void);
158
159 char read_serial_port(int8 port);
160 char read_serial_port_nothing(int8 port);
161 char read_serial_port_imagewriter(int8 port);
162 char read_serial_port_loopbackplug(int8 port);
163 char read_serial_port_localport(int8 port);
164 #ifndef __MSVCRT__
165 char read_serial_port_telnetd(int8 port);
166 #endif
167
168 void write_serial_port_nothing(int8 port, char data);
169 void write_serial_port_loopbackplug(int8 port, char data);
170 void write_serial_port_localport(int8 port, char data);
171 void write_serial_port_imagewriter(int8 port, char data);
172 #ifndef __MSVCRT__
173 void write_serial_port_telnetd(int8 port, char c);
174 #endif
175
176 uint32 get_baud_rate(uint8 port);
177 void set_baud_rate(int port, uint32 baud);
178
179
180 static inline void on_read_irq_handle(int port);
181
182 /*
183 * There's a clever way to reverse all the bits in an 8-bit word
184 * W = abcdefgh;
185 * W = (W & 0xf0)>>4 | (W & 0x0f)<<4 = efghabcd
186 * W = (W & 0xcc)>>2 | (W & 0x33)<<2 = ghefcdab
187 * W = (W & 0xaa)>>1 | (W & 0x55)<<1 = hgfedcba
188 */
189
reversebit(uint8 c)190 static inline uint8 reversebit(uint8 c)
191 {
192 c = (c & 0xf0)>>4 | (c & 0x0f)<<4;
193 c = (c & 0xcc)>>2 | (c & 0x33)<<2;
194 c = (c & 0xaa)>>1 | (c & 0x55)<<1;
195 return c;
196 }
197
BITREVERSE(uint8 d)198 static inline uint8 BITREVERSE(uint8 d)
199 {
200 #ifdef __POWERPC__
201 return d;
202 #else
203 return reversebit(d) & 0xff;
204 #endif
205 }
206
207 #ifdef BYTES_HIGHFIRST
208 #define BITORD(x) (BITREVERSE(x))
209 #else
210 #define BITORD(x) (x)
211 #endif
212
213
crc16(uint16 crc,uint8 data)214 uint16 crc16(uint16 crc, uint8 data)
215 {
216 crc=(SWAP16(crc))^(BITREVERSE(data));
217 crc^=(crc & 0x00f0)>>4;
218 crc^=(crc<<12);
219 return crc^(((crc & 0x00ff)<<4)<<1);
220 }
221
222
223
scc_hardware_reset_port(int8 port)224 void scc_hardware_reset_port(int8 port)
225 {
226 register uint8 d;
227
228 d=BITORD(scc_r[port].r[0 ]); scc_r[port].r[0]=BITORD( (d & (8|16|32|128)) | 64 | 4);
229 d=BITORD(scc_r[port].r[1 ]); scc_r[port].r[1]=BITORD((d & 1) | 2 | 4);
230 d=BITORD(scc_r[port].r[10]); scc_r[port].r[10]=BITORD(d&64);
231
232 scc_r[port].r[3]=0; // no need to use bitord, 0 is 0 no matter how you flip it. :)
233 scc_w[port].w[0]=0;
234 scc_w[port].w[10]=0;
235
236 d=BITORD(scc_w[port].w[1]); scc_w[port].w[1]=BITORD(d &(4|32));
237
238 scc_w[port].w[11]=BITORD(16);
239 scc_w[port].w[15]=BITORD(255-7);
240
241
242 // wr2 is itself.
243 // wr6 is itself
244 // wr7 is itself
245 // wr12 is itself
246 // wr13 is itself
247
248 d=BITORD(scc_w[port].w[3]); scc_w[port].w[3] = BITORD(d & 254);
249 d=BITORD(scc_w[port].w[4]); scc_w[port].w[4] = BITORD(d | 4);
250 d=BITORD(scc_w[port].w[5]); scc_w[port].w[5] = BITORD(d &(64|32|1) );
251 d=BITORD(scc_w[port].w[17]); scc_w[port].w[17]= BITORD(32);
252 d=BITORD(scc_w[port].w[9]); scc_w[port].w[9] = BITORD((d&3)|128|64);
253
254
255 d=BITORD(scc_w[port].w[14]); scc_w[port].w[14] = BITORD( (d &(128|64)) | (32|16));
256
257 irq_on_next_rx_char[port]=0;
258
259 scc_bits_per_char_mask[0]=255;
260 scc_bits_per_char_mask[1]=255;
261 }
262
263
264
scc_channel_reset_port(int8 port)265 void scc_channel_reset_port(int8 port)
266 {
267 register uint8 d;
268
269 d=BITORD(scc_r[port].r[0 ]); scc_r[port].r[0 ]=BITORD((d&(8|16|32|128) ) | 64 | 4);
270 d=BITORD(scc_r[port].r[1 ]); scc_r[port].r[1 ]=BITORD((d&1) | 2 | 4);
271 d=BITORD(scc_r[port].r[10]); scc_r[port].r[10]=BITORD(d & 64);
272
273 scc_r[port].r[3]=0;
274 scc_w[port].w[0 ]=0;
275
276 //wr2=wr2
277 //wr6=wr6
278 //wr7=wr7
279 //wr12=wr12
280 //wr13=wr13
281
282 d=BITORD(scc_w[port].w[1 ]);scc_w[port].w[1 ]=BITORD(d&(4|32));
283 d=BITORD(scc_w[port].w[3 ]);scc_w[port].w[3 ]=BITORD(d&254);
284 d=BITORD(scc_w[port].w[4 ]);scc_w[port].w[4 ]=BITORD(d|4);
285 d=BITORD(scc_w[port].w[5 ]);scc_w[port].w[5 ]=BITORD(d&(64|32|1));
286
287 d=BITORD(scc_w[port].w[17]);scc_w[port].w[17]=BITORD(32);
288
289 d=BITORD(scc_w[0 ].w[9 ]);scc_w[port].w[9 ]=BITORD(d&(255-32));
290 d=BITORD(scc_w[port].w[10]);scc_w[port].w[10]=BITORD(d & (64|32));
291 d=BITORD(scc_w[port].w[11]);scc_w[port].w[11]=BITORD(16);
292
293 d=BITORD(scc_w[port].w[14]);scc_w[port].w[14]=BITORD((d&(128|64) ) | (32|16));
294 d=BITORD(scc_w[port].w[15]);scc_w[port].w[15]=BITORD(255-7);
295
296 irq_on_next_rx_char[port]=0;
297 scc_bits_per_char_mask[0]=255;
298 scc_bits_per_char_mask[1]=255;
299 }
300
301
initialize_scc(void)302 void initialize_scc(void)
303 {
304 int i;
305
306 if ( !scc_fifos_allocated )
307 {
308 DEBUG_LOG(0,"Allocating FIFO's");
309 if (fliflo_buff_create(&SCC_READ[0] ,SCC_BUFFER_SIZE)) {EXIT(404,0,"Out of memory!");}
310 if (fliflo_buff_create(&SCC_WRITE[0],SCC_BUFFER_SIZE)) {EXIT(405,0,"Out of memory!");}
311 if (fliflo_buff_create(&SCC_READ[1] ,SCC_BUFFER_SIZE)) {EXIT(406,0,"Out of memory!");}
312 if (fliflo_buff_create(&SCC_WRITE[1],SCC_BUFFER_SIZE)) {EXIT(407,0,"Out of memory!");}
313 scc_fifos_allocated=1;
314
315 for (i=0; i<18; i++) {scc_w[0].w[i]=0;scc_w[1].w[i]=0;scc_r[0].r[i]=0;scc_r[0].r[i]=0;}
316 }
317
318 // set handlers to default methods
319 scc_fn[0].set_dtr = set_dtr; // void (*set_dtr)(uint8 port, uint8 value);
320 scc_fn[0].send_break = send_break; // void (*send_break)(uint8 port);
321 scc_fn[0].set_rts = set_rts; // void (*set_rts)(uint8 port, uint8 value);
322 scc_fn[0].get_dcd = get_dcd; // int (*get_dcd)(uint8 port);
323 scc_fn[0].get_cts = get_cts; // int (*get_cts)(uint8 port);
324 scc_fn[0].get_break = get_break; // int (*get_break)(uint8 port);
325 scc_fn[0].signal_parity_error = signal_parity_error; // void (*signal_parity_error)(uint8 port);
326 scc_fn[0].signal_crc_error = signal_crc_error; // void (*signal_crc_error)(uint8 port);
327 scc_fn[0].set_even_parity = set_even_parity; // void (*set_even_parity)(uint8 port);
328 scc_fn[0].set_odd_parity = set_odd_parity; // void (*set_odd_parity)(uint8 port);
329 scc_fn[0].set_no_parity = set_no_parity; // void (*set_no_parity)(uint8 port);
330 scc_fn[0].set_bits_per_char = set_bits_per_char; // void (*set_bits_per_char)(uint8 port, uint8 bitsperchar);
331 scc_fn[0].set_stop_bits = set_stop_bits; // void (*set_stop_bits)(uint8 port,uint8 stopbits);
332 scc_fn[0].read_serial_port = read_serial_port; // char (*read_serial_port)(int8 port);
333 scc_fn[0].write_serial_port = write_serial_port; // void (*write_serial_port)(int8 port, char data);
334 scc_fn[0].scc_hardware_reset_port = scc_hardware_reset_port; // void (*scc_hardware_reset_port)(int8 port);
335 scc_fn[0].scc_channel_reset_port = scc_channel_reset_port; // void (*scc_channel_reset_port)(int8 port);
336 scc_fn[0].set_baud_rate = set_baud_rate;
337
338
339
340
341 scc_fn[1].send_break = send_break;
342 scc_fn[1].set_dtr = set_dtr;
343 scc_fn[1].set_rts = set_rts;
344 scc_fn[1].get_dcd = get_dcd;
345 scc_fn[1].get_cts = get_cts;
346 scc_fn[1].get_break = get_break;
347 scc_fn[1].signal_parity_error = signal_parity_error;
348 scc_fn[1].signal_crc_error = signal_crc_error;
349 scc_fn[1].set_even_parity = set_even_parity;
350 scc_fn[1].set_odd_parity = set_odd_parity;
351 scc_fn[1].set_no_parity = set_no_parity;
352 scc_fn[1].set_bits_per_char = set_bits_per_char;
353 scc_fn[1].set_stop_bits = set_stop_bits;
354 scc_fn[1].read_serial_port = read_serial_port;
355 scc_fn[1].write_serial_port = write_serial_port;
356 scc_fn[1].scc_hardware_reset_port = scc_hardware_reset_port;
357 scc_fn[1].scc_channel_reset_port = scc_channel_reset_port;
358 scc_fn[1].set_baud_rate = set_baud_rate;
359
360 scc_fn[0].scc_hardware_reset_port(0);
361 scc_fn[1].scc_hardware_reset_port(1);
362
363 irq_on_next_rx_char[0]=0;
364 irq_on_next_rx_char[1]=0;
365 scc_interrupts_enabled=0;
366 scc_bits_per_char_mask[0]=255;
367 scc_bits_per_char_mask[1]=255;
368
369
370
371 switch (serial_a)
372 {
373 case SCC_LOCALPORT: scc_fn[1].read_serial_port=read_serial_port_localport;
374 scc_fn[1].write_serial_port=write_serial_port_localport; break;
375
376 case SCC_IMAGEWRITER_PS:
377 case SCC_IMAGEWRITER_PCL:
378 case SCC_IMAGEWRITER: scc_fn[1].read_serial_port=read_serial_port_imagewriter;
379 scc_fn[1].write_serial_port=write_serial_port_imagewriter; break;
380
381 case SCC_LOOPBACKPLUG: scc_fn[1].read_serial_port=read_serial_port_loopbackplug;
382 scc_fn[1].write_serial_port=write_serial_port_loopbackplug;
383 scc_fn[1].set_dtr=set_dtr_loopbackplug;
384 scc_fn[1].set_rts=set_rts_loopbackplug; break;
385
386 #ifndef __MSVCRT__
387
388 case SCC_TELNETD: scc_fn[1].read_serial_port=read_serial_port_telnetd;
389 scc_fn[1].write_serial_port=write_serial_port_telnetd;
390 break;
391 #else
392 case SCC_TELNETD: //ALERT_LOG(0,"TELNETD does not work on Win32");
393 #endif
394
395 default:
396 // ALERT_LOG(0,"Not sure what to connect to this port");
397 case SCC_NOTHING:
398 scc_fn[1].read_serial_port=read_serial_port_nothing;
399 scc_fn[1].write_serial_port=write_serial_port_nothing;
400 break;
401 }
402
403 switch (serial_b)
404 {
405 case SCC_LOCALPORT: scc_fn[0].read_serial_port=read_serial_port_localport;
406 scc_fn[0].write_serial_port=write_serial_port_localport; break;
407
408
409 case SCC_IMAGEWRITER_PS:
410 case SCC_IMAGEWRITER_PCL:
411 case SCC_IMAGEWRITER: scc_fn[0].read_serial_port=read_serial_port_imagewriter;
412 scc_fn[0].write_serial_port=write_serial_port_imagewriter; break;
413
414 case SCC_LOOPBACKPLUG: scc_fn[0].read_serial_port=read_serial_port_loopbackplug;
415 scc_fn[0].write_serial_port=write_serial_port_loopbackplug;
416 scc_fn[0].set_dtr=set_dtr_loopbackplug;
417 scc_fn[0].set_rts=set_rts_loopbackplug; break;
418
419 #ifndef __MSVCRT__
420
421 case SCC_TELNETD: scc_fn[0].read_serial_port=read_serial_port_telnetd;
422 scc_fn[0].write_serial_port=write_serial_port_telnetd; break;
423 #else
424 case SCC_TELNETD: //ALERT_LOG(0,"TELNETD does not work on Win32");
425 #endif
426 default:
427 //ALERT_LOG(0,"oops, not sure what to connect the SCC to.");
428
429 case SCC_NOTHING:
430 scc_fn[0].read_serial_port=read_serial_port_nothing;
431 scc_fn[0].write_serial_port=write_serial_port_nothing; break;
432 }
433
434
435
436
437
438 DEBUG_LOG(0,"r %p %p w %p %p",SCC_READ[0].buffer,&SCC_READ[1].buffer,SCC_WRITE[0].buffer,SCC_WRITE[1].buffer);
439 }
440
441
scc_control_loop(void)442 void scc_control_loop(void)
443 {
444 // If IRQ's are pending, this must be set before the IRQ gets issued.
445 // after the IRQ is issued, they must be cleared?
446 // if ( !port) scc_r[port].r[3]=0;
447 // IRQ pending. These must be set by loop IRQ routine!
448 scc_running=1;
449 if ( fliflo_buff_has_data(&SCC_READ[0]) || fliflo_buff_has_data(&SCC_READ[1])) scc_running=2;
450 if ( fliflo_buff_is_full(&SCC_READ[0]) || fliflo_buff_is_full(&SCC_READ[1])) scc_running=3;
451
452 DEBUG_LOG(0,"r %p %p w %p %p",SCC_READ[0].buffer,&SCC_READ[1].buffer,SCC_WRITE[0].buffer,SCC_WRITE[1].buffer);
453
454 // need to insert code in here that allows other fn's to handle their respective devices - i.e. read from ports, and fill buffers, etc.
455
456
457 }
458
459
460
461 #ifdef DEBUG
dump_scc(void)462 void dump_scc(void)
463 {
464 int i;
465
466 if (!debug_log_enabled) return;
467
468 fprintf(buglog,"\n\nSRC: scc read b: "); for (i=0; i<16; i++) fprintf(buglog,"%d:%02x ",i,scc_r[0].r[i]);
469 fprintf(buglog,"SCR: scc write b:"); for (i=0; i<16; i++) fprintf(buglog,"%d:%02x ",i,scc_w[0].w[i]);
470 fprintf(buglog,"\n");
471 fprintf(buglog,"SRC: scc read a: "); for (i=0; i<16; i++) fprintf(buglog,"%d:%02x ",i,scc_r[1].r[i]);
472 fprintf(buglog,"SRC: scc write a:"); for (i=0; i<16; i++) fprintf(buglog,"%d:%02x ",i,scc_w[1].w[i]);
473 fprintf(buglog,"\n");
474 fprintf(buglog,"SRC: size of port b rx queue:%d, port a:%d\n",fliflo_buff_size(&SCC_READ[0]), fliflo_buff_size(&SCC_READ[1]));
475 fprintf(buglog,"SRC: size of port b tx queue:%d, port a:%d\n",fliflo_buff_size(&SCC_WRITE[0]),fliflo_buff_size(&SCC_WRITE[1]));
476 fprintf(buglog,"SRC: port b rx data available:%d , port a:%d\n",scc_r[0].s.rr0.r.rx_char_available,scc_r[1].s.rr0.r.rx_char_available);
477 fprintf(buglog,"SRC: internalloopback port b:%d port a:%d\n",scc_w[0].s.wr14.r.localloopback,scc_w[1].s.wr14.r.localloopback);
478 fprintf(buglog,"SRC: autoecho port b:%d port a:%d\n",scc_w[0].s.wr14.r.auto_echo,scc_w[1].s.wr14.r.auto_echo);
479
480 DEBUG_LOG(0,"r %p %p w %p %p",SCC_READ[0].buffer,&SCC_READ[1].buffer,SCC_WRITE[0].buffer,SCC_WRITE[1].buffer);
481
482
483 DEBUG_LOG(0,"RR5[%d] 0:rx_char_available:%d, 2:tx_buffer_empty:%d, 3:dcd:%d, 5:cts:%d, 7:break_abort:%d, 4:sync_hunt:%d, 6:tx_underrun_eom:%d, 1:zero_count:%d",
484 0,
485 scc_r[0].s.rr0.r.rx_char_available,
486 scc_r[0].s.rr0.r.tx_buffer_empty,
487 scc_r[0].s.rr0.r.dcd,
488 scc_r[0].s.rr0.r.cts,
489 scc_r[0].s.rr0.r.break_abort,
490 scc_r[0].s.rr0.r.sync_hunt,
491 scc_r[0].s.rr0.r.tx_underrun_eom,
492 scc_r[0].s.rr0.r.zero_count);
493
494 DEBUG_LOG(0,"RR5[%d] 0:rx_char_available:%d, 2:tx_buffer_empty:%d, 3:dcd:%d, 5:cts:%d, 7:break_abort:%d, 4:sync_hunt:%d, 6:tx_underrun_eom:%d, 1:zero_count:%d\n\n",
495 1,
496 scc_r[1].s.rr0.r.rx_char_available,
497 scc_r[1].s.rr0.r.tx_buffer_empty,
498 scc_r[1].s.rr0.r.dcd,
499 scc_r[1].s.rr0.r.cts,
500 scc_r[1].s.rr0.r.break_abort,
501 scc_r[1].s.rr0.r.sync_hunt,
502 scc_r[1].s.rr0.r.tx_underrun_eom,
503 scc_r[1].s.rr0.r.zero_count);
504 }
505 #else
dump_scc(void)506 void dump_scc(void) {}
507 #endif
508
509 // this calculates the baud rate, but it also sets it if the port connection supports the set_baud_rate method.
510 // so the name isn't what it seems.
get_baud_rate(uint8 port)511 uint32 get_baud_rate(uint8 port)
512 {
513 static uint32 baud=0, lastbaud[2];
514 uint32 tc=0, Clock_Freq;
515
516 // SERB port=0, SERA Port=1
517
518 //Clock_Freq=port ? 3686400:4000000;
519 Clock_Freq=port ? 125000:115200;
520
521 tc=scc_w[port].w[12]+((scc_w[port].w[13]<<8));
522
523
524 DEBUG_LOG(0,"Freq:%ld TimeConst:%d (%02x.%02x) for port:%d",Clock_Freq, tc, scc_w[port].w[13],scc_w[port].w[12],port);
525
526
527 switch(scc_w[port].s.wr4.r.clockmultipliermode)
528 // =INT(3686400/(2*(tc)*16+2))
529 { case 0 : baud= Clock_Freq/(tc*(1 )+2); DEBUG_LOG(0,"clock multiplier=1 baud-with-x1 %d baud withx1:%d",baud,Clock_Freq/(tc+2) ); break;
530 case 1 : baud= Clock_Freq/(tc*(16)+2); DEBUG_LOG(0,"clock multiplier=16 baud-with-x16 %d baud withx1:%d",baud,Clock_Freq/(tc+2) ); break;
531 case 2 : baud= Clock_Freq/(tc*(32)+2); DEBUG_LOG(0,"clock multiplier=32 baud-with-x32 %d baud withx1:%d",baud,Clock_Freq/(tc+2) ); break;
532 case 3 : baud= Clock_Freq/(tc*(64)+2); DEBUG_LOG(0,"clock multiplier=64 baud-with-x64 %d baud withx1:%d",baud,Clock_Freq/(tc+2) ); break;
533 } //Baud =K/(2*(TC(port)+2))
534
535 if (!scc_w[port].s.wr14.r.br_generator_enable || !scc_w[port].s.wr14.r.br_generator_source)
536 {
537 DEBUG_LOG(0,"BAUD RATE GENERATOR DISABLED! PORT:%d w[12]=%02x w[13]=%02x clock multiplier=%02x (wr[4]=%02x) detected:%d",
538 port,
539 scc_w[port].w[12],
540 scc_w[port].w[13],
541 scc_w[port].s.wr4.r.clockmultipliermode,
542 scc_w[port].w[4],
543 baud );
544
545
546 return lastbaud[port];
547 }
548
549 // correct weird differences between the formula and the table
550 if (baud>57600-9999) baud=57600;
551 else if (baud>38400-5000) baud=38400;
552 else if (baud>19200-2000) baud=19200;
553 else if (baud> 9600-800) baud= 9600;
554 else if (baud> 4800-500) baud= 4800;
555 else if (baud> 2400-400) baud= 2400;
556 else if (baud> 1200-200) baud= 1200;
557 else if (baud> 300-50) baud= 300;
558 else if (baud> 110-30) baud= 110;
559 else if (baud> 50-10) baud= 50;
560 DEBUG_LOG(0,"Normalized Baud:%d",baud);
561
562
563
564 switch(baud) // make sure we don't set it to some oddball value
565 {
566 case 110 : // not always supported
567 case 300 : // not always supported
568 case 1200 :
569 case 2400 :
570 case 4800 :
571 case 9600 :
572 case 19200 :
573 case 34800 :
574 case 57600 :
575 case 224000: // only Macs with serial ports will handle this one
576
577 DEBUG_LOG(0,"Baud Rate:%d",baud);
578
579 if (baud!=lastbaud[port]) // was there a baud rate change?
580 { if (scc_fn[port].set_baud_rate) // is there a handler to change bps on the port?
581 scc_fn[port].set_baud_rate(port,baud); } // yup, use it's method
582
583 lastbaud[port]=baud;
584 break;
585 default:
586 DEBUG_LOG(0,"Weird Baud Rate:%d requested by Lisa or buggy code in emulation",baud);
587
588 }
589
590
591
592 DEBUG_LOG(0,"BAUD RATE PORT:%d w[12]=%02x w[13]=%02x clock multiplier=%02x (wr[4]=%02x) detected:%d",
593 port,
594 scc_w[port].w[12],
595 scc_w[port].w[13],
596 scc_w[port].s.wr4.r.clockmultipliermode,
597 scc_w[port].w[4],
598 baud );
599
600 //debug_on("scc snapshot");
601 //dump_scc();
602 //debug_off();
603
604 return baud;
605 }
606
607
608 // as above, incase it's useful later - the logarithm (given a value, the bit # of the highest 1 bit )
609 //
610 // uint8 bitlog[64]={0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
611 // 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5}
612
613
z8530_find_highest_ius(uint8 value,int clear_value)614 static inline uint8 z8530_find_highest_ius(uint8 value, int clear_value)
615 {
616 // uint8 bit=0; // this is much faster with a simple lookup
617 // if (value & BIT5) bit=BIT5; // I'm leaving this dead code here as an explanation of
618 // else if (value & BIT4) bit=BIT4; // how the lookup highest_bit[] and inverse were created.
619 // else if (value & BIT3) bit=BIT3; //
620 // else if (value & BIT2) bit=BIT2; // swap'em around if your architecture is faster w/o memory lookups
621 // else if (value & BIT1) bit=BIT1; // i.e. comment out the last return, then uncomment this block
622 // else if (value & BIT0) bit=BIT0; //
623 // //
624 // return (clear_value ? (value & (~bit)) : bit); //
625 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
626
627 // is clear_value turned on?
628 return (clear_value ? (value & (highest_bit_val_inv[value & 63])): // yes - return value with the highest 1 bit cleared.
629 highest_bit_val[value & 63] ); // no - just return highest 1 bit from value, don't clear it
630 }
631
632
633
on_read_irq_handle(int port)634 static inline void on_read_irq_handle(int port)
635 {
636 // if Master IRQ Enable is off, nothing to do
637 if (!scc_w[port].s.wr9.r.MIE) return;
638
639 switch(scc_w[port].s.wr1.r.rxintmode)
640 { case 1 : scc_w[port].s.wr1.r.rxintmode=0; // clear mode, then fall through
641 case 2 : if (!port) scc_r[1].s.rr3.r.ch_b_rx_irq_pending=1; // RR3A
642 else scc_r[1].s.rr3.r.ch_a_rx_irq_pending=1; // fall through to return
643 default: return; // case 0,3 - just return, not applicable
644 }
645 }
646
on_special_irq_handle(int port)647 static inline void on_special_irq_handle(int port)
648 {
649 // if Master IRQ Enable is off, or the mode is off, skip the rest
650 if (!scc_w[port].s.wr9.r.MIE) return;
651
652 switch(scc_w[port].s.wr1.r.rxintmode)
653 { case 1 : scc_w[port].s.wr1.r.rxintmode=0; // clear mode and fall through
654 case 2 : // fall through to 3
655 case 3 : if (!port) scc_r[1].s.rr3.r.ch_b_ext_status_irq_pending=1; // set IRQ for the port
656 else scc_r[1].s.rr3.r.ch_a_ext_status_irq_pending=1; // fall through to return
657 default: return; // case 0 - return
658 }
659 }
660
661
662
663 int poll_telnet_serial_read(int portnum);
664
665
get_scc_pending_irq(void)666 int get_scc_pending_irq(void)
667 {
668 int data;
669
670 if (!scc_w[1].s.wr9.r.MIE) {DEBUG_LOG(0,"MIE is off"); return 0;} // Master IRQ Enable bit - if not set, no IRQ's to return.
671
672 #ifndef __MSVCRT__
673 if (serial_b==SCC_TELNETD)
674 { data=poll_telnet_serial_read(0);
675 if (data>-1) { fliflo_buff_add(&SCC_READ[0],(uint8)(data) & scc_bits_per_char_mask[0]);
676 RX_CHAR_AVAILABLE(0);
677
678 ALERT_LOG(0,"Received %02x %c from scc port:%d serial_b fliflo size is:%d",
679 (uint8)(data),
680 ((data >31) ? ((uint8)(data)):'.'),
681 0,
682 fliflo_buff_size(&SCC_READ[0]));
683 }
684 }
685
686 if (serial_a==SCC_TELNETD)
687 {
688 data=poll_telnet_serial_read(1);
689 if (data>-1) {
690 fliflo_buff_add(&SCC_READ[1],(uint8)(data) & scc_bits_per_char_mask[1]);
691 RX_CHAR_AVAILABLE(1);
692
693 ALERT_LOG(0,"Received %02x %c from scc port:%d serial_a fliflo size is:%d",
694 (uint8)(data),
695 ((data >31) ? ((uint8)(data)):'.'),
696 1,
697 fliflo_buff_size(&SCC_READ[1])
698 );
699
700 }
701 }
702 #endif
703 // if IRQ on next char is enabled and the fliflo has data, flag IRQ
704 if ( (irq_on_next_rx_char[0] && fliflo_buff_has_data(&SCC_READ[0])) ||
705 ((scc_w[0].s.wr1.r.rxintmode) && fliflo_buff_has_data(&SCC_READ[0] )) )
706 {
707 DEBUG_LOG(0,"chb has data");
708 on_read_irq_handle(0);
709 scc_r[1].s.rr3.r.ch_b_ext_status_irq_pending=1;
710 RX_CHAR_AVAILABLE(0);
711
712 }
713 else scc_r[1].s.rr3.r.ch_b_ext_status_irq_pending=0; //20051111
714
715 if ( (irq_on_next_rx_char[1] && fliflo_buff_has_data(&SCC_READ[1])) ||
716 ((scc_w[1].s.wr1.r.rxintmode) && fliflo_buff_has_data(&SCC_READ[1] )) )
717 {
718 DEBUG_LOG(0,"cha has data");
719 on_read_irq_handle(1);
720 scc_r[1].s.rr3.r.ch_a_ext_status_irq_pending=1;
721 RX_CHAR_AVAILABLE(1);
722 }
723 else scc_r[1].s.rr3.r.ch_a_ext_status_irq_pending=0; //20051111
724
725
726 // if there's no more data, don't trigger an IRQ for it.
727 if (!fliflo_buff_has_data(&SCC_READ[0]) && z8530_last_irq_status_bits==4 ) {z8530_last_irq_status_bits=0; scc_r[1].s.rr3.r.ch_b_rx_irq_pending=0;}
728 if (!fliflo_buff_has_data(&SCC_READ[1]) && z8530_last_irq_status_bits==12) {z8530_last_irq_status_bits=0; scc_r[1].s.rr3.r.ch_a_rx_irq_pending=0;}
729
730
731
732 DEBUG_LOG(0,"Returning: %d or %d",(scc_r[1].r[3]) , z8530_last_irq_status_bits );
733
734
735 return (scc_r[1].r[3]) || z8530_last_irq_status_bits; // if zero, no irq, else irq
736 }
737
738
739
740
lisa_wb_Oxd200_sccz8530(uint32 address,uint8 data)741 void lisa_wb_Oxd200_sccz8530(uint32 address,uint8 data)
742 {
743 uint8 access, port=0, odata, regnum=0; //d,
744
745 #ifdef DEBUG
746 char *multiplier;
747 switch(scc_w[port].s.wr4.r.clockmultipliermode)
748 { case 0 : multiplier= "1"; break;
749 case 1 : multiplier="16"; break;
750 case 2 : multiplier="32"; break;
751 case 3 : multiplier="64"; break;
752 default: multiplier="unknown";
753 }
754
755 DEBUG_LOG(0,"TC:%d, Baud:%ld %d bps %s parity Clock Multiplier:%s",(scc_w[port].w[12]+(scc_w[port].w[13]<<8)),get_baud_rate(port) ,
756 (5+scc_w[port].s.wr3.r.rxbitsperchar),
757 (( scc_w[port].s.wr4.r.parityenable) ? ((scc_w[port].s.wr4.r.evenparity) ? "Even":"Odd") : "No"),
758 multiplier);
759 #endif
760
761 dump_scc();
762
763
764 switch ((address & 0x000007) | 0x00FCD240)
765 {
766 case SERIAL_PORT_B_CONTROL: access=0; port=0; break;
767 case SERIAL_PORT_B_DATA : access=1; port=0; break;
768 case SERIAL_PORT_A_CONTROL: access=0; port=1; break;
769 case SERIAL_PORT_A_DATA: access=1; port=1; break;
770 default: DEBUG_LOG(0,"Warning invalid access! %08x :=%02x",address,data);
771 return; // invalid address, just ignore it.
772 }
773
774 DEBUG_LOG(0,"SRC:SCC: access:%d port %d",access,port);
775
776 if ( access) // Write to data port.
777 {
778 if (scc_w[1].s.wr9.r.soft_int_ack) {scc_r[0].r[2]=0; z8530_last_irq_status_bits=0; scc_r[port].r[2]=0;}
779 DEBUG_LOG(0,"SRC:SCC: access:%d port %d",access,port);
780 if (!scc_w[port].s.wr5.r.txenable) {DEBUG_LOG(0,"TX not enabled!"); return;} // can't send until tx is enabled.
781
782
783 if ( scc_w[port].s.wr14.r.localloopback) {DEBUG_LOG(0,"loopback data: %02x",data & scc_bits_per_char_mask[port]);
784 DEBUG_LOG(0,"SCC_READ[port] is %p",&SCC_READ[port]);
785 DEBUG_LOG(0,"scc_bits_char_mask is:%02x",scc_bits_per_char_mask[port]);
786 DEBUG_LOG(0,"pointer for add is: %p",fliflo_buff_add);
787 DEBUG_LOG(0,"pointer for is full: %p",fliflo_buff_is_full);
788 DEBUG_LOG(0,"pointer for get is: %p",fliflo_buff_get);
789
790 fliflo_buff_add(&SCC_READ[port],data & scc_bits_per_char_mask[port]);} // loopback? add the data to port's own receive buffer instead.
791 else // real writes - with option auto_echo
792 {
793 TX_BUFF_EMPTY(port);
794
795 if (z8530_event==-1) z8530_event=cpu68k_clocks+Z8530_XMIT_DELAY;
796
797
798 if ( scc_w[port].s.wr14.r.auto_echo) {DEBUG_LOG(0,"autoecho is on"); fliflo_buff_add(&SCC_READ[port],data & scc_bits_per_char_mask[port]);} // copy to receive buffer too, as in loopback
799
800 if (scc_fn[port].write_serial_port ) {DEBUG_LOG(0,"write to write_serial_port_method byte:%02x",data);
801 scc_fn[port].write_serial_port(port,data);
802 TX_BUFF_EMPTY(port);
803
804 }
805 else {DEBUG_LOG(0,"write method is null, calling generic handler to write %02x",data);
806 write_serial_port(port,data);
807 TX_BUFF_EMPTY(port);
808 }
809 }
810
811 DEBUG_LOG(0,"SRC:SCC Write to port %d data %02x adjusted for bits/char:%02x",port,data,data & scc_bits_per_char_mask[port]);
812 dump_scc();
813 return;
814 }
815
816 odata=data;
817 data=BITORD(data); // do this here, so the bit fields will work properly. If done before dealing with data
818 // it would reverse the data, which would be a bad idea. :)
819
820 regnum=scc_w[port].s.wr0.r.reg; if (scc_w[port].s.wr0.r.cmd==1) {regnum|=8; scc_w[port].s.wr0.r.cmd=0;}
821 DEBUG_LOG(0,"Register for SCC access is %02x - register 0 is: %02x, writing %02x to reg %d",regnum,scc_w[port].w[0],
822 odata,regnum);
823
824 scc_w[port].s.wr0.r.reg=0; // reset register pointer back to zero for next round.
825
826 switch ( regnum)
827 {
828 case 0: DEBUG_LOG(0,"Write to 0 odata=%02x data=%02x",odata,data);
829 scc_w[port].w[0] = data;
830 //scc_w[port].w[regnum]=data & (0xff-7);
831
832 if ( scc_w[port].s.wr0.r.reset == 1) {scc_r[port].s.rr1.r.crc_framing_error=0; DEBUG_LOG(0,"reset rx crc checker");}
833 else if ( scc_w[port].s.wr0.r.reset == 2) {scc_r[port].s.rr1.r.crc_framing_error=0; DEBUG_LOG(0,"reset tx crc checker");}
834 else if ( scc_w[port].s.wr0.r.reset == 3) {scc_r[port].s.rr0.r.tx_underrun_eom=0; DEBUG_LOG(0,"reset xmit_underrun_eom");}
835
836 switch(scc_w[port].s.wr0.r.cmd)
837 {
838
839 case 0: break; // NULL Command
840
841
842
843 case 2:
844 DEBUG_LOG(0,"WR0:CMD=2 Reset IRQ status flags %02x",data); // cmd=2
845 scc_r[0].s.rr2.v=0; // was data ??
846 //scc_w[0].s.wr2.v=data;
847 break; // reset irq status flags
848 case 3:
849 DEBUG_LOG(0,"WR0:CMD=send sdlc abort");
850 //send_sdlc_abort(port); // send sdlc abort
851 scc_r[port].s.rr0.r.tx_underrun_eom=1;
852 scc_w[port].s.wr0.r.cmd=0; // clear command for next cycle (except for previous highpoint)
853 break;
854 case 4:
855 DEBUG_LOG(0,"WR0:irq on next rx char");
856 scc_w[port].s.wr1.r.rxintmode=1; // maybe this is all I'd need for this?
857
858 irq_on_next_rx_char[port]=1; // might not need this variable anymore.
859
860 scc_w[port].s.wr0.r.cmd=0; // clear command for next cycle (except for previous highpoint)
861 break;
862 case 5:
863 DEBUG_LOG(0,"WR0:Clear next xmit pending irq");
864 scc_r[port].s.rr3.r.ch_a_tx_irq_pending=0;
865 scc_r[!port].s.rr3.r.ch_a_tx_irq_pending=0;
866 scc_w[port].s.wr0.r.cmd=0; // clear command for next cycle (except for previous highpoint)
867
868 //2006.08.07
869 if ( (port && z8530_last_irq_status_bits==8) || (!port && z8530_last_irq_status_bits==128)) z8530_last_irq_status_bits=0;
870 break;
871 case 6:
872 DEBUG_LOG(0,"WR0:Reset Error bits");
873 scc_r[port].s.rr1.r.all_sent=0; // reset error bits
874 scc_r[port].s.rr1.r.parity_error=0;
875 scc_r[port].s.rr1.r.rx_overrun_error=0;
876 scc_r[port].s.rr1.r.crc_framing_error=0;
877 scc_r[port].s.rr1.r.sdlc_end_of_frame=0;
878 scc_w[port].s.wr0.r.cmd=0; // clear command for next cycle (except for previous highpoint)
879 break;
880
881 case 7:
882
883 DEBUG_LOG(0,"WR0:Reset highest irq under service"); // reset highest Interrupt Under Service ????
884 scc_r[1].r[3]=0; // z8530_find_highest_ius(scc_r[1].r[3], 1) & 63; // the 2nd param tells the fn to clear it
885 scc_r[0].r[2]=0;
886 z8530_last_irq_status_bits=0;
887
888
889
890 scc_w[port].s.wr0.r.cmd=0; // clear command for next cycle (except for previous highpoint)
891 break;
892 }
893
894
895 DEBUG_LOG(0,"SRC:SCC port:%d set regnum %02x to data/bitrevdata:%02x/%02x", port,regnum,odata,data);
896 dump_scc();
897 return;
898
899 case 1: scc_w[port].w[1] = data; DEBUG_LOG(0,"Write to 1 odata=%02x data=%02x",odata,data);
900
901 DEBUG_LOG(0,"wr1:irq: extintenable:%d, txintenable:%d, parityspecial:%d, rxintmode:%d, waitdmareqon:%d, waitdmareqfn:%d, waitdmareqenable:%d",
902 scc_w[port].s.wr1.r.extintenable,
903 scc_w[port].s.wr1.r.txintenable,
904 scc_w[port].s.wr1.r.parityspecial,
905 scc_w[port].s.wr1.r.rxintmode,
906 scc_w[port].s.wr1.r.waitdmareqon,
907 scc_w[port].s.wr1.r.waitdmareqfn,
908 scc_w[port].s.wr1.r.waitdmareqenable);
909
910
911 if ( scc_w[port].s.wr1.v && scc_w[0].s.wr9.r.MIE) scc_interrupts_enabled=1; else scc_interrupts_enabled=0;
912 DEBUG_LOG(0,"IRQ enabled is:%d",scc_interrupts_enabled);
913 break;
914
915 case 2: DEBUG_LOG(0,"Storing %02x (irq vector bits) in register w2 %02x=odata",data,odata);
916
917 scc_w[0 ].w[2] = data; // interrupt vector bits - there is only one port 2
918 scc_w[1 ].w[2] = data; // what does this actually do? enable the IRQ's????????????? is it an AND mask?
919 DEBUG_LOG(0,"IRQ vector bits:%d,%d,%d,%d,%d,%d,%d,%d",
920 scc_w[0].s.wr2.r.v0,scc_w[0].s.wr2.r.v1,scc_w[0].s.wr2.r.v2,scc_w[0].s.wr2.r.v3,
921 scc_w[0].s.wr2.r.v4,scc_w[0].s.wr2.r.v5,scc_w[0].s.wr2.r.v6,scc_w[0].s.wr2.r.v7);
922 break;
923
924 case 3: scc_w[port].w[3] = data; DEBUG_LOG(0,"Write to 3 data=%02x,odata=%02x",data,odata);
925
926 set_bits_per_char(port,5+scc_w[port].s.wr3.r.rxbitsperchar);
927 DEBUG_LOG(0,"RX Bits per char is %d for port %d", (5+scc_w[port].s.wr3.r.rxbitsperchar), port);
928
929 break;
930
931 case 4: scc_w[port].w[4] = data; DEBUG_LOG(0,"Write to 4 data=%02x odata=%02x",data,odata);
932
933 if ( scc_w[port].s.wr4.r.parityenable)
934 {
935 DEBUG_LOG(0,"Parity Enabled");
936 if (scc_w[port].s.wr4.r.evenparity) {DEBUG_LOG(0,"Even parity"); set_even_parity(port);}
937 else {DEBUG_LOG(0,"Odd parity"); set_odd_parity(port);}
938 }
939 else set_no_parity(port);
940
941 set_stop_bits(port,scc_w[port].s.wr4.r.stopbits);
942 DEBUG_LOG(0,"port:%d Stop bits set to:%d",port,scc_w[port].s.wr4.r.stopbits);
943
944 #ifdef DEBUG
945 switch(scc_w[port].s.wr4.r.clockmultipliermode)
946 {
947 case 0 : DEBUG_LOG(0,"clock multiplier X1 mode:%d",scc_w[port].s.wr4.r.clockmultipliermode); break;
948 case 1 : DEBUG_LOG(0,"clock multiplier X16 mode:%d",scc_w[port].s.wr4.r.clockmultipliermode); break;
949 case 2 : DEBUG_LOG(0,"clock multiplier X32 mode:%d",scc_w[port].s.wr4.r.clockmultipliermode); break;
950 case 3 : DEBUG_LOG(0,"clock multiplier X64 mode:%d",scc_w[port].s.wr4.r.clockmultipliermode); break;
951 }
952 #endif
953
954 get_baud_rate(port);
955
956 break;
957
958 case 5: scc_w[port].w[5] = data; DEBUG_LOG(0,"Write to 5 data=%02x odata=%02x",data,odata);
959
960 DEBUG_LOG(0,"RTS:%d, DTR:%d, break:%d",scc_w[port].s.wr5.r.RTS,scc_w[port].s.wr5.r.DTR,scc_w[port].s.wr5.r.sendbreak);
961 if (scc_fn[port].set_rts) scc_fn[port].set_rts(port,scc_w[port].s.wr5.r.RTS);
962 if (scc_fn[port].set_dtr) scc_fn[port].set_dtr(port,scc_w[port].s.wr5.r.DTR);
963 if (scc_w[port].s.wr5.r.sendbreak) {if (scc_fn[port].send_break) scc_fn[port].send_break(port);}
964
965 switch(scc_w[port].s.wr5.r.txbitsperchar)
966 {
967 case 0 : set_bits_per_char(port,5); break;
968 case 1 : set_bits_per_char(port,7); break;
969 case 2 : set_bits_per_char(port,6); break;
970 case 3 : set_bits_per_char(port,8); break;
971 }
972 break;
973
974 case 6: scc_w[port].w[6] = data; DEBUG_LOG(0,"Unsupported - Write to 6 syncbits data=%02x, %02x=odata",data,odata);break; // sync bits
975 case 7: scc_w[port].w[7] = data; DEBUG_LOG(0,"Unsupported - Write to 7 data=%02x odata=%02x",data,odata);
976
977 #ifdef ESCC
978 if ( scc_w[port].s.wr15.r.wr7prime)
979 { //7PRIME
980 scc_w[port].w.w7prime=data;
981 // whatever needs to be added
982
983 DEBUG_LOG(0,"auto_tx_flag:%d", scc_w[port].s.wr7prime.r.autotx );
984 DEBUG_LOG(0,"auto_EOM_reset:%d", scc_w[port].s.wr7prime.r.autoeomreset );
985 DEBUG_LOG(0,"auto_RTS_deactivation:%d", scc_w[port].s.wr7prime.r.autortsdeactivation );
986 DEBUG_LOG(0,"rx_FIFO_half_full:%d", scc_w[port].s.wr7prime.r.rxfifohalffull );
987 DEBUG_LOG(0,"DTRREQ_timing_mode:%d", scc_w[port].s.wr7prime.r.dtr_req_timing_mode );
988 DEBUG_LOG(0,"tx_FIFO_Empty:%d", scc_w[port].s.wr7prime.r.txfifoempty );
989 DEBUG_LOG(0,"ext_read_enable:%d", scc_w[port].s.wr7prime.r.extendedreadenable );
990
991 dump_scc();
992 return;
993 }
994 #endif
995 break;
996
997 case 8: scc_w[port].w[8] = data; DEBUG_LOG(0,"Write to 8 (XMIT REGISTER DATA - Unsuppported!) data=%02x odata=%02x",data,odata);
998
999 break;
1000
1001 case 9: DEBUG_LOG(0,"Write to 9 MIE data=%02x odata=%02x",data,odata); // there is only one port 9
1002
1003
1004 switch (scc_w[0].s.wr9.r.reset)
1005 {
1006 case 1 : scc_channel_reset_port(0); DEBUG_LOG(0,"resetting port 0 (B)"); break;
1007 case 2 : scc_channel_reset_port(1); DEBUG_LOG(0,"resetting port 1 (A)"); break;
1008 case 3 : scc_hardware_reset_port(0); scc_hardware_reset_port(1); DEBUG_LOG(0,"hw reset port0+1"); break;
1009 }
1010
1011 // possible bug in the docs MIE goes to 0 on a hw reset, but looks like it should not!
1012
1013 DEBUG_LOG(0,"wr9 MIE VIS:%d", scc_w[0].s.wr9.r.VIS);
1014 DEBUG_LOG(0,"wr9 MIE NV:%d", scc_w[0].s.wr9.r.NV);
1015 DEBUG_LOG(0,"wr9 MIE DLC:%d", scc_w[0].s.wr9.r.DLC);
1016 DEBUG_LOG(0,"wr9 MIE MIE:%d", scc_w[0].s.wr9.r.MIE);
1017 DEBUG_LOG(0,"wr9 MIE status_hi_lo:%d", scc_w[0].s.wr9.r.status_hi_lo);
1018 DEBUG_LOG(0,"wr9 MIE soft_int_ack:%d", scc_w[0].s.wr9.r.soft_int_ack);
1019 DEBUG_LOG(0,"wr9 MIE reset:%d", scc_w[0].s.wr9.r.reset);
1020
1021 scc_interrupts_enabled=(scc_w[port].w[1] && scc_w[0].s.wr9.r.MIE);
1022
1023 scc_w[0 ].w[9] = data;
1024 scc_w[1 ].w[9] = data;
1025
1026 break;
1027
1028 case 10: scc_w[port].w[10]= data; DEBUG_LOG(0,"Unsupported Write to 10 data=%02x odata=%02x",data,odata);break;
1029
1030 case 11: scc_w[port].w[11]= data; DEBUG_LOG(0,"Write to 11 data=%02x odata=%02x",data,odata);
1031
1032 DEBUG_LOG(0,"reg11: CLOCK Control! xmit_extern_control:%d,trxc_pin_is_output:%d, xmit_clock_src:%d, rx_clock_src:%d, rtxc_xtal:%d",
1033 scc_w[port].s.wr11.r.xmit_extern_control,
1034 scc_w[port].s.wr11.r.trxc_pin_is_output,
1035 scc_w[port].s.wr11.r.xmit_clock_src,
1036 scc_w[port].s.wr11.r.rx_clock_src,
1037 scc_w[port].s.wr11.r.rtxc_xtal );
1038 break;
1039
1040 case 12: scc_w[port].w[12]= data;
1041 DEBUG_LOG(0,"Write to 12 TimeConstant Low data=%02x odata=%02x::TimeConst:%d: Baud Rate:%ld",data,odata,
1042 (scc_w[port].w[12]+(scc_w[port].w[13]<<8)),get_baud_rate(port));
1043 break;
1044
1045 case 13: scc_w[port].w[13]= data;
1046 DEBUG_LOG(0,"Write to 13 TimeConstant Low data=%02x odata=%02x::TimeConst:%d: Baud Rate:%ld",data,odata,
1047 (scc_w[port].w[12]+(scc_w[port].w[13]<<8)),get_baud_rate(port));
1048 break;
1049
1050 case 14: scc_w[port].w[14]= data; // write of 0x13 should be baud rate generator + loopback: 00010011
1051
1052 DEBUG_LOG(0,"autoecho: %d",scc_w[port].s.wr14.r.auto_echo);
1053 DEBUG_LOG(0,"loopback: %d",scc_w[port].s.wr14.r.localloopback);
1054
1055 DEBUG_LOG(0,"baud rate generator enable: %d",scc_w[port].s.wr14.r.br_generator_enable);
1056 DEBUG_LOG(0,"baud rate generator source %d", scc_w[port].s.wr14.r.br_generator_source);
1057
1058 scc_r[port].s.rr0.r.zero_count=1;
1059
1060 DEBUG_LOG(0,"extintenable:%d", scc_w[port].s.wr1.r.extintenable);
1061 DEBUG_LOG(0,"zc_irq_en:%d", scc_w[port].s.wr15.r.zero_count_interrupt_enable);
1062 DEBUG_LOG(0,"scc_w[port].s.wr1.r.rxintmode:%d",scc_w[port].s.wr1.r.rxintmode);
1063
1064 if (scc_w[port].s.wr14.r.br_generator_enable && scc_w[port].s.wr1.r.extintenable &&
1065 scc_w[port].s.wr15.r.zero_count_interrupt_enable) on_special_irq_handle(port);
1066
1067
1068 DEBUG_LOG(0,"chb irq ext pending:%d",scc_r[1].s.rr3.r.ch_b_ext_status_irq_pending);
1069 DEBUG_LOG(0,"cha irq ext pending:%d",scc_r[1].s.rr3.r.ch_a_ext_status_irq_pending);
1070 DEBUG_LOG(0,"cheat on");
1071
1072 if (!port) scc_r[1].s.rr3.r.ch_b_ext_status_irq_pending=1;
1073 else scc_r[1].s.rr3.r.ch_a_ext_status_irq_pending=1;
1074
1075
1076 DEBUG_LOG(0,"dtr req: %d",scc_w[port].s.wr14.r.dtr_req_fn);
1077 DEBUG_LOG(0,"autoecho: %d",scc_w[port].s.wr14.r.auto_echo);
1078 DEBUG_LOG(0,"loopback: %d",scc_w[port].s.wr14.r.localloopback);
1079 DEBUG_LOG(0,"dpll command: %d",scc_w[port].s.wr14.r.dpll_cmd);
1080 DEBUG_LOG(0,"Write to 14 data=%02x odata=%02x wr14.v=%02x",data,odata,scc_w[port].s.wr14.v);
1081 DEBUG_LOG(0,"w[14]=%p wr14]%p",&scc_w[port].w[14],&scc_w[port].s.wr14.v);
1082 DEBUG_LOG(0,"sizeof w14 is %d",sizeof(wr14_t));
1083 if ( data & 16)
1084 { DEBUG_LOG(0,"loopback SHOULD be on."); }
1085
1086 break;
1087
1088 case 15: scc_w[port].w[15]= data; DEBUG_LOG(0,"Write to 15 data=%02x odata=%02x",data,odata);
1089
1090 DEBUG_LOG(0,"wr7prime:%d", scc_w[port].s.wr15.r.wr7prime);
1091 DEBUG_LOG(0,"zero_count_interrupt_enable:%d", scc_w[port].s.wr15.r.zero_count_interrupt_enable);
1092 DEBUG_LOG(0,"sldc_fifo_enable:%d", scc_w[port].s.wr15.r.sldc_fifo_enable);
1093 DEBUG_LOG(0,"dcd_interrupt_enable:%d", scc_w[port].s.wr15.r.dcd_interrupt_enable);
1094 DEBUG_LOG(0,"sync_hunt_interrupt_enable:%d", scc_w[port].s.wr15.r.sync_hunt_interrupt_enable);
1095 DEBUG_LOG(0,"cts_interrupt_enable:%d", scc_w[port].s.wr15.r.cts_interrupt_enable);
1096 DEBUG_LOG(0,"tx_underrun_eom_interrupt_enable:%d", scc_w[port].s.wr15.r.tx_underrun_eom_interrupt_enable);
1097 DEBUG_LOG(0,"break_abort_interrupt_enable:%d", scc_w[port].s.wr15.r.break_abort_interrupt_enable);
1098 break;
1099 }
1100 dump_scc();
1101 } // end of function
1102
1103
1104
1105
lisa_rb_Oxd200_sccz8530(uint32 address)1106 uint8 lisa_rb_Oxd200_sccz8530(uint32 address)
1107 {
1108 uint8 access, port, regnum=0; //d
1109
1110 // note if scc_w[port].w14.localloopback external data should be ignored!
1111
1112 dump_scc();
1113
1114 switch ((address & 0x000007) | 0x00FCD240)
1115 {
1116 case SERIAL_PORT_B_CONTROL: access=0; port=0; break;
1117 case SERIAL_PORT_B_DATA : access=1; port=0; break;
1118 case SERIAL_PORT_A_CONTROL: access=0; port=1; break;
1119 case SERIAL_PORT_A_DATA: access=1; port=1; break;
1120 default: DEBUG_LOG(0,"Warning invalid access! %08x",address);
1121 return 0; // invalid address, just ignore it.
1122 }
1123 DEBUG_LOG(0,"SRC:SCC: access:%d port %d",access,port);
1124
1125
1126
1127
1128 if ( access ) //--------------- Data Port ---------------------------------------------------------------------------------
1129 {
1130 if (scc_w[1].s.wr9.r.soft_int_ack) {scc_r[0].r[2]=0; z8530_last_irq_status_bits=0; }
1131
1132 if ((!port && z8530_last_irq_status_bits==12) || (port && z8530_last_irq_status_bits==4)) z8530_last_irq_status_bits=0; //20060804
1133
1134 if (!scc_w[port].s.wr3.r.rxenable) {DEBUG_LOG(0,"read failed rx disabled on port %d",port);return 0;} // can't read anything unless this is on.
1135 else
1136 { uint8 c;
1137
1138 if (fliflo_buff_has_data(&SCC_READ[port]))
1139 c=fliflo_buff_get(&SCC_READ[port]) & scc_bits_per_char_mask[port];
1140 else c=scc_fn[port].read_serial_port(port); // if nothing already waiting in fliflo, call read fn as needed.
1141
1142 DEBUG_LOG(0,"read char %02x %c from fifo or fn port:%d fliflo size is:%d",
1143 c,(c > 31 ? c:'.'),
1144 port,fliflo_buff_size(&SCC_READ[port]));
1145
1146 return c;
1147 }
1148 }
1149
1150 regnum=scc_w[port].s.wr0.r.reg; if (scc_w[port].s.wr0.r.cmd==1) {regnum|=8; scc_w[port].s.wr0.r.cmd=0;}
1151 DEBUG_LOG(0,"SRC:SCC: access:%d port %d regnum:%d wr0 is %02x",access,port,regnum,scc_w[port].w[0]);
1152 scc_w[port].s.wr0.r.reg=0; // reset register pointer back to zero for next round.
1153 if (scc_w[port].s.wr0.r.cmd==1) scc_w[port].s.wr0.r.cmd=0; // reset highpoint for next command
1154
1155 #ifdef ENHANCED_Z85C30
1156 if ( (scc_r[port].w[15] & 4)==0) // WR15 D2=0
1157 #endif
1158 switch (regnum)
1159 {
1160 case 4: DEBUG_LOG(0,"Read from register 4");
1161 #ifdef ENHANCED_Z85C30
1162 if (scc_r[port].w[15] & 4) return BITORD((scc_w[port].w[4]));
1163 #endif
1164
1165 // fall through to return rr0.
1166
1167 case 0: DEBUG_LOG(0,"Read from register 0");
1168
1169 // need to insert other pollers here for polled I/O
1170 //poll_telnet_serial_read(port);
1171 #ifndef __MSVCRT__
1172 if (serial_b==SCC_TELNETD)
1173 { int data=poll_telnet_serial_read(0);
1174 if (data>-1)
1175 {
1176 fliflo_buff_add(&SCC_READ[0],(uint8)(data) & scc_bits_per_char_mask[0]);
1177
1178 DEBUG_LOG(0,"Received %02x %c from scc port:%d",
1179 (uint8)(data),
1180 ((data >31) ? ((uint8)(data)):'.'),
1181 port);
1182 }
1183
1184 }
1185
1186 if (serial_a==SCC_TELNETD)
1187 {
1188 int data=poll_telnet_serial_read(1);
1189 if (data>-1) fliflo_buff_add(&SCC_READ[1],(uint8)(data) & scc_bits_per_char_mask[1]);
1190 }
1191 #endif
1192
1193 scc_r[port].s.rr0.r.rx_char_available= fliflo_buff_has_data(&SCC_READ[port]);
1194 scc_r[port].s.rr0.r.tx_buffer_empty = fliflo_buff_is_empty(&SCC_WRITE[port]);
1195 scc_r[port].s.rr0.r.dcd=get_dcd(port);
1196 scc_r[port].s.rr0.r.cts=get_cts(port);
1197 scc_r[port].s.rr0.r.break_abort=get_break(port);
1198 scc_r[port].s.rr0.r.sync_hunt=0;
1199 scc_r[port].s.rr0.r.tx_underrun_eom=(!scc_w[port].s.wr5.r.txenable);
1200 scc_r[port].s.rr0.r.zero_count=0;
1201
1202
1203
1204
1205 // sync hunt fakeout
1206 scc_r[port].s.rr0.r.sync_hunt=(scc_r[port].s.rr0.r.cts && scc_r[port].s.rr0.r.dcd);
1207
1208 DEBUG_LOG(0,"RR0[%d] 0:rx_char_available:%d, 2:tx_buffer_empty:%d, 3:dcd:%d, 5:cts:%d, 7:break_abort:%d, 4:sync_hunt:%d, 6:tx_underrun_eom:%d, 1:zero_count:%d",
1209 port,
1210 scc_r[port].s.rr0.r.rx_char_available,
1211 scc_r[port].s.rr0.r.tx_buffer_empty,
1212 scc_r[port].s.rr0.r.dcd,
1213 scc_r[port].s.rr0.r.cts,
1214 scc_r[port].s.rr0.r.break_abort,
1215 scc_r[port].s.rr0.r.sync_hunt,
1216 scc_r[port].s.rr0.r.tx_underrun_eom,
1217 scc_r[port].s.rr0.r.zero_count);
1218
1219 if (scc_r[port].s.rr0.r.rx_char_available)
1220 {
1221 DEBUG_LOG(0,"RR0[%d] rcv buffer size is:%d bit0:rx_char_available:%d, 2:tx_buffer_empty:%d, 3:dcd:%d, 5:cts:%d, 7:break_abort:%d, 4:sync_hunt:%d, 6:tx_underrun_eom:%d, 1:zero_count:%d",
1222 port,fliflo_buff_size(&SCC_READ[port]),
1223 scc_r[port].s.rr0.r.rx_char_available,
1224 scc_r[port].s.rr0.r.tx_buffer_empty,
1225 scc_r[port].s.rr0.r.dcd,
1226 scc_r[port].s.rr0.r.cts,
1227 scc_r[port].s.rr0.r.break_abort,
1228 scc_r[port].s.rr0.r.sync_hunt,
1229 scc_r[port].s.rr0.r.tx_underrun_eom,
1230 scc_r[port].s.rr0.r.zero_count);
1231 }
1232
1233 return BITORD(scc_r[port].r[0]);
1234
1235 case 5: DEBUG_LOG(0,"Read from register 5");
1236 #ifdef ENHANCED_Z85C30
1237 if (scc_r[port].w[15] & 4) return BITORD((scc_w[port].w[5]));
1238 #endif
1239 // fall through to return rr1
1240
1241 case 1: DEBUG_LOG(0,"Read from register 1");
1242
1243 scc_r[port].s.rr1.r.rx_overrun_error=fliflo_buff_is_full(&SCC_READ[port]);
1244 scc_r[port].s.rr1.r.parity_error=0; // should we check for this? We can check this one
1245 scc_r[port].s.rr1.r.crc_framing_error=0; // only for sdlc?
1246
1247 scc_r[port].s.rr1.r.all_sent=fliflo_buff_is_empty(&SCC_WRITE[port]);
1248
1249
1250 scc_r[port].s.rr1.r.residue_code_2=0; // for sdlc only, not implemented here.
1251 scc_r[port].s.rr1.r.residue_code_1=1;
1252 scc_r[port].s.rr1.r.residue_code_0=1;
1253
1254
1255 DEBUG_LOG(0,"RR1: all_sent:%d, residue_code_2:%d, residue_code_1:%d, residue_code_0:%d, parity_error:%d, rx_overrun_error:%d, crc_framing_error:%d, sdlc_end_of_frame:%d",
1256 scc_r[port].s.rr1.r.all_sent,
1257 scc_r[port].s.rr1.r.residue_code_2,
1258 scc_r[port].s.rr1.r.residue_code_1,
1259 scc_r[port].s.rr1.r.residue_code_0,
1260 scc_r[port].s.rr1.r.parity_error,
1261 scc_r[port].s.rr1.r.rx_overrun_error,
1262 scc_r[port].s.rr1.r.crc_framing_error,
1263 scc_r[port].s.rr1.r.sdlc_end_of_frame);
1264
1265 return BITORD(scc_r[port].r[1]);
1266
1267 case 6: DEBUG_LOG(0,"Read from register 6");
1268 #ifdef ENHANCED_Z85C30
1269 if (scc_r[port].w[15] & 4) return BITORD((scc_r[port].r[6]));
1270 #endif
1271 // fall through to rr2
1272
1273 case 2: DEBUG_LOG(0,"Read from register 2");
1274
1275 //scc_r[port].r[2]=scc_w[0].w[2]; // there is only one port 2!
1276 DEBUG_LOG(0,"IRQ vector bits:%d,%d,%d,%d,%d,%d,%d,%d",
1277 scc_w[0].s.wr2.r.v0,scc_w[0].s.wr2.r.v1,scc_w[0].s.wr2.r.v2,scc_w[0].s.wr2.r.v3,
1278 scc_w[0].s.wr2.r.v4,scc_w[0].s.wr2.r.v5,scc_w[0].s.wr2.r.v6,scc_w[0].s.wr2.r.v7);
1279
1280 /*-----------------3/31/2005 2:24PM-----------------
1281 * Unimplemented code
1282 * --------------------------------------------------
1283 if (scc_w[0].s.wr9.r.soft_int_ack) scc_r[port].r[3]=0; ???????????
1284 *
1285 * ***************
1286 *** Bit 5: Software Interrupt Acknowledge control bit
1287 *** If bit D5 is set, reading Read Register 2 (RR2) results in an
1288 *** interrupt acknowledge cycle to be executed internally. Like
1289 *** a hardware INTACK cycle, a software acknowledge caus-
1290 *** es the INT pin to return High, the IEO pin to go Low, and
1291 *** sets the IUS latch for the highest priority interrupt pending.
1292 */
1293
1294
1295 //V3|V2|V1 Status High/Status Low =0
1296 //V4|V5|V6 Status High/Status Low =1
1297
1298 DEBUG_LOG(0,"About to read register 2 which contains %02x, (reordered is %02x) on port %d - z8530_last_irq_status_bits is:%02x",
1299 scc_r[port].r[2],BITORD(scc_r[port].r[2]),
1300 port,z8530_last_irq_status_bits);
1301
1302
1303 if (port)
1304 {
1305 // if software interrupt ack is on, it clears the IRQ on access to rr2.
1306 if (scc_w[1].s.wr9.r.soft_int_ack) {scc_r[0].r[2]=0; z8530_last_irq_status_bits=0; scc_r[port].r[2]=0;}
1307 return scc_w[1].s.wr2.v;
1308 }
1309 else
1310 {
1311
1312 uint8 r2=BITORD(scc_r[port].r[2]);
1313
1314 scc_r[0].r[2]=0; /// 200608-8 <--- here here here here
1315 DEBUG_LOG(0,"PORT B, will include status bits");
1316 if (scc_w[0].s.wr9.r.status_hi_lo)
1317 { DEBUG_LOG(0,"HILO is HI - status bits in v4,5,6");
1318 scc_r[0].s.rr2.r.v4=(z8530_last_irq_status_bits & 8) ? 1:0;
1319 scc_r[0].s.rr2.r.v5=(z8530_last_irq_status_bits & 4) ? 1:0;
1320 scc_r[0].s.rr2.r.v6=(z8530_last_irq_status_bits & 2) ? 1:0;
1321 }
1322 else
1323 {
1324 DEBUG_LOG(0,"HILO is LO - status bits in v1,2,3");
1325 scc_r[0].s.rr2.r.v1=(z8530_last_irq_status_bits & 2) ? 1:0;
1326 scc_r[0].s.rr2.r.v2=(z8530_last_irq_status_bits & 4) ? 1:0;
1327 scc_r[0].s.rr2.r.v3=(z8530_last_irq_status_bits & 8) ? 1:0;
1328 }
1329 DEBUG_LOG(0,"Returning %02x which reordered is %02x from register %d on port %d",
1330 scc_r[port].r[2],BITORD(scc_r[port].r[2]),
1331 2,port);
1332
1333
1334 // if software interrupt ack is on, it clears the IRQ on access to rr2.
1335 if (scc_w[1].s.wr9.r.soft_int_ack) {scc_r[0].r[2]=0; z8530_last_irq_status_bits=0; scc_r[port].r[2]=0;}
1336
1337 DEBUG_LOG(0,"before exit, z8530_last_irq_status_bits:%d rr2=%02x returning:%02x",z8530_last_irq_status_bits,scc_r[port].r[2],r2);
1338
1339 return r2;
1340 }
1341
1342 case 7: DEBUG_LOG(0,"Read from register 7");
1343 #ifdef ENHANCED_Z85C30
1344 if (scc_r[port].w[15] & 4) return BITORD((scc_r[port].r[7]));
1345 #endif
1346 // fall through to rr3
1347
1348 case 3: DEBUG_LOG(0,"Read from register 3 irq pending");
1349 {
1350 uint8 ret=BITORD(scc_r[port].r[3]); // IRQ pending. These must be set by loop IRQ routine!
1351 scc_r[port].r[3]=0;
1352 return ret;
1353 }
1354
1355 case 8: DEBUG_LOG(0,"Read from register 8");
1356 scc_r[port].r[8]=fliflo_buff_peek(&SCC_READ[port]);
1357 return scc_r[port].r[8];
1358
1359 case 14: DEBUG_LOG(0,"Read from register 14");
1360 #ifdef ENHANCED_Z85C30
1361 if (scc_r[port].w[15] & 4) return BITORD((scc_w[port].w.w7prime));
1362 #endif
1363 // fall through for rr10
1364 case 10: DEBUG_LOG(0,"Read from register 10 - returning 0 - sdlc not implemented");
1365 return 0;
1366 // return BITORD(scc_r[port].r[10]); // sdlc not implemented
1367
1368
1369 case 12: DEBUG_LOG(0,"Read from register 12");
1370 return BITORD(scc_w[port].w[12]); // return wr12
1371
1372 case 9: DEBUG_LOG(0,"Read from register 9");
1373 #ifdef ENHANCED_Z85C30
1374 if (scc_r[port].w[15] & 4) return BITORD((scc_w[port].w[3]));
1375 #endif
1376 // fall through to 13
1377 case 13: DEBUG_LOG(0,"Read from register 13"); // return wr13
1378 return BITORD(scc_w[port].w[13]);
1379
1380
1381 case 11: DEBUG_LOG(0,"Read from register 11");
1382 #ifdef ENHANCED_Z85C30
1383 if (scc_r[port].w[15] & 4) return BITORD((scc_w[port].w[10]));
1384 #endif
1385 // fall through to rr15
1386 case 15: DEBUG_LOG(0,"Read from register 15");
1387 return BITORD(scc_w[port].w[15]); // return wr15
1388 }
1389
1390
1391 #ifdef ENHANCED_Z85C30
1392 // This is not needed for the Lisa, but it's here for future reuse of this code.
1393 if ( (scc_w[port].w[15] & 4)==4 && (scc[port].w[17] & 32)==0) // WR15 D2=1
1394 switch ( regnum)
1395 {
1396 case 0: return scc_r[port].r[0];
1397 case 1: return scc_r[port].r[1];
1398 case 2: return scc_r[port].r[2];
1399 case 3: return scc_r[port].r[3];
1400 case 4: return (scc_r[port].r[0]);
1401 case 5: return (scc_r[port].r[1]);
1402 case 6: return scc_r[port].r[6];
1403 case 7: return scc_r[port].r[7];
1404 case 8: return scc_r[port].r[8];
1405 case 9: return (scc_r[port].r[13]);
1406 case 10: return scc_r[port].r[10];
1407 case 11: return (scc_r[port].r[15]);
1408 case 12: return scc_r[port].r[12];
1409 case 13: return scc_r[port].r[13];
1410 case 14: return scc_r[port].r[14];
1411 case 15: return scc_r[port].r[15];
1412 }
1413
1414 if ( (scc_w[port].w[15] & 4)==4 && (scc_w[port].w[17] & 32)==32) // WR15 D2=1, WR7' D6=1
1415 switch (regnum)
1416 {
1417 case 0: return scc_r[port].r[0];
1418 case 1: return scc_r[port].r[1];
1419 case 2: return scc_r[port].r[2];
1420 case 3: return scc_r[port].r[3];
1421 case 4: return (scc_w[port].w[4]);
1422 case 5: return (scc_w[port].w[5]);
1423 case 6: return scc_r[port].r[6];
1424 case 7: return scc_r[port].r[7];
1425 case 8: return scc_r[port].r[8];
1426 case 9: return (scc_w[port].w[3]);
1427 case 10: return scc_r[port].r[10];
1428 case 11: return (scc_w[port].w[10]);
1429 case 12: return scc_r[port].r[12];
1430 case 13: return scc_r[port].r[13];
1431 case 14: return (scc_w[port].w[17]);
1432 case 15: return scc_r[port].r[15];
1433 }
1434
1435 } // end of read fn
1436 #endif
1437 DEBUG_LOG(0,"Oops! There's a bug somewhere! cases failed!");
1438 return 0;
1439 }
1440
1441 /*
1442 rs232 loopback plug emulation
1443 TX->RX
1444 RTS->CTS
1445 DTR->CD+DSR+RI
1446 */
1447
1448
1449
1450 // interface functions to host machine -- need to fill these in!
1451
1452 void send_break(uint8 port) {DEBUG_LOG(0,"generic Send Break on port %d", port); return ;}
1453 void set_dtr(uint8 port, uint8 value) {DEBUG_LOG(0,"generic Set DTR on port %d to %d", port,value); return ;}
1454 void set_rts(uint8 port, uint8 value) {DEBUG_LOG(0,"generic Set RTS on port %d to %d", port,value); return ;}
1455
1456 int get_dcd(uint8 port) {DEBUG_LOG(0,"generic Get Carrier Detect on port %d is %d",port,
1457 scc_r[port].s.rr0.r.dcd);
1458 scc_r[port].s.rr0.r.dcd=1;
1459
1460 if ((port && scc_a_IW!=-1) || (!port && scc_b_IW!=-1)) return 1; //0,0 1,1 no good
1461
1462 return scc_r[port].s.rr0.r.dcd; ;}
1463
1464 int get_cts(uint8 port) {DEBUG_LOG(0,"generic Get Clear to send on port %d is %d", port,
1465 scc_r[port].s.rr0.r.cts);
1466
1467 if ((port && scc_a_IW!=-1) || (!port && scc_b_IW!=-1)) return 0;
1468
1469
1470 //return scc_r[port].s.rr0.r.cts;
1471 return 1; /*2006.07.11*/ ;}
1472
1473 int get_break(uint8 port) {DEBUG_LOG(0,"generic Get brk status on port %d", port);
1474
1475 // if break - also set this::: use this code when enabling break support
1476 // if (scc_w[port].wr15.s.break_abort_interrupt_enable) scc_r[1].s.rr3.ch_b_ext_status_irq_pending=1;
1477
1478
1479 return 0;}
1480 void signal_parity_error(uint8 port) {DEBUG_LOG(0,"generic Signal parity error port %d", port); return ;}
1481 void signal_crc_error(uint8 port) {DEBUG_LOG(0,"generic Signal CRC error on port %d", port); return ;}
1482
1483 void set_even_parity(uint8 port) {DEBUG_LOG(0,"generic Set even parity on port %d", port); return ;}
1484 void set_odd_parity(uint8 port) {DEBUG_LOG(0,"generic Set odd parity on port %d", port); return ;}
1485 void set_no_parity(uint8 port) {DEBUG_LOG(0,"generic Set no parity on port %d", port); return ;}
1486
1487
1488 void set_dtr_loopbackplug(uint8 port, uint8 value)
1489 { scc_r[port].s.rr0.r.dcd=value;
1490 DEBUG_LOG(0,"Set loopback DTR on port %d to %d", port,value); return ;}
1491
1492 void set_rts_loopbackplug(uint8 port, uint8 value)
1493 { scc_r[port].s.rr0.r.cts=value;
1494
1495 // weird loopback test cable
1496 if (0==port && value==0) scc_r[port].s.rr0.r.cts=1;
1497 if (0==port && 0==scc_w[port].s.wr5.r.RTS && 0!=scc_w[port].s.wr5.r.DTR)
1498 scc_r[port].s.rr0.r.cts=0;
1499
1500 DEBUG_LOG(0,"Set loopback RTS on port %d to %d", port,value); return ;}
1501
1502
1503 void set_baud_rate(int port, uint32 baud) { } // dummy function
1504
1505 void set_bits_per_char(uint8 port, uint8 bitsperchar)
1506 {
1507 DEBUG_LOG(0,"Set bits/char on port %d to %d", port,bitsperchar);
1508 switch(bitsperchar)
1509 {
1510 case 5: scc_bits_per_char_mask[port]= 31;return;
1511 case 6: scc_bits_per_char_mask[port]= 63;return;
1512 case 7: scc_bits_per_char_mask[port]=127;return;
1513 case 8: scc_bits_per_char_mask[port]=255;return;
1514 default: DEBUG_LOG(0,"*BUG* bits/char was set to %d",bitsperchar);
1515 scc_bits_per_char_mask[port]=255;return;
1516 }
1517 }
1518
1519 void set_stop_bits(uint8 port,uint8 stopbits) {return;} //0=0 no stop bits,1=1 stop bit,2=1.5 stop bits,3=2 stop bits
1520
1521
1522
1523 char read_serial_port_nothing(int8 port) {return 0; }
1524 char read_serial_port_imagewriter(int8 port) {return 0; }
1525 char read_serial_port_loopbackplug(int8 port) {return -1;} // this should never be called!
1526 char read_serial_port_localport(int8 port)
1527 {
1528 if (port)
1529 { if (scc_a_port_F) return fgetc(scc_a_port_F); else return 0; }
1530 else
1531 { if (scc_b_port_F) return fgetc(scc_b_port_F); else return 0; }
1532
1533 return 0;
1534 }
1535
1536
1537
1538 char read_serial_port(int8 port) // generic handler
1539 {
1540
1541 DEBUG_LOG(0,"r %p %p w %p %p",SCC_READ[0].buffer,&SCC_READ[1].buffer,SCC_WRITE[0].buffer,SCC_WRITE[1].buffer);
1542 DEBUG_LOG(0,"SRC:port:%d",port);
1543 if (port)
1544 {
1545 if (serial_a==SCC_NOTHING) return 0;
1546 if (serial_a==SCC_IMAGEWRITER) return 0;
1547 if (serial_a==SCC_LOCALPORT)
1548 {if (scc_a_port_F) return fgetc(scc_a_port_F); else return 0;}
1549 }
1550 else
1551 {
1552
1553 if (serial_b==SCC_NOTHING) return 0;
1554 if (serial_b==SCC_IMAGEWRITER) return 0;
1555 if (serial_b==SCC_LOCALPORT)
1556 {if (scc_b_port_F) return fgetc(scc_b_port_F);}
1557 }
1558
1559 return 0;
1560 }
1561
1562
1563
1564 void write_serial_port_nothing(int8 port, char data) {DEBUG_LOG(0,"wrote %02x to port %d",data,port);return;}
1565 void write_serial_port_loopbackplug(int8 port, char data) {DEBUG_LOG(0,"wrote %02x to port %d",data,port); fliflo_buff_add(&SCC_READ[(!port)&1],data & scc_bits_per_char_mask[(!port)&1]);}
1566
1567 void write_serial_port_imagewriter(int8 port, char data)
1568 { if (port) { DEBUG_LOG(0,"wrote %02x to port %d",data,port);
1569 if (scc_a_IW!=-1)
1570 {DEBUG_LOG(0,"Write %02x to imagewriter",data); ImageWriterLoop(scc_a_IW,data);} }
1571
1572 else { DEBUG_LOG(0,"wrote %02x to port %d",data,port);
1573 if (scc_b_IW!=-1)
1574 {DEBUG_LOG(0,"Write %02x to imagewriter",data); ImageWriterLoop(scc_b_IW,data);} }
1575 }
1576
1577 void write_serial_port_localport(int8 port, char data)
1578 { if (port) { DEBUG_LOG(0,"wrote %02x to port %d",data,port);if (serial_a==SCC_LOCALPORT) {if (scc_a_port_F) fputc(data,scc_a_port_F); }}
1579 else { DEBUG_LOG(0,"wrote %02x to port %d",data,port);if (serial_b==SCC_LOCALPORT) {if (scc_b_port_F) fputc(data,scc_b_port_F); }}
1580 }
1581
1582 void write_serial_port(int8 port, char data)
1583 {
1584
1585 DEBUG_LOG(0,"r %p %p w %p %p",SCC_READ[0].buffer,&SCC_READ[1].buffer,SCC_WRITE[0].buffer,SCC_WRITE[1].buffer);
1586 DEBUG_LOG(0,"SRC:port:%d",port);
1587 if (port)
1588 {
1589 if (serial_a==SCC_NOTHING) return;
1590 if (serial_a==SCC_LOOPBACKPLUG) {fliflo_buff_add(&SCC_READ[port],data & scc_bits_per_char_mask[port]); return;}
1591 if (serial_a==SCC_IMAGEWRITER)
1592 {
1593 if (scc_a_IW!=-1) ImageWriterLoop(scc_a_IW,data);
1594 return;
1595 }
1596
1597 if (serial_a==SCC_LOCALPORT) {if (scc_a_port_F) fputc(data,scc_a_port_F);}
1598 return;
1599 }
1600 else
1601 {
1602
1603 if (serial_b==SCC_NOTHING) return;
1604 if (serial_b==SCC_LOOPBACKPLUG) {fliflo_buff_add(&SCC_READ[port],data & scc_bits_per_char_mask[port]); return;}
1605 if (serial_b==SCC_IMAGEWRITER)
1606 {
1607 if (scc_b_IW!=-1)
1608 ImageWriterLoop(scc_b_IW,data);
1609 return;
1610 }
1611 if (serial_b==SCC_LOCALPORT) {if (scc_b_port_F) fputc(data,scc_b_port_F);}
1612 }
1613
1614 return;
1615 }
1616
1617
1618
1619
1620
1621 ////////////////////////////// Telnet Server hookups - rewrite this code so it works for two ports ////////////////////////////
1622
1623
1624 #define MAX_SERIAL_PORTS 2
1625 #define MAXPENDING 1 /*Max connection requests*/
1626 #define BUFFSIZE 3 /* Telnet protocol has a max of 3 chars per block ff xx xx */
1627
1628 #define MAX_SERIAL_PORTS 2 // 14 is maximum with a 4 port serial port card in each expansion port slot,
1629 // but need details on this (ROM+schematics+mem map) before we can implement them.
1630
1631
1632
1633 int port_state[MAX_SERIAL_PORTS]; // 0=waiting for connection, 1=connected, -1=telnetd not used.
1634
1635
1636 ///// telnetd code - unix only ////////////////////////////////////////////////////////////////////////////////////////////////
1637 #ifndef __MSVCRT__
1638 struct pollfd pfd_accept[MAX_SERIAL_PORTS], pfd_recv[MAX_SERIAL_PORTS];
1639
1640 unsigned telnet_buffer[MAX_SERIAL_PORTS][BUFFSIZE];
1641
1642 struct sockaddr_in telnetserver[MAX_SERIAL_PORTS],
1643 telnetclient[MAX_SERIAL_PORTS];
1644
1645 int serversock[MAX_SERIAL_PORTS],
1646 clientsock[MAX_SERIAL_PORTS];
1647
1648
1649 // stuff to send to telnet client.
1650 char telnethax[]={0xff,0xfb,0x01,0xff,0xfb,0x03,0xff,0xfd,0x0f3};
1651
1652 char read_serial_port_telnetd(int8 port)
1653 {
1654 int c=poll_telnet_serial_read(port);
1655 return (c>-1) ? (char) c : 0;
1656 }
1657
1658
1659 void write_serial_port_telnetd(int8 port, char c)
1660 {
1661 char buffer[2];
1662 buffer[0]=c;
1663 DEBUG_LOG(0,"Write char %02x %c to port %d",c,(c>31 ? c:'.'),port);
1664 send(clientsock[port],buffer,1,0); // should this be telnetserver?
1665 }
1666
1667
1668 void init_telnet_serial_port(int portnum)
1669 {
1670 // this sets up the listener
1671
1672 ALERT_LOG(0,"Initializing telnetd for serial port #%d",portnum);
1673
1674 /*Create the TCP socket*/
1675 if ((serversock[portnum]=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP|SO_REUSEADDR)) < 0)
1676 {
1677 ALERT_LOG(0,"could not create the socket for serial port #%d - port now disabled because:%d %s",portnum,errno,strerror(errno));
1678 port_state[portnum]=-1;
1679 return;
1680 }
1681
1682 /*Construct the server sock addr_instructure*/
1683
1684 memset(&telnetserver[portnum].sin_zero,0,8); /*Clearstruct*/
1685
1686 telnetserver[portnum].sin_family=AF_INET; /*Internet/IP*/
1687 //telnetserver[portnum].sin_addr.s_addr=htonl(INADDR_ANY); /*address to listen on - want 127.0.0.1 instead!!!! */
1688 telnetserver[portnum].sin_addr.s_addr=htonl(INADDR_LOOPBACK); //htonl(INADDR_ANY); //INADDR_LOOPBACK); /*address to listen on - want 127.0.0.1 instead!!!! */
1689
1690 if (portnum) telnetserver[portnum].sin_port=htons(scc_a_telnet_port); /*serverport*/
1691 else telnetserver[portnum].sin_port=htons(scc_b_telnet_port); /*serverport*/
1692
1693 ALERT_LOG(0,"SCC-telnetd Listening on port #%04x at address:%08x (porta:%d,portb:%d :: %04x,%04x)",
1694 telnetserver[portnum].sin_port,
1695 telnetserver[portnum].sin_addr.s_addr,
1696 scc_a_telnet_port,scc_b_telnet_port,
1697 htons(scc_a_telnet_port),htons(scc_b_telnet_port)
1698 );
1699
1700 /*Bind the server socket*/
1701 if (bind(serversock[portnum],(struct sockaddr*)&telnetserver[portnum], sizeof(telnetserver[portnum])) < 0) // could not bind to the server port, so, bye bye
1702 {
1703 ALERT_LOG(0,"Cannot bind for serial port #%d - port now disabled because:%d %s",portnum,errno,strerror(errno));
1704 port_state[portnum]=-1;
1705 return;
1706 }
1707
1708 /*Listenonthetelnetserveret*/
1709
1710 if(listen(serversock[portnum],MAXPENDING)<0)
1711 { ALERT_LOG(0,"Cannot Listen for serial port #%d - port now disabled",portnum);
1712 port_state[portnum]=-1;
1713 return;
1714 }
1715
1716 // if we got here, we're all set!
1717 ALERT_LOG(0,"Serial port socket %d now initialized and waiting for a connection\n",portnum);
1718 port_state[portnum]=0;
1719 return;
1720 }
1721
1722
1723 // returns -1 if no data (or not connected), -2 if break detected, otherwise the data itself.
1724 int poll_telnet_serial_read(int portnum)
1725 {
1726 int pollret=0, received=0;
1727 unsigned char buffer[MAX_SERIAL_PORTS][3];
1728
1729 if (portnum<0 || portnum>MAX_SERIAL_PORTS)
1730 return -1; // non existant port
1731 if (port_state[portnum]==-1) return -1; // port disabled
1732
1733
1734 if (port_state[portnum]==0) // we're waiting for a telnet connection (LISTEN_STATE)
1735 {
1736 int pollret;
1737 unsigned int clientlen=sizeof(telnetclient[portnum]);
1738
1739 pfd_accept[portnum].fd=serversock[portnum];
1740 pfd_accept[portnum].events=(POLLIN|POLLPRI);
1741 //pfd1.revents
1742
1743 pollret=(poll(&pfd_accept[portnum],1,0)); // we can change this to poll all ports at once, but some may already be connected.
1744 if (pollret==0) return -1; // timeout
1745 if (pollret==-1) return -1; // error on poll
1746
1747 if (pollret>0)
1748 {
1749 /*Wait for client connection*/
1750 if((clientsock[portnum]= accept(serversock[portnum],(struct sockaddr*)&telnetclient[portnum], &clientlen))<0)
1751 return -1; // shit happens, rama, rama.
1752
1753 ALERT_LOG(0,"Serial Port #%d Client connected:%s\n",portnum,inet_ntoa(telnetclient[portnum].sin_addr));
1754 port_state[portnum]=1; // change to connected state
1755
1756 // on accept, send the telnet configuration string.
1757 send(clientsock[portnum],telnethax,9,0);
1758 return -1; // we don't yet have any useful data from the client, so return nothing.
1759 }
1760 }
1761
1762 // we're already connected, so poll for data.
1763
1764 pfd_recv[portnum].fd=clientsock[portnum];
1765 pfd_recv[portnum].events=(POLLIN|POLLPRI);
1766
1767 pollret=(poll(&pfd_recv[portnum],1,0));
1768 if (pollret==0) return -1; //timeout
1769 if (pollret< 0) return -1; // perror("got poll error doh!");
1770
1771 if (pollret>0)
1772 if (pfd_recv[portnum].revents & (POLLIN|POLLPRI)) // we got data
1773 {
1774
1775 /*Receiv emessage*/
1776
1777 if ((received=recv(clientsock[portnum],buffer[portnum],BUFFSIZE,0)) < 0) // got an error, disconnect
1778 {
1779 // close this socket and start over
1780 ALERT_LOG(0,"Failed to receive initial bytes from client, closing client connection. Bye bye.");
1781 port_state[portnum]=0;
1782 close(clientsock[portnum]);
1783 }
1784
1785 if (received>0)
1786 {
1787 if (buffer[portnum][0]==0xff) // special telnet sequence?
1788 switch (buffer[portnum][1]) // 3=^C, 8=^H
1789 {
1790 case 0xf3: return -2; // printf("break\n"); break;
1791 case 0xf1: return -1; // printf("nop\n"); break;
1792 case 0xef: return -1; // printf("eor\n"); break;
1793 case 0xee: return 3; // printf("abort\n"); break;
1794 case 0xf4: return 3; // printf("interrupt process\n"); break;
1795 case 0xf9: return -1; // printf("Go ahead\n"); break;
1796 case 0xf8: return -1; // printf("Erase Line\n"); break;
1797 case 0xf7: return 8; // printf("Erase character\n"); break;
1798 case 0xf6: return -1; // printf("Are You there?\n"); break;
1799 case 0xf5: return 3; // printf("Abort Output\n"); break;
1800
1801 case 0x00: return 0xff; // printf("sync\n"); break; // sync or maybe 0xff itself???
1802
1803 case 0xff: return 0xff; // maybe 0xff itself???
1804
1805 default: return -1; // printf("unknown\n"); break;
1806 }
1807 buffer[portnum][1]=0; buffer[portnum][2]=0; // clear remaining buffers
1808 DEBUG_LOG(0,"Got %c %02x",buffer[portnum][0],buffer[portnum][0]);
1809
1810 return buffer[portnum][0];
1811 }
1812 }
1813
1814 return -1; // nothing for the client to deal with
1815 }
1816
1817
1818 #endif
1819 /////////////////////////////////////////////////////////////////////////////
1820
1821
1822