|
|
1.1 root 1: /*-----------------------------------------------------------------------------
2: Talking BIOS device driver for the AT&T PC6300.
3: Copyright (C) Karl Dahlke 1987
4: This software may be freely used and distributed
5: for any non-profit purpose.
6: *-----------------------------------------------------------------------------
7: */
8:
9: /* cursup.c: cursor support; should really be statics */
10:
11: #include "speech.h"
12:
13: #define NLINES 25 /* number of lines on the screen */
14:
15: /* variables for screen memory reading, console only, need not be replicated */
16: static short scrncur; /* screen memory cursor */
17: static short temp_s; /* temp cursor into screen memory */
18: static char *temp_b; /* temp cursor into internal buffer */
19: int sdscreenmode;
20: #ifdef MSDOS
21: char far *sdscreenmem;
22: #else
23: char *sdscreenmem;
24: #endif
25:
26: /* find and set location of screen memory */
27: /* I'm surprised mmas.s doesn't do this somewhere */
28: sdscrnset()
29: {
30: /* fix this, how can we tell where the screen is? */
31: #ifdef MSDOS
32: sdscreenmem = (char far *) 0xb8000000;
33: #else
34: extern char *map_pv();
35: /* screen is deliciously under 4K */
36: sdscreenmem = map_pv(0xb8000, 80*2*25);
37: #endif
38: } /* sdscrnset */
39:
40: /* get current character.
41: * assumes there is text in the circular buffer,
42: * hence the cursor actually points to a valid character.
43: * Grab the character from the circular buffer or from screen memory,
44: * depending on the value of the flag sdscreenmode.
45: * This and subsequent routines access the temp cursor.
46: * After a letter or word is read, the temp cursor
47: * is copied to the real cursor via cursor_set(). */
48: getc()
49: {
50: if(sdscreenmode) {
51: if(temp_s & 1) return '\r';
52: return sdscreenmem[temp_s];
53: }
54: return *(temp_b);
55: } /* getc */
56:
57: /* increment cursor */
58: /* returns 1 for increment past boundary, 0 if ok */
59: incptr()
60: {
61: if(sdscreenmode) {
62: if(temp_s++ & 1) return temp_s == NLINES*80*2;
63: if(temp_s % (80*2) != 80*2-1) ++temp_s;
64: return 0;
65: }
66: if(++temp_b == sdc->buftop) temp_b = sdc->bufbot;
67: return temp_b == sdc->bufhead;
68: } /* incptr */
69:
70: /* decrement cursor */
71: /* returns 1 for increment past boundary, 0 if ok */
72: decptr()
73: {
74: char *oldb;
75: if(sdscreenmode) {
76: if(temp_s-- & 1) return 0;
77: if(temp_s < 0) return 1;
78: if(temp_s % (80*2) != 80*2-1) --temp_s;
79: return 0;
80: }
81: oldb = temp_b;
82: if(oldb == sdc->bufbot) temp_b = sdc->buftop;
83: --temp_b;
84: return oldb == sdc->buftail;
85: } /* decptr */
86:
87: /* back up cursor n spaces.
88: * Always check for boundary conditions.
89: * Even if you just came forward n spaces, and you've decided
90: * you need to retreat, additional characters may have been printed in
91: * the meantime. These advance the head of the buffer,
92: * which forces the tail forward.
93: * Thus there may not be n characters to back up over. */
94: curmove(n, go_fn)
95: int (*go_fn)();
96: {
97: while(n--)
98: if((*go_fn)()) break;
99: } /* curmove */
100:
101: cursor_copy()
102: {
103: if(sdscreenmode) temp_s = scrncur;
104: else temp_b = sdc->bufcur;
105: } /* cursor_copy */
106:
107: cursor_set()
108: {
109: if(sdscreenmode) scrncur = temp_s;
110: else sdc->bufcur = temp_b;
111: } /* cursor_set */
112:
113: /* is buffer empty? */
114: bufempty()
115: {
116: return !sdscreenmode && sdc->bufhead == sdc->buftail;
117: } /* bufempty */
118:
119: /* move cursor to the top of the buffer */
120: buftop()
121: {
122: if(sdscreenmode) scrncur = 0;
123: else sdc->bufcur = sdc->buftail;
124: } /* buftop */
125:
126: /* move cursor to the bottom of the buffer */
127: bufbot()
128: {
129: if(sdscreenmode) scrncur = NLINES*80*2 - 1;
130: else {
131: temp_b = sdc->bufhead;
132: decptr();
133: sdc->bufcur = temp_b;
134: }
135: } /* bufbot */
136:
137: /* move temp cursor to the bottom of the buffer */
138: bufbot_temp()
139: {
140: if(sdscreenmode) temp_s = NLINES*80*2 - 2;
141: else temp_b = sdc->bufhead;
142: } /* bufbot_temp */
143:
144: /* clear the buffer; do not call if sdscreenmode is set */
145: bufclear()
146: {
147: sdc->bufhead = sdc->bufcur = sdc->buftail;
148: } /* bufclear */
149:
150: /* find cursor on screen; not yet used */
151: static findcur()
152: {
153: register i;
154: for(i=0; i<NLINES*80*2; i+=2)
155: if(sdscreenmem[i] == 0x20 && sdscreenmem[i+1] == 15) { temp_s = i; return 0; }
156: return 1;
157: } /* findcur */
158:
159: /* the previous routines manipulate a virtual reading cursor that lives within
160: * the circular buffer or screen memory, depending on the value of the flag
161: * sdscreenmode. The following routines exploit the previous routines
162: * to move the cursor to the next word, last line, etc. */
163:
164: /* back up cursor until new line is reached */
165: backnl()
166: {
167: short count = 0;
168: while(++count, !decptr())
169: if(getc() == '\r') break;
170: incptr();
171: return count;
172: } /* backnl */
173:
174: /* advance cursor past newline */
175: nextnl()
176: {
177: while(getc() != '\r')
178: if(incptr()) return 1;
179: return incptr();
180: } /* nextnl */
181:
182: /* back up cursor to the beginning of the current symbol */
183: backsym()
184: {
185: int forward, backward;
186: char c = getc();
187:
188: if(!isalnum(c)) {
189: if(isspace(c)) return;
190: /* a punctuation mark, an atomic token.
191: * But wait, if there are more than four in a row,
192: * we have a linear token. Pull back to the start. */
193: for(forward=0; !incptr(); ++forward)
194: if(c != getc()) break;
195: curmove(forward+1, decptr); /* back to square 1 */
196: for(backward=0; !decptr(); ++backward)
197: if(c != getc()) break;
198: incptr();
199: if(forward+backward < 4)
200: curmove(backward, incptr);
201: return;
202: }
203:
204: do
205: if(!isalnum(getc())) break;
206: while(!decptr());
207: incptr();
208: } /* backsym */
209:
210: /* advance cursor to the end of the current symbol */
211: nextsym()
212: {
213: int forward, backward;
214: char c = getc();
215:
216: if(!isalnum(c)) {
217: if(isspace(c)) return;
218: for(backward=0; !decptr(); ++backward)
219: if(c != getc()) break;
220: curmove(backward+1, incptr); /* back to square 1 */
221: for(forward=0; !incptr(); ++forward)
222: if(c != getc()) break;
223: decptr();
224: if(forward+backward < 4)
225: curmove(forward, decptr);
226: return;
227: }
228:
229: do
230: if(!isalnum(getc())) break;
231: while(!incptr());
232: decptr();
233: } /* nextsym */
234:
235: /* search through the buffer for a string */
236: bufsearch(updown, string)
237: char updown; /* direction of search */
238: char *string;
239: {
240: char fail;
241:
242: if(sdc->oneline) {
243: if(updown) {
244: backnl();
245: fail = decptr();
246: } else fail = nextnl();
247: } else fail = updown ? decptr() : incptr();
248: if(fail) return 1;
249:
250: do {
251: if(getc() == *string) {
252: if(wordmatch(string)) return 0; /* success */
253: }
254: fail = updown ? decptr() : incptr();
255: } while(!fail);
256: return 1;
257: } /* bufsearch */
258:
259: static wordmatch(s)
260: char *s;
261: {
262: short count = 0;
263:
264: if(!*++s) return 1;
265:
266: while(!incptr()) {
267: ++count; /* another advance */
268: if(getc() != *s) break;
269: if(!*++s) return 1;
270: } /* while matches */
271:
272: /* put the cursor back */
273: curmove(count, decptr);
274: return 0;
275: } /* wordmatch */
276:
277: #ifdef MSDOS
278: strlen(s)
279: char *s;
280: {
281: int i = 0;
282: while(*s++) ++i;
283: return i;
284: } /* strlen */
285: #endif
286:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.