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