995
|
1 /*
|
|
2 * The functions in this file negotiate with the operating system for
|
|
3 * characters, and write characters in a barely buffered fashion on the display.
|
|
4 * All operating systems.
|
|
5 */
|
|
6 #include <stdio.h>
|
|
7 #include "ueed.h"
|
|
8
|
|
9 #ifdef AMIGA
|
|
10 #define NEW 1006
|
|
11 #define LEN 1
|
|
12
|
|
13 static long terminal;
|
|
14 #endif
|
|
15
|
|
16 #ifdef VMS
|
|
17 #include <stsdef.h>
|
|
18 #include <ssdef.h>
|
|
19 #include <descrip.h>
|
|
20 #include <iodef.h>
|
|
21 #include <ttdef.h>
|
|
22
|
|
23 #define NIBUF 128 /* Input buffer size */
|
|
24 #define NOBUF 1024 /* MM says bug buffers win! */
|
|
25 #define EFN 0 /* Event flag */
|
|
26
|
|
27
|
|
28 char obuf[NOBUF]; /* Output buffer */
|
|
29 int nobuf; /* # of bytes in above */
|
|
30 char ibuf[NIBUF]; /* Input buffer */
|
|
31 int nibuf; /* # of bytes in above */
|
|
32 int ibufi; /* Read index */
|
|
33 int oldmode[2]; /* Old TTY mode bits */
|
|
34 int newmode[2]; /* New TTY mode bits */
|
|
35 short iochan; /* TTY I/O channel */
|
|
36 #endif
|
|
37
|
|
38 #ifdef CPM
|
|
39 #include <bdos.h>
|
|
40 #endif
|
|
41
|
|
42 #ifdef MSDOS
|
|
43 #undef LATTICE
|
|
44 #include <dos.h>
|
|
45 #endif
|
|
46
|
|
47 #ifdef RAINBOW
|
|
48 #include "rainbow.h"
|
|
49 #endif
|
|
50
|
|
51 #ifdef V7
|
|
52 #include <sgtty.h> /* for stty/gtty functions */
|
|
53
|
|
54 struct sgttyb ostate; /* saved tty state */
|
|
55 struct sgttyb nstate; /* values for editor mode */
|
|
56 #endif
|
|
57
|
|
58 #ifdef OS9
|
|
59 #include <sgstat.h> /* for stty/gtty functions */
|
|
60 struct sgbuf ostate; /* saved tty state */
|
|
61 struct sgbuf nstate; /* values for editor mode */
|
|
62 #endif
|
|
63
|
|
64 #ifdef OSK
|
|
65 #include <sgstat.h> /* same as os9/6809 */
|
|
66 struct sgbuf ostate;
|
|
67 struct sgbuf nstate;
|
|
68 #endif
|
|
69
|
|
70 /*
|
|
71 * This function is called once to set up the terminal device streams.
|
|
72 * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns
|
|
73 * a channel to it and sets it raw. On CPM it is a no-op.
|
|
74 */
|
|
75 ttopen()
|
|
76 {
|
|
77 #ifdef AMIGA
|
|
78 terminal = Open("RAW:1/1/639/199/MicroEmacs", NEW);
|
|
79 #endif
|
|
80 #ifdef VMS
|
|
81 struct dsc$descriptor idsc;
|
|
82 struct dsc$descriptor odsc;
|
|
83 char oname[40];
|
|
84 int iosb[2];
|
|
85 int status;
|
|
86
|
|
87 odsc.dsc$a_pointer = "SYS$INPUT";
|
|
88 odsc.dsc$w_length = strlen(odsc.dsc$a_pointer);
|
|
89 odsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
90 odsc.dsc$b_class = DSC$K_CLASS_S;
|
|
91 idsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
92 idsc.dsc$b_class = DSC$K_CLASS_S;
|
|
93 do {
|
|
94 idsc.dsc$a_pointer = odsc.dsc$a_pointer;
|
|
95 idsc.dsc$w_length = odsc.dsc$w_length;
|
|
96 odsc.dsc$a_pointer = &oname[0];
|
|
97 odsc.dsc$w_length = sizeof(oname);
|
|
98 status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
|
|
99 if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
|
|
100 exit(status);
|
|
101 if (oname[0] == 0x1B) {
|
|
102 odsc.dsc$a_pointer += 4;
|
|
103 odsc.dsc$w_length -= 4;
|
|
104 }
|
|
105 } while (status == SS$_NORMAL);
|
|
106 status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
|
|
107 if (status != SS$_NORMAL)
|
|
108 exit(status);
|
|
109 status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
|
|
110 oldmode, sizeof(oldmode), 0, 0, 0, 0);
|
|
111 if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
|
|
112 exit(status);
|
|
113 newmode[0] = oldmode[0];
|
|
114 newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
|
|
115 status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
|
|
116 newmode, sizeof(newmode), 0, 0, 0, 0);
|
|
117 if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
|
|
118 exit(status);
|
|
119 #endif
|
|
120 #ifdef CPM
|
|
121 #endif
|
|
122 #ifdef MSDOS
|
|
123 #endif
|
|
124 #ifdef V7
|
|
125 gtty(1, &ostate); /* save old state */
|
|
126 gtty(1, &nstate); /* get base of new state */
|
|
127 nstate.sg_flags |= RAW;
|
|
128 nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */
|
|
129 stty(1, &nstate); /* set mode */
|
|
130 #endif
|
|
131 #ifdef OS9
|
|
132 getstat(0, 0, &ostate); /* save old state */
|
|
133 getstat(0, 0, &nstate); /* get base of new state *
|
|
134 /
|
|
135 nstate.sg_echo = 0; /* no echo for now... */
|
|
136 nstate.sg_bellch = 0;
|
|
137 nstate.sg_bsech = 0;
|
|
138 nstate.sg_kbach = 0;
|
|
139 nstate.sg_kbich = 0;
|
|
140 nstate.sg_psch = 0;
|
|
141 nstate.sg_dulnch = 0;
|
|
142 nstate.sg_rlnch = 0;
|
|
143 nstate.sg_eofch = 0;
|
|
144 nstate.sg_eorch = 0;
|
|
145 nstate.sg_dlnch = 0;
|
|
146 nstate.sg_bspch = 0;
|
|
147 nstate.sg_pause = 0;
|
|
148 nstate.sg_alf = 0;
|
|
149 nstate.sg_backsp = 0;
|
|
150 setstat(0, 0, &nstate); /* set mode */
|
|
151 stdin->_flag &= ~_SCF;
|
|
152 stdin->_flag |= _RBF;
|
|
153 stdout->_flag &= ~_SCF;
|
|
154 stdout->_flag |= _RBF;
|
|
155 setbuf(stdout,0);
|
|
156 #endif
|
|
157 #ifdef OSK
|
|
158 getstat(0, 0, &ostate); /* save old state */
|
|
159 getstat(0, 0, &nstate); /* get base of new state *
|
|
160 /
|
|
161 nstate.sg_echo = 0; /* no echo for now... */
|
|
162 nstate.sg_bellch = 0;
|
|
163 nstate.sg_bsech = 0;
|
|
164 nstate.sg_kbach = 0;
|
|
165
|
|
166 nstate.sg_kbich = 0;
|
|
167 nstate.sg_psch = 0;
|
|
168 nstate.sg_dulnch = 0;
|
|
169 nstate.sg_rlnch = 0;
|
|
170 nstate.sg_eofch = 0;
|
|
171 nstate.sg_eorch = 0;
|
|
172 nstate.sg_dlnch = 0;
|
|
173 nstate.sg_bspch = 0;
|
|
174 nstate.sg_pause = 0;
|
|
175 nstate.sg_alf = 0;
|
|
176 nstate.sg_backsp = 0;
|
|
177 nstate.sg_xoff =0; /* new for OSK */
|
|
178 nstate.sg_xon =0;
|
|
179 setstat(0, 0, &nstate); /* set mode */
|
|
180 stdin->_flag &= ~_SCF;
|
|
181 stdin->_flag |= _RBF;
|
|
182 stdout->_flag &= ~_SCF;
|
|
183 stdout->_flag |= _RBF;
|
|
184 setbuf(stdout,0);
|
|
185 #endif
|
|
186 }
|
|
187
|
|
188 /*
|
|
189 * This function gets called just before we go back home to the command
|
|
190 * interpreter. On VMS it puts the terminal back in a reasonable state.
|
|
191 * Another no-operation on CPM.
|
|
192 */
|
|
193 ttclose()
|
|
194 {
|
|
195 #ifdef AMIGA
|
|
196 Close(terminal);
|
|
197 #endif
|
|
198 #ifdef VMS
|
|
199 int status;
|
|
200 int iosb[1];
|
|
201
|
|
202 ttflush();
|
|
203 status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
|
|
204 oldmode, sizeof(oldmode), 0, 0, 0, 0);
|
|
205 if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
|
|
206 exit(status);
|
|
207 status = SYS$DASSGN(iochan);
|
|
208 if (status != SS$_NORMAL)
|
|
209 exit(status);
|
|
210 #endif
|
|
211 #ifdef CPM
|
|
212 #endif
|
|
213 #ifdef MSDOS
|
|
214 #endif
|
|
215 #ifdef V7
|
|
216 stty(1, &ostate);
|
|
217 #endif
|
|
218 #ifdef OS9
|
|
219 setstat(0, 0, &ostate);
|
|
220 #endif
|
|
221 #ifdef OSK
|
|
222 setstat(0, 0, &ostate);
|
|
223 #endif
|
|
224 }
|
|
225
|
|
226 /*
|
|
227 * Write a character to the display. On VMS, terminal output is buffered, and
|
|
228 * we just put the characters in the big array, after checking for overflow.
|
|
229 * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
|
|
230 * MS-DOS (use the very very raw console output routine).
|
|
231 */
|
|
232 ttputc(c)
|
|
233 char c;
|
|
234 {
|
|
235 #ifdef AMIGA
|
|
236 Write(terminal, &c, LEN);
|
|
237 #endif
|
|
238 #ifdef VMS
|
|
239 if (nobuf >= NOBUF)
|
|
240 ttflush();
|
|
241 obuf[nobuf++] = c;
|
|
242 #endif
|
|
243
|
|
244 #ifdef CPM
|
|
245 bios(BCONOUT, c, 0);
|
|
246 #endif
|
|
247
|
|
248 #ifdef MSDOS & CWC86
|
|
249 dosb(CONDIO, c, 0);
|
|
250 #endif
|
|
251
|
|
252 #ifdef RAINBOW
|
|
253 Put_Char(c); /* fast video */
|
|
254 #endif
|
|
255
|
|
256 #ifdef V7
|
|
257 fputc(c, stdout);
|
|
258 #endif
|
|
259 #ifdef OS9
|
|
260 putc(c, stdout);
|
|
261 #endif
|
|
262 #ifdef OSK
|
|
263 putc(c, stdout);
|
|
264 #endif
|
|
265 }
|
|
266
|
|
267 /*
|
|
268 * Flush terminal buffer. Does real work where the terminal output is buffered
|
|
269 * up. A no-operation on systems where byte at a time terminal I/O is done.
|
|
270 */
|
|
271 ttflush()
|
|
272 {
|
|
273 #ifdef AMIGA
|
|
274 #endif
|
|
275 #ifdef VMS
|
|
276 int status;
|
|
277 int iosb[2];
|
|
278
|
|
279 status = SS$_NORMAL;
|
|
280 if (nobuf != 0) {
|
|
281 status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
|
|
282 iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
|
|
283 if (status == SS$_NORMAL)
|
|
284 status = iosb[0] & 0xFFFF;
|
|
285 nobuf = 0;
|
|
286 }
|
|
287 return (status);
|
|
288 #endif
|
|
289 #ifdef CPM
|
|
290 #endif
|
|
291 #ifdef MSDOS
|
|
292 #endif
|
|
293 #ifdef V7
|
|
294 fflush(stdout);
|
|
295 #endif
|
|
296 #ifdef OS9
|
|
297 fflush(stdout);
|
|
298 #endif
|
|
299 #ifdef OSK
|
|
300 fflush(stdout);
|
|
301 #endif
|
|
302 }
|
|
303
|
|
304 /*
|
|
305 * Read a character from the terminal, performing no editing and doing no echo
|
|
306 * at all. More complex in VMS that almost anyplace else, which figures. Very
|
|
307 * simple on CPM, because the system can do exactly what you want.
|
|
308 */
|
|
309 ttgetc()
|
|
310 {
|
|
311 #ifdef AMIGA
|
|
312 char ch;
|
|
313
|
|
314 Read(terminal, &ch, LEN);
|
|
315 return (int) ch;
|
|
316 #endif
|
|
317 #ifdef VMS
|
|
318 int status;
|
|
319 int iosb[2];
|
|
320 int term[2];
|
|
321
|
|
322 while (ibufi >= nibuf) {
|
|
323 ibufi = 0;
|
|
324 term[0] = 0;
|
|
325 term[1] = 0;
|
|
326 status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
|
|
327 iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
|
|
328 if (status != SS$_NORMAL)
|
|
329 exit(status);
|
|
330 status = iosb[0] & 0xFFFF;
|
|
331 if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
|
|
332 exit(status);
|
|
333 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
|
|
334 if (nibuf == 0) {
|
|
335 status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
|
|
336 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
|
|
337 if (status != SS$_NORMAL
|
|
338 || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
|
|
339 exit(status);
|
|
340 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
|
|
341 }
|
|
342 }
|
|
343 return (ibuf[ibufi++] & 0xFF); /* Allow multinational */
|
|
344 #endif
|
|
345
|
|
346 #ifdef CPM
|
|
347 return (biosb(BCONIN, 0, 0));
|
|
348 #endif
|
|
349
|
|
350 #ifdef RAINBOW
|
|
351 int Ch;
|
|
352
|
|
353 while ((Ch = Read_Keyboard()) < 0);
|
|
354
|
|
355 if ((Ch & Function_Key) == 0)
|
|
356 if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
|
|
357 Ch &= 0xFF;
|
|
358
|
|
359 return Ch;
|
|
360 #endif
|
|
361
|
|
362 #ifdef MSDOS
|
|
363 #ifdef MWC86
|
|
364 return (dosb(CONRAW, 0, 0));
|
|
365 #endif
|
|
366 #endif
|
|
367
|
|
368 #ifdef V7
|
|
369 return(fgetc(stdin));
|
|
370 #endif
|
|
371 #ifdef OS9
|
|
372 char ch;
|
|
373
|
|
374 read(0, &ch, 1);
|
|
375 return((int)ch);
|
|
376 #endif
|
|
377 #ifdef OSK
|
|
378 char ch;
|
|
379
|
|
380 read(0, &ch, 1);
|
|
381 return((int)ch);
|
|
382 #endif
|
|
383 }
|
|
384
|