* remote-e7000.c, ser-e7kpc.c, serial.c: Remove // comments.
[deliverable/binutils-gdb.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) */
This page took 0.05846 seconds and 5 git commands to generate.