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