1 /* $NetBSD: grfabs.c,v 1.20 2023/12/20 00:40:42 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1995 Leo Weppelman.
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 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 * atari abstract graphics driver.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: grfabs.c,v 1.20 2023/12/20 00:40:42 thorpej Exp $");
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/queue.h>
38
39 #include <machine/cpu.h>
40 #include <machine/iomap.h>
41 #include <machine/video.h>
42 #include <machine/mfp.h>
43 #include <atari/dev/grfabs_reg.h>
44
45 /*
46 * Function decls
47 */
48 static dmode_t *get_best_display_mode(dimen_t *, int, dmode_t *);
49
50 /*
51 * List of available graphic modes
52 */
53 static MODES modes;
54
55 /*
56 * Ugh.. Stuff needed to allocate console structures before the VM-system
57 * is running.
58 * Decision to use these: atari_realconfig == 0
59 */
60 view_t gra_con_view;
61 colormap_t gra_con_cmap;
62 long gra_con_colors[MAX_CENTRIES];
63
64 /*
65 * Default colors.....
66 * Currently the TT-low (256 colors) just uses 16 times the 16-color default.
67 * If you have a sensible 256 scale, feel free to add.....
68 * The first 2 colors in all maps are {black,white}, so ite (text) displays
69 * are initially readable. Also, this enables me to supply only 1 map. The
70 * 4 color mode uses the first four entries of the 16 color mode thus giving
71 * a gray scale display. (Maybe we can add an intensity bit to the ite...)
72 */
73 u_long gra_def_color16[16] = {
74 0x00000000, /* black */
75 0x00ffffff, /* white */
76 0x000c0c0c, /* light gray */
77 0x00808008, /* gray */
78 0x0000000c, /* blue */
79 0x00000c00, /* green */
80 0x00000c0c, /* cyan */
81 0x00c00000, /* red */
82 0x00c0000c, /* magenta */
83 0x00c00c00, /* brown */
84 0x000000ff, /* light blue */
85 0x0000ff00, /* light green */
86 0x0000ffff, /* light cyan */
87 0x00ff0000, /* light red */
88 0x00ff00ff, /* light magenta */
89 0x00ffff00 /* light brown */
90 };
91
92 /*
93 * XXX: called from ite console init routine.
94 * Initialize list of possible video modes.
95 */
96 int
grfabs_probe(grf_probe_t probe_fun)97 grfabs_probe(grf_probe_t probe_fun)
98 {
99 static int inited = 0;
100
101 if (!inited) {
102 LIST_INIT(&modes);
103 inited = 1;
104 }
105 (*probe_fun)(&modes);
106
107 return ((modes.lh_first == NULL) ? 0 : 1);
108 }
109
110 view_t *
grf_alloc_view(dmode_t * d,dimen_t * dim,u_char depth)111 grf_alloc_view(dmode_t *d, dimen_t *dim, u_char depth)
112 {
113 if (!d)
114 d = get_best_display_mode(dim, depth, NULL);
115 if (d)
116 return ((d->grfabs_funcs->alloc_view)(d, dim, depth));
117 return(NULL);
118 }
119
120 dmode_t *
grf_get_best_mode(dimen_t * dim,u_char depth)121 grf_get_best_mode(dimen_t *dim, u_char depth)
122 {
123 return (get_best_display_mode(dim, depth, NULL));
124 }
125
126 void
grf_display_view(view_t * v)127 grf_display_view(view_t *v)
128 {
129 (v->mode->grfabs_funcs->display_view)(v);
130 }
131
132 void
grf_remove_view(view_t * v)133 grf_remove_view(view_t *v)
134 {
135 (v->mode->grfabs_funcs->remove_view)(v);
136 }
137
138 void
grf_save_view(view_t * v)139 grf_save_view(view_t *v)
140 {
141 (v->mode->grfabs_funcs->save_view)(v);
142 }
143
144 void
grf_free_view(view_t * v)145 grf_free_view(view_t *v)
146 {
147 (v->mode->grfabs_funcs->free_view)(v);
148 }
149
150 int
grf_get_colormap(view_t * v,colormap_t * cm)151 grf_get_colormap(view_t *v, colormap_t *cm)
152 {
153 colormap_t *gcm;
154 int i, n;
155 u_long *sv_entry;
156
157 gcm = v->colormap;
158 n = cm->size < gcm->size ? cm->size : gcm->size;
159
160 /*
161 * Copy struct from view but be carefull to keep 'entry'
162 */
163 sv_entry = cm->entry;
164 *cm = *gcm;
165 cm->entry = sv_entry;
166
167 /*
168 * Copy the colors
169 */
170 memset(cm->entry, 0, cm->size * sizeof(long));
171 for (i = 0; i < n; i++)
172 cm->entry[i] = gcm->entry[i];
173 return (0);
174 }
175
176 int
grf_use_colormap(view_t * v,colormap_t * cm)177 grf_use_colormap(view_t *v, colormap_t *cm)
178 {
179 return (v->mode->grfabs_funcs->use_colormap)(v, cm);
180 }
181
182 static dmode_t *
get_best_display_mode(dimen_t * dim,int depth,dmode_t * curr_mode)183 get_best_display_mode(dimen_t *dim, int depth, dmode_t *curr_mode)
184 {
185 dmode_t *save;
186 dmode_t *dm;
187 long dx, dy, dd, ct;
188 long size_diff, depth_diff;
189
190 save = NULL;
191 size_diff = 0;
192 depth_diff = 0;
193 dm = modes.lh_first;
194 while (dm != NULL) {
195 dx = abs(dm->size.width - dim->width);
196 dy = abs(dm->size.height - dim->height);
197 dd = abs(dm->depth - depth);
198 ct = dx + dy;
199
200 if ((save != NULL) && (size_diff == 0)) {
201 if (dd > depth_diff) {
202 dm = dm->link.le_next;
203 continue;
204 }
205 }
206 if ((save == NULL) || (ct <= size_diff)) {
207 save = dm;
208 size_diff = ct;
209 depth_diff = dd;
210 }
211 dm = dm->link.le_next;
212 }
213 /*
214 * Did we do better than the current mode?
215 */
216 if ((save != NULL) && (curr_mode != NULL)) {
217 dx = abs(curr_mode->size.width - dim->width);
218 dy = abs(curr_mode->size.height - dim->height);
219 dd = abs(curr_mode->depth - depth);
220 ct = dx + dy;
221 if ((ct <= size_diff) && (dd <= depth_diff))
222 return (NULL);
223 }
224 return (save);
225 }
226