]>
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 | ||
b52373a2 JG |
52 | static int fd; |
53 | ||
5d2b030a SG |
54 | static char * |
55 | aptr(p) | |
56 | short p; | |
ae0ea72e | 57 | { |
ae0ea72e | 58 | return (char *)((unsigned)async - OFFSET + p); |
ae0ea72e SC |
59 | } |
60 | ||
5d2b030a | 61 | static ASYNC_STRUCT * |
b52373a2 | 62 | getivec(int which) |
ae0ea72e | 63 | { |
5d2b030a | 64 | ASYNC_STRUCT *a; |
ae0ea72e SC |
65 | |
66 | if (peek(0, which*4) != OFFSET) | |
67 | return 0; | |
ae0ea72e SC |
68 | a = (ASYNC_STRUCT *)(0xe0000000 + peek(0, which*4+2)*16 + peek(0, which*4)); |
69 | ||
ae0ea72e SC |
70 | if (a->signature != SIGNATURE) |
71 | return 0; | |
72 | if (a->version != VERSION) | |
73 | return 0; | |
74 | return a; | |
75 | } | |
76 | ||
5d2b030a | 77 | static int |
b52373a2 | 78 | dos_async_init() |
ae0ea72e SC |
79 | { |
80 | int i; | |
5d2b030a SG |
81 | ASYNC_STRUCT *a1; |
82 | ASYNC_STRUCT *a2; | |
ae0ea72e SC |
83 | a1 = getivec(12); |
84 | a2 = getivec(11); | |
85 | async = 0; | |
86 | if (a1) | |
87 | async = a1; | |
88 | if (a2) | |
89 | async = a2; | |
90 | if (a1 && a2) | |
91 | { | |
92 | if (a1 < a2) | |
93 | async = a1; | |
94 | else | |
95 | async = a2; | |
96 | } | |
97 | if (async == 0) | |
98 | { | |
99 | error("GDB can not connect to asynctsr program, check that it is installed\n\ | |
100 | and that serial I/O is not being redirected (perhaps by NFS)\n\n\ | |
101 | example configuration:\n\ | |
102 | C> mode com2:9600,n,8,1,p\n\ | |
103 | C> asynctsr 2\n\ | |
104 | C> gdb \n"); | |
105 | ||
106 | } | |
107 | iov = async->iov; | |
108 | outportb(com_ier, 0x0f); | |
109 | outportb(com_bfr, 0x03); | |
110 | outportb(com_mcr, 0x0b); | |
111 | async->getp = async->putp = async->buffer_start; | |
112 | ||
ae0ea72e SC |
113 | if (iov > 0x300) |
114 | return 1; | |
115 | else | |
116 | return 2; | |
117 | } | |
118 | ||
5d2b030a SG |
119 | static void |
120 | dos_async_tx(c) | |
121 | const char c; | |
ae0ea72e | 122 | { |
ae0ea72e | 123 | while (~inportb(com_lsr) & 0x20); |
5d2b030a | 124 | |
ae0ea72e | 125 | outportb(com_tb, c); |
ae0ea72e SC |
126 | } |
127 | ||
5d2b030a | 128 | static int |
b52373a2 | 129 | dos_async_ready() |
ae0ea72e SC |
130 | { |
131 | return (async->getp != async->putp); | |
132 | } | |
133 | ||
5d2b030a | 134 | static int |
b52373a2 | 135 | dos_async_rx() |
ae0ea72e SC |
136 | { |
137 | char rv; | |
5d2b030a | 138 | |
ae0ea72e | 139 | while (!dos_async_ready()) |
5d2b030a SG |
140 | if (kbhit()) |
141 | { | |
142 | printf("abort!\n"); | |
143 | return 0; | |
144 | } | |
145 | ||
ae0ea72e | 146 | rv = *aptr(async->getp++); |
ae0ea72e | 147 | if (async->getp >= async->buffer_end) |
5d2b030a | 148 | async->getp = async->buffer_start; |
ae0ea72e | 149 | |
5d2b030a | 150 | return rv; |
ae0ea72e SC |
151 | } |
152 | ||
5d2b030a SG |
153 | static int |
154 | dosasync_read (fd, buf, len, timeout) | |
155 | int fd; | |
156 | char *buf; | |
157 | int len; | |
158 | int timeout; | |
ae0ea72e SC |
159 | { |
160 | long now, then; | |
5d2b030a SG |
161 | int l = len; |
162 | ||
ae0ea72e | 163 | time (&now); |
5d2b030a SG |
164 | then = now + timeout; |
165 | ||
ae0ea72e | 166 | while (l--) |
ae0ea72e | 167 | { |
5d2b030a SG |
168 | if (timeout) |
169 | { | |
170 | while (!dos_async_ready()) | |
171 | { | |
172 | time (&now); | |
173 | if (now >= then) | |
174 | return len - l - 1; | |
175 | } | |
176 | } | |
177 | *buf++ = dos_async_rx(); | |
ae0ea72e | 178 | } |
ae0ea72e | 179 | |
5d2b030a | 180 | return len; |
ae0ea72e SC |
181 | } |
182 | ||
5d2b030a SG |
183 | static int |
184 | dosasync_write(fd, buf, len) | |
185 | int fd; | |
186 | const char *buf; | |
187 | int len; | |
188 | { | |
189 | int l = len; | |
ae0ea72e | 190 | |
5d2b030a SG |
191 | while (l--) |
192 | dos_async_tx (*buf++); | |
ae0ea72e | 193 | |
5d2b030a | 194 | return len; |
ae0ea72e SC |
195 | } |
196 | ||
5d2b030a SG |
197 | static int |
198 | go32_open (scb, name) | |
199 | serial_t scb; | |
200 | const char *name; | |
b52373a2 | 201 | { |
5d2b030a SG |
202 | scb->fd = dos_async_init(); |
203 | if (scb->fd) | |
204 | return 1; | |
ae0ea72e | 205 | |
5d2b030a | 206 | return 0; |
ae0ea72e SC |
207 | } |
208 | ||
5d2b030a SG |
209 | static void |
210 | go32_raw (scb) | |
211 | serial_t scb; | |
ae0ea72e | 212 | { |
5d2b030a | 213 | /* Always in raw mode */ |
ae0ea72e SC |
214 | } |
215 | ||
5d2b030a SG |
216 | static int |
217 | go32_readchar (scb, timeout) | |
218 | serial_t scb; | |
219 | int timeout; | |
ae0ea72e SC |
220 | { |
221 | char buf; | |
5d2b030a SG |
222 | |
223 | if (dosasync_read(scb->fd, &buf, 1, timeout)) | |
5a6242dd | 224 | return buf; |
ae0ea72e | 225 | else |
5a6242dd | 226 | return -2; /* Timeout, I guess */ |
ae0ea72e SC |
227 | } |
228 | ||
5d2b030a SG |
229 | static int |
230 | go32_setbaudrate (scb, rate) | |
231 | serial_t scb; | |
232 | int rate; | |
ae0ea72e SC |
233 | { |
234 | return 0; | |
235 | } | |
236 | ||
5d2b030a SG |
237 | static int |
238 | go32_write (scb, str, len) | |
239 | serial_t scb; | |
240 | const char *str; | |
241 | int len; | |
242 | { | |
243 | dosasync_write(scb->fd, str, len); | |
244 | } | |
245 | ||
246 | static void | |
247 | go32_close () | |
ae0ea72e | 248 | { |
ae0ea72e SC |
249 | } |
250 | ||
5d2b030a SG |
251 | static void |
252 | go32_restore (scb) | |
253 | serial_t scb; | |
ae0ea72e | 254 | { |
ae0ea72e SC |
255 | } |
256 | ||
5d2b030a SG |
257 | static struct serial_ops go32_ops = |
258 | { | |
259 | "hardwire", | |
260 | 0, | |
261 | go32_open, | |
262 | go32_close, | |
263 | go32_readchar, | |
264 | go32_write, | |
265 | go32_raw, | |
266 | go32_restore, | |
267 | go32_setbaudrate | |
268 | }; | |
269 | ||
270 | _initialize_ser_go32 () | |
ae0ea72e | 271 | { |
5d2b030a | 272 | serial_add_interface (&go32_ops); |
ae0ea72e | 273 | } |