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