|
|
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.