1 /*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)ttzapple.c 8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14
15 #include "ww.h"
16 #include "tt.h"
17 #include "char.h"
18
19 /*
20 zz|zapple|perfect apple:\
21 :am:pt:co#80:li#24:le=^H:nd=^F:up=^K:do=^J:\
22 :ho=\E0:ll=\E1:cm=\E=%+ %+ :ch=\E<%+ :cv=\E>%+ :\
23 :cl=\E4:ce=\E2:cd=\E3:rp=\E@%.%+ :\
24 :so=\E+:se=\E-:\
25 :dc=\Ec:DC=\EC%+ :ic=\Ei:IC=\EI%+ :\
26 :al=\Ea:AL=\EA%+ :dl=\Ed:DL=\ED%+ :\
27 :sf=\Ef:SF=\EF%+ :sr=\Er:SR=\ER%+ :cs=\E?%+ %+ :\
28 :is=\E-\ET :
29 */
30
31 #define NCOL 80
32 #define NROW 24
33 #define TOKEN_MAX 32
34
35 extern short gen_frame[];
36
37 /* for error correction */
38 int zz_ecc;
39 int zz_lastc;
40
41 /* for checkpointing */
42 int zz_sum;
43
zz_setmodes(new)44 zz_setmodes(new)
45 {
46 if (new & WWM_REV) {
47 if ((tt.tt_modes & WWM_REV) == 0)
48 ttesc('+');
49 } else
50 if (tt.tt_modes & WWM_REV)
51 ttesc('-');
52 tt.tt_modes = new;
53 }
54
zz_insline(n)55 zz_insline(n)
56 {
57 if (n == 1)
58 ttesc('a');
59 else {
60 ttesc('A');
61 ttputc(n + ' ');
62 }
63 }
64
zz_delline(n)65 zz_delline(n)
66 {
67 if (n == 1)
68 ttesc('d');
69 else {
70 ttesc('D');
71 ttputc(n + ' ');
72 }
73 }
74
zz_putc(c)75 zz_putc(c)
76 char c;
77 {
78 if (tt.tt_nmodes != tt.tt_modes)
79 zz_setmodes(tt.tt_nmodes);
80 ttputc(c);
81 if (++tt.tt_col == NCOL)
82 tt.tt_col = 0, tt.tt_row++;
83 }
84
zz_write(p,n)85 zz_write(p, n)
86 register char *p;
87 register n;
88 {
89 if (tt.tt_nmodes != tt.tt_modes)
90 zz_setmodes(tt.tt_nmodes);
91 ttwrite(p, n);
92 tt.tt_col += n;
93 if (tt.tt_col == NCOL)
94 tt.tt_col = 0, tt.tt_row++;
95 }
96
zz_move(row,col)97 zz_move(row, col)
98 register row, col;
99 {
100 register x;
101
102 if (tt.tt_row == row) {
103 same_row:
104 if ((x = col - tt.tt_col) == 0)
105 return;
106 if (col == 0) {
107 ttctrl('m');
108 goto out;
109 }
110 switch (x) {
111 case 2:
112 ttctrl('f');
113 case 1:
114 ttctrl('f');
115 goto out;
116 case -2:
117 ttctrl('h');
118 case -1:
119 ttctrl('h');
120 goto out;
121 }
122 if ((col & 7) == 0 && x > 0 && x <= 16) {
123 ttctrl('i');
124 if (x > 8)
125 ttctrl('i');
126 goto out;
127 }
128 ttesc('<');
129 ttputc(col + ' ');
130 goto out;
131 }
132 if (tt.tt_col == col) {
133 switch (row - tt.tt_row) {
134 case 2:
135 ttctrl('j');
136 case 1:
137 ttctrl('j');
138 goto out;
139 case -2:
140 ttctrl('k');
141 case -1:
142 ttctrl('k');
143 goto out;
144 }
145 if (col == 0) {
146 if (row == 0)
147 goto home;
148 if (row == NROW - 1)
149 goto ll;
150 }
151 ttesc('>');
152 ttputc(row + ' ');
153 goto out;
154 }
155 if (col == 0) {
156 if (row == 0) {
157 home:
158 ttesc('0');
159 goto out;
160 }
161 if (row == tt.tt_row + 1) {
162 /*
163 * Do newline first to match the sequence
164 * for scroll down and return
165 */
166 ttctrl('j');
167 ttctrl('m');
168 goto out;
169 }
170 if (row == NROW - 1) {
171 ll:
172 ttesc('1');
173 goto out;
174 }
175 }
176 /* favor local motion for better compression */
177 if (row == tt.tt_row + 1) {
178 ttctrl('j');
179 goto same_row;
180 }
181 if (row == tt.tt_row - 1) {
182 ttctrl('k');
183 goto same_row;
184 }
185 ttesc('=');
186 ttputc(' ' + row);
187 ttputc(' ' + col);
188 out:
189 tt.tt_col = col;
190 tt.tt_row = row;
191 }
192
zz_start()193 zz_start()
194 {
195 ttesc('T');
196 ttputc(TOKEN_MAX + ' ');
197 ttesc('U');
198 ttputc('!');
199 zz_ecc = 1;
200 zz_lastc = -1;
201 ttesc('v');
202 ttflush();
203 zz_sum = 0;
204 zz_setscroll(0, NROW - 1);
205 zz_clear();
206 zz_setmodes(0);
207 }
208
zz_reset()209 zz_reset()
210 {
211 zz_setscroll(0, NROW - 1);
212 tt.tt_modes = WWM_REV;
213 zz_setmodes(0);
214 tt.tt_col = tt.tt_row = -10;
215 }
216
zz_end()217 zz_end()
218 {
219 ttesc('T');
220 ttputc(' ');
221 ttesc('U');
222 ttputc(' ');
223 zz_ecc = 0;
224 }
225
zz_clreol()226 zz_clreol()
227 {
228 ttesc('2');
229 }
230
zz_clreos()231 zz_clreos()
232 {
233 ttesc('3');
234 }
235
zz_clear()236 zz_clear()
237 {
238 ttesc('4');
239 tt.tt_col = tt.tt_row = 0;
240 }
241
zz_insspace(n)242 zz_insspace(n)
243 {
244 if (n == 1)
245 ttesc('i');
246 else {
247 ttesc('I');
248 ttputc(n + ' ');
249 }
250 }
251
zz_delchar(n)252 zz_delchar(n)
253 {
254 if (n == 1)
255 ttesc('c');
256 else {
257 ttesc('C');
258 ttputc(n + ' ');
259 }
260 }
261
zz_scroll_down(n)262 zz_scroll_down(n)
263 {
264 if (n == 1)
265 if (tt.tt_row == NROW - 1)
266 ttctrl('j');
267 else
268 ttesc('f');
269 else {
270 ttesc('F');
271 ttputc(n + ' ');
272 }
273 }
274
zz_scroll_up(n)275 zz_scroll_up(n)
276 {
277 if (n == 1)
278 ttesc('r');
279 else {
280 ttesc('R');
281 ttputc(n + ' ');
282 }
283 }
284
zz_setscroll(top,bot)285 zz_setscroll(top, bot)
286 {
287 ttesc('?');
288 ttputc(top + ' ');
289 ttputc(bot + ' ');
290 tt.tt_scroll_top = top;
291 tt.tt_scroll_bot = bot;
292 }
293
294 int zz_debug = 0;
295
zz_set_token(t,s,n)296 zz_set_token(t, s, n)
297 char *s;
298 {
299 if (tt.tt_nmodes != tt.tt_modes)
300 zz_setmodes(tt.tt_nmodes);
301 if (zz_debug) {
302 char buf[100];
303 zz_setmodes(WWM_REV);
304 (void) sprintf(buf, "%02x=", t);
305 ttputs(buf);
306 tt.tt_col += 3;
307 }
308 ttputc(0x80);
309 ttputc(t + 1);
310 s[n - 1] |= 0x80;
311 ttwrite(s, n);
312 s[n - 1] &= ~0x80;
313 }
314
315 /*ARGSUSED*/
zz_put_token(t,s,n)316 zz_put_token(t, s, n)
317 char *s;
318 {
319 if (tt.tt_nmodes != tt.tt_modes)
320 zz_setmodes(tt.tt_nmodes);
321 if (zz_debug) {
322 char buf[100];
323 zz_setmodes(WWM_REV);
324 (void) sprintf(buf, "%02x>", t);
325 ttputs(buf);
326 tt.tt_col += 3;
327 }
328 ttputc(t + 0x81);
329 }
330
zz_rint(p,n)331 zz_rint(p, n)
332 char *p;
333 {
334 register i;
335 register char *q;
336
337 if (!zz_ecc)
338 return n;
339 for (i = n, q = p; --i >= 0;) {
340 register c = (unsigned char) *p++;
341
342 if (zz_lastc == 0) {
343 switch (c) {
344 case 0:
345 *q++ = 0;
346 zz_lastc = -1;
347 break;
348 case 1: /* start input ecc */
349 zz_ecc = 2;
350 zz_lastc = -1;
351 wwnreadstat++;
352 break;
353 case 2: /* ack checkpoint */
354 tt.tt_ack = 1;
355 zz_lastc = -1;
356 wwnreadack++;
357 break;
358 case 3: /* nack checkpoint */
359 tt.tt_ack = -1;
360 zz_lastc = -1;
361 wwnreadnack++;
362 break;
363 default:
364 zz_lastc = c;
365 wwnreadec++;
366 }
367 } else if (zz_ecc == 1) {
368 if (c)
369 *q++ = c;
370 else
371 zz_lastc = 0;
372 } else {
373 if (zz_lastc < 0) {
374 zz_lastc = c;
375 } else if (zz_lastc == c) {
376 *q++ = zz_lastc;
377 zz_lastc = -1;
378 } else {
379 wwnreadec++;
380 zz_lastc = c;
381 }
382 }
383 }
384 return q - (p - n);
385 }
386
zz_checksum(p,n)387 zz_checksum(p, n)
388 register char *p;
389 register n;
390 {
391 while (--n >= 0) {
392 register c = *p++ & 0x7f;
393 c ^= zz_sum;
394 zz_sum = c << 1 | c >> 11 & 1;
395 }
396 }
397
zz_compress(flag)398 zz_compress(flag)
399 {
400 if (flag)
401 tt.tt_checksum = 0;
402 else
403 tt.tt_checksum = zz_checksum;
404 }
405
zz_checkpoint()406 zz_checkpoint()
407 {
408 static char x[] = { ctrl('['), 'V', 0, 0 };
409
410 zz_checksum(x, sizeof x);
411 ttesc('V');
412 ttputc(' ' + (zz_sum & 0x3f));
413 ttputc(' ' + (zz_sum >> 6 & 0x3f));
414 ttflush();
415 zz_sum = 0;
416 }
417
tt_zapple()418 tt_zapple()
419 {
420 tt.tt_insspace = zz_insspace;
421 tt.tt_delchar = zz_delchar;
422 tt.tt_insline = zz_insline;
423 tt.tt_delline = zz_delline;
424 tt.tt_clreol = zz_clreol;
425 tt.tt_clreos = zz_clreos;
426 tt.tt_scroll_down = zz_scroll_down;
427 tt.tt_scroll_up = zz_scroll_up;
428 tt.tt_setscroll = zz_setscroll;
429 tt.tt_availmodes = WWM_REV;
430 tt.tt_wrap = 1;
431 tt.tt_retain = 0;
432 tt.tt_ncol = NCOL;
433 tt.tt_nrow = NROW;
434 tt.tt_start = zz_start;
435 tt.tt_reset = zz_reset;
436 tt.tt_end = zz_end;
437 tt.tt_write = zz_write;
438 tt.tt_putc = zz_putc;
439 tt.tt_move = zz_move;
440 tt.tt_clear = zz_clear;
441 tt.tt_setmodes = zz_setmodes;
442 tt.tt_frame = gen_frame;
443 tt.tt_padc = TT_PADC_NONE;
444 tt.tt_ntoken = 127;
445 tt.tt_set_token = zz_set_token;
446 tt.tt_put_token = zz_put_token;
447 tt.tt_token_min = 1;
448 tt.tt_token_max = TOKEN_MAX;
449 tt.tt_set_token_cost = 2;
450 tt.tt_put_token_cost = 1;
451 tt.tt_compress = zz_compress;
452 tt.tt_checksum = zz_checksum;
453 tt.tt_checkpoint = zz_checkpoint;
454 tt.tt_reset = zz_reset;
455 tt.tt_rint = zz_rint;
456 return 0;
457 }
458