Commit | Line | Data |
---|---|---|
5d2b030a SG |
1 | /* Remote serial interface for local (hardwired) serial ports for GO32. |
2 | Copyright 1992, 1993 Free Software Foundation, Inc. | |
ae0ea72e SC |
3 | |
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | ||
ae0ea72e SC |
20 | #include "defs.h" |
21 | #include "serial.h" | |
5140562f | 22 | #include <sys/dos.h> |
ae0ea72e SC |
23 | |
24 | #define SIGNATURE 0x4154 | |
25 | #define VERSION 1 | |
26 | #define OFFSET 0x104 | |
27 | ||
ae0ea72e | 28 | #define peek(a,b) (*(unsigned short *)(0xe0000000 + (a)*16 + (b))) |
ae0ea72e SC |
29 | |
30 | typedef struct { | |
31 | short jmp_op; | |
32 | short signature; | |
33 | short version; | |
34 | short buffer_start; | |
35 | short buffer_end; | |
36 | short getp; | |
37 | short putp; | |
38 | short iov; | |
39 | } ASYNC_STRUCT; | |
40 | ||
5d2b030a | 41 | static ASYNC_STRUCT *async; |
ae0ea72e SC |
42 | static int iov; |
43 | #define com_rb iov | |
44 | #define com_tb iov | |
45 | #define com_ier iov+1 | |
46 | #define com_ifr iov+2 | |
47 | #define com_bfr iov+3 | |
48 | #define com_mcr iov+4 | |
49 | #define com_lsr iov+5 | |
50 | #define com_msr iov+6 | |
51 | ||
b83bf6b3 SG |
52 | static int |
53 | strncasecmp(str1, str2, len) | |
54 | char *str1, *str2; | |
55 | register int len; | |
56 | { | |
57 | unsigned char c1, c2; | |
58 | ||
59 | for (; len != 0; --len) | |
60 | { | |
61 | c1 = *str1++; | |
62 | c2 = *str2++; | |
63 | ||
64 | if (toupper(c1) != toupper(c2)) | |
65 | return toupper(c1) - toupper(c2); | |
66 | ||
67 | if (c1 == '\0') | |
68 | return 0; | |
69 | } | |
70 | return 0; | |
71 | } | |
b52373a2 | 72 | |
5d2b030a SG |
73 | static char * |
74 | aptr(p) | |
75 | short p; | |
ae0ea72e | 76 | { |
ae0ea72e | 77 | return (char *)((unsigned)async - OFFSET + p); |
ae0ea72e SC |
78 | } |
79 | ||
5d2b030a | 80 | static ASYNC_STRUCT * |
b52373a2 | 81 | getivec(int which) |
ae0ea72e | 82 | { |
5d2b030a | 83 | ASYNC_STRUCT *a; |
ae0ea72e SC |
84 | |
85 | if (peek(0, which*4) != OFFSET) | |
86 | return 0; | |
b83bf6b3 | 87 | |
ae0ea72e SC |
88 | a = (ASYNC_STRUCT *)(0xe0000000 + peek(0, which*4+2)*16 + peek(0, which*4)); |
89 | ||
ae0ea72e SC |
90 | if (a->signature != SIGNATURE) |
91 | return 0; | |
b83bf6b3 | 92 | |
ae0ea72e SC |
93 | if (a->version != VERSION) |
94 | return 0; | |
b83bf6b3 | 95 | |
ae0ea72e SC |
96 | return a; |
97 | } | |
98 | ||
5d2b030a | 99 | static int |
b83bf6b3 SG |
100 | dos_async_init(port) |
101 | int port; | |
ae0ea72e SC |
102 | { |
103 | int i; | |
b83bf6b3 SG |
104 | |
105 | switch (port) | |
07861607 | 106 | { |
b83bf6b3 SG |
107 | case 1: |
108 | async = getivec (12); | |
109 | break; | |
110 | case 2: | |
111 | async = getivec (11); | |
112 | break; | |
113 | default: | |
114 | return 0; | |
07861607 SG |
115 | } |
116 | ||
b83bf6b3 | 117 | if (!async) |
07861607 SG |
118 | { |
119 | error("GDB can not connect to asynctsr program, check that it is installed\n\ | |
ae0ea72e SC |
120 | and that serial I/O is not being redirected (perhaps by NFS)\n\n\ |
121 | example configuration:\n\ | |
122 | C> mode com2:9600,n,8,1,p\n\ | |
123 | C> asynctsr 2\n\ | |
124 | C> gdb \n"); | |
125 | ||
07861607 SG |
126 | } |
127 | ||
ae0ea72e SC |
128 | iov = async->iov; |
129 | outportb(com_ier, 0x0f); | |
130 | outportb(com_bfr, 0x03); | |
131 | outportb(com_mcr, 0x0b); | |
132 | async->getp = async->putp = async->buffer_start; | |
133 | ||
b83bf6b3 | 134 | return 1; |
ae0ea72e SC |
135 | } |
136 | ||
5d2b030a SG |
137 | static void |
138 | dos_async_tx(c) | |
139 | const char c; | |
ae0ea72e | 140 | { |
ae0ea72e | 141 | while (~inportb(com_lsr) & 0x20); |
5d2b030a | 142 | |
ae0ea72e | 143 | outportb(com_tb, c); |
ae0ea72e SC |
144 | } |
145 | ||
5d2b030a | 146 | static int |
b52373a2 | 147 | dos_async_ready() |
ae0ea72e SC |
148 | { |
149 | return (async->getp != async->putp); | |
150 | } | |
151 | ||
5d2b030a | 152 | static int |
b52373a2 | 153 | dos_async_rx() |
ae0ea72e SC |
154 | { |
155 | char rv; | |
5d2b030a | 156 | |
ae0ea72e | 157 | while (!dos_async_ready()) |
5d2b030a SG |
158 | if (kbhit()) |
159 | { | |
160 | printf("abort!\n"); | |
161 | return 0; | |
162 | } | |
163 | ||
ae0ea72e | 164 | rv = *aptr(async->getp++); |
ae0ea72e | 165 | if (async->getp >= async->buffer_end) |
5d2b030a | 166 | async->getp = async->buffer_start; |
ae0ea72e | 167 | |
5d2b030a | 168 | return rv; |
ae0ea72e SC |
169 | } |
170 | ||
5d2b030a SG |
171 | static int |
172 | dosasync_read (fd, buf, len, timeout) | |
173 | int fd; | |
174 | char *buf; | |
175 | int len; | |
176 | int timeout; | |
ae0ea72e SC |
177 | { |
178 | long now, then; | |
5d2b030a SG |
179 | int l = len; |
180 | ||
ae0ea72e | 181 | time (&now); |
5d2b030a SG |
182 | then = now + timeout; |
183 | ||
ae0ea72e | 184 | while (l--) |
ae0ea72e | 185 | { |
5d2b030a SG |
186 | if (timeout) |
187 | { | |
188 | while (!dos_async_ready()) | |
189 | { | |
190 | time (&now); | |
191 | if (now >= then) | |
192 | return len - l - 1; | |
193 | } | |
194 | } | |
195 | *buf++ = dos_async_rx(); | |
ae0ea72e | 196 | } |
ae0ea72e | 197 | |
5d2b030a | 198 | return len; |
ae0ea72e SC |
199 | } |
200 | ||
5d2b030a SG |
201 | static int |
202 | dosasync_write(fd, buf, len) | |
203 | int fd; | |
204 | const char *buf; | |
205 | int len; | |
206 | { | |
207 | int l = len; | |
ae0ea72e | 208 | |
5d2b030a SG |
209 | while (l--) |
210 | dos_async_tx (*buf++); | |
ae0ea72e | 211 | |
5d2b030a | 212 | return len; |
ae0ea72e SC |
213 | } |
214 | ||
5d2b030a SG |
215 | static int |
216 | go32_open (scb, name) | |
217 | serial_t scb; | |
218 | const char *name; | |
b52373a2 | 219 | { |
b83bf6b3 SG |
220 | int port; |
221 | ||
222 | if (strncasecmp (name, "com", 3) != 0) | |
223 | { | |
224 | errno = ENOENT; | |
4febd102 | 225 | return -1; |
b83bf6b3 SG |
226 | } |
227 | ||
228 | port = name[3] - '0'; | |
229 | ||
230 | if ((port != 1) && (port != 2)) | |
231 | { | |
232 | errno = ENOENT; | |
4febd102 | 233 | return -11; |
b83bf6b3 SG |
234 | } |
235 | ||
236 | scb->fd = dos_async_init(port); | |
07861607 | 237 | if (!scb->fd) |
4febd102 | 238 | return -1; |
ae0ea72e | 239 | |
5d2b030a | 240 | return 0; |
ae0ea72e SC |
241 | } |
242 | ||
5d2b030a SG |
243 | static void |
244 | go32_raw (scb) | |
245 | serial_t scb; | |
ae0ea72e | 246 | { |
5d2b030a | 247 | /* Always in raw mode */ |
ae0ea72e SC |
248 | } |
249 | ||
5d2b030a SG |
250 | static int |
251 | go32_readchar (scb, timeout) | |
252 | serial_t scb; | |
253 | int timeout; | |
ae0ea72e SC |
254 | { |
255 | char buf; | |
5d2b030a SG |
256 | |
257 | if (dosasync_read(scb->fd, &buf, 1, timeout)) | |
5a6242dd | 258 | return buf; |
ae0ea72e | 259 | else |
4febd102 | 260 | return SERIAL_TIMEOUT; |
ae0ea72e SC |
261 | } |
262 | ||
5d2b030a SG |
263 | static int |
264 | go32_setbaudrate (scb, rate) | |
265 | serial_t scb; | |
266 | int rate; | |
ae0ea72e SC |
267 | { |
268 | return 0; | |
269 | } | |
270 | ||
5d2b030a SG |
271 | static int |
272 | go32_write (scb, str, len) | |
273 | serial_t scb; | |
274 | const char *str; | |
275 | int len; | |
276 | { | |
277 | dosasync_write(scb->fd, str, len); | |
4febd102 SG |
278 | |
279 | return 0; | |
5d2b030a SG |
280 | } |
281 | ||
282 | static void | |
283 | go32_close () | |
ae0ea72e | 284 | { |
ae0ea72e SC |
285 | } |
286 | ||
5d2b030a SG |
287 | static void |
288 | go32_restore (scb) | |
289 | serial_t scb; | |
ae0ea72e | 290 | { |
ae0ea72e SC |
291 | } |
292 | ||
5d2b030a SG |
293 | static struct serial_ops go32_ops = |
294 | { | |
295 | "hardwire", | |
296 | 0, | |
297 | go32_open, | |
298 | go32_close, | |
299 | go32_readchar, | |
300 | go32_write, | |
301 | go32_raw, | |
302 | go32_restore, | |
303 | go32_setbaudrate | |
304 | }; | |
305 | ||
306 | _initialize_ser_go32 () | |
ae0ea72e | 307 | { |
5d2b030a | 308 | serial_add_interface (&go32_ops); |
ae0ea72e | 309 | } |