* sim-options.c (standard_options): Add --endian.
[deliverable/binutils-gdb.git] / gdb / ser-e7kpc.c
CommitLineData
55679787
SC
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
6c9638b4 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
55679787 20
e36491f4 21/*#define DEBUGIFY*/
16a43bf4
DP
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)
5b59224e
DP
29/* we define the 32-bit calls which thunk to 16-bit dll calls
30 */
31#include "win-e7kpc.h"
16a43bf4
DP
32#include "target.h"
33#ifdef _MSC_VER
34/* msvc uses strnicmp instead of strncasecmp */
5b59224e 35#define strncasecmp strnicmp
16a43bf4
DP
36#define W32SUT_32
37#include "windefs.h"
38#include "w32sut.h"
39#endif
40#include "gdbwin.h"
41
5b59224e
DP
42#else
43#include <sys/dos.h>
55679787 44#include "defs.h"
16a43bf4 45#endif /* _WIN32 */
55679787 46#include "serial.h"
55679787
SC
47
48
49static int e7000pc_open PARAMS ((serial_t scb, const char *name));
50static void e7000pc_raw PARAMS ((serial_t scb));
51static int e7000pc_readchar PARAMS ((serial_t scb, int timeout));
52static int e7000pc_setbaudrate PARAMS ((serial_t scb, int rate));
53static int e7000pc_write PARAMS ((serial_t scb, const char *str, int len));
54static void e7000pc_close PARAMS ((serial_t scb));
55static serial_ttystate e7000pc_get_tty_state PARAMS ((serial_t scb));
56static int e7000pc_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
57static char *aptr PARAMS ((short p));
58
59static int dos_async_init PARAMS ((int port));
60static void dos_async_tx PARAMS ((const char c));
61static 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
91static unsigned long fa;
92static unsigned long irqtod;
93static unsigned long ready;
94static unsigned long fb;
95static unsigned long cpd ;
96static unsigned long cdp ;
97static unsigned long ready;
98static unsigned long pon;
99static unsigned long irqtop;
100static unsigned long board_at;
101
16a43bf4
DP
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. */
5b59224e
DP
105static void dosmemget(int offset, int length, void *buffer);
106static void dosmemput(const void *buffer, int length, int offset);
107
16a43bf4
DP
108/* dll entry points for w32se7kpc.dll; call kernel32 to thunk for us */
109typedef 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 */
120HANDLE hWine7kpc = 0;
121
122typedef int (APIENTRY * PWIN_LOAD_E7KPC) (void);
123typedef void (APIENTRY * PWIN_UNLOAD_E7KPC) (void);
124typedef void (APIENTRY * PWIN_MEM_GET) (unsigned char *buf, int len, int offset);
125typedef void (APIENTRY * PWIN_MEM_PUT) (unsigned char *buf, int len, int offset);
126typedef void (APIENTRY * PWIN_REMOTE_DEBUG) (int val);
127
128PWIN_LOAD_E7KPC pwin_load_e7kpc=NULL;
129PWIN_UNLOAD_E7KPC pwin_unload_e7kpc=NULL;
130PWIN_MEM_GET pwin_mem_get=NULL;
131PWIN_MEM_PUT pwin_mem_put=NULL;
132PWIN_REMOTE_DEBUG pwin_remote_debug=NULL;
133
134static int last_remote_debug = 0;
135static int wine7kpc_loaded = 0;
136static void win_unload_e7kpc (void);
137
138static int win_load_e7kpc (void)
5b59224e 139{
16a43bf4
DP
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;
5b59224e 147}
16a43bf4
DP
148
149static void win_unload_e7kpc (void)
5b59224e 150{
16a43bf4
DP
151 DBG(("win_unload_e7kpc\n"));
152 if (pwin_unload_e7kpc && wine7kpc_loaded)
153 pwin_unload_e7kpc();
154 wine7kpc_loaded = 0;
5b59224e
DP
155}
156
16a43bf4
DP
157static 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 {
16a43bf4
DP
162 pwin_remote_debug(remote_debug);
163 last_remote_debug=remote_debug;
164 }
165 if (pwin_mem_get)
166 {
16a43bf4
DP
167 pwin_mem_get (buf, offset, len);
168 }
16a43bf4
DP
169}
170
171static 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
183static void dosmemget(int offset, int length, void *buffer)
184{
185 win_mem_get(buffer, offset, length);
186}
187
188static void dosmemput(const void *buffer, int length, int offset)
189{
190 win_mem_put((unsigned char*)buffer, offset, length);
191}
192
193#endif /* _WIN32 */
5b59224e 194
55679787
SC
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
200static unsigned char bb;
201static unsigned short sb;
202
203
204static 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
215static int
216e7000pc_init ()
217{
218 /* Look around in memory for the board's signature */
219
220 int try;
221
16a43bf4 222 DBG(("e7000pc_init()\n"));
55679787
SC
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;
16a43bf4
DP
236
237 RMT_DBG(("e7000pc_init: looking for board's signature, try=%d\n", try));
238
55679787
SC
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);
16a43bf4 250 DBG(("Yippie! Connected :-)\n"));
55679787
SC
251 printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
252 sigs[try].addr);
253 return 1;
254 }
16a43bf4 255 DBG(("Bummer! e7000pc not on :-(\n"));
55679787
SC
256 error ("The E7000 PC board is working, but the E7000 is turned off.\n");
257 return 0;
258 }
259 }
260
16a43bf4 261 DBG(("Bummer! Can't connect :-(\n"));
55679787
SC
262 error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
263and that the switch settings are correct. Some other DOS programs can \n\
264stop the board from working. Try starting from a very minimal boot, \n\
265perhaps you need to disable EMM386 over the region where the board has\n\
266its I/O space, remove other unneeded cards, etc etc\n");
267 return 0;
268
269}
270
271static int pbuf_size;
272static int pbuf_index;
273
274static
275int
276e7000_get ()
277{
278 static char pbuf[1000];
279 char tmp[1000];
280 int x;
16a43bf4 281 DBG(("e7000_get()\n"));
55679787
SC
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 */
16a43bf4
DP
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 */
55679787
SC
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
314static int
315dosasync_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;
55679787 325
16a43bf4 326 DBG(("dosasync_read(fd=x%x,buf,len=x%x,timeout=x%x)\n",fd,len,timeout));
55679787
SC
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
16a43bf4 335 * read the stuff in, suck it over */
55679787
SC
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
16a43bf4 350 if (timeout == 0 || (now >= then && timeout > 0))
55679787 351 {
16a43bf4
DP
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));
55679787
SC
358 return i;
359 }
360 }
361 return len;
362}
363
364
365static int
366dosasync_write (fd, buf, len)
367 int fd;
368 const char *buf;
369 int len;
370{
371 int i;
372 char dummy[1000];
373
16a43bf4 374 DBG(("dosasync_write(fd=x%x,buf=x%x,len=x%x)\n",fd,buf,len));
55679787
SC
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
16a43bf4
DP
399
400#ifdef _WIN32
401static int
402load_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
55679787
SC
467static int
468e7000pc_open (scb, name)
469 serial_t scb;
470 const char *name;
471{
16a43bf4 472 DBG(("e7000pc_open\n"));
55679787
SC
473 if (strncasecmp (name, "pc", 2) != 0)
474 {
475 errno = ENOENT;
476 return -1;
477 }
16a43bf4
DP
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 }
5b59224e
DP
485 if (win_load_e7kpc () != 0)
486 {
487 errno = ENOENT;
488 return -1;
489 }
16a43bf4 490#endif /* _WIN32 */
55679787
SC
491 scb->fd = e7000pc_init ();
492
493 if (!scb->fd)
16a43bf4
DP
494 {
495 DBG(("Error! !scb->fd\n"));
55679787 496 return -1;
16a43bf4 497 }
55679787 498
16a43bf4 499 DBG(("e7000pc_open done! :-)\n"));
55679787
SC
500 return 0;
501}
502
503static int
504e7000pc_noop (scb)
505 serial_t scb;
506{
507 return 0;
508}
509
510static void
511e7000pc_raw (scb)
512 serial_t scb;
513{
514 /* Always in raw mode */
515}
516
517static int
518e7000pc_readchar (scb, timeout)
519 serial_t scb;
520 int timeout;
521{
522 char buf;
523
16a43bf4 524 DBG(("e7000pc_readchar\n"));
55679787
SC
525 top:
526
16a43bf4
DP
527 /* FIXME! How does dosasync_read ever return 0?
528 * it always goes thru the loop once, so i>0
529 */
55679787
SC
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
539struct 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
546static serial_ttystate
547e7000pc_get_tty_state (scb)
548 serial_t scb;
549{
550 struct e7000pc_ttystate *state;
16a43bf4 551 DBG(("e7000pc_get_tty_state\n"));
55679787
SC
552
553 state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
554
555 return (serial_ttystate) state;
556}
557
558static int
559e7000pc_set_tty_state (scb, ttystate)
560 serial_t scb;
561 serial_ttystate ttystate;
562{
563 return 0;
564}
565
566static int
567e7000pc_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
575static void
576e7000pc_print_tty_state (scb, ttystate)
577 serial_t scb;
578 serial_ttystate ttystate;
579{
580 /* Nothing to print. */
581 return;
582}
583
584static int
585e7000pc_setbaudrate (scb, rate)
586 serial_t scb;
587 int rate;
588{
589 return 0;
590}
591
592static int
593e7000pc_write (scb, str, len)
594 serial_t scb;
595 const char *str;
596 int len;
597{
16a43bf4 598 DBG(("e7000pc_write(scb,str=%s,len=x%x)\n",str,len));
55679787
SC
599 dosasync_write (scb->fd, str, len);
600
601 return 0;
602}
603
604static void
605e7000pc_close (scb)
606 serial_t scb;
607{
16a43bf4
DP
608 DBG(("e7000pc_close\n"));
609#ifdef _WIN32
5b59224e
DP
610 win_unload_e7kpc ();
611#endif
55679787
SC
612}
613
614static 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
633void
634_initialize_ser_e7000pc ()
635{
636 serial_add_interface (&e7000pc_ops);
637}
638#else
639
640void
641_initialize_ser_e7000pc ()
642{
643
644}
16a43bf4 645#endif /* defined(__GO32__) || defined(_WIN32) */
This page took 0.190488 seconds and 4 git commands to generate.