ite_tv.c revision 1.1 1 /* $NetBSD: ite_tv.c,v 1.1 1997/01/26 12:04:54 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[0x7e];
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 /* prototype */
79 void tv_init __P((struct ite_softc *));
80 void tv_deinit __P((struct ite_softc *));
81 void tv_putc __P((struct ite_softc *, int, int, int, int));
82 void tv_cursor __P((struct ite_softc *, int));
83 void tv_clear __P((struct ite_softc *, int, int, int, int));
84 void tv_scroll __P((struct ite_softc *, int, int, int, int));
85
86
87 static __inline void
88 txrascpy (src, dst, size, mode)
89 u_char src, dst;
90 short size;
91 signed short mode;
92 {
93 /*int s;*/
94 u_short saved_r21 = CRTC.r21;
95 char d;
96
97 d = (mode < 0) ? -1 : 1;
98 src *= FONTHEIGHT / 4;
99 dst *= FONTHEIGHT / 4;
100 size *= 4;
101 if (d < 0) {
102 src += (FONTHEIGHT / 4) - 1;
103 dst += (FONTHEIGHT / 4) - 1;
104 }
105
106 /* specify same time write mode & page */
107 CRTC.r21 = (mode & 0x0f) | 0x0100;
108 /*mfp.ddr = 0;*/ /* port is input */
109
110 /*s = splhigh();*/
111 while (--size >= 0) {
112 /* wait for hsync */
113 while (mfp.gpip & MFP_GPIP_HSYNC)
114 asm("nop");
115 while (!(mfp.gpip & MFP_GPIP_HSYNC))
116 asm("nop");
117 CRTC.r22 = (src << 8) | dst; /* specify raster number */
118 /* start raster copy */
119 CRTC.crtctrl = 8;
120
121 src += d;
122 dst += d;
123 }
124 /*splx(s);*/
125
126 /* wait for hsync */
127 while (mfp.gpip & MFP_GPIP_HSYNC)
128 asm("nop");
129 while (!(mfp.gpip & MFP_GPIP_HSYNC))
130 asm("nop");
131 /* stop raster copy */
132 CRTC.crtctrl = 0;
133
134 CRTC.r21 = saved_r21;
135 }
136
137 /*
138 * Initialize
139 */
140 void
141 tv_init(ip)
142 struct ite_softc *ip;
143 {
144 short i;
145 u_char glyph = IODEVbase->io_sram[0x59];
146
147 /*
148 * initialize private variables
149 */
150 tv_top = 0;
151 for (i = 0; i < PLANELINES; i++)
152 tv_row[i] = (void *)&IODEVbase->tvram[ROWOFFSET(i)];
153 /* shadow ANK font */
154 bcopy((void *)&IODEVbase->cgrom0_8x16, kern_font, 256 * FONTHEIGHT);
155 /* glyph */
156 if (glyphmode & 4)
157 bcopy(&kern_font[0x82 * 16], &kern_font['|' * 16], 16);
158 if (glyphmode & 2)
159 bcopy(&kern_font[0x81 * 16], &kern_font['~' * 16], 16);
160 if (glyphmode & 1)
161 bcopy(&kern_font[0x80 * 16], &kern_font['\\' * 16], 16);
162 /* set font address cache */
163 for (i = 0; i < 256; i++)
164 tv_font[i] = &kern_font[i * FONTHEIGHT];
165 for (i = 0x21; i < 0x30; i++)
166 tv_kfont[i] = &IODEVbase->cgrom0_16x16[(i-0x21)*32*0x5e];
167 for (; i < 0x50; i++)
168 tv_kfont[i] = &IODEVbase->cgrom1_16x16[(i-0x30)*32*0x5e];
169 for (; i < 0x7f; i++)
170 tv_kfont[i] = &IODEVbase->cgrom2_16x16[(i-0x50)*32*0x5e];
171
172 /*
173 * initialize part of ip
174 */
175 ip->cols = ip->grf->g_display.gd_dwidth / FONTWIDTH;
176 ip->rows = ip->grf->g_display.gd_dheight / FONTHEIGHT;
177 /* set draw routine dynamically */
178 ip->isw->ite_putc = tv_putc;
179 ip->isw->ite_cursor = tv_cursor;
180 ip->isw->ite_clear = tv_clear;
181 ip->isw->ite_scroll = tv_scroll;
182
183 /*
184 * Intialize colormap
185 */
186 #define RED (0x1f << 6)
187 #define BLUE (0x1f << 1)
188 #define GREEN (0x1f << 11)
189 IODEVbase->tpalet[0] = 0; /* black */
190 IODEVbase->tpalet[1] = 1 | RED; /* red */
191 IODEVbase->tpalet[2] = 1 | GREEN; /* green */
192 IODEVbase->tpalet[3] = 1 | RED | GREEN; /* yellow */
193 IODEVbase->tpalet[4] = 1 | BLUE; /* blue */
194 IODEVbase->tpalet[5] = 1 | BLUE | RED; /* magenta */
195 IODEVbase->tpalet[6] = 1 | BLUE | GREEN; /* cyan */
196 IODEVbase->tpalet[7] = 1 | BLUE | RED | GREEN; /* white */
197 }
198
199 /*
200 * Deinitialize
201 */
202 void
203 tv_deinit(ip)
204 struct ite_softc *ip;
205 {
206 ip->flags &= ~ITE_INITED; /* XXX? */
207 mfp.udr = 0x48; /* send character from keyboard disable */
208 }
209
210 typedef void tv_putcfunc __P((struct ite_softc *, int, char *));
211 static tv_putcfunc tv_putc_nm;
212 static tv_putcfunc tv_putc_in;
213 static tv_putcfunc tv_putc_ul;
214 static tv_putcfunc tv_putc_ul_in;
215 static tv_putcfunc tv_putc_bd;
216 static tv_putcfunc tv_putc_bd_in;
217 static tv_putcfunc tv_putc_bd_ul;
218 static tv_putcfunc tv_putc_bd_ul_in;
219
220 static tv_putcfunc *putc_func[ATTR_ALL + 1] = {
221 tv_putc_nm,
222 tv_putc_in,
223 tv_putc_ul,
224 tv_putc_ul_in,
225 tv_putc_bd,
226 tv_putc_bd_in,
227 tv_putc_bd_ul,
228 tv_putc_bd_ul_in,
229 /* no support for blink */
230 tv_putc_nm,
231 tv_putc_in,
232 tv_putc_ul,
233 tv_putc_ul_in,
234 tv_putc_bd,
235 tv_putc_bd_in,
236 tv_putc_bd_ul,
237 tv_putc_bd_ul_in,
238 };
239
240 /*
241 * simple put character function
242 */
243 void
244 tv_putc(ip, ch, y, x, mode)
245 struct ite_softc *ip;
246 int ch, y, x, mode;
247 {
248 char *p = CHADDR(y, x);
249 short fh;
250
251 /* multi page write mode */
252 CRTC.r21 = 0x0100 | ip->fgcolor << 4;
253
254 /* draw plane */
255 putc_func[mode](ip, ch, p);
256
257 /* erase plane */
258 CRTC.r21 ^= 0x00f0;
259 if (ip->save_char) {
260 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
261 *(u_short *)p = 0;
262 } else {
263 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
264 *p = 0;
265 }
266
267 /* crtc mode reset */
268 CRTC.r21 = 0;
269 }
270
271 void
272 tv_putc_nm(ip, ch, p)
273 struct ite_softc *ip;
274 int ch;
275 char *p;
276 {
277 short fh, hi;
278 char *f;
279 short *kf;
280
281 hi = ip->save_char & 0x7f;
282
283 if (hi >= 0x21 && hi <= 0x7e) {
284 /* multibyte character */
285 kf = (short *)tv_kfont[hi];
286 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
287 /* draw plane */
288 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
289 *(u_short *)p = *kf++;
290 return;
291 }
292
293 /* singlebyte character */
294 if (*ip->GL == CSET_JISKANA)
295 ch |= 0x80;
296 f = tv_font[ch];
297
298 /* draw plane */
299 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
300 *p = *f++;
301 }
302
303 void
304 tv_putc_in(ip, ch, p)
305 struct ite_softc *ip;
306 int ch;
307 char *p;
308 {
309 short fh, hi;
310 char *f;
311 short *kf;
312
313 hi = ip->save_char & 0x7f;
314
315 if (hi >= 0x21 && hi <= 0x7e) {
316 /* multibyte character */
317 kf = (short *)tv_kfont[hi];
318 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
319 /* draw plane */
320 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
321 *(u_short *)p = ~*kf++;
322 return;
323 }
324
325 /* singlebyte character */
326 if (*ip->GL == CSET_JISKANA)
327 ch |= 0x80;
328 f = tv_font[ch];
329
330 /* draw plane */
331 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
332 *p = ~*f++;
333 }
334
335 void
336 tv_putc_bd(ip, ch, p)
337 struct ite_softc *ip;
338 int ch;
339 char *p;
340 {
341 short fh, hi;
342 char *f;
343 short *kf;
344
345 hi = ip->save_char & 0x7f;
346
347 if (hi >= 0x21 && hi <= 0x7e) {
348 /* multibyte character */
349 kf = (short *)tv_kfont[hi];
350 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
351 /* draw plane */
352 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
353 ch = *kf++;
354 *(u_short *)p = ch | (ch >> 1);
355 }
356 return;
357 }
358
359 /* singlebyte character */
360 if (*ip->GL == CSET_JISKANA)
361 ch |= 0x80;
362 f = tv_font[ch];
363
364 /* draw plane */
365 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
366 ch = *f++;
367 *p = ch | (ch >> 1);
368 }
369 }
370
371 static __inline int
372 expbits (data)
373 int data;
374 {
375 int i, nd = 0;
376 if (data & 1)
377 nd |= 0x02;
378 for (i=1; i < 32; i++) {
379 if (data & (1 << i))
380 nd |= 0x5 << (i-1);
381 }
382 nd &= ~data;
383 return (~nd);
384 }
385
386 void
387 tv_putc_ul(ip, ch, p)
388 struct ite_softc *ip;
389 int ch;
390 char *p;
391 {
392 short fh, hi;
393 char *f;
394 short *kf;
395
396 hi = ip->save_char & 0x7f;
397
398 if (hi >= 0x21 && hi <= 0x7e) {
399 /* multibyte character */
400 kf = (short *)tv_kfont[hi];
401 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
402 /* draw plane */
403 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
404 *(u_short *)p = *kf++;
405 *(u_short *)p = expbits(*kf++);
406 p += ROWBYTES;
407 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
408 *(u_short *)p = *kf++;
409 return;
410 }
411
412 /* singlebyte character */
413 if (*ip->GL == CSET_JISKANA)
414 ch |= 0x80;
415 f = tv_font[ch];
416
417 /* draw plane */
418 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
419 *p = *f++;
420 *p = expbits(*f++);
421 p += ROWBYTES;
422 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
423 *p = *f++;
424 }
425
426 void
427 tv_putc_bd_in(ip, ch, p)
428 struct ite_softc *ip;
429 int ch;
430 char *p;
431 {
432 short fh, hi;
433 char *f;
434 short *kf;
435
436 hi = ip->save_char & 0x7f;
437
438 if (hi >= 0x21 && hi <= 0x7e) {
439 /* multibyte character */
440 kf = (short *)tv_kfont[hi];
441 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
442 /* draw plane */
443 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
444 ch = *kf++;
445 *(u_short *)p = ~(ch | (ch >> 1));
446 }
447 return;
448 }
449
450 /* singlebyte character */
451 if (*ip->GL == CSET_JISKANA)
452 ch |= 0x80;
453 f = tv_font[ch];
454
455 /* draw plane */
456 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
457 ch = *f++;
458 *p = ~(ch | (ch >> 1));
459 }
460 }
461
462 void
463 tv_putc_ul_in(ip, ch, p)
464 struct ite_softc *ip;
465 int ch;
466 char *p;
467 {
468 short fh, hi;
469 char *f;
470 short *kf;
471
472 hi = ip->save_char & 0x7f;
473
474 if (hi >= 0x21 && hi <= 0x7e) {
475 /* multibyte character */
476 kf = (short *)tv_kfont[hi];
477 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
478 /* draw plane */
479 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
480 *(u_short *)p = ~*kf++;
481 *(u_short *)p = ~expbits(*kf++);
482 p += ROWBYTES;
483 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
484 *(u_short *)p = ~*kf++;
485 return;
486 }
487
488 /* singlebyte character */
489 if (*ip->GL == CSET_JISKANA)
490 ch |= 0x80;
491 f = tv_font[ch];
492
493 /* draw plane */
494 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
495 *p = ~*f++;
496 *p = ~expbits(*f++);
497 p += ROWBYTES;
498 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
499 *p = ~*f++;
500 }
501
502 void
503 tv_putc_bd_ul(ip, ch, p)
504 struct ite_softc *ip;
505 int ch;
506 char *p;
507 {
508 short fh, hi;
509 char *f;
510 short *kf;
511
512 hi = ip->save_char & 0x7f;
513
514 if (hi >= 0x21 && hi <= 0x7e) {
515 /* multibyte character */
516 kf = (short *)tv_kfont[hi];
517 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
518 /* draw plane */
519 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
520 ch = *kf++;
521 *(u_short *)p = ch | (ch >> 1);
522 }
523 ch = *kf++;
524 *(u_short *)p = expbits(ch | (ch >> 1));
525 p += ROWBYTES;
526 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
527 ch = *kf++;
528 *(u_short *)p = ch | (ch >> 1);
529 }
530 return;
531 }
532
533 /* singlebyte character */
534 if (*ip->GL == CSET_JISKANA)
535 ch |= 0x80;
536 f = tv_font[ch];
537
538 /* draw plane */
539 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
540 ch = *f++;
541 *p = ch | (ch >> 1);
542 }
543 ch = *f++;
544 *p = expbits(ch | (ch >> 1));
545 p += ROWBYTES;
546 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
547 ch = *f++;
548 *p = ch | (ch >> 1);
549 }
550 }
551
552 void
553 tv_putc_bd_ul_in(ip, ch, p)
554 struct ite_softc *ip;
555 int ch;
556 char *p;
557 {
558 short fh, hi;
559 char *f;
560 short *kf;
561
562 hi = ip->save_char & 0x7f;
563
564 if (hi >= 0x21 && hi <= 0x7e) {
565 /* multibyte character */
566 kf = (short *)tv_kfont[hi];
567 kf += ((ch & 0x7f) - 0x21) * FONTHEIGHT;
568 /* draw plane */
569 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
570 ch = *kf++;
571 *(u_short *)p = ~(ch | (ch >> 1));
572 }
573 ch = *kf++;
574 *(u_short *)p = ~expbits(ch | (ch >> 1));
575 p += ROWBYTES;
576 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
577 ch = *kf++;
578 *(u_short *)p = ~(ch | (ch >> 1));
579 }
580 return;
581 }
582
583 /* singlebyte character */
584 if (*ip->GL == CSET_JISKANA)
585 ch |= 0x80;
586 f = tv_font[ch];
587
588 /* draw plane */
589 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
590 ch = *f++;
591 *p = ~(ch | (ch >> 1));
592 }
593 ch = *f++;
594 *p = ~expbits(ch | (ch >> 1));
595 p += ROWBYTES;
596 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
597 ch = *f++;
598 ch |= ch >> 1;
599 *p = ~(ch | (ch >> 1));
600 }
601 }
602
603 /*
604 * draw/erase/move cursor
605 */
606 void
607 tv_cursor(ip, flag)
608 struct ite_softc *ip;
609 int flag;
610 {
611 u_char *p;
612 short fh;
613
614 /* erase */
615 switch (flag) {
616 /*case DRAW_CURSOR:*/
617 /*case ERASE_CURSOR:*/
618 /*case MOVE_CURSOR:*/
619 case START_CURSOROPT:
620 /*
621 * old: ip->cursorx, ip->cursory
622 * new: ip->curx, ip->cury
623 */
624 p = CHADDR(ip->cursory, ip->cursorx);
625 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
626 *p = ~*p;
627 break;
628 }
629
630 /* draw */
631 switch (flag) {
632 /*case MOVE_CURSOR:*/
633 case END_CURSOROPT:
634 /*
635 * Use exclusive-or.
636 */
637 p = CHADDR(ip->cury, ip->curx);
638 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
639 *p = ~*p;
640
641 ip->cursorx = ip->curx;
642 ip->cursory = ip->cury;
643 break;
644 }
645 }
646
647 /*
648 * clear rectangle
649 */
650 void
651 tv_clear(ip, y, x, height, width)
652 struct ite_softc *ip;
653 int y, x, height, width;
654 {
655 char *p;
656 short fh;
657
658 CRTC.r21 = 0x01f0;
659 while (height--) {
660 p = CHADDR(y++, x);
661 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
662 bzero(p, width);
663 }
664 /* crtc mode reset */
665 CRTC.r21 = 0;
666 }
667
668 /*
669 * scroll lines/columns
670 */
671 void
672 tv_scroll(ip, srcy, srcx, count, dir)
673 struct ite_softc *ip;
674 int srcy, srcx, count, dir;
675 {
676 int dst, siz, pl;
677
678 switch (dir) {
679 case SCROLL_UP:
680 /*
681 * src: srcy
682 * dst: (srcy - count)
683 * siz: (ip->bottom_margin - sy + 1)
684 */
685 dst = srcy - count;
686 siz = ip->bottom_margin - srcy + 1;
687 if (dst == 0 && ip->bottom_margin == ip->rows - 1) {
688 /* special case, hardware scroll */
689 tv_top = (tv_top + count) % PLANELINES;
690 CRTC.r11 = tv_top * FONTHEIGHT;
691 } else {
692 srcy = PHYSLINE(srcy);
693 dst = PHYSLINE(dst);
694 txrascpy(srcy, dst, siz, 0x0f);
695 }
696 break;
697
698 case SCROLL_DOWN:
699 /*
700 * src: srcy
701 * dst: (srcy + count)
702 * siz: (ip->bottom_margin - dy + 1)
703 */
704 dst = srcy + count;
705 siz = ip->bottom_margin - dst + 1;
706 if (srcy == 0 && ip->bottom_margin == ip->rows - 1) {
707 /* special case, hardware scroll */
708 tv_top = (tv_top + PLANELINES - count) % PLANELINES;
709 CRTC.r11 = tv_top * FONTHEIGHT;
710 } else {
711 srcy = PHYSLINE(srcy) + siz - 1;
712 dst = PHYSLINE(dst) + siz - 1;
713 txrascpy(srcy, dst, siz, 0x0f | 0x8000);
714 }
715 break;
716
717 case SCROLL_LEFT:
718 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
719 short fh;
720 char *src = CHADDR(srcy, srcx) + pl;
721 char *dst = CHADDR(srcy, srcx - count) + pl;
722
723 siz = ip->cols - srcx;
724 for (fh = 0; fh < FONTHEIGHT; fh++) {
725 bcopy(src, dst, siz);
726 src += ROWBYTES;
727 dst += ROWBYTES;
728 }
729 }
730 break;
731
732 case SCROLL_RIGHT:
733 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
734 short fh;
735 char *src = CHADDR(srcy, srcx) + pl;
736 char *dst = CHADDR(srcy, srcx + count) + pl;
737
738 siz = ip->cols - (srcx + count);
739 for (fh = 0; fh < FONTHEIGHT; fh++) {
740 bcopy(src, dst, siz);
741 src += ROWBYTES;
742 dst += ROWBYTES;
743 }
744 }
745 break;
746 }
747 }
748