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