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