* remote-hms.c, ser-go32.c, serial.h: Change from
[external/binutils.git] / gdb / ser-go32.c
1 /* Remote serial interface for GO32, for GDB, the GNU Debugger.
2    Copyright 1992 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /* This file shows most of the obvious problems of code written for
21    the IBM PC.  FIXME.    -- gnu@cygnus.com, Sep92 */
22
23 #include "defs.h"
24 #include "serial.h"
25
26 #include <sys/dos.h>
27
28 #define SIGNATURE 0x4154
29 #define VERSION 1
30 #define OFFSET 0x104
31
32 /*#define MONO 1*/
33
34 #define dprintf if(0)printf
35
36 #ifdef __GNUC__
37 #define far
38 #define peek(a,b) (*(unsigned short *)(0xe0000000 + (a)*16 + (b)))
39 #endif
40
41 typedef struct {
42   short jmp_op;
43   short signature;
44   short version;
45   short buffer_start;
46   short buffer_end;
47   short getp;
48   short putp;
49   short iov;
50 } ASYNC_STRUCT;
51
52 static ASYNC_STRUCT far *async;
53 static int iov;
54 #define com_rb  iov
55 #define com_tb  iov
56 #define com_ier iov+1
57 #define com_ifr iov+2
58 #define com_bfr iov+3
59 #define com_mcr iov+4
60 #define com_lsr iov+5
61 #define com_msr iov+6
62
63 static int fd;
64
65
66 #if MONO
67 #include <sys/pc.h>
68 static int mono_pos=0;
69 #define mono_rx 0x07
70 #define mono_tx 0x70
71
72 void
73 mono_put(char byte, char attr)
74 {
75   ScreenSecondary[320+mono_pos+80] = 0x0720;
76   ScreenSecondary[320+mono_pos] = (attr<<8) | (byte&0xff);
77   mono_pos = (mono_pos+1) % 1200;
78 }
79
80 #endif
81
82 static char far *
83 aptr(short p)
84 {
85 #ifdef __GNUC__
86   return (char *)((unsigned)async - OFFSET + p);
87 #else
88   return (char far *)MK_FP(FP_SEG(async), p);
89 #endif
90 }
91
92 static ASYNC_STRUCT far *
93 getivec(int which)
94 {
95   ASYNC_STRUCT far *a;
96
97   if (peek(0, which*4) != OFFSET)
98     return 0;
99 #ifdef __GNUC__
100   a = (ASYNC_STRUCT *)(0xe0000000 + peek(0, which*4+2)*16 + peek(0, which*4));
101
102 #else
103   a = (ASYNC_STRUCT far *)MK_FP(peek(0,which*4+2),peek(0,which*4));
104 #endif
105   if (a->signature != SIGNATURE)
106     return 0;
107   if (a->version != VERSION)
108     return 0;
109   return a;
110 }
111
112 int
113 dos_async_init()
114 {
115   int i;
116   ASYNC_STRUCT far *a1;
117   ASYNC_STRUCT far *a2;
118   a1 = getivec(12);
119   a2 = getivec(11);
120   async = 0;
121   if (a1)
122     async = a1;
123   if (a2)
124     async = a2;
125   if (a1 && a2)
126   {
127     if (a1 < a2)
128       async = a1;
129     else
130       async = a2;
131   }
132   if (async == 0)
133   {
134     error("GDB can not connect to asynctsr program, check that it is installed\n\
135 and that serial I/O is not being redirected (perhaps by NFS)\n\n\
136 example configuration:\n\
137 C> mode com2:9600,n,8,1,p\n\
138 C> asynctsr 2\n\
139 C> gdb \n");
140
141   }
142   iov = async->iov;
143   outportb(com_ier, 0x0f);
144   outportb(com_bfr, 0x03);
145   outportb(com_mcr, 0x0b);
146   async->getp = async->putp = async->buffer_start;
147   
148 #if MONO
149   for (i=0; i<1200; i++)
150     ScreenSecondary[320+i] = 0x0720;
151 #endif
152   if (iov > 0x300)
153     return 1;
154   else
155     return 2;
156 }
157
158 void
159 dos_async_tx(char c)
160 {
161   dprintf("dos_async_tx: enter %x - with IOV %x", c, com_lsr);
162   fflush(stdout);
163   while (~inportb(com_lsr) & 0x20);
164   outportb(com_tb, c);
165 #if MONO
166   mono_put(c, mono_tx);
167 #endif
168   dprintf("exit\n");
169 }
170
171 int
172 dos_async_ready()
173 {
174   return (async->getp != async->putp);
175 }
176
177 int
178 dos_async_rx()
179 {
180   char rv;
181   dprintf("dos_async_rx: enter - ");
182   fflush(stdout);
183   while (!dos_async_ready())
184    if (kbhit())
185    {
186      printf("abort!\n");
187      return 0;
188    }
189   dprintf("async=%x getp=%x\n", async, async->getp);
190   fflush(stdout);
191   rv = *aptr(async->getp++);
192 #if MONO
193   mono_put(rv, mono_rx);
194 #endif
195   if (async->getp >= async->buffer_end)
196    async->getp = async->buffer_start;
197   dprintf("exit %x\n", rv);
198   return rv;
199 }
200
201 int
202 dos_kb_ready()
203 {
204   return (peek(0x40,0x1a) != peek(0x40,0x1c));
205 }
206
207 int
208 dos_kb_rx()
209 {
210 #ifdef __GNUC__
211   return getkey();
212 #else
213   return getch();
214 #endif
215 }
216
217 int
218 dosasync_read (int fd, char *buffer, int length, int timeout)
219 {
220   long now, then;
221   int l = length;
222   time (&now);
223   then = now+timeout;
224   dprintf("dosasync_read: enter(%d,%d)\n", length, timeout);
225   while (l--)
226   {
227     if (timeout)
228     {
229       while (!dos_async_ready())
230       {
231         time (&now);
232         if (now == then)
233         {
234           dprintf("dosasync_read: timeout(%d)\n", length-l-1);
235           return length-l-1;
236         }
237       }
238     }
239     *buffer++ = dos_async_rx();
240   }
241   dprintf("dosasync_read: exit %d\n", length);
242   return length;
243 }
244
245 int
246 dosasync_write(int fd, const char *buffer, int length)
247 {
248   int l = length;
249   while (l--)
250    dos_async_tx(*buffer++);
251   return length;
252 }
253
254
255
256 char *
257 strlwr(char *s)
258 {
259   char *p = s;
260   while (*s)
261   {
262     if ((*s >= 'A') && (*s <= 'Z'))
263       *s += 'a'-'A';
264     s++;
265   }
266   return p;
267 }
268
269 sigsetmask()
270 {
271 }
272 \f
273 const char *
274 serial_default_name ()
275 {
276   return "com1";
277 }
278
279
280 void
281 serial_raw ()
282 {
283   /* Always in raw mode */
284 }
285
286
287 int
288 serial_open (name)
289       const char *name;
290 {
291   fd = dos_async_init();
292   if (fd) return 1;
293   return 0;
294 }
295
296 int
297 serial_readchar (to)
298       int to;
299 {
300   char buf;
301   if (dosasync_read(fd, &buf, 1, to))  
302     return buf;
303   else
304     return -2; /* Timeout, I guess */
305 }
306
307 int
308 serial_setbaudrate (rate)
309       int rate;
310 {
311   return 0;
312 }
313
314 int
315 serial_nextbaudrate (rate)
316       int rate;
317 {
318   return 0;
319 }
320
321 int
322 serial_write (str, len)
323       const char *str;
324       int len;
325 {
326   dosasync_write(fd, str, len);
327 }
328
329 int
330 serial_close ()
331 {
332 }