1 /* Remote serial interface using Hitachi E7000 PC ISA card in a PC
3 Copyright 1994 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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. */
24 #define RMT_DBG(x) if (remote_debug) printf_unfiltered x
27 #if defined(__GO32__) || defined(_WIN32)
29 /* we define the 32-bit calls which thunk to 16-bit dll calls
31 #include "win-e7kpc.h"
34 /* msvc uses strnicmp instead of strncasecmp */
35 #define strncasecmp strnicmp
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));
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 (());
65 #define OFF_DPD 0x0000
66 #define OFF_DDP 0x1000
67 #define OFF_CPD 0x2000
68 #define OFF_CDP 0x2400
72 #define OFF_IRQTOD 0x3008
73 #define OFF_IRQTOP 0x300a
74 #define OFF_READY 0x300c
75 #define OFF_PON 0x300e
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;
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);
108 /* dll entry points for w32se7kpc.dll; call kernel32 to thunk for us */
109 typedef BOOL (APIENTRY * PUTREGISTER) (
114 UT32PROC * ppfn32Thunk,
115 FARPROC pfnUT32Callback,
119 /* dll entry points for w95e7kpc.dll and w31e7kpc.dll */
120 HANDLE hWine7kpc = 0;
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);
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;
134 static int last_remote_debug = 0;
135 static int wine7kpc_loaded = 0;
136 static void win_unload_e7kpc (void);
138 static int win_load_e7kpc (void)
140 if (pwin_load_e7kpc && !wine7kpc_loaded)
142 wine7kpc_loaded = pwin_load_e7kpc();
144 make_final_cleanup(win_unload_e7kpc, 0);
146 return wine7kpc_loaded;
149 static void win_unload_e7kpc (void)
151 DBG(("win_unload_e7kpc\n"));
152 if (pwin_unload_e7kpc && wine7kpc_loaded)
157 static void win_mem_get (unsigned char *buf, int offset, int len)
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)
162 pwin_remote_debug(remote_debug);
163 last_remote_debug=remote_debug;
167 pwin_mem_get (buf, offset, len);
171 static void win_mem_put (unsigned char *buf, int offset, int len)
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)
176 pwin_remote_debug(remote_debug);
177 last_remote_debug=remote_debug;
180 pwin_mem_put (buf, offset, len);
183 static void dosmemget(int offset, int length, void *buffer)
185 win_mem_get(buffer, offset, length);
188 static void dosmemput(const void *buffer, int length, int offset)
190 win_mem_put((unsigned char*)buffer, offset, length);
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)
200 static unsigned char bb;
201 static unsigned short sb;
218 /* Look around in memory for the board's signature */
222 DBG(("e7000pc_init()\n"));
223 for (try = 0; sigs[try].sw; try++)
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;
237 RMT_DBG(("e7000pc_init: looking for board's signature, try=%d\n", try));
239 val = GET_WORD (ready);
241 if (val == (0xaaa0 | sigs[try].sw))
243 if (GET_BYTE (pon) & 0xf)
248 SET_BYTE (irqtop, 1); /* Disable interrupts from e7000 */
250 DBG(("Yippie! Connected :-)\n"));
251 printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
255 DBG(("Bummer! e7000pc not on :-(\n"));
256 error ("The E7000 PC board is working, but the E7000 is turned off.\n");
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");
271 static int pbuf_size;
272 static int pbuf_index;
278 static char pbuf[1000];
281 DBG(("e7000_get()\n"));
282 if (pbuf_index < pbuf_size)
284 x = pbuf[pbuf_index++];
286 else if ((GET_BYTE (fb) & 1))
289 pbuf_size = GET_WORD(cdp + 2);
291 dosmemget (cdp + 8, pbuf_size + 1, tmp);
293 /* Tell the E7000 we've eaten */
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.
300 for (i = 0; i < pbuf_size; i++)
305 x = pbuf[pbuf_index++];
315 dosasync_read (fd, buf, len, timeout)
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 */
329 then = now + timeout;
332 int ch = e7000_get();
334 /* While there's room in the buffer, and we've already
335 * read the stuff in, suck it over */
339 while (i < len && pbuf_index < pbuf_size )
350 if (timeout == 0 || (now >= then && timeout > 0))
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.
357 DBG(("timeout; read x%x chars\n", i));
366 dosasync_write (fd, buf, len)
374 DBG(("dosasync_write(fd=x%x,buf=x%x,len=x%x)\n",fd,buf,len));
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++)
383 dummy[8 + i ^ 1] = buf[i];
386 /* Wait for the card to get ready */
387 while ((GET_BYTE(fa) & 1) != 0)
390 /* Blast onto the ISA card */
391 dosmemput (dummy, 8 + len + 1, cpd);
394 SET_BYTE(irqtod, 1); /* Interrupt the E7000 */
406 DBG(("load_wine7kpc()\n"));
407 if (win_host()==winnt)
409 printf_filtered( "e7000pc not supported on this host.\n" );
412 if (win_host()==win32s)
413 strcpy(dll, "w31e7kpc.Dll");
414 else if (win_host()==win95)
415 strcpy(dll, "w95e7kpc.Dll");
418 /* load dll for windows support of e7000pc */
419 DBG(("LoadLibrary(%s)\n",dll));
420 hWine7kpc = LoadLibrary (dll);
423 DBG(("LoadLibrary(%s) failed\n",dll));
424 printf_filtered( "Error: unable to load %s.\n",dll);
427 pwin_load_e7kpc = (PWIN_LOAD_E7KPC) GetProcAddress (hWine7kpc, "win_load_e7kpc");
428 if (!pwin_load_e7kpc)
430 DBG(("!pwin_load_e7kpc\n"));
431 printf_filtered( "Error: unable to resolve win_load_e7kpc.\n" );
434 pwin_unload_e7kpc = (PWIN_UNLOAD_E7KPC) GetProcAddress (hWine7kpc, "win_unload_e7kpc");
435 if (!pwin_unload_e7kpc)
437 DBG(("!pwin_unload_e7kpc\n"));
438 printf_filtered( "Error: unable to resolve win_unload_e7kpc.\n" );
441 pwin_mem_get = (PWIN_MEM_GET) GetProcAddress (hWine7kpc, "win_mem_get");
444 DBG(("!pwin_mem_get\n"));
445 printf_filtered( "Error: unable to resolve win_mem_get.\n" );
448 pwin_mem_put= (PWIN_MEM_PUT) GetProcAddress (hWine7kpc, "win_mem_put");
451 DBG(("!pwin_mem_put\n"));
452 printf_filtered( "Error: unable to resolve win_mem_put.\n" );
455 pwin_remote_debug= (PWIN_REMOTE_DEBUG) GetProcAddress (hWine7kpc, "win_remote_debug");
456 if (!pwin_remote_debug)
458 DBG(("!pwin_remote_debug\n"));
459 printf_filtered( "Error: unable to resolve win_remote_debug.\n" );
462 DBG(("load_wine7kpc Done! :-)\n"));
468 e7000pc_open (scb, name)
472 DBG(("e7000pc_open\n"));
473 if (strncasecmp (name, "pc", 2) != 0)
479 if (!load_wine7kpc()) /* load windows dll for e7kpc support */
481 DBG(("Error! load_wine7kpc failed\n"));
482 printf_filtered("Failed to initialize dll for e7000pc support.\n" );
485 if (win_load_e7kpc () != 0)
491 scb->fd = e7000pc_init ();
495 DBG(("Error! !scb->fd\n"));
499 DBG(("e7000pc_open done! :-)\n"));
514 /* Always in raw mode */
518 e7000pc_readchar (scb, timeout)
524 DBG(("e7000pc_readchar\n"));
527 /* FIXME! How does dosasync_read ever return 0?
528 * it always goes thru the loop once, so i>0
530 if (dosasync_read (scb->fd, &buf, 1, timeout))
532 if (buf == 0) goto top;
536 return SERIAL_TIMEOUT;
539 struct e7000pc_ttystate {
543 /* e7000pc_{get set}_tty_state() are both dummys to fill out the function
544 vector. Someday, they may do something real... */
546 static serial_ttystate
547 e7000pc_get_tty_state (scb)
550 struct e7000pc_ttystate *state;
551 DBG(("e7000pc_get_tty_state\n"));
553 state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
555 return (serial_ttystate) state;
559 e7000pc_set_tty_state (scb, ttystate)
561 serial_ttystate ttystate;
567 e7000pc_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
569 serial_ttystate new_ttystate;
570 serial_ttystate old_ttystate;
576 e7000pc_print_tty_state (scb, ttystate)
578 serial_ttystate ttystate;
580 /* Nothing to print. */
585 e7000pc_setbaudrate (scb, rate)
593 e7000pc_write (scb, str, len)
598 DBG(("e7000pc_write(scb,str=%s,len=x%x)\n",str,len));
599 dosasync_write (scb->fd, str, len);
608 DBG(("e7000pc_close\n"));
614 static struct serial_ops e7000pc_ops =
622 e7000pc_noop, /* flush output */
623 e7000pc_noop, /* flush input */
624 e7000pc_noop, /* send break -- currently used only for nindy */
626 e7000pc_get_tty_state,
627 e7000pc_set_tty_state,
628 e7000pc_print_tty_state,
629 e7000pc_noflush_set_tty_state,
634 _initialize_ser_e7000pc ()
636 serial_add_interface (&e7000pc_ops);
641 _initialize_ser_e7000pc ()
645 #endif /* defined(__GO32__) || defined(_WIN32) */