OSDN Git Service

From John David Anglin:
[pf3gnuchains/pf3gnuchains3x.git] / gdb / ser-mac.c
1 /* Remote serial interface for local (hardwired) serial ports for Macintosh.
2    Copyright 1994 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.  Written by Stan Shebs.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "serial.h"
23
24 #include <Types.h>
25 #include <Devices.h>
26 /* This is the regular Mac Serial.h, but copied to a different name
27    so as not to get confused with the GDB serial.h above.  */
28 #include "MacSerial.h"
29
30 /* This is unused for now.  We just return a placeholder. */
31
32 struct mac_ttystate
33   {
34     int bogus;
35   };
36
37 static int mac_open PARAMS ((serial_t scb, const char *name));
38 static void mac_raw PARAMS ((serial_t scb));
39 static int mac_readchar PARAMS ((serial_t scb, int timeout));
40 static int mac_setbaudrate PARAMS ((serial_t scb, int rate));
41 static int mac_write PARAMS ((serial_t scb, const char *str, int len));
42 static void mac_close PARAMS ((serial_t scb));
43 static serial_ttystate mac_get_tty_state PARAMS ((serial_t scb));
44 static int mac_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
45 static char *aptr PARAMS ((short p));
46
47 short input_refnum;
48 short output_refnum;
49
50 char *mac_input_buffer;
51 char *mac_output_buffer;
52
53 static int
54 mac_open (scb, name)
55      serial_t scb;
56      const char *name;
57 {
58   OSErr err;
59
60   /* Alloc buffer space first - that way any allocation failures are
61      intercepted before the serial driver gets involved. */
62   if (mac_input_buffer == NULL)
63     mac_input_buffer = (char *) xmalloc (4096);
64   /* Match on a name and open a port. */
65   if (strcmp (name, "modem") == 0)
66     {
67       err = OpenDriver ("\p.AIn", &input_refnum);
68       if (err != 0)
69         {
70           return (-1);
71         }
72       err = OpenDriver ("\p.AOut", &output_refnum);
73       if (err != 0)
74         {
75           CloseDriver (input_refnum);
76           return (-1);
77         }
78     }
79   else if (strcmp (name, "printer") == 0)
80     {
81       err = OpenDriver ("\p.BIn", &input_refnum);
82       if (err != 0)
83         {
84           return (-1);
85         }
86       err = OpenDriver ("\p.BOut", &output_refnum);
87       if (err != 0)
88         {
89           CloseDriver (input_refnum);
90           return (-1);
91         }
92       /* fake */
93       scb->fd = 1;
94       return 0;
95     }
96   else
97     {
98       error ("You must specify a valid serial port name; your choices are `modem' or `printer'.");
99       errno = ENOENT;
100       return (-1);
101     }
102   /* We got something open. */
103   if (1 /* using custom buffer */)
104     SerSetBuf (input_refnum, mac_input_buffer, 4096);
105   /* Set to a GDB-preferred state. */
106   SerReset (input_refnum,  stop10|noParity|data8|baud9600);
107   SerReset (output_refnum, stop10|noParity|data8|baud9600);
108   {
109     CntrlParam cb;
110     struct SerShk *handshake;
111
112     cb.ioCRefNum = output_refnum;
113     cb.csCode = 14;
114     handshake = (struct SerShk *) &cb.csParam[0];
115     handshake->fXOn = 0;
116     handshake->fCTS = 0;
117     handshake->xOn = 0;
118     handshake->xOff = 0;
119     handshake->errs = 0;
120     handshake->evts = 0;
121     handshake->fInX = 0;
122     handshake->fDTR = 0;
123     err = PBControl ((ParmBlkPtr) &cb, 0);
124     if (err < 0)
125       return (-1);
126   }
127   /* fake */
128   scb->fd = 1;
129   return 0;
130 }
131
132 static int
133 mac_noop (scb)
134      serial_t scb;
135 {
136   return 0;
137 }
138
139 static void
140 mac_raw (scb)
141      serial_t scb;
142 {
143   /* Always effectively in raw mode. */
144 }
145
146 /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
147    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
148    char if successful.  Returns -2 if timeout expired, EOF if line dropped
149    dead, or -3 for any other error (see errno in that case). */
150
151 static int
152 mac_readchar (scb, timeout)
153      serial_t scb;
154      int timeout;
155 {
156   int status, n;
157   /* time_t */ unsigned long start_time, now;
158   OSErr err;
159   CntrlParam cb;
160   IOParam pb;
161
162   if (scb->bufcnt-- > 0)
163     return *scb->bufp++;
164
165   time (&start_time);
166
167   while (1)
168     {
169       cb.ioCRefNum = input_refnum;
170       cb.csCode = 2;
171       err = PBStatus ((ParmBlkPtr) &cb, 0);
172       if (err < 0)
173         return SERIAL_ERROR;
174       n = *((long *) &cb.csParam[0]);
175       if (n > 0)
176         {
177           pb.ioRefNum = input_refnum;
178           pb.ioBuffer = (Ptr) (scb->buf);
179           pb.ioReqCount = (n > 64 ? 64 : n);
180           err = PBRead ((ParmBlkPtr) &pb, 0);
181           if (err < 0)
182             return SERIAL_ERROR;
183           scb->bufcnt = pb.ioReqCount;
184           scb->bufcnt--;
185           scb->bufp = scb->buf;
186           return *scb->bufp++;
187         }
188       else if (timeout == 0)
189         return SERIAL_TIMEOUT;
190       else if (timeout == -1)
191         ;
192       else
193         {
194           time (&now);
195           if (now > start_time + timeout)
196             return SERIAL_TIMEOUT;
197         }
198       PROGRESS (1);
199     }
200 }
201
202 /* mac_{get set}_tty_state() are both dummys to fill out the function
203    vector.  Someday, they may do something real... */
204
205 static serial_ttystate
206 mac_get_tty_state (scb)
207      serial_t scb;
208 {
209   struct mac_ttystate *state;
210
211   state = (struct mac_ttystate *) xmalloc (sizeof *state);
212
213   return (serial_ttystate) state;
214 }
215
216 static int
217 mac_set_tty_state (scb, ttystate)
218      serial_t scb;
219      serial_ttystate ttystate;
220 {
221   return 0;
222 }
223
224 static int
225 mac_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
226      serial_t scb;
227      serial_ttystate new_ttystate;
228      serial_ttystate old_ttystate;
229 {
230   return 0;
231 }
232
233 static void
234 mac_print_tty_state (scb, ttystate)
235      serial_t scb;
236      serial_ttystate ttystate;
237 {
238   /* Nothing to print.  */
239   return;
240 }
241
242 /* If there is a tricky formula to relate real baud rates
243    to what the serial driver wants, we should use it.  Until
244    we get one, this table will have to do.  */
245
246 static struct {
247   int real_rate;
248   int bits;
249 } mac_baud_rate_table[] = {
250   { 57600, baud57600 },
251   { 38400, 1 },
252   { 19200, baud19200 },
253   { 9600, baud9600 },
254   { 7200, baud7200 },
255   { 4800, baud4800 },
256   { 3600, baud3600 },
257   { 2400, baud2400 },
258   { 1800, baud1800 },
259   { 1200, baud1200 },
260   { 600, baud600 },
261   { 300, baud300 },
262   { 0, 0 }
263 };
264
265 static int
266 mac_set_baud_rate (scb, rate)
267      serial_t scb;
268      int rate;
269 {
270   int i, bits;
271
272   for (i = 0; mac_baud_rate_table[i].real_rate != 0; ++i)
273     {
274       if (mac_baud_rate_table[i].real_rate == rate)
275         {
276           bits = mac_baud_rate_table[i].bits;
277           break;
278         }
279     }
280   SerReset (input_refnum,  stop10|noParity|data8|bits);
281   SerReset (output_refnum, stop10|noParity|data8|bits);
282 }
283
284 static int
285 mac_set_stop_bits (scb, num)
286      serial_t scb;
287      int num;
288 {
289   return 0;
290 }
291
292 int first_mac_write = 0;
293
294 static int
295 mac_write (scb, str, len)
296      serial_t scb;
297      const char *str;
298      int len;
299 {
300   OSErr err;
301   IOParam pb;
302
303   if (first_mac_write++ < 4)
304     {
305       sleep (1);
306     }
307   pb.ioRefNum = output_refnum;
308   pb.ioBuffer = (Ptr) str;
309   pb.ioReqCount = len;
310   err = PBWrite ((ParmBlkPtr) &pb, 0);
311   if (err < 0)
312     {
313       return 1;
314     }
315   return 0;
316 }
317
318 static void
319 mac_close (serial_t scb)
320 {
321   if (input_refnum)
322     {
323       if (1 /* custom buffer */)
324         SerSetBuf (input_refnum, mac_input_buffer, 0);
325       CloseDriver (input_refnum);
326       input_refnum = 0;
327     }
328   if (output_refnum)
329     {
330       if (0 /* custom buffer */)
331         SerSetBuf (input_refnum, mac_output_buffer, 0);
332       CloseDriver (output_refnum);
333       output_refnum = 0;
334     }
335 }
336
337 static struct serial_ops mac_ops =
338 {
339   "hardwire",
340   0,
341   mac_open,
342   mac_close,
343   mac_readchar,
344   mac_write,
345   mac_noop,                     /* flush output */
346   mac_noop,                     /* flush input */
347   mac_noop,                     /* send break -- currently only for nindy */
348   mac_raw,
349   mac_get_tty_state,
350   mac_set_tty_state,
351   mac_print_tty_state,
352   mac_noflush_set_tty_state,
353   mac_set_baud_rate,
354   mac_set_stop_bits,
355   mac_noop,                     /* wait for output to drain */
356 };
357
358 void
359 _initialize_ser_mac ()
360 {
361   serial_add_interface (&mac_ops);
362 }