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 //DBG(("calling pwin_remote_debug\n"));
163 pwin_remote_debug(remote_debug
);
164 last_remote_debug
=remote_debug
;
168 //DBG(("calling pwin_mem_get\n"));
169 pwin_mem_get (buf
, offset
, len
);
171 //DBG(("leaving win_mem_get; buf=<%s>\n", buf));
174 static void win_mem_put (unsigned char *buf
, int offset
, int len
)
176 DBG(("win_mem_put(buf=<%s> offset=<x%x> len=<%d>)\n", buf
, offset
, len
));
177 if (remote_debug
!=last_remote_debug
&& pwin_remote_debug
)
179 pwin_remote_debug(remote_debug
);
180 last_remote_debug
=remote_debug
;
183 pwin_mem_put (buf
, offset
, len
);
186 static void dosmemget(int offset
, int length
, void *buffer
)
188 win_mem_get(buffer
, offset
, length
);
191 static void dosmemput(const void *buffer
, int length
, int offset
)
193 win_mem_put((unsigned char*)buffer
, offset
, length
);
198 #define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);}
199 #define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);}
200 #define GET_BYTE(x) ( dosmemget(x,1,&bb), bb)
201 #define GET_WORD(x) ( dosmemget(x,2,&sb), sb)
203 static unsigned char bb
;
204 static unsigned short sb
;
221 /* Look around in memory for the board's signature */
225 DBG(("e7000pc_init()\n"));
226 for (try = 0; sigs
[try].sw
; try++)
230 board_at
= sigs
[try].addr
;
231 fa
= board_at
+ OFF_FA
;
232 fb
= board_at
+ OFF_FB
;
233 cpd
= board_at
+ OFF_CPD
;
234 cdp
= board_at
+ OFF_CDP
;
235 ready
=board_at
+ OFF_READY
;
236 pon
= board_at
+ OFF_PON
;
237 irqtop
= board_at
+ OFF_IRQTOP
;
238 irqtod
= board_at
+ OFF_IRQTOD
;
240 RMT_DBG(("e7000pc_init: looking for board's signature, try=%d\n", try));
242 val
= GET_WORD (ready
);
244 //DBG(("e7000pc_init: GET_WORD returns x%x\n", val));
246 if (val
== (0xaaa0 | sigs
[try].sw
))
248 if (GET_BYTE (pon
) & 0xf)
253 SET_BYTE (irqtop
, 1); /* Disable interrupts from e7000 */
255 DBG(("Yippie! Connected :-)\n"));
256 printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
260 DBG(("Bummer! e7000pc not on :-(\n"));
261 error ("The E7000 PC board is working, but the E7000 is turned off.\n");
266 DBG(("Bummer! Can't connect :-(\n"));
267 error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
268 and that the switch settings are correct. Some other DOS programs can \n\
269 stop the board from working. Try starting from a very minimal boot, \n\
270 perhaps you need to disable EMM386 over the region where the board has\n\
271 its I/O space, remove other unneeded cards, etc etc\n");
276 static int pbuf_size
;
277 static int pbuf_index
;
283 static char pbuf
[1000];
286 DBG(("e7000_get()\n"));
287 if (pbuf_index
< pbuf_size
)
289 x
= pbuf
[pbuf_index
++];
291 else if ((GET_BYTE (fb
) & 1))
294 pbuf_size
= GET_WORD(cdp
+ 2);
296 dosmemget (cdp
+ 8, pbuf_size
+ 1, tmp
);
298 /* Tell the E7000 we've eaten */
301 /* FIXME! We get in an infinite loop inside e7000_open...
302 * This is called from dosasync_readchar
303 * called from remote-e7000.c trying to sync up.
305 for (i
= 0; i
< pbuf_size
; i
++)
310 x
= pbuf
[pbuf_index
++];
320 dosasync_read (fd
, buf
, len
, timeout
)
331 DBG(("dosasync_read(fd=x%x,buf,len=x%x,timeout=x%x)\n",fd
,len
,timeout
));
332 /* Then look for some more if we're still hungry */
334 then
= now
+ timeout
;
337 int ch
= e7000_get();
338 //DBG(("%d: e7000_get gotta x%x\n", i, ch\n"));
340 /* While there's room in the buffer, and we've already
341 * read the stuff in, suck it over */
345 //DBG(("e7000_get got x%x; before loop2: len=x%x, pbuf_index=x%x, pbuf_size=x%x\n", ch, len, pbuf_index, pbuf_size));
346 while (i
< len
&& pbuf_index
< pbuf_size
)
357 if (timeout
== 0 || (now
>= then
&& timeout
> 0))
359 /* We timeout here but return i anyway...
360 * were we supposed to send a TIMEOUT ?
361 * While syncing, len = 1 and timeout=1..
362 * so always take this path and return 1 char.
364 DBG(("timeout; read x%x chars\n", i
));
368 //DBG(("Yay! read x%x chars\n", len));
374 dosasync_write (fd
, buf
, len
)
382 DBG(("dosasync_write(fd=x%x,buf=x%x,len=x%x)\n",fd
,buf
,len
));
384 /* Construct copy locally */
385 ((short *)dummy
)[0] = CMD_CI
;
386 ((short *)dummy
)[1] = len
;
387 ((short *)dummy
)[2] = 0;
388 ((short *)dummy
)[3] = 0;
389 for (i
= 0; i
< len
; i
++)
391 dummy
[8 + i
^ 1] = buf
[i
];
394 /* Wait for the card to get ready */
395 while ((GET_BYTE(fa
) & 1) != 0)
398 /* Blast onto the ISA card */
399 dosmemput (dummy
, 8 + len
+ 1, cpd
);
402 SET_BYTE(irqtod
, 1); /* Interrupt the E7000 */
414 DBG(("load_wine7kpc()\n"));
415 if (win_host()==winnt
)
417 printf_filtered( "e7000pc not supported on this host.\n" );
420 if (win_host()==win32s
)
421 strcpy(dll
, "w31e7kpc.Dll");
422 else if (win_host()==win95
)
423 strcpy(dll
, "w95e7kpc.Dll");
426 /* load dll for windows support of e7000pc */
427 DBG(("LoadLibrary(%s)\n",dll
));
428 hWine7kpc
= LoadLibrary (dll
);
431 DBG(("LoadLibrary(%s) failed\n",dll
));
432 printf_filtered( "Error: unable to load %s.\n",dll
);
435 pwin_load_e7kpc
= (PWIN_LOAD_E7KPC
) GetProcAddress (hWine7kpc
, "win_load_e7kpc");
436 if (!pwin_load_e7kpc
)
438 DBG(("!pwin_load_e7kpc\n"));
439 printf_filtered( "Error: unable to resolve win_load_e7kpc.\n" );
442 pwin_unload_e7kpc
= (PWIN_UNLOAD_E7KPC
) GetProcAddress (hWine7kpc
, "win_unload_e7kpc");
443 if (!pwin_unload_e7kpc
)
445 DBG(("!pwin_unload_e7kpc\n"));
446 printf_filtered( "Error: unable to resolve win_unload_e7kpc.\n" );
449 pwin_mem_get
= (PWIN_MEM_GET
) GetProcAddress (hWine7kpc
, "win_mem_get");
452 DBG(("!pwin_mem_get\n"));
453 printf_filtered( "Error: unable to resolve win_mem_get.\n" );
456 pwin_mem_put
= (PWIN_MEM_PUT
) GetProcAddress (hWine7kpc
, "win_mem_put");
459 DBG(("!pwin_mem_put\n"));
460 printf_filtered( "Error: unable to resolve win_mem_put.\n" );
463 pwin_remote_debug
= (PWIN_REMOTE_DEBUG
) GetProcAddress (hWine7kpc
, "win_remote_debug");
464 if (!pwin_remote_debug
)
466 DBG(("!pwin_remote_debug\n"));
467 printf_filtered( "Error: unable to resolve win_remote_debug.\n" );
470 DBG(("load_wine7kpc Done! :-)\n"));
476 e7000pc_open (scb
, name
)
480 DBG(("e7000pc_open\n"));
481 if (strncasecmp (name
, "pc", 2) != 0)
487 if (!load_wine7kpc()) /* load windows dll for e7kpc support */
489 DBG(("Error! load_wine7kpc failed\n"));
490 printf_filtered("Failed to initialize dll for e7000pc support.\n" );
493 //DBG(("calling win_load_e7kpc\n"));
494 if (win_load_e7kpc () != 0)
500 //DBG(("calling e7000pc_init\n"));
501 scb
->fd
= e7000pc_init ();
505 DBG(("Error! !scb->fd\n"));
509 DBG(("e7000pc_open done! :-)\n"));
524 /* Always in raw mode */
528 e7000pc_readchar (scb
, timeout
)
534 DBG(("e7000pc_readchar\n"));
537 /* FIXME! How does dosasync_read ever return 0?
538 * it always goes thru the loop once, so i>0
540 if (dosasync_read (scb
->fd
, &buf
, 1, timeout
))
542 if (buf
== 0) goto top
;
546 return SERIAL_TIMEOUT
;
549 struct e7000pc_ttystate
{
553 /* e7000pc_{get set}_tty_state() are both dummys to fill out the function
554 vector. Someday, they may do something real... */
556 static serial_ttystate
557 e7000pc_get_tty_state (scb
)
560 struct e7000pc_ttystate
*state
;
561 DBG(("e7000pc_get_tty_state\n"));
563 state
= (struct e7000pc_ttystate
*) xmalloc (sizeof *state
);
565 return (serial_ttystate
) state
;
569 e7000pc_set_tty_state (scb
, ttystate
)
571 serial_ttystate ttystate
;
577 e7000pc_noflush_set_tty_state (scb
, new_ttystate
, old_ttystate
)
579 serial_ttystate new_ttystate
;
580 serial_ttystate old_ttystate
;
586 e7000pc_print_tty_state (scb
, ttystate
)
588 serial_ttystate ttystate
;
590 /* Nothing to print. */
595 e7000pc_setbaudrate (scb
, rate
)
603 e7000pc_write (scb
, str
, len
)
608 DBG(("e7000pc_write(scb,str=%s,len=x%x)\n",str
,len
));
609 dosasync_write (scb
->fd
, str
, len
);
618 DBG(("e7000pc_close\n"));
624 static struct serial_ops e7000pc_ops
=
632 e7000pc_noop
, /* flush output */
633 e7000pc_noop
, /* flush input */
634 e7000pc_noop
, /* send break -- currently used only for nindy */
636 e7000pc_get_tty_state
,
637 e7000pc_set_tty_state
,
638 e7000pc_print_tty_state
,
639 e7000pc_noflush_set_tty_state
,
644 _initialize_ser_e7000pc ()
646 serial_add_interface (&e7000pc_ops
);
651 _initialize_ser_e7000pc ()
655 #endif /* defined(__GO32__) || defined(_WIN32) */