video_subr.c revision 1.1.4.2 1 1.1.4.2 bouyer /* $NetBSD: video_subr.c,v 1.1.4.2 2001/03/12 13:30:08 bouyer Exp $ */
2 1.1.4.2 bouyer
3 1.1.4.2 bouyer /*-
4 1.1.4.2 bouyer * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 1.1.4.2 bouyer * All rights reserved.
6 1.1.4.2 bouyer *
7 1.1.4.2 bouyer * This code is derived from software contributed to The NetBSD Foundation
8 1.1.4.2 bouyer * by UCHIYAMA Yasushi.
9 1.1.4.2 bouyer *
10 1.1.4.2 bouyer * Redistribution and use in source and binary forms, with or without
11 1.1.4.2 bouyer * modification, are permitted provided that the following conditions
12 1.1.4.2 bouyer * are met:
13 1.1.4.2 bouyer * 1. Redistributions of source code must retain the above copyright
14 1.1.4.2 bouyer * notice, this list of conditions and the following disclaimer.
15 1.1.4.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
16 1.1.4.2 bouyer * notice, this list of conditions and the following disclaimer in the
17 1.1.4.2 bouyer * documentation and/or other materials provided with the distribution.
18 1.1.4.2 bouyer * 3. All advertising materials mentioning features or use of this software
19 1.1.4.2 bouyer * must display the following acknowledgement:
20 1.1.4.2 bouyer * This product includes software developed by the NetBSD
21 1.1.4.2 bouyer * Foundation, Inc. and its contributors.
22 1.1.4.2 bouyer * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1.4.2 bouyer * contributors may be used to endorse or promote products derived
24 1.1.4.2 bouyer * from this software without specific prior written permission.
25 1.1.4.2 bouyer *
26 1.1.4.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1.4.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1.4.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1.4.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1.4.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1.4.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1.4.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1.4.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1.4.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1.4.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1.4.2 bouyer * POSSIBILITY OF SUCH DAMAGE.
37 1.1.4.2 bouyer */
38 1.1.4.2 bouyer
39 1.1.4.2 bouyer #include <sys/param.h>
40 1.1.4.2 bouyer #include <sys/systm.h>
41 1.1.4.2 bouyer #include <sys/malloc.h>
42 1.1.4.2 bouyer
43 1.1.4.2 bouyer #include <machine/bootinfo.h>
44 1.1.4.2 bouyer
45 1.1.4.2 bouyer #include <dev/hpc/video_subr.h>
46 1.1.4.2 bouyer
47 1.1.4.2 bouyer #define BPP2 ({ \
48 1.1.4.2 bouyer u_int8_t bitmap; \
49 1.1.4.2 bouyer bitmap = *(volatile u_int8_t*)addr; \
50 1.1.4.2 bouyer *(volatile u_int8_t*)addr = \
51 1.1.4.2 bouyer (bitmap & ~(0x3 << ((3 - (x % 4)) * 2))); \
52 1.1.4.2 bouyer })
53 1.1.4.2 bouyer
54 1.1.4.2 bouyer #define BPP4 ({ \
55 1.1.4.2 bouyer u_int8_t bitmap; \
56 1.1.4.2 bouyer bitmap = *(volatile u_int8_t*)addr; \
57 1.1.4.2 bouyer *(volatile u_int8_t*)addr = \
58 1.1.4.2 bouyer (bitmap & ~(0xf << ((1 - (x % 2)) * 4))); \
59 1.1.4.2 bouyer })
60 1.1.4.2 bouyer
61 1.1.4.2 bouyer #define BPP8 ({ \
62 1.1.4.2 bouyer *(volatile u_int8_t*)addr = 0xff; \
63 1.1.4.2 bouyer })
64 1.1.4.2 bouyer
65 1.1.4.2 bouyer #define BRESENHAM(a, b, c, d, func) ({ \
66 1.1.4.2 bouyer u_int32_t fbaddr = vc->vc_fbvaddr; \
67 1.1.4.2 bouyer u_int32_t fbwidth = vc->vc_fbwidth; \
68 1.1.4.2 bouyer u_int32_t fbdepth = vc->vc_fbdepth; \
69 1.1.4.2 bouyer len = a, step = b -1; \
70 1.1.4.2 bouyer if (step == 0) \
71 1.1.4.2 bouyer return; \
72 1.1.4.2 bouyer kstep = len == 0 ? 0 : 1; \
73 1.1.4.2 bouyer for (i = k = 0, j = step / 2; i <= step; i++) { \
74 1.1.4.2 bouyer x = xbase c; \
75 1.1.4.2 bouyer y = ybase d; \
76 1.1.4.2 bouyer addr = fbaddr + (((y * fbwidth + x) * fbdepth) >> 3); \
77 1.1.4.2 bouyer func; \
78 1.1.4.2 bouyer j -= len; \
79 1.1.4.2 bouyer while (j < 0) { \
80 1.1.4.2 bouyer j += step; \
81 1.1.4.2 bouyer k += kstep; \
82 1.1.4.2 bouyer } \
83 1.1.4.2 bouyer } \
84 1.1.4.2 bouyer })
85 1.1.4.2 bouyer
86 1.1.4.2 bouyer #define DRAWLINE(func) ({ \
87 1.1.4.2 bouyer if (x < 0) { \
88 1.1.4.2 bouyer if (y < 0) { \
89 1.1.4.2 bouyer if (_y < _x) { \
90 1.1.4.2 bouyer BRESENHAM(_y, _x, -i, -k, func); \
91 1.1.4.2 bouyer } else { \
92 1.1.4.2 bouyer BRESENHAM(_x, _y, -k, -i, func); \
93 1.1.4.2 bouyer } \
94 1.1.4.2 bouyer } else { \
95 1.1.4.2 bouyer if (_y < _x) { \
96 1.1.4.2 bouyer BRESENHAM(_y, _x, -i, +k, func); \
97 1.1.4.2 bouyer } else { \
98 1.1.4.2 bouyer BRESENHAM(_x, _y, -k, +i, func); \
99 1.1.4.2 bouyer } \
100 1.1.4.2 bouyer } \
101 1.1.4.2 bouyer } else { \
102 1.1.4.2 bouyer if (y < 0) { \
103 1.1.4.2 bouyer if (_y < _x) { \
104 1.1.4.2 bouyer BRESENHAM(_y, _x, +i, -k, func); \
105 1.1.4.2 bouyer } else { \
106 1.1.4.2 bouyer BRESENHAM(_x, _y, +k, -i, func); \
107 1.1.4.2 bouyer } \
108 1.1.4.2 bouyer } else { \
109 1.1.4.2 bouyer if (_y < _x) { \
110 1.1.4.2 bouyer BRESENHAM(_y, _x, +i, +k, func); \
111 1.1.4.2 bouyer } else { \
112 1.1.4.2 bouyer BRESENHAM(_x, _y, +k, +i, func); \
113 1.1.4.2 bouyer } \
114 1.1.4.2 bouyer } \
115 1.1.4.2 bouyer } \
116 1.1.4.2 bouyer })
117 1.1.4.2 bouyer
118 1.1.4.2 bouyer #define LINEFUNC(b) \
119 1.1.4.2 bouyer static void linebpp##b (struct video_chip *, int, int, int, int); \
120 1.1.4.2 bouyer static void \
121 1.1.4.2 bouyer linebpp##b##(vc, x0, y0, x1, y1) \
122 1.1.4.2 bouyer struct video_chip *vc; \
123 1.1.4.2 bouyer int x0, y0, x1, y1; \
124 1.1.4.2 bouyer { \
125 1.1.4.2 bouyer u_int32_t addr; \
126 1.1.4.2 bouyer int i, j, k, len, step, kstep; \
127 1.1.4.2 bouyer int x, _x, y, _y; \
128 1.1.4.2 bouyer int xbase, ybase; \
129 1.1.4.2 bouyer x = x1 - x0; \
130 1.1.4.2 bouyer y = y1 - y0; \
131 1.1.4.2 bouyer _x = abs(x); \
132 1.1.4.2 bouyer _y = abs(y); \
133 1.1.4.2 bouyer xbase = x0; \
134 1.1.4.2 bouyer ybase = y0; \
135 1.1.4.2 bouyer DRAWLINE(BPP##b##); \
136 1.1.4.2 bouyer }
137 1.1.4.2 bouyer
138 1.1.4.2 bouyer #define DOTFUNC(b) \
139 1.1.4.2 bouyer static void dotbpp##b (struct video_chip *, int, int); \
140 1.1.4.2 bouyer static void \
141 1.1.4.2 bouyer dotbpp##b##(vc, x, y) \
142 1.1.4.2 bouyer struct video_chip *vc; \
143 1.1.4.2 bouyer int x, y; \
144 1.1.4.2 bouyer { \
145 1.1.4.2 bouyer u_int32_t addr; \
146 1.1.4.2 bouyer addr = vc->vc_fbvaddr + (((y * vc->vc_fbwidth + x) * \
147 1.1.4.2 bouyer vc->vc_fbdepth) >> 3); \
148 1.1.4.2 bouyer BPP##b; \
149 1.1.4.2 bouyer }
150 1.1.4.2 bouyer
151 1.1.4.2 bouyer LINEFUNC(2)
152 1.1.4.2 bouyer LINEFUNC(4)
153 1.1.4.2 bouyer LINEFUNC(8)
154 1.1.4.2 bouyer DOTFUNC(2)
155 1.1.4.2 bouyer DOTFUNC(4)
156 1.1.4.2 bouyer DOTFUNC(8)
157 1.1.4.2 bouyer static void linebpp_unimpl(struct video_chip *, int, int, int, int);
158 1.1.4.2 bouyer static void dotbpp_unimpl(struct video_chip *, int, int);
159 1.1.4.2 bouyer
160 1.1.4.2 bouyer int
161 1.1.4.2 bouyer cmap_work_alloc(u_int8_t **r, u_int8_t **g, u_int8_t **b, u_int32_t **rgb,
162 1.1.4.2 bouyer int cnt)
163 1.1.4.2 bouyer {
164 1.1.4.2 bouyer KASSERT(r && g && b && rgb && LEGAL_CLUT_INDEX(cnt - 1));
165 1.1.4.2 bouyer
166 1.1.4.2 bouyer *r = malloc(cnt * sizeof(u_int8_t), M_DEVBUF, M_WAITOK);
167 1.1.4.2 bouyer *g = malloc(cnt * sizeof(u_int8_t), M_DEVBUF, M_WAITOK);
168 1.1.4.2 bouyer *b = malloc(cnt * sizeof(u_int8_t), M_DEVBUF, M_WAITOK);
169 1.1.4.2 bouyer *rgb = malloc(cnt * sizeof(u_int32_t), M_DEVBUF, M_WAITOK);
170 1.1.4.2 bouyer
171 1.1.4.2 bouyer return (!(*r && *g && *b && *rgb));
172 1.1.4.2 bouyer }
173 1.1.4.2 bouyer
174 1.1.4.2 bouyer void
175 1.1.4.2 bouyer cmap_work_free(u_int8_t *r, u_int8_t *g, u_int8_t *b, u_int32_t *rgb)
176 1.1.4.2 bouyer {
177 1.1.4.2 bouyer if (r)
178 1.1.4.2 bouyer free(r, M_DEVBUF);
179 1.1.4.2 bouyer if (g)
180 1.1.4.2 bouyer free(g, M_DEVBUF);
181 1.1.4.2 bouyer if (b)
182 1.1.4.2 bouyer free(b, M_DEVBUF);
183 1.1.4.2 bouyer if (rgb)
184 1.1.4.2 bouyer free(rgb, M_DEVBUF);
185 1.1.4.2 bouyer }
186 1.1.4.2 bouyer
187 1.1.4.2 bouyer void
188 1.1.4.2 bouyer rgb24_compose(u_int32_t *rgb24, u_int8_t *r, u_int8_t *g, u_int8_t *b, int cnt)
189 1.1.4.2 bouyer {
190 1.1.4.2 bouyer int i;
191 1.1.4.2 bouyer KASSERT(rgb24 && r && g && b && LEGAL_CLUT_INDEX(cnt - 1));
192 1.1.4.2 bouyer
193 1.1.4.2 bouyer for (i = 0; i < cnt; i++) {
194 1.1.4.2 bouyer *rgb24++ = RGB24(r[i], g[i], b[i]);
195 1.1.4.2 bouyer }
196 1.1.4.2 bouyer }
197 1.1.4.2 bouyer
198 1.1.4.2 bouyer void
199 1.1.4.2 bouyer rgb24_decompose(u_int32_t *rgb24, u_int8_t *r, u_int8_t *g, u_int8_t *b,
200 1.1.4.2 bouyer int cnt)
201 1.1.4.2 bouyer {
202 1.1.4.2 bouyer int i;
203 1.1.4.2 bouyer KASSERT(rgb24 && r && g && b && LEGAL_CLUT_INDEX(cnt - 1));
204 1.1.4.2 bouyer
205 1.1.4.2 bouyer for (i = 0; i < cnt; i++) {
206 1.1.4.2 bouyer u_int32_t rgb = *rgb24++;
207 1.1.4.2 bouyer *r++ = (rgb >> 16) & 0xff;
208 1.1.4.2 bouyer *g++ = (rgb >> 8) & 0xff;
209 1.1.4.2 bouyer *b++ = rgb & 0xff;
210 1.1.4.2 bouyer }
211 1.1.4.2 bouyer }
212 1.1.4.2 bouyer
213 1.1.4.2 bouyer /*
214 1.1.4.2 bouyer * Debug routines.
215 1.1.4.2 bouyer */
216 1.1.4.2 bouyer void
217 1.1.4.2 bouyer video_calibration_pattern(struct video_chip *vc)
218 1.1.4.2 bouyer {
219 1.1.4.2 bouyer int x, y;
220 1.1.4.2 bouyer
221 1.1.4.2 bouyer x = vc->vc_fbwidth - 40;
222 1.1.4.2 bouyer y = vc->vc_fbheight - 40;
223 1.1.4.2 bouyer video_line(vc, 40, 40, x , 40);
224 1.1.4.2 bouyer video_line(vc, x , 40, x , y );
225 1.1.4.2 bouyer video_line(vc, x , y , 40, y );
226 1.1.4.2 bouyer video_line(vc, 40, y , 40, 40);
227 1.1.4.2 bouyer video_line(vc, 40, 40, x , y );
228 1.1.4.2 bouyer video_line(vc, x, 40, 40, y );
229 1.1.4.2 bouyer }
230 1.1.4.2 bouyer
231 1.1.4.2 bouyer static void
232 1.1.4.2 bouyer linebpp_unimpl(struct video_chip *vc, int x0, int y0, int x1, int y1)
233 1.1.4.2 bouyer {
234 1.1.4.2 bouyer return;
235 1.1.4.2 bouyer }
236 1.1.4.2 bouyer
237 1.1.4.2 bouyer static void
238 1.1.4.2 bouyer dotbpp_unimpl(struct video_chip *vc, int x, int y)
239 1.1.4.2 bouyer {
240 1.1.4.2 bouyer return;
241 1.1.4.2 bouyer }
242 1.1.4.2 bouyer
243 1.1.4.2 bouyer void
244 1.1.4.2 bouyer video_attach_drawfunc(struct video_chip *vc)
245 1.1.4.2 bouyer {
246 1.1.4.2 bouyer switch (vc->vc_fbdepth) {
247 1.1.4.2 bouyer default:
248 1.1.4.2 bouyer vc->vc_drawline = linebpp_unimpl;
249 1.1.4.2 bouyer vc->vc_drawdot = dotbpp_unimpl;
250 1.1.4.2 bouyer break;
251 1.1.4.2 bouyer case 8:
252 1.1.4.2 bouyer vc->vc_drawline = linebpp8;
253 1.1.4.2 bouyer vc->vc_drawdot = dotbpp8;
254 1.1.4.2 bouyer break;
255 1.1.4.2 bouyer case 4:
256 1.1.4.2 bouyer vc->vc_drawline = linebpp4;
257 1.1.4.2 bouyer vc->vc_drawdot = dotbpp4;
258 1.1.4.2 bouyer break;
259 1.1.4.2 bouyer case 2:
260 1.1.4.2 bouyer vc->vc_drawline = linebpp2;
261 1.1.4.2 bouyer vc->vc_drawdot = dotbpp2;
262 1.1.4.2 bouyer break;
263 1.1.4.2 bouyer }
264 1.1.4.2 bouyer }
265 1.1.4.2 bouyer
266 1.1.4.2 bouyer void
267 1.1.4.2 bouyer video_line(struct video_chip *vc, int x0, int y0, int x1, int y1)
268 1.1.4.2 bouyer {
269 1.1.4.2 bouyer if (vc->vc_drawline)
270 1.1.4.2 bouyer vc->vc_drawline(vc, x0, y0, x1, y1);
271 1.1.4.2 bouyer }
272 1.1.4.2 bouyer
273 1.1.4.2 bouyer void
274 1.1.4.2 bouyer video_dot(struct video_chip *vc, int x, int y)
275 1.1.4.2 bouyer {
276 1.1.4.2 bouyer if (vc->vc_drawdot)
277 1.1.4.2 bouyer vc->vc_drawdot(vc, x, y);
278 1.1.4.2 bouyer }
279 1.1.4.2 bouyer
280 1.1.4.2 bouyer int
281 1.1.4.2 bouyer video_reverse_color()
282 1.1.4.2 bouyer {
283 1.1.4.2 bouyer struct {
284 1.1.4.2 bouyer int reverse, normal;
285 1.1.4.2 bouyer } ctype[] = {
286 1.1.4.2 bouyer { BIFB_D2_M2L_3, BIFB_D2_M2L_0 },
287 1.1.4.2 bouyer { BIFB_D2_M2L_3x2, BIFB_D2_M2L_0x2 },
288 1.1.4.2 bouyer { BIFB_D8_FF, BIFB_D8_00 },
289 1.1.4.2 bouyer { BIFB_D16_FFFF, BIFB_D16_0000, },
290 1.1.4.2 bouyer { -1, -1 } /* terminator */
291 1.1.4.2 bouyer }, *ctypep;
292 1.1.4.2 bouyer u_int16_t fbtype;
293 1.1.4.2 bouyer
294 1.1.4.2 bouyer /* check reverse color */
295 1.1.4.2 bouyer fbtype = bootinfo->fb_type;
296 1.1.4.2 bouyer for (ctypep = ctype; ctypep->normal != -1 ; ctypep++) {
297 1.1.4.2 bouyer if (fbtype == ctypep->normal) {
298 1.1.4.2 bouyer return (0);
299 1.1.4.2 bouyer } else if (fbtype == ctypep->reverse) {
300 1.1.4.2 bouyer return (1);
301 1.1.4.2 bouyer }
302 1.1.4.2 bouyer }
303 1.1.4.2 bouyer printf(": WARNING unknown frame buffer type 0x%04x.\n", fbtype);
304 1.1.4.2 bouyer return (0);
305 1.1.4.2 bouyer }
306