Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/bdos/conbdos.lis
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

353 lines
11 KiB
Plaintext

1File: CONBDOS.C Page 1
1
2 /********************************************************
3 * *
4 * CP/M-68K BDOS Character I/O Routines *
5 * *
6 * This module does BDOS functions 1 thru 11 *
7 * *
8 * It contains the following functions which *
9 * are called from the BDOS main routine: *
10 * constat(); *
11 * conin(); *
12 * tabout(); *
13 * rawconio(); *
14 * prt_line(); *
15 * readline(); *
16 * *
17 * Copyright (c) 1982 Digital Research, Inc. *
18 * *
19 ********************************************************/
20
21 #include "bdosinc.h"
22
23 #include "bdosdef.h"
24
25 #include "biosdef.h"
26
27
28 #define ctrlc 0x03
29 #define ctrle 0x05
30 #define ctrlp 0x10
31 #define ctrlq 0x11
32 #define ctrlr 0x12
33 #define ctrls 0x13
34 #define ctrlu 0x15
35 #define ctrlx 0x18
36
37 #define cr 0x0d
38 #define lf 0x0a
39 #define tab 0x09
40 #define rub 0x7f
41 #define bs 0x08
42 #define space 0x20
43
44
45 EXTERN warmboot(); /* External function definition */
46
47
48 /******************/
49 /* console status */
50 /******************/
51
52 BOOLEAN constat()
53 {
54 BSETUP
55
56 return( GBL.kbchar ? TRUE : bconstat() );
57 }
58
59 /********************/
1File: CONBDOS.C Page 2
60 /* check for ctrl/s */
61 /* used internally */
62 /********************/
63 conbrk()
64 {
65 REG UBYTE ch;
66 REG BOOLEAN stop;
67 BSETUP
68
69 stop = FALSE;
70 if ( bconstat() ) do
71 {
72 if ( (ch = bconin()) == ctrlc ) warmboot(1);
73 if ( ch == ctrls ) stop = TRUE;
74 else if (ch == ctrlq) stop = FALSE;
75 else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
76 else /* Insert character in ring buffer */
77 { /* */
78 if(GBL.kbchar < TBUFSIZ) /* Room? */
79 { /************************************/
80 *GBL.insptr++ = ch; /* Yes, insert the character in buff*/
81 GBL.kbchar++; /* Up count */
82 } /************************************/
83 } /* Note if no room, character is */
84 /* Ignomiously discarded (!) */
85 /************************************/
86 } while (stop);
87 }
88
89
90 /******************/
91 /* console output */
92 /* used internally*/
93 /******************/
94
95 conout(ch)
96 REG UBYTE ch;
97 {
98 BSETUP
99
100 conbrk(); /* check for control-s break */
101 bconout(ch); /* output character to console */
102 if (GBL.lstecho) blstout(ch); /* if ctrl-p on, echo to list dev */
103 if (ch >= ' ') GBL.column++; /* keep track of screen column */
104 else if (ch == cr) GBL.column = 0;
105 else if (ch == bs) GBL.column--;
106 }
107
108
109 /*************************************/
110 /* console output with tab expansion */
111 /*************************************/
112
113 tabout(ch)
114 REG UBYTE ch; /* character to output to console */
115 {
116 BSETUP
117
118 if (ch == tab) do
1File: CONBDOS.C Page 3
119 conout(' ');
120 while (GBL.column & 7);
121 else conout(ch);
122 }
123
124 /*******************************/
125 /* console output with tab and */
126 /* control character expansion */
127 /*******************************/
128
129 cookdout(ch)
130 REG UBYTE ch; /* character to output to console */
131 {
132 if (ch == tab) tabout(ch); /* if tab, expand it */
133 else
134 {
135 if ( (UWORD)ch < (UWORD)' ' )
136 {
137 conout( '^' );
138 ch |= 0x40;
139 }
140 conout(ch); /* output the character */
141 }
142 }
143
144
145 /*****************/
146 /* console input */
147 /*****************/
148
149 UBYTE getch() /* Get char from buffer or bios */
150 /* For internal use only */
151 {
152 REG UBYTE temp;
153 BSETUP
154
155 if(GBL.kbchar)
156 {
157 temp = *GBL.remptr++; /* Fetch the character */
158 GBL.kbchar--; /* Decrement the count */
159 if(!GBL.kbchar) /* Gone to zero? */
160 GBL.remptr = GBL.insptr = &(GBL.t_buff[0]);
161 return(temp);
162 }
163 return( bconin() ); /* else get char from bios */
164 }
165
166 UBYTE conin() /* BDOS console input function */
167 {
168 REG UBYTE ch;
169 BSETUP
170
171 conout( ch = getch() );
172 if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
173 return(ch);
174 }
175
176 /******************
177 * raw console i/o *
1File: CONBDOS.C Page 4
178 ******************/
179
180 UBYTE rawconio(parm) /* BDOS raw console I/O function */
181
182 REG UWORD parm;
183 {
184 BSETUP
185
186 if (parm == 0xff) return(getch());
187 else if (parm == 0xfe) return(constat());
188 else bconout(parm & 0xff);
189 }
190
191
192 /****************************************************/
193 /* print line up to delimiter($) with tab expansion */
194 /****************************************************/
195
196 prt_line(p)
197 REG UBYTE *p;
198 {
199 BSETUP
200
201 while( *p != GBL.delim ) tabout( *p++ );
202 }
203
204
205 /**********************************************/
206 /* read line with editing and bounds checking */
207 /**********************************************/
208
209 /* Two subroutines first */
210
211 newline(startcol)
212 REG UWORD startcol;
213 {
214 BSETUP
215
216 conout(cr); /* go to new line */
217 conout(lf);
218 while(startcol)
219 {
220 conout(' ');
221 startcol -= 1; /* start output at starting column */
222 }
223 }
224
225
226 backsp(bufp, col)
227 /* backspace one character position */
228 REG struct conbuf *bufp; /* pointer to console buffer */
229 REG WORD col; /* starting console column */
230 {
231 REG UBYTE ch; /* current character */
232 REG WORD i;
233 REG UBYTE *p; /* character pointer */
234 BSETUP
235
236 if (bufp->retlen) --(bufp->retlen);
1File: CONBDOS.C Page 5
237 /* if buffer non-empty, decrease it by 1 */
238 i = UBWORD(bufp->retlen); /* get new character count */
239 p = &(bufp->cbuf[0]); /* point to character buffer */
240 while (i--) /* calculate column position */
241 { /* across entire char buffer */
242 ch = *p++; /* get next char */
243 if ( ch == tab )
244 {
245 col += 8;
246 col &= ~7; /* for tab, go to multiple of 8 */
247 }
248 else if ( (UWORD)ch < (UWORD)' ' ) col += 2;
249 /* control chars put out 2 printable chars */
250 else col += 1;
251 }
252 while (GBL.column > col)
253 {
254 conout(bs); /* backspace until we get to proper column */
255 conout(' ');
256 conout(bs);
257 }
258 }
259
260
261 readline(p) /* BDOS function 10 */
262 REG struct conbuf *p;
263
264 {
265 REG UBYTE ch;
266 REG UWORD i;
267 REG UWORD j;
268 REG UBYTE *q;
269 UWORD stcol;
270
271 BSETUP
272
273 stcol = GBL.column; /* set up starting column */
274 if (GBL.chainp != NULL) /* chain to program code */
275 {
276 i = UBWORD(*(GBL.chainp++));
277 j = UBWORD(p->maxlen);
278 if (j < i) i = j; /* don't overflow console buffer! */
279 p->retlen = (UBYTE)i;
280 q = p->cbuf;
281 while (i)
282 {
283 cookdout( *q++ = *(GBL.chainp++) );
284 i -= 1;
285 }
286 GBL.chainp = NULL;
287 return;
288 }
289
290 p->retlen = 0; /* start out with empty buffer */
291 while ( UBWORD(p->retlen) < UBWORD(p->maxlen) )
292 { /* main loop for read console buffer */
293
294 if ( ((ch=getch()) == ctrlc) && !(p->retlen) )
295 {
1File: CONBDOS.C Page 6
296 cookdout(ctrlc);
297 warmboot(1);
298 }
299
300 else if ( (ch == cr) || (ch == lf) )
301 { /* if cr or lf, exit */
302 conout(cr);
303 break;
304 }
305
306 else if (ch == bs) backsp(p, stcol); /* backspace */
307
308 else if (ch == rub) /* delete character */
309 {
310 if (GBL.echodel)
311 {
312 if (p->retlen)
313 {
314 i = UBWORD(--(p->retlen));
315 conout( p->cbuf[i] );
316 }
317 }
318 else backsp(p, stcol);
319 }
320
321 else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
322 /* control-p */
323 else if (ch == ctrlx) /* control-x */
324 do backsp(p,stcol); while (p->retlen);
325
326 else if (ch == ctrle) newline(stcol); /* control-e */
327
328 else if (ch == ctrlu) /* control-u */
329 {
330 conout('#');
331 newline(stcol);
332 p->retlen = 0;
333 }
334
335 else if (ch == ctrlr) /* control-r */
336 {
337 conout('#');
338 newline(stcol);
339 for (i=0; i < UBWORD(p->retlen); i++)
340 cookdout( p->cbuf[i] );
341 }
342
343 else /* normal character */
344 cookdout( p->cbuf[UBWORD((p->retlen)++)] = ch );
345 }
346 }