* Makefile.in (SUBDIRS): Add mswin so that make cleanup cleans up
[platform/upstream/binutils.git] / gdb / ser-e7kpc.c
1 /* Remote serial interface using Hitachi E7000 PC ISA card in a PC
2
3    Copyright 1994 Free Software Foundation, Inc.
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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #if defined __GO32__ || defined _WIN32
22 #include "defs.h"
23 #include "serial.h"
24 #include "gdb_string.h"
25
26 /* MSVC uses strnicmp instead of strncasecmp */
27 #ifdef _MSC_VER
28 #define strncasecmp strnicmp
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31 #define W32SUT_32
32 #include <w32sut.h>
33 #endif
34
35 #ifdef __GO32__
36 #include <sys/dos.h>
37 #endif
38
39 static int e7000pc_open PARAMS ((serial_t scb, const char *name));
40 static void e7000pc_raw PARAMS ((serial_t scb));
41 static int e7000pc_readchar PARAMS ((serial_t scb, int timeout));
42 static int e7000pc_setbaudrate PARAMS ((serial_t scb, int rate));
43 static int e7000pc_write PARAMS ((serial_t scb, const char *str, int len));
44 static void e7000pc_close PARAMS ((serial_t scb));
45 static serial_ttystate e7000pc_get_tty_state PARAMS ((serial_t scb));
46 static int e7000pc_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
47 static char *aptr PARAMS ((short p));
48
49 static int dos_async_init PARAMS ((int port));
50 static void dos_async_tx PARAMS ((const char c));
51 static int dos_async_rx PARAMS (());
52
53
54
55 #define OFF_DPD         0x0000
56 #define OFF_DDP         0x1000
57 #define OFF_CPD         0x2000
58 #define OFF_CDP         0x2400
59 #define OFF_FA          0x3000
60 #define OFF_FB          0x3002
61 #define OFF_FC          0x3004
62 #define OFF_IRQTOD      0x3008
63 #define OFF_IRQTOP      0x300a
64 #define OFF_READY       0x300c
65 #define OFF_PON         0x300e
66
67 #define IDLE       0x0000           
68 #define CMD_CI     0x4349           
69 #define CMD_CO     0x434f           
70 #define CMD_LO     0x4c4f           
71 #define CMD_LS     0x4c53           
72 #define CMD_SV     0x5356           
73 #define CMD_SS     0x5353           
74 #define CMD_OK     0x4f4b           
75 #define CMD_ER     0x4552           
76 #define CMD_NF     0x4e46           
77 #define CMD_AB     0x4142           
78 #define CMD_ED     0x4544           
79 #define CMD_CE     0x4345           
80
81 static unsigned long fa;
82 static unsigned long irqtod;
83 static unsigned long ready;
84 static unsigned long fb;
85 static unsigned long cpd ;
86 static unsigned long cdp ;
87 static unsigned long ready;
88 static unsigned long pon;
89 static unsigned long irqtop;
90 static unsigned long board_at;
91
92 #ifdef __GO32__
93
94 #define SET_BYTE(x,y)   { char _buf = y;dosmemput(&_buf,1, x);}
95 #define SET_WORD(x,y)   { short _buf = y;dosmemput(&_buf,2, x);}
96 #define GET_BYTE(x)     ( dosmemget(x,1,&bb), bb)
97 #define GET_WORD(x)     ( dosmemget(x,2,&sb), sb)
98 static unsigned char bb;
99 static unsigned short sb;
100
101 #else /* win32 */
102
103 #define SET_BYTE(x,y)   *(volatile unsigned char *)(x) = (y)
104 #define SET_WORD(x,y)   *(volatile unsigned short *)(x) = (y)
105 #define GET_BYTE(x)     (*(volatile unsigned char *)(x))
106 #define GET_WORD(x)     (*(volatile unsigned short *)(x))
107 #define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
108 #define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
109 #endif
110
111 static struct sw 
112 {
113   int sw;
114   int addr;
115 } sigs[] = {
116   {0x14, 0xd0000},
117   {0x15, 0xd4000},
118   {0x16, 0xd8000},
119   {0x17, 0xdc000},
120   0};
121
122 #ifndef __GO32__
123 /* Get the base of the data segment.  This is needed to calculate the offset
124    between data segment addresses and the base of linear memory, which is where
125    device registers reside.  Note that this is really only necessary for
126    Win32s, since Win95 and NT keep the data segment at linear 0.  */
127
128 static unsigned long
129 get_ds_base (void)
130 {
131   unsigned short dsval;
132   LDT_ENTRY ldt;
133   unsigned long dsbase;
134
135   __asm
136     {
137       mov dsval,ds
138     }
139
140   dsbase = 0;
141
142   GetThreadSelectorEntry (GetCurrentThread(), dsval, &ldt);
143
144   dsbase = ldt.HighWord.Bits.BaseHi << 24 | ldt.HighWord.Bits.BaseMid << 16
145              | ldt.BaseLow;
146
147   return dsbase;
148 }
149 #else /* !__GO32__ */
150 #define get_ds_base() 0
151 #endif /* __GO32__ */ 
152
153 static int
154 e7000pc_init ()
155 {
156   int try;
157   unsigned long dsbase;
158   
159   dsbase = get_ds_base ();
160
161   /* Look around in memory for the board's signature */
162
163   for (try = 0; sigs[try].sw; try++)
164     {
165       int val;
166       board_at = sigs[try].addr - dsbase;
167       fa = board_at + OFF_FA;
168       fb = board_at + OFF_FB;
169       cpd = board_at + OFF_CPD;
170       cdp = board_at + OFF_CDP;
171       ready =board_at + OFF_READY;
172       pon = board_at + OFF_PON;       
173       irqtop = board_at + OFF_IRQTOP;
174       irqtod = board_at + OFF_IRQTOD;
175       
176       val = GET_WORD (ready);
177
178       if (val == (0xaaa0  | sigs[try].sw))
179         {
180           if (GET_WORD (pon) & 0xf)
181             {
182               SET_WORD (fa, 0);
183               SET_WORD (fb, 0);
184
185               SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */
186               SET_WORD (ready, 1);
187               printf_filtered ("\nConnected to the E7000PC at address 0x%x\n", 
188                                sigs[try].addr);
189               return 1;       
190             }
191           error ("The E7000 PC board is working, but the E7000 is turned off.\n");
192           return 0;
193         }
194     }
195
196   error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
197 and that the switch settings are correct.  Some other DOS programs can \n\
198 stop the board from working.  Try starting from a very minimal boot, \n\
199 perhaps you need to disable EMM386 over the region where the board has\n\
200 its I/O space, remove other unneeded cards, etc etc\n");
201   return 0;
202
203 }
204
205 static int pbuf_size;
206 static int pbuf_index;
207
208 /* Return next byte from cdp.  If no more, then return -1.  */
209
210 static int 
211 e7000_get (void)
212 {
213   static char pbuf[1000];
214   char tmp[1000];
215   int x;
216
217   if (pbuf_index < pbuf_size) 
218     {
219       x = pbuf[pbuf_index++];
220     }
221   else if ((GET_WORD (fb) & 1))
222     {
223       int i;
224       pbuf_size = GET_WORD (cdp + 2);
225
226       dosmemget (cdp + 8, pbuf_size + 1, tmp);
227
228       /* Tell the E7000 we've eaten */
229       SET_WORD (fb, 0); 
230       /* Swap it around */
231       for (i = 0; i < pbuf_size; i++) 
232         {
233           pbuf[i] = tmp[i^1];
234         }
235       pbuf_index = 0;
236       x =  pbuf[pbuf_index++];
237     }
238   else 
239     { 
240       x = -1;
241     }
242   return x;
243 }
244
245 /* Works just like read(), except that it takes a TIMEOUT in seconds.  Note
246    that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */
247
248 static int
249 dosasync_read (fd, buf, len, timeout)
250      int fd;
251      char *buf;
252      int len;
253      int timeout;
254
255 {
256   long now;
257   long then;
258   int i = 0;
259
260   /* Then look for some more if we're still hungry */
261   time (&now);
262   then = now + timeout;
263   while (i < len)
264     {
265       int ch = e7000_get();
266       
267       /* While there's room in the buffer, and we've already
268          read the stuff in, suck it over */
269       if (ch != -1) 
270         {
271           buf[i++] = ch;
272           while (i < len && pbuf_index < pbuf_size )
273             {
274               ch = e7000_get();
275               if (ch == -1)
276                 break;
277               buf[i++] = ch;
278             }
279         }
280
281       time (&now);
282
283       if (timeout == 0)
284         return i;
285       if (now >= then && timeout > 0)
286         {
287           return i;
288         }
289     }
290   return len;
291 }
292
293
294 static int
295 dosasync_write (fd, buf, len)
296      int fd;
297      const char *buf;
298      int len;
299 {
300   int i;
301   char dummy[1000];  
302   
303   /* Construct copy locally */
304   ((short *)dummy)[0] = CMD_CI;
305   ((short *)dummy)[1] = len;
306   ((short *)dummy)[2] = 0;
307   ((short *)dummy)[3] = 0;
308   for (i = 0; i < len ; i++) 
309     {
310       dummy[8 + i ^ 1] = buf[i];
311     }
312
313   /* Wait for the card to get ready */
314   while (GET_WORD (fa) & 1) ;
315
316   /* Blast onto the ISA card */
317   dosmemput (dummy, 8 + len + 1,  cpd);
318
319   SET_WORD (fa, 1);
320   SET_WORD (irqtod, 1); /* Interrupt the E7000 */
321
322   return len;
323 }
324
325 static int
326 e7000pc_open (scb, name)
327      serial_t scb;
328      const char *name;
329 {
330   if (strncasecmp (name, "pc", 2) != 0)
331     {
332       errno = ENOENT;
333       return -1;
334     }
335
336   scb->fd = e7000pc_init ();
337
338   if (!scb->fd)
339     return -1;
340
341   return 0;
342 }
343
344 static int
345 e7000pc_noop (scb)
346      serial_t scb;
347 {
348   return 0;
349 }
350
351 static void
352 e7000pc_raw (scb)
353      serial_t scb;
354 {
355   /* Always in raw mode */
356 }
357
358 static int
359 e7000pc_readchar (scb, timeout)
360      serial_t scb;
361      int timeout;
362 {
363   char buf;
364
365  top:
366
367   if (dosasync_read (scb->fd, &buf, 1, timeout))
368     {
369       if (buf == 0) goto top;
370       return buf;
371     }
372   else
373     return SERIAL_TIMEOUT;
374 }
375
376 struct e7000pc_ttystate {
377   int dummy;
378 };
379
380 /* e7000pc_{get set}_tty_state() are both dummys to fill out the function
381    vector.  Someday, they may do something real... */
382
383 static serial_ttystate
384 e7000pc_get_tty_state (scb)
385      serial_t scb;
386 {
387   struct e7000pc_ttystate *state;
388
389   state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
390
391   return (serial_ttystate) state;
392 }
393
394 static int
395 e7000pc_set_tty_state (scb, ttystate)
396      serial_t scb;
397      serial_ttystate ttystate;
398 {
399   return 0;
400 }
401
402 static int
403 e7000pc_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
404      serial_t scb;
405      serial_ttystate new_ttystate;
406      serial_ttystate old_ttystate;
407 {
408   return 0;
409 }
410
411 static void
412 e7000pc_print_tty_state (scb, ttystate)
413      serial_t scb;
414      serial_ttystate ttystate;
415 {
416   /* Nothing to print.  */
417   return;
418 }
419
420 static int
421 e7000pc_setbaudrate (scb, rate)
422      serial_t scb;
423      int rate;
424 {
425   return 0;
426 }
427
428 static int
429 e7000pc_write (scb, str, len)
430      serial_t scb;
431      const char *str;
432      int len;
433 {
434   dosasync_write (scb->fd, str, len);
435
436   return 0;
437 }
438
439 static void
440 e7000pc_close (scb)
441      serial_t scb;
442 {
443 }
444
445 static struct serial_ops e7000pc_ops =
446 {
447   "pc",
448   0,
449   e7000pc_open,
450   e7000pc_close,
451   e7000pc_readchar,
452   e7000pc_write,
453   e7000pc_noop,                 /* flush output */
454   e7000pc_noop,                 /* flush input */
455   e7000pc_noop,                 /* send break -- currently used only for nindy */
456   e7000pc_raw,
457   e7000pc_get_tty_state,
458   e7000pc_set_tty_state,
459   e7000pc_print_tty_state,
460   e7000pc_noflush_set_tty_state,
461   e7000pc_setbaudrate,
462 };
463
464 void
465 _initialize_ser_e7000pc ()
466 {
467   serial_add_interface (&e7000pc_ops);
468 }
469 #else
470
471 void
472 _initialize_ser_e7000pc ()
473 {
474
475 }
476 #endif