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