xref: /netbsd-src/sys/arch/luna68k/stand/boot/bmd.c (revision 2c375dfeefc2fa4344bdc70d51780afd037cdb6c)
1 /*	$NetBSD: bmd.c,v 1.10 2024/07/05 19:28:36 andvar Exp $	*/
2 
3 /*
4  * Copyright (c) 1992 OMRON Corporation.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * OMRON Corporation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by the University of
20  *	California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *	@(#)bmd.c	8.2 (Berkeley) 8/15/93
38  */
39 /*
40  * Copyright (c) 1992, 1993
41  *	The Regents of the University of California.  All rights reserved.
42  *
43  * This code is derived from software contributed to Berkeley by
44  * OMRON Corporation.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. Neither the name of the University nor the names of its contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  *
70  *	@(#)bmd.c	8.2 (Berkeley) 8/15/93
71  */
72 /*
73 
74  * bmd.c --- Bitmap-Display raw-level driver routines
75  *
76  *	by A.Fujita, SEP-09-1992
77  */
78 
79 
80 #include <sys/param.h>
81 #include <luna68k/stand/boot/samachdep.h>
82 #include <machine/board.h>
83 
84 /*
85  *  RFCNT register
86  */
87 
88 union bmd_rfcnt {
89 	struct {
90 		int16_t	rfc_hcnt;
91 		int16_t	rfc_vcnt;
92 	} p;
93 	uint32_t u;
94 };
95 
96 #define isprint(c)	((c) >= 0x20 && (c) < 0x7f)
97 
98 /*
99  *  Width & Height
100  */
101 
102 #define BMAP_OFFSET	8
103 
104 #define PB_WIDTH	2048			/* Plane Width   (Bit) */
105 #define PB_HEIGHT	1024			/* Plane Height  (Bit) */
106 #define PL_WIDTH	64			/* Plane Width  (long) */
107 #define PS_WIDTH	128			/* Plane Width  (long) */
108 #define P_WIDTH		256			/* Plane Width  (Byte) */
109 
110 #define SB_WIDTH	1280			/* Screen Width  (Bit) */
111 #define SB_HEIGHT	1024			/* Screen Height (Bit) */
112 #define SL_WIDTH	40			/* Screen Width (Long) */
113 #define S_WIDTH		160			/* Screen Width (Byte) */
114 
115 #define FB_WIDTH	12			/* Font Width    (Bit) */
116 #define FB_HEIGHT	20			/* Font Height   (Bit) */
117 
118 
119 #define NEXT_LINE(addr)			(addr +  (PL_WIDTH * FB_HEIGHT))
120 #define SKIP_NEXT_LINE(addr)		(addr += (PL_WIDTH - SL_WIDTH))
121 
122 
123 static void	bmd_draw_char(uint8_t *, uint8_t *, int, int, int);
124 static void	bmd_reverse_char(uint8_t *, uint8_t *, int, int);
125 static void	bmd_erase_char(uint8_t *, uint8_t *, int, int);
126 static void	bmd_erase_screen(volatile uint32_t *);
127 static void	bmd_scroll_screen(volatile uint32_t *, volatile uint32_t *,
128 		    int, int, int, int);
129 
130 
131 struct bmd_linec {
132 	struct bmd_linec *bl_next;
133 	struct bmd_linec *bl_prev;
134 	int	bl_col;
135 	int	bl_end;
136 	uint8_t	bl_line[128];
137 };
138 
139 struct bmd_softc {
140 	int	bc_stat;
141 	uint8_t *bc_raddr;
142 	uint8_t *bc_waddr;
143 	int	bc_xmin;
144 	int	bc_xmax;
145 	int	bc_ymin;
146 	int	bc_ymax;
147 	int	bc_col;
148 	int	bc_row;
149 	struct bmd_linec *bc_bl;
150 	char	bc_escseq[8];
151 	char   *bc_esc;
152 	void  (*bc_escape)(int);
153 };
154 
155 #define STAT_NORMAL	0x0000
156 #define STAT_ESCAPE	0x0001
157 #define STAT_INSERT	0x0100
158 
159 static struct	bmd_softc bmd_softc;
160 static struct	bmd_linec bmd_linec[52];
161 
162 static void	bmd_escape(int);
163 static void	bmd_escape_0(int);
164 #if 0
165 static void	bmd_escape_1(int);
166 #endif
167 
168 
169 /*
170  * Escape-Sequence
171  */
172 
173 static void
bmd_escape(int c)174 bmd_escape(int c)
175 {
176 	struct bmd_softc *bp = &bmd_softc;
177 
178 	switch (c) {
179 
180 	case '[':
181 		bp->bc_escape = bmd_escape_0;
182 		break;
183 
184 	default:
185 		bp->bc_stat &= ~STAT_ESCAPE;
186 		bp->bc_esc = &bp->bc_escseq[0];
187 		bp->bc_escape = bmd_escape;
188 		break;
189 	}
190 }
191 
192 static void
bmd_escape_0(int c)193 bmd_escape_0(int c)
194 {
195 	struct bmd_softc *bp = &bmd_softc;
196 	struct bmd_linec *bq = bp->bc_bl;
197 
198 	switch (c) {
199 
200 	case 'A':
201 		if (bp->bc_row > bp->bc_ymin) {
202 			bp->bc_row--;
203 		}
204 		break;
205 
206 	case 'C':
207 		if (bq->bl_col < bp->bc_xmax - 1) {
208 			bq->bl_col++;
209 		}
210 		break;
211 
212 	case 'K':
213 		if (bq->bl_col < bp->bc_xmax) {
214 			int col;
215 			for (col = bq->bl_col; col < bp->bc_xmax; col++)
216 				bmd_erase_char(bp->bc_raddr,
217 					       bp->bc_waddr,
218 					       col, bp->bc_row);
219 		}
220 		bq->bl_end = bq->bl_col;
221 		break;
222 
223 	case 'H':
224 		bq->bl_col = bq->bl_end = bp->bc_xmin;
225 		bp->bc_row = bp->bc_ymin;
226 		break;
227 
228 	default:
229 #if 0
230 		*bp->bc_esc++ = c;
231 		bp->bc_escape = bmd_escape_1;
232 		return;
233 #endif
234 		break;
235 	}
236 
237 	bp->bc_stat &= ~STAT_ESCAPE;
238 	bp->bc_esc = &bp->bc_escseq[0];
239 	bp->bc_escape = bmd_escape;
240 }
241 
242 #if 0
243 static void
244 bmd_escape_1(int c)
245 {
246 	struct bmd_softc *bp = &bmd_softc;
247 	struct bmd_linec *bq = bp->bc_bl;
248 	int col = 0, row = 0;
249 	char *p;
250 
251 	switch (c) {
252 
253 	case 'J':
254 		bp->bc_stat &= ~STAT_ESCAPE;
255 		bp->bc_esc = &bp->bc_escseq[0];
256 		bp->bc_escape = bmd_escape;
257 		break;
258 
259 	case 'H':
260 		for (p = &bp->bc_escseq[0]; *p != ';'; p++)
261 			row = (row * 10) + (*p - 0x30);
262 		p++;
263 		for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++)
264 			col = (col * 10) + (*p - 0x30);
265 
266 		bq->bl_col = col + bp->bc_xmin;
267 		bp->bc_row = row + bp->bc_ymin;
268 
269 		bp->bc_stat &= ~STAT_ESCAPE;
270 		bp->bc_esc = &bp->bc_escseq[0];
271 		bp->bc_escape = bmd_escape;
272 		break;
273 
274 	default:
275 		*bp->bc_esc++ = c;
276 		break;
277 	}
278 }
279 #endif
280 
281 /*
282  * Entry Routine
283  */
284 
285 void
bmdinit(void)286 bmdinit(void)
287 {
288 	volatile uint32_t *bmd_rfcnt = (uint32_t *)BMAP_RFCNT;
289 	volatile uint32_t *bmd_bmsel = (uint32_t *)BMAP_BMSEL;
290 	struct bmd_softc *bp = &bmd_softc;
291 	struct bmd_linec *bq;
292 	int i;
293 	union bmd_rfcnt rfcnt;
294 
295 	/*
296 	 *  adjust plane position
297 	 */
298 
299 	/* plane-0 hardware address */
300 	bp->bc_raddr = (uint8_t *)(BMAP_BMAP0 + BMAP_OFFSET);
301 	/* common bitmap hardware address */
302 	bp->bc_waddr = (uint8_t *)(BMAP_BMP   + BMAP_OFFSET);
303 
304 	rfcnt.p.rfc_hcnt = 7;			/* shift left   16 dot */
305 	rfcnt.p.rfc_vcnt = -27;			/* shift down    1 dot */
306 	*bmd_rfcnt = rfcnt.u;
307 
308 	bp->bc_stat  = STAT_NORMAL;
309 
310 	bp->bc_xmin  = 8;
311 	bp->bc_xmax  = 96;
312 	bp->bc_ymin  = 2;
313 	bp->bc_ymax  = 48;
314 
315 	bp->bc_row = bp->bc_ymin;
316 
317 	for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
318 		bmd_linec[i].bl_next = &bmd_linec[i + 1];
319 		bmd_linec[i].bl_prev = &bmd_linec[i - 1];
320 	}
321 	bmd_linec[bp->bc_ymax - 1].bl_next = &bmd_linec[bp->bc_ymin];
322 	bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax - 1];
323 
324 	bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
325 	bq->bl_col = bq->bl_end = bp->bc_xmin;
326 
327 	bp->bc_col = bp->bc_xmin;
328 
329 	bp->bc_esc = &bp->bc_escseq[0];
330 	bp->bc_escape = bmd_escape;
331 
332 	*bmd_bmsel = 0xff;				/* all planes */
333 	bmd_erase_screen((uint32_t *)bp->bc_waddr);	/* clear screen */
334 	*bmd_bmsel = 0x01;				/* 1 plane */
335 
336 	/* turn on cursor */
337 	bmd_reverse_char(bp->bc_raddr,
338 			 bp->bc_waddr,
339 			 bq->bl_col, bp->bc_row);
340 }
341 
342 void
bmdadjust(int16_t hcnt,int16_t vcnt)343 bmdadjust(int16_t hcnt, int16_t vcnt)
344 {
345 	volatile uint32_t *bmd_rfcnt = (uint32_t *)BMAP_RFCNT;
346 	union bmd_rfcnt rfcnt;
347 
348 	printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);
349 
350 	rfcnt.p.rfc_hcnt = hcnt;		/* shift left   16 dot */
351 	rfcnt.p.rfc_vcnt = vcnt;		/* shift down    1 dot */
352 
353 	*bmd_rfcnt = rfcnt.u;
354 }
355 
356 int
bmdputc(int c)357 bmdputc(int c)
358 {
359 	struct bmd_softc *bp = &bmd_softc;
360 	struct bmd_linec *bq = bp->bc_bl;
361 	int i;
362 
363 	c &= 0x7F;
364 
365 	/* turn off cursor */
366 	bmd_reverse_char(bp->bc_raddr,
367 			 bp->bc_waddr,
368 			 bq->bl_col, bp->bc_row);
369 
370 	/* do escape-sequence */
371 	if (bp->bc_stat & STAT_ESCAPE) {
372 		*bp->bc_esc++ = c;
373 		(*bp->bc_escape)(c);
374 		goto done;
375 	}
376 
377 	if (isprint(c)) {
378 		bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
379 			      bq->bl_col, bp->bc_row, c);
380 		bq->bl_col++;
381 		bq->bl_end++;
382 		if (bq->bl_col >= bp->bc_xmax) {
383 			bq->bl_col = bq->bl_end = bp->bc_xmin;
384 			bp->bc_row++;
385 			if (bp->bc_row >= bp->bc_ymax) {
386 				bmd_scroll_screen((uint32_t *)bp->bc_raddr,
387 						  (uint32_t *)bp->bc_waddr,
388 						  bp->bc_xmin, bp->bc_xmax,
389 						  bp->bc_ymin, bp->bc_ymax);
390 
391 				bp->bc_row = bp->bc_ymax - 1;
392 			}
393 		}
394 	} else {
395 		switch (c) {
396 		case 0x08:				/* BS */
397 			if (bq->bl_col > bp->bc_xmin) {
398 				bq->bl_col--;
399 			}
400 			break;
401 
402 		case 0x09:				/* HT */
403 		case 0x0B:				/* VT */
404 			i = ((bq->bl_col / 8) + 1) * 8;
405 			if (i < bp->bc_xmax) {
406 				bq->bl_col = bq->bl_end = i;
407 			}
408 			break;
409 
410 		case 0x0A:				/* NL */
411 			bp->bc_row++;
412 			if (bp->bc_row >= bp->bc_ymax) {
413 				bmd_scroll_screen((uint32_t *)bp->bc_raddr,
414 						  (uint32_t *)bp->bc_waddr,
415 						  bp->bc_xmin, bp->bc_xmax,
416 						  bp->bc_ymin, bp->bc_ymax);
417 
418 				bp->bc_row = bp->bc_ymax - 1;
419 			}
420 			break;
421 
422 		case 0x0D:				/* CR */
423 			bq->bl_col = bp->bc_xmin;
424 			break;
425 
426 		case 0x1B:				/* ESC */
427 			bp->bc_stat |= STAT_ESCAPE;
428 			*bp->bc_esc++ = 0x1b;
429 			break;
430 
431 		case 0x7F:				/* DEL */
432 			if (bq->bl_col > bp->bc_xmin) {
433 				bq->bl_col--;
434 				bmd_erase_char(bp->bc_raddr,
435 					       bp->bc_waddr,
436 					       bq->bl_col, bp->bc_row);
437 			}
438 			break;
439 
440 		default:
441 			break;
442 		}
443 	}
444 
445  done:
446 	/* turn on  cursor */
447 	bmd_reverse_char(bp->bc_raddr,
448 			 bp->bc_waddr,
449 			 bq->bl_col, bp->bc_row);
450 
451 	return c;
452 }
453 
454 void
bmdclear(void)455 bmdclear(void)
456 {
457 	struct bmd_softc *bp = &bmd_softc;
458 	struct bmd_linec *bq = bp->bc_bl;
459 
460 	/* clear screen */
461 	bmd_erase_screen((uint32_t *)bp->bc_waddr);
462 
463 	bq->bl_col = bq->bl_end = bp->bc_xmin;
464 	bp->bc_row = bp->bc_ymin;
465 
466 	/* turn on cursor */
467 	bmd_reverse_char(bp->bc_raddr,
468 			 bp->bc_waddr,
469 			 bq->bl_col, bp->bc_row);
470 }
471 
472 
473 /*
474  *  character operation routines
475  */
476 
477 static void
bmd_draw_char(uint8_t * raddr,uint8_t * waddr,int col,int row,int c)478 bmd_draw_char(uint8_t *raddr, uint8_t *waddr, int col, int row, int c)
479 {
480 	volatile uint16_t *p, *q;
481 	volatile uint32_t *lp, *lq;
482 	const uint16_t *fp;
483 	int i;
484 
485 	fp = &bmdfont[c][0];
486 
487 	switch (col % 4) {
488 
489 	case 0:
490 		p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
491 		    + ((col / 4) * 6));
492 		q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
493 		    + ((col / 4) * 6));
494 		for (i = 0; i < FB_HEIGHT; i++) {
495 			*q = (*p & 0x000F) | (*fp & 0xFFF0);
496 			p += 128;
497 			q += 128;
498 			fp++;
499 		}
500 		break;
501 
502 	case 1:
503 		lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
504 		    + ((col / 4) * 6));
505 		lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
506 		    + ((col / 4) * 6));
507 		for (i = 0; i < FB_HEIGHT; i++) {
508 			*lq = (*lp & 0xFFF000FF) |
509 			    ((uint32_t)(*fp & 0xFFF0) << 4);
510 			lp += 64;
511 			lq += 64;
512 			fp++;
513 		}
514 		break;
515 
516 	case 2:
517 		lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
518 		    + ((col / 4) * 6) + 2);
519 		lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
520 		    + ((col / 4) * 6) + 2);
521 		for (i = 0; i < FB_HEIGHT; i++) {
522 			*lq = (*lp & 0xFF000FFF) |
523 			    ((uint32_t)(*fp & 0xFFF0) << 8);
524 			lp += 64;
525 			lq += 64;
526 			fp++;
527 		}
528 		break;
529 
530 	case 3:
531 		p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
532 		    + ((col / 4) * 6) + 4);
533 		q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
534 		    + ((col / 4) * 6) + 4);
535 		for (i = 0; i < FB_HEIGHT; i++) {
536 			*q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
537 			p += 128;
538 			q += 128;
539 			fp++;
540 		}
541 		break;
542 
543 	default:
544 		break;
545 	}
546 }
547 
548 static void
bmd_reverse_char(uint8_t * raddr,uint8_t * waddr,int col,int row)549 bmd_reverse_char(uint8_t *raddr, uint8_t *waddr, int col, int row)
550 {
551 	volatile uint16_t *p, *q;
552 	volatile uint32_t *lp, *lq;
553 	int i;
554 
555 	switch (col % 4) {
556 
557 	case 0:
558 		p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
559 		    + ((col / 4) * 6));
560 		q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
561 		    + ((col / 4) * 6));
562 		for (i = 0; i < FB_HEIGHT; i++) {
563 			*q = (*p & 0x000F) | (~(*p) & 0xFFF0);
564 			p += 128;
565 			q += 128;
566 		}
567 		break;
568 
569 	case 1:
570 		lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
571 		    + ((col / 4) * 6));
572 		lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
573 		    + ((col / 4) * 6));
574 		for (i = 0; i < FB_HEIGHT; i++) {
575 			*lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00);
576 			lp += 64;
577 			lq += 64;
578 		}
579 		break;
580 
581 	case 2:
582 		lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
583 		    + ((col / 4) * 6) + 2);
584 		lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
585 		    + ((col / 4) * 6) + 2);
586 		for (i = 0; i < FB_HEIGHT; i++) {
587 			*lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000);
588 			lp += 64;
589 			lq += 64;
590 		}
591 		break;
592 
593 	case 3:
594 		p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
595 		    + ((col / 4) * 6) + 4);
596 		q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
597 		    + ((col / 4) * 6) + 4);
598 		for (i = 0; i < FB_HEIGHT; i++) {
599 			*q = (*p & 0xF000) | (~(*p) & 0x0FFF);
600 			p += 128;
601 			q += 128;
602 		}
603 		break;
604 
605 	default:
606 		break;
607 	}
608 }
609 
610 static void
bmd_erase_char(uint8_t * raddr,uint8_t * waddr,int col,int row)611 bmd_erase_char(uint8_t *raddr, uint8_t *waddr, int col, int row)
612 {
613 
614 	bmd_draw_char(raddr, waddr, col, row, 0);
615 }
616 
617 
618 /*
619  * screen operation routines
620  */
621 
622 static void
bmd_erase_screen(volatile uint32_t * lp)623 bmd_erase_screen(volatile uint32_t *lp)
624 {
625 	int i, j;
626 
627 	for (i = 0; i < SB_HEIGHT; i++) {
628 		for (j = 0; j < SL_WIDTH; j++)
629 			*lp++ = 0;
630 		SKIP_NEXT_LINE(lp);
631 	}
632 }
633 
634 static void
bmd_scroll_screen(volatile uint32_t * lp,volatile uint32_t * lq,int xmin,int xmax,int ymin,int ymax)635 bmd_scroll_screen(volatile uint32_t *lp, volatile uint32_t *lq,
636     int xmin, int xmax, int ymin, int ymax)
637 {
638 	int i, j;
639 
640 	lp += ((PL_WIDTH * FB_HEIGHT) * (ymin + 1));
641 	lq += ((PL_WIDTH * FB_HEIGHT) *  ymin);
642 
643 	for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) {
644 		for (j = 0; j < SL_WIDTH; j++) {
645 			*lq++ = *lp++;
646 		}
647 		lp += (PL_WIDTH - SL_WIDTH);
648 		lq += (PL_WIDTH - SL_WIDTH);
649 	}
650 
651 	for (i = 0; i < FB_HEIGHT; i++) {
652 		for (j = 0; j < SL_WIDTH; j++) {
653 			*lq++ = 0;
654 		}
655 		lq += (PL_WIDTH - SL_WIDTH);
656 	}
657 }
658