xref: /freebsd/sys/dev/syscons/daemon/daemon_saver.c (revision b95b56c7a06bd268299c6d3b1104e09831e600dc)
1e8adebf2SKazutaka YOKOTA /*-
2e8adebf2SKazutaka YOKOTA  * Copyright (c) 1997 Sandro Sigala, Brescia, Italy.
3068eabc6SKazutaka YOKOTA  * Copyright (c) 1997 Chris Shenton
4e8adebf2SKazutaka YOKOTA  * Copyright (c) 1995 S ren Schmidt
5e8adebf2SKazutaka YOKOTA  * All rights reserved.
6e8adebf2SKazutaka YOKOTA  *
7e8adebf2SKazutaka YOKOTA  * Redistribution and use in source and binary forms, with or without
8e8adebf2SKazutaka YOKOTA  * modification, are permitted provided that the following conditions
9e8adebf2SKazutaka YOKOTA  * are met:
10e8adebf2SKazutaka YOKOTA  * 1. Redistributions of source code must retain the above copyright
11e8adebf2SKazutaka YOKOTA  *    notice, this list of conditions and the following disclaimer
12e8adebf2SKazutaka YOKOTA  *    in this position and unchanged.
13e8adebf2SKazutaka YOKOTA  * 2. Redistributions in binary form must reproduce the above copyright
14e8adebf2SKazutaka YOKOTA  *    notice, this list of conditions and the following disclaimer in the
15e8adebf2SKazutaka YOKOTA  *    documentation and/or other materials provided with the distribution.
16e8adebf2SKazutaka YOKOTA  *
17e8adebf2SKazutaka YOKOTA  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18e8adebf2SKazutaka YOKOTA  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19e8adebf2SKazutaka YOKOTA  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20e8adebf2SKazutaka YOKOTA  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21e8adebf2SKazutaka YOKOTA  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22e8adebf2SKazutaka YOKOTA  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23e8adebf2SKazutaka YOKOTA  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24e8adebf2SKazutaka YOKOTA  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25e8adebf2SKazutaka YOKOTA  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26e8adebf2SKazutaka YOKOTA  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e8adebf2SKazutaka YOKOTA  *
28c3aac50fSPeter Wemm  * $FreeBSD$
29e8adebf2SKazutaka YOKOTA  */
30e8adebf2SKazutaka YOKOTA 
31e8adebf2SKazutaka YOKOTA #include <sys/param.h>
32e8adebf2SKazutaka YOKOTA #include <sys/systm.h>
330640d357SPeter Wemm #include <sys/module.h>
34ce834215SKazutaka YOKOTA #include <sys/malloc.h>
35f4863d1aSKazutaka YOKOTA #include <sys/kernel.h>
36f4863d1aSKazutaka YOKOTA #include <sys/sysctl.h>
376e8394b8SKazutaka YOKOTA #include <sys/consio.h>
386e8394b8SKazutaka YOKOTA #include <sys/fbio.h>
39e8adebf2SKazutaka YOKOTA 
4033b77e2dSBruce Evans #include <machine/pc/display.h>
41e8adebf2SKazutaka YOKOTA 
426e8394b8SKazutaka YOKOTA #include <dev/fb/fbreg.h>
436e8394b8SKazutaka YOKOTA #include <dev/fb/splashreg.h>
446e8394b8SKazutaka YOKOTA #include <dev/syscons/syscons.h>
45068eabc6SKazutaka YOKOTA 
46b95b56c7SYoshihiro Takahashi #ifdef PC98
47b95b56c7SYoshihiro Takahashi #include <pc98/pc98/pc98_machdep.h>
48b95b56c7SYoshihiro Takahashi #endif
49b95b56c7SYoshihiro Takahashi 
50e8adebf2SKazutaka YOKOTA #define DAEMON_MAX_WIDTH	32
51e8adebf2SKazutaka YOKOTA #define DAEMON_MAX_HEIGHT	19
52e8adebf2SKazutaka YOKOTA 
53ce834215SKazutaka YOKOTA static char *message;
54ce834215SKazutaka YOKOTA static int messagelen;
552ad872c5SKazutaka YOKOTA static int blanked;
56068eabc6SKazutaka YOKOTA 
57068eabc6SKazutaka YOKOTA /* Who is the author of this ASCII pic? */
58e8adebf2SKazutaka YOKOTA 
59e8adebf2SKazutaka YOKOTA static char *daemon_pic[] = {
60e8adebf2SKazutaka YOKOTA         "             ,        ,",
61e8adebf2SKazutaka YOKOTA 	"            /(        )`",
62e8adebf2SKazutaka YOKOTA 	"            \\ \\___   / |",
63e8adebf2SKazutaka YOKOTA 	"            /- _  `-/  '",
64e8adebf2SKazutaka YOKOTA 	"           (/\\/ \\ \\   /\\",
65e8adebf2SKazutaka YOKOTA 	"           / /   | `    \\",
66e8adebf2SKazutaka YOKOTA 	"           O O   ) /    |",
67e8adebf2SKazutaka YOKOTA 	"           `-^--'`<     '",
68e8adebf2SKazutaka YOKOTA 	"          (_.)  _  )   /",
69e8adebf2SKazutaka YOKOTA 	"           `.___/`    /",
70e8adebf2SKazutaka YOKOTA 	"             `-----' /",
71e8adebf2SKazutaka YOKOTA 	"<----.     __ / __   \\",
72e8adebf2SKazutaka YOKOTA 	"<----|====O)))==) \\) /====",
73e8adebf2SKazutaka YOKOTA 	"<----'    `--' `.__,' \\",
74e8adebf2SKazutaka YOKOTA 	"             |        |",
75e8adebf2SKazutaka YOKOTA 	"              \\       /       /\\",
76e8adebf2SKazutaka YOKOTA 	"         ______( (_  / \\______/",
77e8adebf2SKazutaka YOKOTA 	"       ,'  ,-----'   |",
78e8adebf2SKazutaka YOKOTA 	"       `--{__________)",
79e8adebf2SKazutaka YOKOTA 	NULL
80e8adebf2SKazutaka YOKOTA };
81e8adebf2SKazutaka YOKOTA 
82e8adebf2SKazutaka YOKOTA static char *daemon_attr[] = {
83e8adebf2SKazutaka YOKOTA         "             R        R",
84e8adebf2SKazutaka YOKOTA 	"            RR        RR",
85e8adebf2SKazutaka YOKOTA 	"            R RRRR   R R",
86e8adebf2SKazutaka YOKOTA 	"            RR W  RRR  R",
87e8adebf2SKazutaka YOKOTA 	"           RWWW W R   RR",
88e8adebf2SKazutaka YOKOTA 	"           W W   W R    R",
89e8adebf2SKazutaka YOKOTA 	"           B B   W R    R",
90e8adebf2SKazutaka YOKOTA 	"           WWWWWWRR     R",
91e8adebf2SKazutaka YOKOTA 	"          RRRR  R  R   R",
92e8adebf2SKazutaka YOKOTA 	"           RRRRRRR    R",
93e8adebf2SKazutaka YOKOTA 	"             RRRRRRR R",
94e8adebf2SKazutaka YOKOTA 	"YYYYYY     RR R RR   R",
95e8adebf2SKazutaka YOKOTA 	"YYYYYYYYYYRRRRYYR RR RYYYY",
96e8adebf2SKazutaka YOKOTA 	"YYYYYY    RRRR RRRRRR R",
97e8adebf2SKazutaka YOKOTA 	"             R        R",
98e8adebf2SKazutaka YOKOTA 	"              R       R       RR",
99e8adebf2SKazutaka YOKOTA 	"         CCCCCCR RR  R RRRRRRRR",
100e8adebf2SKazutaka YOKOTA 	"       CC  CCCCCCC   C",
101e8adebf2SKazutaka YOKOTA 	"       CCCCCCCCCCCCCCC",
102e8adebf2SKazutaka YOKOTA 	NULL
103e8adebf2SKazutaka YOKOTA };
104e8adebf2SKazutaka YOKOTA 
105068eabc6SKazutaka YOKOTA /*
106068eabc6SKazutaka YOKOTA  * Reverse a graphics character, or return unaltered if no mirror;
107068eabc6SKazutaka YOKOTA  * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov>
108068eabc6SKazutaka YOKOTA  */
109068eabc6SKazutaka YOKOTA 
110068eabc6SKazutaka YOKOTA static char
111068eabc6SKazutaka YOKOTA xflip_symbol(char symbol)
112068eabc6SKazutaka YOKOTA {
113068eabc6SKazutaka YOKOTA 	static const char lchars[] = "`'(){}[]\\/<>";
114068eabc6SKazutaka YOKOTA 	static const char rchars[] = "'`)(}{][/\\><";
115068eabc6SKazutaka YOKOTA 	int pos;
116068eabc6SKazutaka YOKOTA 
117068eabc6SKazutaka YOKOTA 	for (pos = 0; lchars[pos] != '\0'; pos++)
118068eabc6SKazutaka YOKOTA 		if (lchars[pos] == symbol)
119068eabc6SKazutaka YOKOTA 			return rchars[pos];
120068eabc6SKazutaka YOKOTA 
121068eabc6SKazutaka YOKOTA 	return symbol;
122068eabc6SKazutaka YOKOTA }
123e8adebf2SKazutaka YOKOTA 
124e8adebf2SKazutaka YOKOTA static void
1256e8394b8SKazutaka YOKOTA clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
12602f2e93bSKazutaka YOKOTA 	    int xlen, int ylen)
12702f2e93bSKazutaka YOKOTA {
12802f2e93bSKazutaka YOKOTA 	int y;
12902f2e93bSKazutaka YOKOTA 
13002f2e93bSKazutaka YOKOTA 	if (xlen <= 0)
13102f2e93bSKazutaka YOKOTA 		return;
1326e8394b8SKazutaka YOKOTA 	for (y = yoff; y < ylen; y++) {
1336e8394b8SKazutaka YOKOTA 		sc_vtb_erase(&sc->cur_scp->scr,
1346e8394b8SKazutaka YOKOTA 			     (ypos + y)*sc->cur_scp->xsize + xpos + xoff,
1356e8394b8SKazutaka YOKOTA 			     xlen - xoff,
1366e8394b8SKazutaka YOKOTA 			     sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
1376e8394b8SKazutaka YOKOTA 	}
13802f2e93bSKazutaka YOKOTA }
13902f2e93bSKazutaka YOKOTA 
14002f2e93bSKazutaka YOKOTA static void
1416e8394b8SKazutaka YOKOTA draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
14202f2e93bSKazutaka YOKOTA 	    int xlen, int ylen)
143e8adebf2SKazutaka YOKOTA {
144e8adebf2SKazutaka YOKOTA 	int x, y;
14502f2e93bSKazutaka YOKOTA 	int px;
146e8adebf2SKazutaka YOKOTA 	int attr;
147e8adebf2SKazutaka YOKOTA 
14802f2e93bSKazutaka YOKOTA 	for (y = yoff; y < ylen; y++) {
14902f2e93bSKazutaka YOKOTA 		if (dxdir < 0)
15002f2e93bSKazutaka YOKOTA 			px = xoff;
15102f2e93bSKazutaka YOKOTA 		else
15202f2e93bSKazutaka YOKOTA 			px = DAEMON_MAX_WIDTH - xlen;
15302f2e93bSKazutaka YOKOTA 		if (px >= strlen(daemon_pic[y]))
15402f2e93bSKazutaka YOKOTA 			continue;
15502f2e93bSKazutaka YOKOTA 		for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
15602f2e93bSKazutaka YOKOTA 			switch (daemon_attr[y][px]) {
1576e8394b8SKazutaka YOKOTA #ifndef PC98
158e8adebf2SKazutaka YOKOTA 			case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
159e8adebf2SKazutaka YOKOTA 			case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
160e8adebf2SKazutaka YOKOTA 			case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
161e8adebf2SKazutaka YOKOTA 			case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
162e8adebf2SKazutaka YOKOTA 			case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
163e8adebf2SKazutaka YOKOTA 			default: attr = (FG_WHITE|BG_BLACK)<<8; break;
1646e8394b8SKazutaka YOKOTA #else /* PC98 */
1656e8394b8SKazutaka YOKOTA 			case 'R': attr = (FG_RED|BG_BLACK)<<8; break;
1666e8394b8SKazutaka YOKOTA 			case 'Y': attr = (FG_BROWN|BG_BLACK)<<8; break;
1676e8394b8SKazutaka YOKOTA 			case 'B': attr = (FG_BLUE|BG_BLACK)<<8; break;
1686e8394b8SKazutaka YOKOTA 			case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
1696e8394b8SKazutaka YOKOTA 			case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
1706e8394b8SKazutaka YOKOTA 			default: attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
1716e8394b8SKazutaka YOKOTA #endif /* PC98 */
172e8adebf2SKazutaka YOKOTA 			}
173068eabc6SKazutaka YOKOTA 			if (dxdir < 0) {	/* Moving left */
1746e8394b8SKazutaka YOKOTA 				sc_vtb_putc(&sc->cur_scp->scr,
1756e8394b8SKazutaka YOKOTA 					    (ypos + y)*sc->cur_scp->xsize
1766e8394b8SKazutaka YOKOTA 						 + xpos + x,
1776e8394b8SKazutaka YOKOTA 					    sc->scr_map[daemon_pic[y][px]],
1786e8394b8SKazutaka YOKOTA 					    attr);
179068eabc6SKazutaka YOKOTA 			} else {		/* Moving right */
1806e8394b8SKazutaka YOKOTA 				sc_vtb_putc(&sc->cur_scp->scr,
1816e8394b8SKazutaka YOKOTA 					    (ypos + y)*sc->cur_scp->xsize
1826e8394b8SKazutaka YOKOTA 						+ xpos + DAEMON_MAX_WIDTH
1836e8394b8SKazutaka YOKOTA 						- px - 1,
1846e8394b8SKazutaka YOKOTA 					    sc->scr_map[xflip_symbol(daemon_pic[y][px])],
1856e8394b8SKazutaka YOKOTA 					    attr);
18602f2e93bSKazutaka YOKOTA 			}
187068eabc6SKazutaka YOKOTA 		}
188e8adebf2SKazutaka YOKOTA 	}
189e8adebf2SKazutaka YOKOTA }
190e8adebf2SKazutaka YOKOTA 
191e8adebf2SKazutaka YOKOTA static void
1926e8394b8SKazutaka YOKOTA clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
19302f2e93bSKazutaka YOKOTA {
19402f2e93bSKazutaka YOKOTA 	if (len <= 0)
19502f2e93bSKazutaka YOKOTA 		return;
1966e8394b8SKazutaka YOKOTA 	sc_vtb_erase(&sc->cur_scp->scr,
1976e8394b8SKazutaka YOKOTA 		     ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff,
1986e8394b8SKazutaka YOKOTA 		     sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
19902f2e93bSKazutaka YOKOTA }
20002f2e93bSKazutaka YOKOTA 
20102f2e93bSKazutaka YOKOTA static void
2026e8394b8SKazutaka YOKOTA draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
203e8adebf2SKazutaka YOKOTA {
204e8adebf2SKazutaka YOKOTA 	int x;
205e8adebf2SKazutaka YOKOTA 
2066e8394b8SKazutaka YOKOTA 	for (x = xoff; x < len; x++) {
207b95b56c7SYoshihiro Takahashi #ifdef PC98
208b95b56c7SYoshihiro Takahashi 		sc_vtb_putc(&sc->cur_scp->scr,
209b95b56c7SYoshihiro Takahashi 			    ypos*sc->cur_scp->xsize + xpos + x,
210b95b56c7SYoshihiro Takahashi 			    sc->scr_map[s[x]], (FG_GREEN | BG_BLACK) << 8);
211b95b56c7SYoshihiro Takahashi #else
2126e8394b8SKazutaka YOKOTA 		sc_vtb_putc(&sc->cur_scp->scr,
2136e8394b8SKazutaka YOKOTA 			    ypos*sc->cur_scp->xsize + xpos + x,
2146e8394b8SKazutaka YOKOTA 			    sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8);
215b95b56c7SYoshihiro Takahashi #endif
2166e8394b8SKazutaka YOKOTA 	}
217e8adebf2SKazutaka YOKOTA }
218e8adebf2SKazutaka YOKOTA 
2192ad872c5SKazutaka YOKOTA static int
2202ad872c5SKazutaka YOKOTA daemon_saver(video_adapter_t *adp, int blank)
221e8adebf2SKazutaka YOKOTA {
222e8adebf2SKazutaka YOKOTA 	static int txpos = 10, typos = 10;
223e8adebf2SKazutaka YOKOTA 	static int txdir = -1, tydir = -1;
224068eabc6SKazutaka YOKOTA 	static int dxpos = 0, dypos = 0;
225068eabc6SKazutaka YOKOTA 	static int dxdir = 1, dydir = 1;
226e8adebf2SKazutaka YOKOTA 	static int moved_daemon = 0;
22702f2e93bSKazutaka YOKOTA 	static int xoff, yoff, toff;
22802f2e93bSKazutaka YOKOTA 	static int xlen, ylen, tlen;
2296e8394b8SKazutaka YOKOTA 	sc_softc_t *sc;
2306e8394b8SKazutaka YOKOTA 	scr_stat *scp;
23102f2e93bSKazutaka YOKOTA 	int min, max;
232e8adebf2SKazutaka YOKOTA 
2336e8394b8SKazutaka YOKOTA 	sc = sc_find_softc(adp, NULL);
2346e8394b8SKazutaka YOKOTA 	if (sc == NULL)
2356e8394b8SKazutaka YOKOTA 		return EAGAIN;
2366e8394b8SKazutaka YOKOTA 	scp = sc->cur_scp;
2376e8394b8SKazutaka YOKOTA 
238e8adebf2SKazutaka YOKOTA 	if (blank) {
2392da199daSDag-Erling Smørgrav 		if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
240f9e730bbSKazutaka YOKOTA 			return EAGAIN;
2412ad872c5SKazutaka YOKOTA 		if (blanked == 0) {
2426e8394b8SKazutaka YOKOTA #ifdef PC98
2436e8394b8SKazutaka YOKOTA 			if (epson_machine_id == 0x20) {
2446e8394b8SKazutaka YOKOTA 				outb(0x43f, 0x42);
2456e8394b8SKazutaka YOKOTA 				outb(0x0c17, inb(0xc17) & ~0x08);
2466e8394b8SKazutaka YOKOTA 				outb(0x43f, 0x40);
2476e8394b8SKazutaka YOKOTA 			}
2486e8394b8SKazutaka YOKOTA #endif /* PC98 */
24902f2e93bSKazutaka YOKOTA 			/* clear the screen and set the border color */
2506e8394b8SKazutaka YOKOTA 			sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
2516e8394b8SKazutaka YOKOTA 				     (FG_LIGHTGREY | BG_BLACK) << 8);
2526e8394b8SKazutaka YOKOTA 			(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
2532b944ee2SKazutaka YOKOTA 			sc_set_border(scp, 0);
25402f2e93bSKazutaka YOKOTA 			xlen = ylen = tlen = 0;
25502f2e93bSKazutaka YOKOTA 		}
2562ad872c5SKazutaka YOKOTA 		if (blanked++ < 2)
2572ad872c5SKazutaka YOKOTA 			return 0;
2582ad872c5SKazutaka YOKOTA 		blanked = 1;
259e8adebf2SKazutaka YOKOTA 
2606e8394b8SKazutaka YOKOTA  		clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
2616e8394b8SKazutaka YOKOTA 		clear_string(sc, txpos, typos, toff, (char *)message, tlen);
26202f2e93bSKazutaka YOKOTA 
263e8adebf2SKazutaka YOKOTA 		if (++moved_daemon) {
26402f2e93bSKazutaka YOKOTA 			/*
26502f2e93bSKazutaka YOKOTA 			 * The daemon picture may be off the screen, if
26602f2e93bSKazutaka YOKOTA 			 * screen size is chagened while the screen
26702f2e93bSKazutaka YOKOTA 			 * saver is inactive. Make sure the origin of
26802f2e93bSKazutaka YOKOTA 			 * the picture is between min and max.
26902f2e93bSKazutaka YOKOTA 			 */
27002f2e93bSKazutaka YOKOTA 			if (scp->xsize <= DAEMON_MAX_WIDTH) {
27102f2e93bSKazutaka YOKOTA 				/*
27202f2e93bSKazutaka YOKOTA 				 * If the screen width is too narrow, we
27302f2e93bSKazutaka YOKOTA 				 * allow part of the picture go off
27402f2e93bSKazutaka YOKOTA 				 * the screen so that the daemon won't
27502f2e93bSKazutaka YOKOTA 				 * flip too often.
27602f2e93bSKazutaka YOKOTA 				 */
27702f2e93bSKazutaka YOKOTA 				min = scp->xsize - DAEMON_MAX_WIDTH - 10;
27802f2e93bSKazutaka YOKOTA 				max = 10;
27902f2e93bSKazutaka YOKOTA 			} else {
28002f2e93bSKazutaka YOKOTA 				min = 0;
28102f2e93bSKazutaka YOKOTA 				max = scp->xsize - DAEMON_MAX_WIDTH;
28202f2e93bSKazutaka YOKOTA 			}
28302f2e93bSKazutaka YOKOTA 			if (dxpos <= min) {
28402f2e93bSKazutaka YOKOTA 				dxpos = min;
28502f2e93bSKazutaka YOKOTA 				dxdir = 1;
28602f2e93bSKazutaka YOKOTA 			} else if (dxpos >= max) {
28702f2e93bSKazutaka YOKOTA 				dxpos = max;
288e8adebf2SKazutaka YOKOTA 				dxdir = -1;
289e8adebf2SKazutaka YOKOTA 			}
290e8adebf2SKazutaka YOKOTA 
29102f2e93bSKazutaka YOKOTA 			if (scp->ysize <= DAEMON_MAX_HEIGHT) {
29202f2e93bSKazutaka YOKOTA 				min = scp->ysize - DAEMON_MAX_HEIGHT - 10;
29302f2e93bSKazutaka YOKOTA 				max = 10;
294e8adebf2SKazutaka YOKOTA 			} else {
29502f2e93bSKazutaka YOKOTA 				min = 0;
29602f2e93bSKazutaka YOKOTA 				max = scp->ysize - DAEMON_MAX_HEIGHT;
297e8adebf2SKazutaka YOKOTA 			}
29802f2e93bSKazutaka YOKOTA 			if (dypos <= min) {
29902f2e93bSKazutaka YOKOTA 				dypos = min;
30002f2e93bSKazutaka YOKOTA 				dydir = 1;
30102f2e93bSKazutaka YOKOTA 			} else if (dypos >= max) {
30202f2e93bSKazutaka YOKOTA 				dypos = max;
30302f2e93bSKazutaka YOKOTA 				dydir = -1;
30402f2e93bSKazutaka YOKOTA 			}
30502f2e93bSKazutaka YOKOTA 
30602f2e93bSKazutaka YOKOTA 			moved_daemon = -1;
30702f2e93bSKazutaka YOKOTA 			dxpos += dxdir; dypos += dydir;
30802f2e93bSKazutaka YOKOTA 
30902f2e93bSKazutaka YOKOTA 			/* clip the picture */
31002f2e93bSKazutaka YOKOTA 			xoff = 0;
31102f2e93bSKazutaka YOKOTA 			xlen = DAEMON_MAX_WIDTH;
31202f2e93bSKazutaka YOKOTA 			if (dxpos + xlen <= 0)
31302f2e93bSKazutaka YOKOTA 				xlen = 0;
31402f2e93bSKazutaka YOKOTA 			else if (dxpos < 0)
31502f2e93bSKazutaka YOKOTA 				xoff = -dxpos;
31602f2e93bSKazutaka YOKOTA 			if (dxpos >= scp->xsize)
31702f2e93bSKazutaka YOKOTA 				xlen = 0;
31802f2e93bSKazutaka YOKOTA 			else if (dxpos + xlen > scp->xsize)
31902f2e93bSKazutaka YOKOTA 				xlen = scp->xsize - dxpos;
32002f2e93bSKazutaka YOKOTA 			yoff = 0;
32102f2e93bSKazutaka YOKOTA 			ylen = DAEMON_MAX_HEIGHT;
32202f2e93bSKazutaka YOKOTA 			if (dypos + ylen <= 0)
32302f2e93bSKazutaka YOKOTA 				ylen = 0;
32402f2e93bSKazutaka YOKOTA 			else if (dypos < 0)
32502f2e93bSKazutaka YOKOTA 				yoff = -dypos;
32602f2e93bSKazutaka YOKOTA 			if (dypos >= scp->ysize)
32702f2e93bSKazutaka YOKOTA 				ylen = 0;
32802f2e93bSKazutaka YOKOTA 			else if (dypos + ylen > scp->ysize)
32902f2e93bSKazutaka YOKOTA 				ylen = scp->ysize - dypos;
33002f2e93bSKazutaka YOKOTA 		}
33102f2e93bSKazutaka YOKOTA 
33202f2e93bSKazutaka YOKOTA 		if (scp->xsize <= messagelen) {
33302f2e93bSKazutaka YOKOTA 			min = scp->xsize - messagelen - 10;
33402f2e93bSKazutaka YOKOTA 			max = 10;
335e8adebf2SKazutaka YOKOTA 		} else {
33602f2e93bSKazutaka YOKOTA 			min = 0;
33702f2e93bSKazutaka YOKOTA 			max = scp->xsize - messagelen;
33802f2e93bSKazutaka YOKOTA 		}
33902f2e93bSKazutaka YOKOTA 		if (txpos <= min) {
34002f2e93bSKazutaka YOKOTA 			txpos = min;
34102f2e93bSKazutaka YOKOTA 			txdir = 1;
34202f2e93bSKazutaka YOKOTA 		} else if (txpos >= max) {
34302f2e93bSKazutaka YOKOTA 			txpos = max;
34402f2e93bSKazutaka YOKOTA 			txdir = -1;
34502f2e93bSKazutaka YOKOTA 		}
34602f2e93bSKazutaka YOKOTA 		if (typos <= 0) {
34702f2e93bSKazutaka YOKOTA 			typos = 0;
34802f2e93bSKazutaka YOKOTA 			tydir = 1;
34902f2e93bSKazutaka YOKOTA 		} else if (typos >= scp->ysize - 1) {
35002f2e93bSKazutaka YOKOTA 			typos = scp->ysize - 1;
35102f2e93bSKazutaka YOKOTA 			tydir = -1;
352e8adebf2SKazutaka YOKOTA 		}
353e8adebf2SKazutaka YOKOTA 		txpos += txdir; typos += tydir;
354e8adebf2SKazutaka YOKOTA 
35502f2e93bSKazutaka YOKOTA 		toff = 0;
35602f2e93bSKazutaka YOKOTA 		tlen = messagelen;
35702f2e93bSKazutaka YOKOTA 		if (txpos + tlen <= 0)
35802f2e93bSKazutaka YOKOTA 			tlen = 0;
35902f2e93bSKazutaka YOKOTA 		else if (txpos < 0)
36002f2e93bSKazutaka YOKOTA 			toff = -txpos;
36102f2e93bSKazutaka YOKOTA 		if (txpos >= scp->xsize)
36202f2e93bSKazutaka YOKOTA 			tlen = 0;
36302f2e93bSKazutaka YOKOTA 		else if (txpos + tlen > scp->xsize)
36402f2e93bSKazutaka YOKOTA 			tlen = scp->xsize - txpos;
36502f2e93bSKazutaka YOKOTA 
3666e8394b8SKazutaka YOKOTA  		draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
3676e8394b8SKazutaka YOKOTA 		draw_string(sc, txpos, typos, toff, (char *)message, tlen);
368e8adebf2SKazutaka YOKOTA 	} else {
3696e8394b8SKazutaka YOKOTA #ifdef PC98
3706e8394b8SKazutaka YOKOTA 		if (epson_machine_id == 0x20) {
3716e8394b8SKazutaka YOKOTA 			outb(0x43f, 0x42);
3726e8394b8SKazutaka YOKOTA 			outb(0x0c17, inb(0xc17) | 0x08);
3736e8394b8SKazutaka YOKOTA 			outb(0x43f, 0x40);
3746e8394b8SKazutaka YOKOTA 		}
3756e8394b8SKazutaka YOKOTA #endif /* PC98 */
3762ad872c5SKazutaka YOKOTA 		blanked = 0;
377e8adebf2SKazutaka YOKOTA 	}
3782ad872c5SKazutaka YOKOTA 	return 0;
379e8adebf2SKazutaka YOKOTA }
380e8adebf2SKazutaka YOKOTA 
381e8adebf2SKazutaka YOKOTA static int
3822ad872c5SKazutaka YOKOTA daemon_init(video_adapter_t *adp)
383e8adebf2SKazutaka YOKOTA {
384ce834215SKazutaka YOKOTA 	messagelen = strlen(hostname) + 3 + strlen(ostype) + 1 +
385ce834215SKazutaka YOKOTA 	    strlen(osrelease);
386ce834215SKazutaka YOKOTA 	message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
387ce834215SKazutaka YOKOTA 	sprintf(message, "%s - %s %s", hostname, ostype, osrelease);
3882ad872c5SKazutaka YOKOTA 	blanked = 0;
3892ad872c5SKazutaka YOKOTA 	return 0;
390e8adebf2SKazutaka YOKOTA }
391e8adebf2SKazutaka YOKOTA 
392e8adebf2SKazutaka YOKOTA static int
3932ad872c5SKazutaka YOKOTA daemon_term(video_adapter_t *adp)
394e8adebf2SKazutaka YOKOTA {
395f4863d1aSKazutaka YOKOTA 	free(message, M_DEVBUF);
3962ad872c5SKazutaka YOKOTA 	return 0;
397e8adebf2SKazutaka YOKOTA }
398e8adebf2SKazutaka YOKOTA 
3992ad872c5SKazutaka YOKOTA static scrn_saver_t daemon_module = {
4002ad872c5SKazutaka YOKOTA 	"daemon_saver", daemon_init, daemon_term, daemon_saver, NULL,
4012ad872c5SKazutaka YOKOTA };
4022ad872c5SKazutaka YOKOTA 
4032ad872c5SKazutaka YOKOTA SAVER_MODULE(daemon_saver, daemon_module);
404