1 /* $NetBSD: ttzapple.c,v 1.9 2009/04/14 08:50:06 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Edward Wang at The University of California, Berkeley. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)ttzapple.c 8.1 (Berkeley) 6/6/93"; 39 #else 40 __RCSID("$NetBSD: ttzapple.c,v 1.9 2009/04/14 08:50:06 lukem Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 #include <stdio.h> 45 #include "ww.h" 46 #include "tt.h" 47 #include "char.h" 48 49 /* 50 zz|zapple|perfect apple:\ 51 :am:pt:co#80:li#24:le=^H:nd=^F:up=^K:do=^J:\ 52 :ho=\E0:ll=\E1:cm=\E=%+ %+ :ch=\E<%+ :cv=\E>%+ :\ 53 :cl=\E4:ce=\E2:cd=\E3:rp=\E@%.%+ :\ 54 :so=\E+:se=\E-:\ 55 :dc=\Ec:DC=\EC%+ :ic=\Ei:IC=\EI%+ :\ 56 :al=\Ea:AL=\EA%+ :dl=\Ed:DL=\ED%+ :\ 57 :sf=\Ef:SF=\EF%+ :sr=\Er:SR=\ER%+ :cs=\E?%+ %+ :\ 58 :is=\E-\ET : 59 */ 60 61 #define NCOL 80 62 #define NROW 24 63 #define TOKEN_MAX 32 64 65 extern short gen_frame[]; 66 67 /* for error correction */ 68 int zz_ecc; 69 int zz_lastc; 70 71 /* for checkpointing */ 72 int zz_sum; 73 74 void zz_checkpoint(void); 75 void zz_checksum(char *, int); 76 void zz_clear(void); 77 void zz_clreol(void); 78 void zz_clreos(void); 79 void zz_compress(int); 80 void zz_delchar(int); 81 void zz_delline(int); 82 void zz_end(void); 83 void zz_insline(int); 84 void zz_insspace(int); 85 void zz_move(int, int); 86 void zz_put_token(int, const char *, int); 87 void zz_putc(char); 88 void zz_reset(void); 89 int zz_rint(char *, int); 90 void zz_scroll_down(int); 91 void zz_scroll_up(int); 92 void zz_setmodes(int); 93 void zz_setscroll(int, int); 94 void zz_set_token(int, char *, int); 95 void zz_start(void); 96 void zz_write(const char *, int); 97 98 void 99 zz_setmodes(int new) 100 { 101 if (new & WWM_REV) { 102 if ((tt.tt_modes & WWM_REV) == 0) 103 ttesc('+'); 104 } else 105 if (tt.tt_modes & WWM_REV) 106 ttesc('-'); 107 tt.tt_modes = new; 108 } 109 110 void 111 zz_insline(int n) 112 { 113 if (n == 1) 114 ttesc('a'); 115 else { 116 ttesc('A'); 117 ttputc(n + ' '); 118 } 119 } 120 121 void 122 zz_delline(int n) 123 { 124 if (n == 1) 125 ttesc('d'); 126 else { 127 ttesc('D'); 128 ttputc(n + ' '); 129 } 130 } 131 132 void 133 zz_putc(char c) 134 { 135 if (tt.tt_nmodes != tt.tt_modes) 136 zz_setmodes(tt.tt_nmodes); 137 ttputc(c); 138 if (++tt.tt_col == NCOL) 139 tt.tt_col = 0, tt.tt_row++; 140 } 141 142 void 143 zz_write(const char *p, int n) 144 { 145 if (tt.tt_nmodes != tt.tt_modes) 146 zz_setmodes(tt.tt_nmodes); 147 ttwrite(p, n); 148 tt.tt_col += n; 149 if (tt.tt_col == NCOL) 150 tt.tt_col = 0, tt.tt_row++; 151 } 152 153 void 154 zz_move(int row, int col) 155 { 156 int x; 157 158 if (tt.tt_row == row) { 159 same_row: 160 if ((x = col - tt.tt_col) == 0) 161 return; 162 if (col == 0) { 163 ttctrl('m'); 164 goto out; 165 } 166 switch (x) { 167 case 2: 168 ttctrl('f'); 169 case 1: 170 ttctrl('f'); 171 goto out; 172 case -2: 173 ttctrl('h'); 174 case -1: 175 ttctrl('h'); 176 goto out; 177 } 178 if ((col & 7) == 0 && x > 0 && x <= 16) { 179 ttctrl('i'); 180 if (x > 8) 181 ttctrl('i'); 182 goto out; 183 } 184 ttesc('<'); 185 ttputc(col + ' '); 186 goto out; 187 } 188 if (tt.tt_col == col) { 189 switch (row - tt.tt_row) { 190 case 2: 191 ttctrl('j'); 192 case 1: 193 ttctrl('j'); 194 goto out; 195 case -2: 196 ttctrl('k'); 197 case -1: 198 ttctrl('k'); 199 goto out; 200 } 201 if (col == 0) { 202 if (row == 0) 203 goto home; 204 if (row == NROW - 1) 205 goto ll; 206 } 207 ttesc('>'); 208 ttputc(row + ' '); 209 goto out; 210 } 211 if (col == 0) { 212 if (row == 0) { 213 home: 214 ttesc('0'); 215 goto out; 216 } 217 if (row == tt.tt_row + 1) { 218 /* 219 * Do newline first to match the sequence 220 * for scroll down and return 221 */ 222 ttctrl('j'); 223 ttctrl('m'); 224 goto out; 225 } 226 if (row == NROW - 1) { 227 ll: 228 ttesc('1'); 229 goto out; 230 } 231 } 232 /* favor local motion for better compression */ 233 if (row == tt.tt_row + 1) { 234 ttctrl('j'); 235 goto same_row; 236 } 237 if (row == tt.tt_row - 1) { 238 ttctrl('k'); 239 goto same_row; 240 } 241 ttesc('='); 242 ttputc(' ' + row); 243 ttputc(' ' + col); 244 out: 245 tt.tt_col = col; 246 tt.tt_row = row; 247 } 248 249 void 250 zz_start(void) 251 { 252 ttesc('T'); 253 ttputc(TOKEN_MAX + ' '); 254 ttesc('U'); 255 ttputc('!'); 256 zz_ecc = 1; 257 zz_lastc = -1; 258 ttesc('v'); 259 ttflush(); 260 zz_sum = 0; 261 zz_setscroll(0, NROW - 1); 262 zz_clear(); 263 zz_setmodes(0); 264 } 265 266 void 267 zz_reset(void) 268 { 269 zz_setscroll(0, NROW - 1); 270 tt.tt_modes = WWM_REV; 271 zz_setmodes(0); 272 tt.tt_col = tt.tt_row = -10; 273 } 274 275 void 276 zz_end(void) 277 { 278 ttesc('T'); 279 ttputc(' '); 280 ttesc('U'); 281 ttputc(' '); 282 zz_ecc = 0; 283 } 284 285 void 286 zz_clreol(void) 287 { 288 ttesc('2'); 289 } 290 291 void 292 zz_clreos(void) 293 { 294 ttesc('3'); 295 } 296 297 void 298 zz_clear(void) 299 { 300 ttesc('4'); 301 tt.tt_col = tt.tt_row = 0; 302 } 303 304 void 305 zz_insspace(int n) 306 { 307 if (n == 1) 308 ttesc('i'); 309 else { 310 ttesc('I'); 311 ttputc(n + ' '); 312 } 313 } 314 315 void 316 zz_delchar(int n) 317 { 318 if (n == 1) 319 ttesc('c'); 320 else { 321 ttesc('C'); 322 ttputc(n + ' '); 323 } 324 } 325 326 void 327 zz_scroll_down(int n) 328 { 329 if (n == 1) { 330 if (tt.tt_row == NROW - 1) 331 ttctrl('j'); 332 else 333 ttesc('f'); 334 } else { 335 ttesc('F'); 336 ttputc(n + ' '); 337 } 338 } 339 340 void 341 zz_scroll_up(int n) 342 { 343 if (n == 1) 344 ttesc('r'); 345 else { 346 ttesc('R'); 347 ttputc(n + ' '); 348 } 349 } 350 351 void 352 zz_setscroll(int top, int bot) 353 { 354 ttesc('?'); 355 ttputc(top + ' '); 356 ttputc(bot + ' '); 357 tt.tt_scroll_top = top; 358 tt.tt_scroll_bot = bot; 359 } 360 361 int zz_debug = 0; 362 363 void 364 zz_set_token(int t, char *s, int n) 365 { 366 if (tt.tt_nmodes != tt.tt_modes) 367 zz_setmodes(tt.tt_nmodes); 368 if (zz_debug) { 369 char buf[100]; 370 zz_setmodes(WWM_REV); 371 (void) sprintf(buf, "%02x=", t); 372 ttputs(buf); 373 tt.tt_col += 3; 374 } 375 ttputc(0x80); 376 ttputc(t + 1); 377 s[n - 1] |= 0x80; 378 ttwrite(s, n); 379 s[n - 1] &= ~0x80; 380 } 381 382 void 383 zz_put_token(int t, const char *s __unused, int n __unused) 384 { 385 if (tt.tt_nmodes != tt.tt_modes) 386 zz_setmodes(tt.tt_nmodes); 387 if (zz_debug) { 388 char buf[100]; 389 zz_setmodes(WWM_REV); 390 (void) sprintf(buf, "%02x>", t); 391 ttputs(buf); 392 tt.tt_col += 3; 393 } 394 ttputc(t + 0x81); 395 } 396 397 int 398 zz_rint(char *p, int n) 399 { 400 int i; 401 char *q; 402 403 if (!zz_ecc) 404 return n; 405 for (i = n, q = p; --i >= 0;) { 406 int c = (unsigned char) *p++; 407 408 if (zz_lastc == 0) { 409 switch (c) { 410 case 0: 411 *q++ = 0; 412 zz_lastc = -1; 413 break; 414 case 1: /* start input ecc */ 415 zz_ecc = 2; 416 zz_lastc = -1; 417 wwnreadstat++; 418 break; 419 case 2: /* ack checkpoint */ 420 tt.tt_ack = 1; 421 zz_lastc = -1; 422 wwnreadack++; 423 break; 424 case 3: /* nack checkpoint */ 425 tt.tt_ack = -1; 426 zz_lastc = -1; 427 wwnreadnack++; 428 break; 429 default: 430 zz_lastc = c; 431 wwnreadec++; 432 } 433 } else if (zz_ecc == 1) { 434 if (c) 435 *q++ = c; 436 else 437 zz_lastc = 0; 438 } else { 439 if (zz_lastc < 0) { 440 zz_lastc = c; 441 } else if (zz_lastc == c) { 442 *q++ = zz_lastc; 443 zz_lastc = -1; 444 } else { 445 wwnreadec++; 446 zz_lastc = c; 447 } 448 } 449 } 450 return q - (p - n); 451 } 452 453 void 454 zz_checksum(char *p, int n) 455 { 456 while (--n >= 0) { 457 int c = *p++ & 0x7f; 458 c ^= zz_sum; 459 zz_sum = c << 1 | (c >> 11 & 1); 460 } 461 } 462 463 void 464 zz_compress(int flag) 465 { 466 if (flag) 467 tt.tt_checksum = 0; 468 else 469 tt.tt_checksum = zz_checksum; 470 } 471 472 void 473 zz_checkpoint(void) 474 { 475 static char x[] = { ctrl('['), 'V', 0, 0 }; 476 477 zz_checksum(x, sizeof x); 478 ttesc('V'); 479 ttputc(' ' + (zz_sum & 0x3f)); 480 ttputc(' ' + (zz_sum >> 6 & 0x3f)); 481 ttflush(); 482 zz_sum = 0; 483 } 484 485 int 486 tt_zapple(void) 487 { 488 tt.tt_insspace = zz_insspace; 489 tt.tt_delchar = zz_delchar; 490 tt.tt_insline = zz_insline; 491 tt.tt_delline = zz_delline; 492 tt.tt_clreol = zz_clreol; 493 tt.tt_clreos = zz_clreos; 494 tt.tt_scroll_down = zz_scroll_down; 495 tt.tt_scroll_up = zz_scroll_up; 496 tt.tt_setscroll = zz_setscroll; 497 tt.tt_availmodes = WWM_REV; 498 tt.tt_wrap = 1; 499 tt.tt_retain = 0; 500 tt.tt_ncol = NCOL; 501 tt.tt_nrow = NROW; 502 tt.tt_start = zz_start; 503 tt.tt_reset = zz_reset; 504 tt.tt_end = zz_end; 505 tt.tt_write = zz_write; 506 tt.tt_putc = zz_putc; 507 tt.tt_move = zz_move; 508 tt.tt_clear = zz_clear; 509 tt.tt_setmodes = zz_setmodes; 510 tt.tt_frame = gen_frame; 511 tt.tt_padc = TT_PADC_NONE; 512 tt.tt_ntoken = 127; 513 tt.tt_set_token = zz_set_token; 514 tt.tt_put_token = zz_put_token; 515 tt.tt_token_min = 1; 516 tt.tt_token_max = TOKEN_MAX; 517 tt.tt_set_token_cost = 2; 518 tt.tt_put_token_cost = 1; 519 tt.tt_compress = zz_compress; 520 tt.tt_checksum = zz_checksum; 521 tt.tt_checkpoint = zz_checkpoint; 522 tt.tt_reset = zz_reset; 523 tt.tt_rint = zz_rint; 524 return 0; 525 } 526