]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/ser-e7kpc.c
* ser-e7kpc.c: New file to support the E7000 with the PC ISA
[thirdparty/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., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #ifdef __GO32__
22 #include "defs.h"
23 #include "serial.h"
24 #include <sys/dos.h>
25
26
27
28 static int e7000pc_open PARAMS ((serial_t scb, const char *name));
29 static void e7000pc_raw PARAMS ((serial_t scb));
30 static int e7000pc_readchar PARAMS ((serial_t scb, int timeout));
31 static int e7000pc_setbaudrate PARAMS ((serial_t scb, int rate));
32 static int e7000pc_write PARAMS ((serial_t scb, const char *str, int len));
33 static void e7000pc_close PARAMS ((serial_t scb));
34 static serial_ttystate e7000pc_get_tty_state PARAMS ((serial_t scb));
35 static int e7000pc_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
36 static char *aptr PARAMS ((short p));
37
38 static int dos_async_init PARAMS ((int port));
39 static void dos_async_tx PARAMS ((const char c));
40 static int dos_async_rx PARAMS (());
41
42
43
44 #define OFF_DPD 0x0000
45 #define OFF_DDP 0x1000
46 #define OFF_CPD 0x2000
47 #define OFF_CDP 0x2400
48 #define OFF_FA 0x3000
49 #define OFF_FB 0x3002
50 #define OFF_FC 0x3004
51 #define OFF_IRQTOD 0x3008
52 #define OFF_IRQTOP 0x300a
53 #define OFF_READY 0x300c
54 #define OFF_PON 0x300e
55
56 #define IDLE 0x0000
57 #define CMD_CI 0x4349
58 #define CMD_CO 0x434f
59 #define CMD_LO 0x4c4f
60 #define CMD_LS 0x4c53
61 #define CMD_SV 0x5356
62 #define CMD_SS 0x5353
63 #define CMD_OK 0x4f4b
64 #define CMD_ER 0x4552
65 #define CMD_NF 0x4e46
66 #define CMD_AB 0x4142
67 #define CMD_ED 0x4544
68 #define CMD_CE 0x4345
69
70 static unsigned long fa;
71 static unsigned long irqtod;
72 static unsigned long ready;
73 static unsigned long fb;
74 static unsigned long cpd ;
75 static unsigned long cdp ;
76 static unsigned long ready;
77 static unsigned long pon;
78 static unsigned long irqtop;
79 static unsigned long board_at;
80
81 #define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);}
82 #define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);}
83 #define GET_BYTE(x) ( dosmemget(x,1,&bb), bb)
84 #define GET_WORD(x) ( dosmemget(x,2,&sb), sb)
85
86 static unsigned char bb;
87 static unsigned short sb;
88
89
90 static struct sw
91 {
92 int sw;
93 int addr;
94 } sigs[] = {
95 {0x14, 0xd0000},
96 {0x15, 0xd4000},
97 {0x16, 0xd8000},
98 {0x17, 0xdc000},
99 0};
100
101 static int
102 e7000pc_init ()
103 {
104 /* Look around in memory for the board's signature */
105
106 int try;
107
108 for (try = 0; sigs[try].sw; try++)
109
110 {
111 int val;
112 board_at = sigs[try].addr;
113 fa = board_at + OFF_FA;
114 fb = board_at + OFF_FB;
115 cpd = board_at + OFF_CPD;
116 cdp = board_at + OFF_CDP;
117 ready =board_at + OFF_READY;
118 pon = board_at + OFF_PON;
119 irqtop = board_at + OFF_IRQTOP;
120 irqtod = board_at + OFF_IRQTOD;
121
122 val = GET_WORD (ready);
123
124 if (val == (0xaaa0 | sigs[try].sw))
125 {
126 if (GET_BYTE (pon) & 0xf)
127 {
128 SET_BYTE(fa, 0);
129 SET_BYTE (fb, 0);
130
131 SET_BYTE (irqtop, 1); /* Disable interrupts from e7000 */
132 SET_WORD (ready, 1);
133 printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
134 sigs[try].addr);
135 return 1;
136 }
137 error ("The E7000 PC board is working, but the E7000 is turned off.\n");
138 return 0;
139 }
140 }
141
142 error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
143 and that the switch settings are correct. Some other DOS programs can \n\
144 stop the board from working. Try starting from a very minimal boot, \n\
145 perhaps you need to disable EMM386 over the region where the board has\n\
146 its I/O space, remove other unneeded cards, etc etc\n");
147 return 0;
148
149 }
150
151 static int pbuf_size;
152 static int pbuf_index;
153
154 static
155 int
156 e7000_get ()
157 {
158 static char pbuf[1000];
159 char tmp[1000];
160 int x;
161 if (pbuf_index < pbuf_size)
162 {
163 x = pbuf[pbuf_index++];
164 }
165 else if ((GET_BYTE (fb) & 1))
166 {
167 int i;
168 pbuf_size = GET_WORD(cdp + 2);
169
170 dosmemget (cdp + 8, pbuf_size + 1, tmp);
171
172 /* Tell the E7000 we've eaten */
173 SET_BYTE(fb,0);
174 /* Swap it around */
175 for (i = 0; i < pbuf_size; i++)
176 {
177 pbuf[i] = tmp[i^1];
178 }
179 pbuf_index = 0;
180 x = pbuf[pbuf_index++];
181 }
182 else
183 {
184 x = -1;
185 }
186 return x;
187 }
188
189 static int
190 dosasync_read (fd, buf, len, timeout)
191 int fd;
192 char *buf;
193 int len;
194 int timeout;
195
196 {
197 long now;
198 long then;
199 int i = 0;
200 int p;
201
202 /* Then look for some more if we're still hungry */
203 time (&now);
204 then = now + timeout;
205 while (i < len)
206 {
207 int ch = e7000_get();
208
209 /* While there's room in the buffer, and we've already
210 read the stuff in, suck it over */
211 if (ch != -1)
212 {
213 buf[i++] = ch;
214 while (i < len && pbuf_index < pbuf_size )
215 {
216 ch = e7000_get();
217 if (ch == -1)
218 break;
219 buf[i++] = ch;
220 }
221 }
222
223 time (&now);
224
225 if (timeout == 0)
226 return i;
227 if (now >= then && timeout > 0)
228 {
229 return i;
230 }
231 }
232 return len;
233 }
234
235
236 static int
237 dosasync_write (fd, buf, len)
238 int fd;
239 const char *buf;
240 int len;
241 {
242 int i;
243 char dummy[1000];
244
245
246 /* Construct copy locally */
247 ((short *)dummy)[0] = CMD_CI;
248 ((short *)dummy)[1] = len;
249 ((short *)dummy)[2] = 0;
250 ((short *)dummy)[3] = 0;
251 for (i = 0; i < len ; i++)
252 {
253 dummy[8 + i ^ 1] = buf[i];
254 }
255
256 /* Wait for the card to get ready */
257 while ((GET_BYTE(fa) & 1) != 0)
258 ;
259
260 /* Blast onto the ISA card */
261 dosmemput (dummy, 8 + len + 1, cpd);
262
263 SET_BYTE(fa, 1);
264 SET_BYTE(irqtod, 1); /* Interrupt the E7000 */
265
266 return len;
267 }
268
269 static int
270 e7000pc_open (scb, name)
271 serial_t scb;
272 const char *name;
273 {
274 if (strncasecmp (name, "pc", 2) != 0)
275 {
276 errno = ENOENT;
277 return -1;
278 }
279
280 scb->fd = e7000pc_init ();
281
282 if (!scb->fd)
283 return -1;
284
285 return 0;
286 }
287
288 static int
289 e7000pc_noop (scb)
290 serial_t scb;
291 {
292 return 0;
293 }
294
295 static void
296 e7000pc_raw (scb)
297 serial_t scb;
298 {
299 /* Always in raw mode */
300 }
301
302 static int
303 e7000pc_readchar (scb, timeout)
304 serial_t scb;
305 int timeout;
306 {
307 char buf;
308
309 top:
310
311 if (dosasync_read (scb->fd, &buf, 1, timeout))
312 {
313 if (buf == 0) goto top;
314 return buf;
315 }
316 else
317 return SERIAL_TIMEOUT;
318 }
319
320 struct e7000pc_ttystate {
321 int dummy;
322 };
323
324 /* e7000pc_{get set}_tty_state() are both dummys to fill out the function
325 vector. Someday, they may do something real... */
326
327 static serial_ttystate
328 e7000pc_get_tty_state (scb)
329 serial_t scb;
330 {
331 struct e7000pc_ttystate *state;
332
333 state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
334
335 return (serial_ttystate) state;
336 }
337
338 static int
339 e7000pc_set_tty_state (scb, ttystate)
340 serial_t scb;
341 serial_ttystate ttystate;
342 {
343 return 0;
344 }
345
346 static int
347 e7000pc_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
348 serial_t scb;
349 serial_ttystate new_ttystate;
350 serial_ttystate old_ttystate;
351 {
352 return 0;
353 }
354
355 static void
356 e7000pc_print_tty_state (scb, ttystate)
357 serial_t scb;
358 serial_ttystate ttystate;
359 {
360 /* Nothing to print. */
361 return;
362 }
363
364 static int
365 e7000pc_setbaudrate (scb, rate)
366 serial_t scb;
367 int rate;
368 {
369 return 0;
370 }
371
372 static int
373 e7000pc_write (scb, str, len)
374 serial_t scb;
375 const char *str;
376 int len;
377 {
378 dosasync_write (scb->fd, str, len);
379
380 return 0;
381 }
382
383 static void
384 e7000pc_close (scb)
385 serial_t scb;
386 {
387 }
388
389 static struct serial_ops e7000pc_ops =
390 {
391 "pc",
392 0,
393 e7000pc_open,
394 e7000pc_close,
395 e7000pc_readchar,
396 e7000pc_write,
397 e7000pc_noop, /* flush output */
398 e7000pc_noop, /* flush input */
399 e7000pc_noop, /* send break -- currently used only for nindy */
400 e7000pc_raw,
401 e7000pc_get_tty_state,
402 e7000pc_set_tty_state,
403 e7000pc_print_tty_state,
404 e7000pc_noflush_set_tty_state,
405 e7000pc_setbaudrate,
406 };
407
408 void
409 _initialize_ser_e7000pc ()
410 {
411 serial_add_interface (&e7000pc_ops);
412 }
413 #else
414
415 void
416 _initialize_ser_e7000pc ()
417 {
418
419 }
420 #endif