* remote-e7000.c, ser-e7kpc.c, serial.c: Remove // comments.
[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 /*#define DEBUGIFY*/
22 #include "debugify.h"
23
24 #define RMT_DBG(x) if (remote_debug) printf_unfiltered x
25
26
27 #if defined(__GO32__) || defined(_WIN32)
28 #if defined(_WIN32)
29 /* we define the 32-bit calls which thunk to 16-bit dll calls 
30  */
31 #include "win-e7kpc.h"
32 #include "target.h"
33 #ifdef _MSC_VER
34 /* msvc uses strnicmp instead of strncasecmp */
35 #define strncasecmp strnicmp
36 #define W32SUT_32
37 #include "windefs.h"
38 #include "w32sut.h"
39 #endif
40 #include "gdbwin.h"
41
42 #else
43 #include <sys/dos.h>
44 #include "defs.h"
45 #endif /* _WIN32 */
46 #include "serial.h"
47
48
49 static int e7000pc_open PARAMS ((serial_t scb, const char *name));
50 static void e7000pc_raw PARAMS ((serial_t scb));
51 static int e7000pc_readchar PARAMS ((serial_t scb, int timeout));
52 static int e7000pc_setbaudrate PARAMS ((serial_t scb, int rate));
53 static int e7000pc_write PARAMS ((serial_t scb, const char *str, int len));
54 static void e7000pc_close PARAMS ((serial_t scb));
55 static serial_ttystate e7000pc_get_tty_state PARAMS ((serial_t scb));
56 static int e7000pc_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
57 static char *aptr PARAMS ((short p));
58
59 static int dos_async_init PARAMS ((int port));
60 static void dos_async_tx PARAMS ((const char c));
61 static int dos_async_rx PARAMS (());
62
63
64
65 #define OFF_DPD         0x0000
66 #define OFF_DDP         0x1000
67 #define OFF_CPD         0x2000
68 #define OFF_CDP         0x2400
69 #define OFF_FA          0x3000
70 #define OFF_FB          0x3002
71 #define OFF_FC          0x3004
72 #define OFF_IRQTOD      0x3008
73 #define OFF_IRQTOP      0x300a
74 #define OFF_READY       0x300c
75 #define OFF_PON         0x300e
76
77 #define IDLE       0x0000           
78 #define CMD_CI     0x4349           
79 #define CMD_CO     0x434f           
80 #define CMD_LO     0x4c4f           
81 #define CMD_LS     0x4c53           
82 #define CMD_SV     0x5356           
83 #define CMD_SS     0x5353           
84 #define CMD_OK     0x4f4b           
85 #define CMD_ER     0x4552           
86 #define CMD_NF     0x4e46           
87 #define CMD_AB     0x4142           
88 #define CMD_ED     0x4544           
89 #define CMD_CE     0x4345           
90
91 static unsigned long fa;
92 static unsigned long irqtod;
93 static unsigned long ready;
94 static unsigned long fb;
95 static unsigned long cpd ;
96 static unsigned long cdp ;
97 static unsigned long ready;
98 static unsigned long pon;
99 static unsigned long irqtop;
100 static unsigned long board_at;
101
102 #ifdef _WIN32
103 /* These routines are normally part of the go32 dos extender.
104  * We redefine them here to be calls into their Windoze equivs. */
105 static void dosmemget(int offset, int length, void *buffer);
106 static void dosmemput(const void *buffer, int length, int offset);
107
108 /* dll entry points for w32se7kpc.dll; call kernel32 to thunk for us */
109 typedef BOOL (APIENTRY * PUTREGISTER) (
110         HANDLE hModule,
111         LPCSTR lpsz16BitDLL,
112         LPCSTR lpszInitName,
113         LPCSTR lpszProcName,
114         UT32PROC * ppfn32Thunk,
115         FARPROC pfnUT32Callback,
116         LPVOID lpBuff
117         );
118
119 /* dll entry points for w95e7kpc.dll and w31e7kpc.dll */
120 HANDLE hWine7kpc = 0;
121
122 typedef int (APIENTRY * PWIN_LOAD_E7KPC) (void);
123 typedef void (APIENTRY * PWIN_UNLOAD_E7KPC) (void);
124 typedef void (APIENTRY * PWIN_MEM_GET) (unsigned char *buf, int len, int offset);
125 typedef void (APIENTRY * PWIN_MEM_PUT) (unsigned char *buf, int len, int offset);
126 typedef void (APIENTRY * PWIN_REMOTE_DEBUG) (int val);
127
128 PWIN_LOAD_E7KPC pwin_load_e7kpc=NULL;
129 PWIN_UNLOAD_E7KPC pwin_unload_e7kpc=NULL;
130 PWIN_MEM_GET pwin_mem_get=NULL;
131 PWIN_MEM_PUT pwin_mem_put=NULL;
132 PWIN_REMOTE_DEBUG pwin_remote_debug=NULL;
133
134 static int last_remote_debug = 0;
135 static int wine7kpc_loaded = 0;
136 static void win_unload_e7kpc (void);
137
138 static int win_load_e7kpc (void)
139 {
140     if (pwin_load_e7kpc && !wine7kpc_loaded)
141     {
142       wine7kpc_loaded = pwin_load_e7kpc();
143       if (wine7kpc_loaded)
144           make_final_cleanup(win_unload_e7kpc, 0);
145     }
146     return wine7kpc_loaded;
147 }
148
149 static void win_unload_e7kpc (void)
150 {
151     DBG(("win_unload_e7kpc\n"));
152     if (pwin_unload_e7kpc && wine7kpc_loaded)
153       pwin_unload_e7kpc();
154     wine7kpc_loaded = 0;
155 }
156
157 static void win_mem_get (unsigned char *buf, int offset, int len)
158 {
159     DBG(("win_mem_get(&buf=<x%x> offset=<x%x> len=<%d>)\n", buf, offset, len));
160     if (remote_debug!=last_remote_debug && pwin_remote_debug)
161     {
162         pwin_remote_debug(remote_debug);
163         last_remote_debug=remote_debug;
164     }
165     if (pwin_mem_get) 
166     {
167         pwin_mem_get (buf, offset, len);
168     }
169 }
170
171 static void win_mem_put (unsigned char *buf, int offset, int len)
172 {
173     DBG(("win_mem_put(buf=<%s> offset=<x%x> len=<%d>)\n", buf, offset, len));
174     if (remote_debug!=last_remote_debug && pwin_remote_debug)
175     {
176         pwin_remote_debug(remote_debug);
177         last_remote_debug=remote_debug;
178     }
179     if (pwin_mem_put)
180       pwin_mem_put (buf, offset, len);
181 }
182
183 static void dosmemget(int offset, int length, void *buffer)
184 {
185     win_mem_get(buffer, offset, length);
186 }
187
188 static void dosmemput(const void *buffer, int length, int offset)
189 {
190     win_mem_put((unsigned char*)buffer, offset, length);
191 }
192
193 #endif /* _WIN32 */
194
195 #define SET_BYTE(x,y)   { char _buf = y;dosmemput(&_buf,1, x);}
196 #define SET_WORD(x,y)   { short _buf = y;dosmemput(&_buf,2, x);}
197 #define GET_BYTE(x)     ( dosmemget(x,1,&bb), bb)
198 #define GET_WORD(x)     ( dosmemget(x,2,&sb), sb)
199
200 static unsigned char bb;
201 static unsigned short sb;
202
203
204 static struct sw 
205 {
206   int sw;
207   int addr;
208 } sigs[] = {
209   {0x14, 0xd0000},
210   {0x15, 0xd4000},
211   {0x16, 0xd8000},
212   {0x17, 0xdc000},
213   0};
214
215 static int
216 e7000pc_init ()
217 {
218   /* Look around in memory for the board's signature */
219
220   int try;
221   
222   DBG(("e7000pc_init()\n"));
223   for (try = 0; sigs[try].sw; try++)
224
225     {
226       int val;
227       board_at = sigs[try].addr;
228       fa = board_at + OFF_FA;
229       fb = board_at + OFF_FB;
230       cpd = board_at + OFF_CPD;
231       cdp = board_at + OFF_CDP;
232       ready =board_at + OFF_READY;
233       pon = board_at + OFF_PON;       
234       irqtop = board_at + OFF_IRQTOP;
235       irqtod = board_at + OFF_IRQTOD;
236
237       RMT_DBG(("e7000pc_init: looking for board's signature, try=%d\n", try));
238
239       val = GET_WORD (ready);
240
241       if (val == (0xaaa0  | sigs[try].sw))
242         {
243           if (GET_BYTE (pon) & 0xf)
244             {
245               SET_BYTE(fa, 0);
246               SET_BYTE (fb, 0);
247
248               SET_BYTE (irqtop, 1); /* Disable interrupts from e7000 */
249               SET_WORD (ready, 1);
250               DBG(("Yippie!  Connected :-)\n"));
251               printf_filtered ("\nConnected to the E7000PC at address 0x%x\n", 
252                                sigs[try].addr);
253               return 1;       
254             }
255           DBG(("Bummer!  e7000pc not on :-(\n"));
256           error ("The E7000 PC board is working, but the E7000 is turned off.\n");
257           return 0;
258         }
259     }
260
261   DBG(("Bummer!  Can't connect :-(\n"));
262   error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
263 and that the switch settings are correct.  Some other DOS programs can \n\
264 stop the board from working.  Try starting from a very minimal boot, \n\
265 perhaps you need to disable EMM386 over the region where the board has\n\
266 its I/O space, remove other unneeded cards, etc etc\n");
267   return 0;
268
269 }
270
271 static int pbuf_size;
272 static int pbuf_index;
273
274 static 
275 int 
276 e7000_get ()
277 {
278   static char pbuf[1000];
279   char tmp[1000];
280   int x;
281   DBG(("e7000_get()\n"));
282   if (pbuf_index < pbuf_size) 
283     {
284       x = pbuf[pbuf_index++];
285     }
286   else if ((GET_BYTE (fb)  & 1))
287     {
288       int i;
289       pbuf_size = GET_WORD(cdp + 2);
290
291       dosmemget (cdp + 8, pbuf_size + 1, tmp);
292
293       /* Tell the E7000 we've eaten */
294       SET_BYTE(fb,0);   
295       /* Swap it around */
296 /* FIXME!  We get in an infinite loop inside e7000_open...
297  * This is called from dosasync_readchar
298  * called from remote-e7000.c trying to sync up.
299  */
300       for (i = 0; i < pbuf_size; i++) 
301         {
302           pbuf[i] = tmp[i^1];
303         }
304       pbuf_index = 0;
305       x =  pbuf[pbuf_index++];
306     }
307   else 
308     { 
309       x = -1;
310     }
311   return x;
312 }
313
314 static int
315 dosasync_read (fd, buf, len, timeout)
316      int fd;
317      char *buf;
318      int len;
319      int timeout;
320
321 {
322   long now;
323   long then;
324   int i = 0;
325
326   DBG(("dosasync_read(fd=x%x,buf,len=x%x,timeout=x%x)\n",fd,len,timeout));
327   /* Then look for some more if we're still hungry */
328   time (&now);
329   then = now + timeout;
330   while (i < len)
331     {
332       int ch = e7000_get();
333       
334       /* While there's room in the buffer, and we've already
335        * read the stuff in, suck it over */
336       if (ch != -1) 
337         {
338           buf[i++] = ch;
339           while (i < len && pbuf_index < pbuf_size )
340             {
341               ch = e7000_get();
342               if (ch == -1)
343                 break;
344               buf[i++] = ch;
345             }
346         }
347
348       time (&now);
349
350       if (timeout == 0 || (now >= then && timeout > 0))
351         {
352 /* We timeout here but return i anyway...  
353  * were we supposed to send a TIMEOUT ?
354  * While syncing, len = 1 and timeout=1..
355  * so always take this path and return 1 char. 
356  */
357           DBG(("timeout; read x%x chars\n", i));
358           return i;
359         }
360     }
361   return len;
362 }
363
364
365 static int
366 dosasync_write (fd, buf, len)
367      int fd;
368      const char *buf;
369      int len;
370 {
371   int i;
372   char dummy[1000];  
373
374   DBG(("dosasync_write(fd=x%x,buf=x%x,len=x%x)\n",fd,buf,len));
375   
376   /* Construct copy locally */
377   ((short *)dummy)[0] = CMD_CI;
378   ((short *)dummy)[1] = len;
379   ((short *)dummy)[2] = 0;
380   ((short *)dummy)[3] = 0;
381   for (i = 0; i < len ; i++) 
382     {
383       dummy[8 + i ^ 1] = buf[i];
384     }
385
386   /* Wait for the card to get ready */
387   while ((GET_BYTE(fa) & 1) != 0)
388     ;
389
390   /* Blast onto the ISA card */
391   dosmemput (dummy, 8 + len + 1,  cpd);
392
393   SET_BYTE(fa, 1);
394   SET_BYTE(irqtod, 1); /* Interrupt the E7000 */
395
396   return len;
397 }
398
399
400 #ifdef _WIN32
401 static int 
402 load_wine7kpc(void)
403 {
404   char dll[64];
405
406   DBG(("load_wine7kpc()\n"));
407   if (win_host()==winnt)
408     {
409         printf_filtered( "e7000pc not supported on this host.\n" );
410         return 0;
411     }
412   if (win_host()==win32s)
413       strcpy(dll, "w31e7kpc.Dll");
414   else if (win_host()==win95)
415       strcpy(dll, "w95e7kpc.Dll");
416   else return 0;
417
418   /* load dll for windows support of e7000pc */
419   DBG(("LoadLibrary(%s)\n",dll));
420   hWine7kpc = LoadLibrary (dll);
421   if (!hWine7kpc)
422     {
423         DBG(("LoadLibrary(%s) failed\n",dll));
424         printf_filtered( "Error: unable to load %s.\n",dll);
425         return 0;
426     }
427   pwin_load_e7kpc = (PWIN_LOAD_E7KPC) GetProcAddress (hWine7kpc, "win_load_e7kpc");
428   if (!pwin_load_e7kpc)
429     {
430         DBG(("!pwin_load_e7kpc\n"));
431         printf_filtered( "Error: unable to resolve win_load_e7kpc.\n" );
432         return 0;
433     }
434   pwin_unload_e7kpc = (PWIN_UNLOAD_E7KPC) GetProcAddress (hWine7kpc, "win_unload_e7kpc");
435   if (!pwin_unload_e7kpc)
436     {
437         DBG(("!pwin_unload_e7kpc\n"));
438         printf_filtered( "Error: unable to resolve win_unload_e7kpc.\n" );
439         return 0;
440     }
441   pwin_mem_get = (PWIN_MEM_GET) GetProcAddress (hWine7kpc, "win_mem_get");
442   if (!pwin_mem_get)
443     {
444         DBG(("!pwin_mem_get\n"));
445         printf_filtered( "Error: unable to resolve win_mem_get.\n" );
446         return 0;
447     }
448   pwin_mem_put= (PWIN_MEM_PUT) GetProcAddress (hWine7kpc, "win_mem_put");
449   if (!pwin_mem_put)
450     {
451         DBG(("!pwin_mem_put\n"));
452         printf_filtered( "Error: unable to resolve win_mem_put.\n" );
453         return 0;
454     }
455   pwin_remote_debug= (PWIN_REMOTE_DEBUG) GetProcAddress (hWine7kpc, "win_remote_debug");
456   if (!pwin_remote_debug)
457     {
458         DBG(("!pwin_remote_debug\n"));
459         printf_filtered( "Error: unable to resolve win_remote_debug.\n" );
460         return 0;
461     }
462   DBG(("load_wine7kpc Done! :-)\n"));
463   return 1;
464 }
465 #endif /* _WIN32 */
466
467 static int
468 e7000pc_open (scb, name)
469      serial_t scb;
470      const char *name;
471 {
472   DBG(("e7000pc_open\n"));
473   if (strncasecmp (name, "pc", 2) != 0)
474     {
475       errno = ENOENT;
476       return -1;
477     }
478 #ifdef _WIN32
479   if (!load_wine7kpc()) /* load windows dll for e7kpc support */
480     {
481         DBG(("Error! load_wine7kpc failed\n"));
482         printf_filtered("Failed to initialize dll for e7000pc support.\n" );
483         return -1;
484     }
485   if (win_load_e7kpc () != 0)
486     {
487       errno = ENOENT;
488       return -1;
489     }
490 #endif /* _WIN32 */
491   scb->fd = e7000pc_init ();
492
493   if (!scb->fd)
494   {
495     DBG(("Error! !scb->fd\n"));
496     return -1;
497   }
498
499   DBG(("e7000pc_open done! :-)\n"));
500   return 0;
501 }
502
503 static int
504 e7000pc_noop (scb)
505      serial_t scb;
506 {
507   return 0;
508 }
509
510 static void
511 e7000pc_raw (scb)
512      serial_t scb;
513 {
514   /* Always in raw mode */
515 }
516
517 static int
518 e7000pc_readchar (scb, timeout)
519      serial_t scb;
520      int timeout;
521 {
522   char buf;
523
524  DBG(("e7000pc_readchar\n"));
525  top:
526
527   /* FIXME!  How does dosasync_read ever return 0?
528    * it always goes thru the loop once, so i>0
529    */
530   if (dosasync_read (scb->fd, &buf, 1, timeout))
531     {
532       if (buf == 0) goto top;
533       return buf;
534     }
535   else
536     return SERIAL_TIMEOUT;
537 }
538
539 struct e7000pc_ttystate {
540   int dummy;
541 };
542
543 /* e7000pc_{get set}_tty_state() are both dummys to fill out the function
544    vector.  Someday, they may do something real... */
545
546 static serial_ttystate
547 e7000pc_get_tty_state (scb)
548      serial_t scb;
549 {
550   struct e7000pc_ttystate *state;
551   DBG(("e7000pc_get_tty_state\n"));
552
553   state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
554
555   return (serial_ttystate) state;
556 }
557
558 static int
559 e7000pc_set_tty_state (scb, ttystate)
560      serial_t scb;
561      serial_ttystate ttystate;
562 {
563   return 0;
564 }
565
566 static int
567 e7000pc_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
568      serial_t scb;
569      serial_ttystate new_ttystate;
570      serial_ttystate old_ttystate;
571 {
572   return 0;
573 }
574
575 static void
576 e7000pc_print_tty_state (scb, ttystate)
577      serial_t scb;
578      serial_ttystate ttystate;
579 {
580   /* Nothing to print.  */
581   return;
582 }
583
584 static int
585 e7000pc_setbaudrate (scb, rate)
586      serial_t scb;
587      int rate;
588 {
589   return 0;
590 }
591
592 static int
593 e7000pc_write (scb, str, len)
594      serial_t scb;
595      const char *str;
596      int len;
597 {
598   DBG(("e7000pc_write(scb,str=%s,len=x%x)\n",str,len));
599   dosasync_write (scb->fd, str, len);
600
601   return 0;
602 }
603
604 static void
605 e7000pc_close (scb)
606      serial_t scb;
607 {
608   DBG(("e7000pc_close\n"));
609 #ifdef _WIN32
610   win_unload_e7kpc ();
611 #endif
612 }
613
614 static struct serial_ops e7000pc_ops =
615 {
616   "pc",
617   0,
618   e7000pc_open,
619   e7000pc_close,
620   e7000pc_readchar,
621   e7000pc_write,
622   e7000pc_noop,                 /* flush output */
623   e7000pc_noop,                 /* flush input */
624   e7000pc_noop,                 /* send break -- currently used only for nindy */
625   e7000pc_raw,
626   e7000pc_get_tty_state,
627   e7000pc_set_tty_state,
628   e7000pc_print_tty_state,
629   e7000pc_noflush_set_tty_state,
630   e7000pc_setbaudrate,
631 };
632
633 void
634 _initialize_ser_e7000pc ()
635 {
636   serial_add_interface (&e7000pc_ops);
637 }
638 #else
639
640 void
641 _initialize_ser_e7000pc ()
642 {
643
644 }
645 #endif /* defined(__GO32__) || defined(_WIN32) */