1 /* $NetBSD: grfconfig.c,v 1.13 2008/07/21 13:36:58 lukem Exp $ */
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ezra Story and Bernd Ernesti.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1997\
35 The NetBSD Foundation, Inc. All rights reserved.");
39 __RCSID("$NetBSD: grfconfig.c,v 1.13 2008/07/21 13:36:58 lukem Exp $");
43 #include <sys/ioctl.h>
51 #include <amiga/dev/grfioctl.h>
53 int main
__P((int, char **));
54 static void print_rawdata
__P((struct grfvideo_mode
*, int));
56 static struct grf_flag
{
57 u_short grf_flag_number
;
58 const char *grf_flag_name
;
60 {GRF_FLAGS_DBLSCAN
, "doublescan"},
61 {GRF_FLAGS_LACE
, "interlace"},
62 {GRF_FLAGS_PHSYNC
, "+hsync"},
63 {GRF_FLAGS_NHSYNC
, "-hsync"},
64 {GRF_FLAGS_PVSYNC
, "+vsync"},
65 {GRF_FLAGS_NVSYNC
, "-vsync"},
66 {GRF_FLAGS_SYNC_ON_GREEN
, "sync-on-green"},
71 * Dynamic mode loader for NetBSD/Amiga grf devices.
78 struct grfvideo_mode gv
[1];
79 struct grf_flag
*grf_flagp
;
84 char rawdata
= 0, testmode
= 0;
87 char buf
[_POSIX2_LINE_MAX
];
90 const char *errortext
;
93 while ((c
= getopt(ac
, av
, "rt")) != -1) {
95 case 'r': /* raw output */
98 case 't': /* test the modefile without setting it */
102 printf("grfconfig [-r] device [file]\n");
113 printf("grfconfig: No grf device specified.\n");
120 if ((grffd
= open(grfdevice
, O_RDWR
)) < 0) {
121 printf("grfconfig: can't open grf device.\n");
124 /* If a mode file is specificied, load it in, don't display any info. */
127 if (!(fp
= fopen(modefile
, "r"))) {
128 printf("grfconfig: Cannot open mode definition "
132 while (fgets(buf
, sizeof(buf
), fp
)) {
133 char *obuf
, tbuf
[_POSIX2_LINE_MAX
], *tbuf2
;
135 * check for end-of-section, comments, strip off trailing
136 * spaces and newline character.
138 for (p
= buf
; isspace((unsigned char)*p
); ++p
)
140 if (*p
== '\0' || *p
== '#')
142 for (p
= strchr(buf
, '\0'); isspace((unsigned char)*--p
);)
148 while ((*tbuf2
= *obuf
) != '\0') {
153 if (isupper((unsigned char)*tbuf2
)) {
154 *tbuf2
= tolower((unsigned char)*tbuf2
);
163 for (i
= 0, *cps
= strtok(buf
, " \b\t\r\n");
164 cps
[i
] != NULL
&& i
< 30; i
++)
165 cps
[i
+ 1] = strtok(NULL
, " \b\t\r\n");
169 printf("grfconfig: too few values in mode "
170 "definition file:\n %s\n", obuf
);
174 gv
->pixel_clock
= atoi(cps
[1]);
175 gv
->disp_width
= atoi(cps
[2]);
176 gv
->disp_height
= atoi(cps
[3]);
177 gv
->depth
= atoi(cps
[4]);
178 gv
->hblank_start
= atoi(cps
[5]);
179 gv
->hsync_start
= atoi(cps
[6]);
180 gv
->hsync_stop
= atoi(cps
[7]);
181 gv
->htotal
= atoi(cps
[8]);
182 gv
->vblank_start
= atoi(cps
[9]);
183 gv
->vsync_start
= atoi(cps
[10]);
184 gv
->vsync_stop
= atoi(cps
[11]);
185 gv
->vtotal
= atoi(cps
[12]);
187 if ((y
= atoi(cps
[0])))
190 if (strncasecmp("c", cps
[0], 1) == 0) {
194 printf("grfconfig: Illegal mode "
195 "number: %s\n", cps
[0]);
199 if ((gv
->pixel_clock
== 0) ||
200 (gv
->disp_width
== 0) ||
201 (gv
->disp_height
== 0) ||
203 (gv
->hblank_start
== 0) ||
204 (gv
->hsync_start
== 0) ||
205 (gv
->hsync_stop
== 0) ||
207 (gv
->vblank_start
== 0) ||
208 (gv
->vsync_start
== 0) ||
209 (gv
->vsync_stop
== 0) ||
211 printf("grfconfig: Illegal value in "
212 "mode #%d:\n %s\n", gv
->mode_num
, obuf
);
216 if (strstr(obuf
, "default") != NULL
) {
217 gv
->disp_flags
= GRF_FLAGS_DEFAULT
;
219 gv
->disp_flags
= GRF_FLAGS_DEFAULT
;
220 for (grf_flagp
= grf_flags
;
221 grf_flagp
->grf_flag_number
; grf_flagp
++) {
222 if (strstr(obuf
, grf_flagp
->grf_flag_name
) != NULL
) {
223 gv
->disp_flags
|= grf_flagp
->grf_flag_number
;
226 if (gv
->disp_flags
== GRF_FLAGS_DEFAULT
) {
227 printf("grfconfig: Your are using an "
228 "mode file with an obsolete "
229 "format.\n See the manpage of "
230 "grfconfig for more information "
231 "about the new mode definition "
238 * Check for impossible gv->disp_flags:
239 * doublescan and interlace,
244 if ((gv
->disp_flags
& GRF_FLAGS_DBLSCAN
) &&
245 (gv
->disp_flags
& GRF_FLAGS_LACE
))
246 errortext
= "Interlace and Doublescan";
247 if ((gv
->disp_flags
& GRF_FLAGS_PHSYNC
) &&
248 (gv
->disp_flags
& GRF_FLAGS_NHSYNC
))
249 errortext
= "+hsync and -hsync";
250 if ((gv
->disp_flags
& GRF_FLAGS_PVSYNC
) &&
251 (gv
->disp_flags
& GRF_FLAGS_NVSYNC
))
252 errortext
= "+vsync and -vsync";
254 if (errortext
!= NULL
) {
255 printf("grfconfig: Illegal flags in "
256 "mode #%d: %s are both defined!\n",
257 gv
->mode_num
, errortext
);
261 /* Check for old horizontal cycle values */
262 if ((gv
->htotal
< (gv
->disp_width
/ 4))) {
263 gv
->hblank_start
*= 8;
264 gv
->hsync_start
*= 8;
267 printf("grfconfig: Old and no longer "
268 "supported horizontal videoclock cycle "
269 "values.\n Wrong mode line:\n %s\n "
270 "This could be a possible good mode "
272 printf("%d ", gv
->mode_num
);
273 print_rawdata(gv
, 0);
274 printf(" See the manpage of grfconfig for "
275 "more information about the new mode "
276 "definition file.\n");
280 /* Check for old interlace or doublescan modes */
281 uplim
= gv
->disp_height
+ (gv
->disp_height
/ 4);
282 lowlim
= gv
->disp_height
- (gv
->disp_height
/ 4);
283 if (((gv
->vtotal
* 2) > lowlim
) &&
284 ((gv
->vtotal
* 2) < uplim
)) {
285 gv
->vblank_start
*= 2;
286 gv
->vsync_start
*= 2;
289 gv
->disp_flags
&= ~GRF_FLAGS_DBLSCAN
;
290 gv
->disp_flags
|= GRF_FLAGS_LACE
;
291 printf("grfconfig: Old and no longer "
292 "supported vertical values for "
293 "interlace modes.\n Wrong mode "
294 "line:\n %s\n This could be a "
295 "possible good mode line:\n ", obuf
);
296 printf("%d ", gv
->mode_num
);
297 print_rawdata(gv
, 0);
298 printf(" See the manpage of grfconfig for "
299 "more information about the new mode "
300 "definition file.\n");
302 } else if (((gv
->vtotal
/ 2) > lowlim
) &&
303 ((gv
->vtotal
/ 2) < uplim
)) {
304 gv
->vblank_start
/= 2;
305 gv
->vsync_start
/= 2;
308 gv
->disp_flags
&= ~GRF_FLAGS_LACE
;
309 gv
->disp_flags
|= GRF_FLAGS_DBLSCAN
;
310 printf("grfconfig: Old and no longer "
311 "supported vertical values for "
312 "doublescan modes.\n Wrong mode "
313 "line:\n %s\n This could be a "
314 "possible good mode line:\n ", obuf
);
315 printf("%d ", gv
->mode_num
);
316 print_rawdata(gv
, 0);
317 printf(" See the manpage of grfconfig for "
318 "more information about the new mode "
319 "definition file.\n");
325 printf("num clk wid hi dep hbs "
326 "hss hse ht vbs vss vse vt "
328 printf("%d ", gv
->mode_num
);
329 print_rawdata(gv
, 1);
331 gv
->mode_descr
[0] = 0;
332 if (ioctl(grffd
, GRFIOCSETMON
, (char *) gv
) < 0)
333 printf("grfconfig: bad monitor "
334 "definition for mode #%d.\n",
340 ioctl(grffd
, GRFGETNUMVM
, &y
);
342 for (c
= 1; c
< y
; c
++) {
343 c
= gv
->mode_num
= (c
!= (y
- 1)) ? c
: 255;
344 if (ioctl(grffd
, GRFGETVMODE
, gv
) < 0)
351 print_rawdata(gv
, 0);
357 printf("%2d: ", gv
->mode_num
);
364 printf("x%d", gv
->depth
);
368 gv
->disp_height
/ gv
->depth
);
370 printf("\t%ld.%ldkHz @ %ldHz",
371 gv
->pixel_clock
/ (gv
->htotal
* 1000),
372 (gv
->pixel_clock
/ (gv
->htotal
* 100))
374 gv
->pixel_clock
/ (gv
->htotal
* gv
->vtotal
));
377 if (gv
->disp_flags
== GRF_FLAGS_DEFAULT
) {
380 for (grf_flagp
= grf_flags
;
381 grf_flagp
->grf_flag_number
; grf_flagp
++) {
382 if (gv
->disp_flags
& grf_flagp
->grf_flag_number
) {
383 printf(" %s", grf_flagp
->grf_flag_name
);
396 print_rawdata(gv
, rawflags
)
397 struct grfvideo_mode
*gv
;
400 struct grf_flag
*grf_flagp
;
402 printf("%ld %d %d %d %d %d %d %d %d %d %d %d",
416 printf(" 0x%.2x", gv
->disp_flags
);
418 if (gv
->disp_flags
== GRF_FLAGS_DEFAULT
) {
421 for (grf_flagp
= grf_flags
;
422 grf_flagp
->grf_flag_number
; grf_flagp
++) {
423 if (gv
->disp_flags
& grf_flagp
->grf_flag_number
) {
424 printf(" %s", grf_flagp
->grf_flag_name
);