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