ite_tv.c revision 1.3 1 /* $NetBSD: ite_tv.c,v 1.3 1997/02/03 21:51:15 oki Exp $ */
2
3 /*
4 * Copyright (c) 1997 Masaru Oki.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Masaru Oki.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <sys/device.h>
35 #include <sys/proc.h>
36 #include <sys/systm.h>
37
38 #include <x68k/x68k/iodevice.h>
39 #include <x68k/dev/itevar.h>
40 #include <x68k/dev/grfioctl.h>
41 #include <x68k/dev/grfvar.h>
42
43 /*
44 * ITE device dependent routine for X680x0 Text-Video framebuffer.
45 * Use X680x0 ROM fixed width font (8x16)
46 */
47
48 #define CRTC (IODEVbase->io_crtc)
49
50 /*
51 * font constant
52 */
53 #define FONTWIDTH 8
54 #define FONTHEIGHT 16
55 #define UNDERLINE 14
56
57 /*
58 * framebuffer constant
59 */
60 #define PLANEWIDTH 1024
61 #define PLANEHEIGHT 1024
62 #define PLANELINES (PLANEHEIGHT / FONTHEIGHT)
63 #define ROWBYTES (PLANEWIDTH / FONTWIDTH)
64 #define PLANESIZE (PLANEHEIGHT * ROWBYTES)
65
66 u_int tv_top;
67 u_char *tv_row[PLANELINES];
68 char *tv_font[256];
69 __volatile char *tv_kfont[0x7f];
70
71 u_char kern_font[256 * FONTHEIGHT];
72 u_char kbdled;
73
74 #define PHYSLINE(y) ((tv_top + (y)) % PLANELINES)
75 #define ROWOFFSET(y) ((y) * FONTHEIGHT * ROWBYTES)
76 #define CHADDR(y, x) (tv_row[PHYSLINE(y)] + (x))
77
78 #define SETGLYPH(to,from) bcopy(&kern_font[(to)*16], &kern_font[(from)*16],16)
79 #define KFONTBASE(left) ((left) * 32 * 0x5e - 0x21 * 32)
80
81 /* prototype */
82 void tv_init __P((struct ite_softc *));
83 void tv_deinit __P((struct ite_softc *));
84 void tv_putc __P((struct ite_softc *, int, int, int, int));
85 void tv_cursor __P((struct ite_softc *, int));
86 void tv_clear __P((struct ite_softc *, int, int, int, int));
87 void tv_scroll __P((struct ite_softc *, int, int, int, int));
88
89
90 static __inline void
91 txrascpy (src, dst, size, mode)
92 u_char src, dst;
93 short size;
94 signed short mode;
95 {
96 /*int s;*/
97 u_short saved_r21 = CRTC.r21;
98 char d;
99
100 d = (mode < 0) ? -1 : 1;
101 src *= FONTHEIGHT / 4;
102 dst *= FONTHEIGHT / 4;
103 size *= 4;
104 if (d < 0) {
105 src += (FONTHEIGHT / 4) - 1;
106 dst += (FONTHEIGHT / 4) - 1;
107 }
108
109 /* specify same time write mode & page */
110 CRTC.r21 = (mode & 0x0f) | 0x0100;
111 /*mfp.ddr = 0;*/ /* port is input */
112
113 /*s = splhigh();*/
114 while (--size >= 0) {
115 /* wait for hsync */
116 while (mfp.gpip & MFP_GPIP_HSYNC)
117 asm("nop");
118 while (!(mfp.gpip & MFP_GPIP_HSYNC))
119 asm("nop");
120 CRTC.r22 = (src << 8) | dst; /* specify raster number */
121 /* start raster copy */
122 CRTC.crtctrl = 8;
123
124 src += d;
125 dst += d;
126 }
127 /*splx(s);*/
128
129 /* wait for hsync */
130 while (mfp.gpip & MFP_GPIP_HSYNC)
131 asm("nop");
132 while (!(mfp.gpip & MFP_GPIP_HSYNC))
133 asm("nop");
134 /* stop raster copy */
135 CRTC.crtctrl = 0;
136
137 CRTC.r21 = saved_r21;
138 }
139
140 /*
141 * Initialize
142 */
143 void
144 tv_init(ip)
145 struct ite_softc *ip;
146 {
147 short i;
148 u_char glyph = IODEVbase->io_sram[0x59];
149
150 /*
151 * initialize private variables
152 */
153 tv_top = 0;
154 for (i = 0; i < PLANELINES; i++)
155 tv_row[i] = (void *)&IODEVbase->tvram[ROWOFFSET(i)];
156 /* shadow ANK font */
157 bcopy((void *)&IODEVbase->cgrom0_8x16, kern_font, 256 * FONTHEIGHT);
158 /* glyph */
159 if (glyph & 4)
160 SETGLYPH(0x82, '|');
161 if (glyph & 2)
162 SETGLYPH(0x81, '~');
163 if (glyph & 1)
164 SETGLYPH(0x80, '\\');
165 /* set font address cache */
166 for (i = 0; i < 256; i++)
167 tv_font[i] = &kern_font[i * FONTHEIGHT];
168 for (i = 0x21; i < 0x30; i++)
169 tv_kfont[i] = &IODEVbase->cgrom0_16x16[KFONTBASE(i-0x21)];
170 for (; i < 0x50; i++)
171 tv_kfont[i] = &IODEVbase->cgrom1_16x16[KFONTBASE(i-0x30)];
172 for (; i < 0x7f; i++)
173 tv_kfont[i] = &IODEVbase->cgrom2_16x16[KFONTBASE(i-0x50)];
174
175 /*
176 * initialize part of ip
177 */
178 ip->cols = ip->grf->g_display.gd_dwidth / FONTWIDTH;
179 ip->rows = ip->grf->g_display.gd_dheight / FONTHEIGHT;
180 /* set draw routine dynamically */
181 ip->isw->ite_putc = tv_putc;
182 ip->isw->ite_cursor = tv_cursor;
183 ip->isw->ite_clear = tv_clear;
184 ip->isw->ite_scroll = tv_scroll;
185
186 /*
187 * Intialize colormap
188 */
189 #define RED (0x1f << 6)
190 #define BLUE (0x1f << 1)
191 #define GREEN (0x1f << 11)
192 IODEVbase->tpalet[0] = 0; /* black */
193 IODEVbase->tpalet[1] = 1 | RED; /* red */
194 IODEVbase->tpalet[2] = 1 | GREEN; /* green */
195 IODEVbase->tpalet[3] = 1 | RED | GREEN; /* yellow */
196 IODEVbase->tpalet[4] = 1 | BLUE; /* blue */
197 IODEVbase->tpalet[5] = 1 | BLUE | RED; /* magenta */
198 IODEVbase->tpalet[6] = 1 | BLUE | GREEN; /* cyan */
199 IODEVbase->tpalet[7] = 1 | BLUE | RED | GREEN; /* white */
200 }
201
202 /*
203 * Deinitialize
204 */
205 void
206 tv_deinit(ip)
207 struct ite_softc *ip;
208 {
209 ip->flags &= ~ITE_INITED; /* XXX? */
210 mfp.udr = 0x48; /* send character from keyboard disable */
211 }
212
213 typedef void tv_putcfunc __P((struct ite_softc *, int, char *));
214 static tv_putcfunc tv_putc_nm;
215 static tv_putcfunc tv_putc_in;
216 static tv_putcfunc tv_putc_ul;
217 static tv_putcfunc tv_putc_ul_in;
218 static tv_putcfunc tv_putc_bd;
219 static tv_putcfunc tv_putc_bd_in;
220 static tv_putcfunc tv_putc_bd_ul;
221 static tv_putcfunc tv_putc_bd_ul_in;
222
223 static tv_putcfunc *putc_func[ATTR_ALL + 1] = {
224 tv_putc_nm,
225 tv_putc_in,
226 tv_putc_ul,
227 tv_putc_ul_in,
228 tv_putc_bd,
229 tv_putc_bd_in,
230 tv_putc_bd_ul,
231 tv_putc_bd_ul_in,
232 /* no support for blink */
233 tv_putc_nm,
234 tv_putc_in,
235 tv_putc_ul,
236 tv_putc_ul_in,
237 tv_putc_bd,
238 tv_putc_bd_in,
239 tv_putc_bd_ul,
240 tv_putc_bd_ul_in,
241 };
242
243 /*
244 * simple put character function
245 */
246 void
247 tv_putc(ip, ch, y, x, mode)
248 struct ite_softc *ip;
249 int ch, y, x, mode;
250 {
251 char *p = CHADDR(y, x);
252 short fh;
253
254 /* multi page write mode */
255 CRTC.r21 = 0x0100 | ip->fgcolor << 4;
256
257 /* draw plane */
258 putc_func[mode](ip, ch, p);
259
260 /* erase plane */
261 CRTC.r21 ^= 0x00f0;
262 if (ip->save_char) {
263 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
264 *(u_short *)p = 0;
265 } else {
266 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
267 *p = 0;
268 }
269
270 /* crtc mode reset */
271 CRTC.r21 = 0;
272 }
273
274 void
275 tv_putc_nm(ip, ch, p)
276 struct ite_softc *ip;
277 int ch;
278 char *p;
279 {
280 short fh, hi;
281 char *f;
282 short *kf;
283
284 hi = ip->save_char & 0x7f;
285
286 if (hi >= 0x21 && hi <= 0x7e) {
287 /* multibyte character */
288 kf = (short *)tv_kfont[hi];
289 kf += (ch & 0x7f) * FONTHEIGHT;
290 /* draw plane */
291 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
292 *(u_short *)p = *kf++;
293 return;
294 }
295
296 /* singlebyte character */
297 if (*ip->GL == CSET_JISKANA)
298 ch |= 0x80;
299 f = tv_font[ch];
300
301 /* draw plane */
302 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
303 *p = *f++;
304 }
305
306 void
307 tv_putc_in(ip, ch, p)
308 struct ite_softc *ip;
309 int ch;
310 char *p;
311 {
312 short fh, hi;
313 char *f;
314 short *kf;
315
316 hi = ip->save_char & 0x7f;
317
318 if (hi >= 0x21 && hi <= 0x7e) {
319 /* multibyte character */
320 kf = (short *)tv_kfont[hi];
321 kf += (ch & 0x7f) * FONTHEIGHT;
322 /* draw plane */
323 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
324 *(u_short *)p = ~*kf++;
325 return;
326 }
327
328 /* singlebyte character */
329 if (*ip->GL == CSET_JISKANA)
330 ch |= 0x80;
331 f = tv_font[ch];
332
333 /* draw plane */
334 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
335 *p = ~*f++;
336 }
337
338 void
339 tv_putc_bd(ip, ch, p)
340 struct ite_softc *ip;
341 int ch;
342 char *p;
343 {
344 short fh, hi;
345 char *f;
346 short *kf;
347
348 hi = ip->save_char & 0x7f;
349
350 if (hi >= 0x21 && hi <= 0x7e) {
351 /* multibyte character */
352 kf = (short *)tv_kfont[hi];
353 kf += (ch & 0x7f) * FONTHEIGHT;
354 /* draw plane */
355 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
356 ch = *kf++;
357 *(u_short *)p = ch | (ch >> 1);
358 }
359 return;
360 }
361
362 /* singlebyte character */
363 if (*ip->GL == CSET_JISKANA)
364 ch |= 0x80;
365 f = tv_font[ch];
366
367 /* draw plane */
368 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
369 ch = *f++;
370 *p = ch | (ch >> 1);
371 }
372 }
373
374 static __inline int
375 expbits (data)
376 int data;
377 {
378 int i, nd = 0;
379 if (data & 1)
380 nd |= 0x02;
381 for (i=1; i < 32; i++) {
382 if (data & (1 << i))
383 nd |= 0x5 << (i-1);
384 }
385 nd &= ~data;
386 return (~nd);
387 }
388
389 void
390 tv_putc_ul(ip, ch, p)
391 struct ite_softc *ip;
392 int ch;
393 char *p;
394 {
395 short fh, hi;
396 char *f;
397 short *kf;
398
399 hi = ip->save_char & 0x7f;
400
401 if (hi >= 0x21 && hi <= 0x7e) {
402 /* multibyte character */
403 kf = (short *)tv_kfont[hi];
404 kf += (ch & 0x7f) * FONTHEIGHT;
405 /* draw plane */
406 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
407 *(u_short *)p = *kf++;
408 *(u_short *)p = expbits(*kf++);
409 p += ROWBYTES;
410 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
411 *(u_short *)p = *kf++;
412 return;
413 }
414
415 /* singlebyte character */
416 if (*ip->GL == CSET_JISKANA)
417 ch |= 0x80;
418 f = tv_font[ch];
419
420 /* draw plane */
421 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
422 *p = *f++;
423 *p = expbits(*f++);
424 p += ROWBYTES;
425 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
426 *p = *f++;
427 }
428
429 void
430 tv_putc_bd_in(ip, ch, p)
431 struct ite_softc *ip;
432 int ch;
433 char *p;
434 {
435 short fh, hi;
436 char *f;
437 short *kf;
438
439 hi = ip->save_char & 0x7f;
440
441 if (hi >= 0x21 && hi <= 0x7e) {
442 /* multibyte character */
443 kf = (short *)tv_kfont[hi];
444 kf += (ch & 0x7f) * FONTHEIGHT;
445 /* draw plane */
446 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
447 ch = *kf++;
448 *(u_short *)p = ~(ch | (ch >> 1));
449 }
450 return;
451 }
452
453 /* singlebyte character */
454 if (*ip->GL == CSET_JISKANA)
455 ch |= 0x80;
456 f = tv_font[ch];
457
458 /* draw plane */
459 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
460 ch = *f++;
461 *p = ~(ch | (ch >> 1));
462 }
463 }
464
465 void
466 tv_putc_ul_in(ip, ch, p)
467 struct ite_softc *ip;
468 int ch;
469 char *p;
470 {
471 short fh, hi;
472 char *f;
473 short *kf;
474
475 hi = ip->save_char & 0x7f;
476
477 if (hi >= 0x21 && hi <= 0x7e) {
478 /* multibyte character */
479 kf = (short *)tv_kfont[hi];
480 kf += (ch & 0x7f) * FONTHEIGHT;
481 /* draw plane */
482 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
483 *(u_short *)p = ~*kf++;
484 *(u_short *)p = ~expbits(*kf++);
485 p += ROWBYTES;
486 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
487 *(u_short *)p = ~*kf++;
488 return;
489 }
490
491 /* singlebyte character */
492 if (*ip->GL == CSET_JISKANA)
493 ch |= 0x80;
494 f = tv_font[ch];
495
496 /* draw plane */
497 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
498 *p = ~*f++;
499 *p = ~expbits(*f++);
500 p += ROWBYTES;
501 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
502 *p = ~*f++;
503 }
504
505 void
506 tv_putc_bd_ul(ip, ch, p)
507 struct ite_softc *ip;
508 int ch;
509 char *p;
510 {
511 short fh, hi;
512 char *f;
513 short *kf;
514
515 hi = ip->save_char & 0x7f;
516
517 if (hi >= 0x21 && hi <= 0x7e) {
518 /* multibyte character */
519 kf = (short *)tv_kfont[hi];
520 kf += (ch & 0x7f) * FONTHEIGHT;
521 /* draw plane */
522 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
523 ch = *kf++;
524 *(u_short *)p = ch | (ch >> 1);
525 }
526 ch = *kf++;
527 *(u_short *)p = expbits(ch | (ch >> 1));
528 p += ROWBYTES;
529 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
530 ch = *kf++;
531 *(u_short *)p = ch | (ch >> 1);
532 }
533 return;
534 }
535
536 /* singlebyte character */
537 if (*ip->GL == CSET_JISKANA)
538 ch |= 0x80;
539 f = tv_font[ch];
540
541 /* draw plane */
542 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
543 ch = *f++;
544 *p = ch | (ch >> 1);
545 }
546 ch = *f++;
547 *p = expbits(ch | (ch >> 1));
548 p += ROWBYTES;
549 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
550 ch = *f++;
551 *p = ch | (ch >> 1);
552 }
553 }
554
555 void
556 tv_putc_bd_ul_in(ip, ch, p)
557 struct ite_softc *ip;
558 int ch;
559 char *p;
560 {
561 short fh, hi;
562 char *f;
563 short *kf;
564
565 hi = ip->save_char & 0x7f;
566
567 if (hi >= 0x21 && hi <= 0x7e) {
568 /* multibyte character */
569 kf = (short *)tv_kfont[hi];
570 kf += (ch & 0x7f) * FONTHEIGHT;
571 /* draw plane */
572 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
573 ch = *kf++;
574 *(u_short *)p = ~(ch | (ch >> 1));
575 }
576 ch = *kf++;
577 *(u_short *)p = ~expbits(ch | (ch >> 1));
578 p += ROWBYTES;
579 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
580 ch = *kf++;
581 *(u_short *)p = ~(ch | (ch >> 1));
582 }
583 return;
584 }
585
586 /* singlebyte character */
587 if (*ip->GL == CSET_JISKANA)
588 ch |= 0x80;
589 f = tv_font[ch];
590
591 /* draw plane */
592 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
593 ch = *f++;
594 *p = ~(ch | (ch >> 1));
595 }
596 ch = *f++;
597 *p = ~expbits(ch | (ch >> 1));
598 p += ROWBYTES;
599 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
600 ch = *f++;
601 ch |= ch >> 1;
602 *p = ~(ch | (ch >> 1));
603 }
604 }
605
606 /*
607 * draw/erase/move cursor
608 */
609 void
610 tv_cursor(ip, flag)
611 struct ite_softc *ip;
612 int flag;
613 {
614 u_char *p;
615 short fh;
616
617 /* erase */
618 switch (flag) {
619 /*case DRAW_CURSOR:*/
620 /*case ERASE_CURSOR:*/
621 /*case MOVE_CURSOR:*/
622 case START_CURSOROPT:
623 /*
624 * old: ip->cursorx, ip->cursory
625 * new: ip->curx, ip->cury
626 */
627 p = CHADDR(ip->cursory, ip->cursorx);
628 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
629 *p = ~*p;
630 break;
631 }
632
633 /* draw */
634 switch (flag) {
635 /*case MOVE_CURSOR:*/
636 case END_CURSOROPT:
637 /*
638 * Use exclusive-or.
639 */
640 p = CHADDR(ip->cury, ip->curx);
641 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
642 *p = ~*p;
643
644 ip->cursorx = ip->curx;
645 ip->cursory = ip->cury;
646 break;
647 }
648 }
649
650 /*
651 * clear rectangle
652 */
653 void
654 tv_clear(ip, y, x, height, width)
655 struct ite_softc *ip;
656 int y, x, height, width;
657 {
658 char *p;
659 short fh;
660
661 CRTC.r21 = 0x01f0;
662 while (height--) {
663 p = CHADDR(y++, x);
664 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
665 bzero(p, width);
666 }
667 /* crtc mode reset */
668 CRTC.r21 = 0;
669 }
670
671 /*
672 * scroll lines/columns
673 */
674 void
675 tv_scroll(ip, srcy, srcx, count, dir)
676 struct ite_softc *ip;
677 int srcy, srcx, count, dir;
678 {
679 int dst, siz, pl;
680
681 switch (dir) {
682 case SCROLL_UP:
683 /*
684 * src: srcy
685 * dst: (srcy - count)
686 * siz: (ip->bottom_margin - sy + 1)
687 */
688 dst = srcy - count;
689 siz = ip->bottom_margin - srcy + 1;
690 if (dst == 0 && ip->bottom_margin == ip->rows - 1) {
691 /* special case, hardware scroll */
692 tv_top = (tv_top + count) % PLANELINES;
693 CRTC.r11 = tv_top * FONTHEIGHT;
694 } else {
695 srcy = PHYSLINE(srcy);
696 dst = PHYSLINE(dst);
697 txrascpy(srcy, dst, siz, 0x0f);
698 }
699 break;
700
701 case SCROLL_DOWN:
702 /*
703 * src: srcy
704 * dst: (srcy + count)
705 * siz: (ip->bottom_margin - dy + 1)
706 */
707 dst = srcy + count;
708 siz = ip->bottom_margin - dst + 1;
709 if (srcy == 0 && ip->bottom_margin == ip->rows - 1) {
710 /* special case, hardware scroll */
711 tv_top = (tv_top + PLANELINES - count) % PLANELINES;
712 CRTC.r11 = tv_top * FONTHEIGHT;
713 } else {
714 srcy = PHYSLINE(srcy) + siz - 1;
715 dst = PHYSLINE(dst) + siz - 1;
716 txrascpy(srcy, dst, siz, 0x0f | 0x8000);
717 }
718 break;
719
720 case SCROLL_LEFT:
721 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
722 short fh;
723 char *src = CHADDR(srcy, srcx) + pl;
724 char *dst = CHADDR(srcy, srcx - count) + pl;
725
726 siz = ip->cols - srcx;
727 for (fh = 0; fh < FONTHEIGHT; fh++) {
728 bcopy(src, dst, siz);
729 src += ROWBYTES;
730 dst += ROWBYTES;
731 }
732 }
733 break;
734
735 case SCROLL_RIGHT:
736 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
737 short fh;
738 char *src = CHADDR(srcy, srcx) + pl;
739 char *dst = CHADDR(srcy, srcx + count) + pl;
740
741 siz = ip->cols - (srcx + count);
742 for (fh = 0; fh < FONTHEIGHT; fh++) {
743 bcopy(src, dst, siz);
744 src += ROWBYTES;
745 dst += ROWBYTES;
746 }
747 }
748 break;
749 }
750 }
751