xref: /netbsd-src/sys/arch/atari/stand/bootpref/bootpref.c (revision 62f5486c1b00a8713d4b74bcbc7a96336f32a63e)
1*62f5486cShe /*	$NetBSD: bootpref.c,v 1.6 2009/03/17 00:18:40 he Exp $	*/
2ce735c34Sleo /*-
3ce735c34Sleo  * Copyright (c) 1998 The NetBSD Foundation, Inc.
4ce735c34Sleo  * All rights reserved.
5ce735c34Sleo  *
6ce735c34Sleo  * This code is derived from software contributed to The NetBSD Foundation
7ce735c34Sleo  * by Julian Coleman.
8ce735c34Sleo  *
9ce735c34Sleo  * Redistribution and use in source and binary forms, with or without
10ce735c34Sleo  * modification, are permitted provided that the following conditions
11ce735c34Sleo  * are met:
12ce735c34Sleo  * 1. Redistributions of source code must retain the above copyright
13ce735c34Sleo  *    notice, this list of conditions and the following disclaimer.
14ce735c34Sleo  * 2. Redistributions in binary form must reproduce the above copyright
15ce735c34Sleo  *    notice, this list of conditions and the following disclaimer in the
16ce735c34Sleo  *    documentation and/or other materials provided with the distribution.
17ce735c34Sleo  *
18ce735c34Sleo  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19ce735c34Sleo  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20ce735c34Sleo  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21ce735c34Sleo  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22ce735c34Sleo  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23ce735c34Sleo  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24ce735c34Sleo  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25ce735c34Sleo  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26ce735c34Sleo  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27ce735c34Sleo  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28ce735c34Sleo  * POSSIBILITY OF SUCH DAMAGE.
29ce735c34Sleo  */
30ce735c34Sleo #include <sys/types.h>
31ce735c34Sleo #include <unistd.h>
32ce735c34Sleo #include <string.h>
33ce735c34Sleo #include <stdlib.h>
34ce735c34Sleo #include <stdio.h>
35ce735c34Sleo #include <fcntl.h>
36ce735c34Sleo #include <errno.h>
37ce735c34Sleo #include <err.h>
38ce735c34Sleo #include <sys/mman.h>
39ce735c34Sleo #include "bootpref.h"
40ce735c34Sleo 
4102cdf4d2Sdsl static void	usage(void);
4202cdf4d2Sdsl static int	openNVRAM(void);
4302cdf4d2Sdsl static void	closeNVRAM(int);
4402cdf4d2Sdsl static u_char	readNVRAM(int, int);
4502cdf4d2Sdsl static void	writeNVRAM(int, int, u_char);
4602cdf4d2Sdsl static void	getNVpref(int, u_char[]);
4702cdf4d2Sdsl static void	setNVpref(int, u_char[], int, int);
4802cdf4d2Sdsl static void	showOS(u_char);
4902cdf4d2Sdsl static void	showLang(u_char);
5002cdf4d2Sdsl static void	showKbdLang(u_char);
5102cdf4d2Sdsl static void	showDateFmt(u_char);
5202cdf4d2Sdsl static void	showDateSep(u_char);
5302cdf4d2Sdsl static void	showVideo2(u_char);
5402cdf4d2Sdsl static void	showVideo1(u_char, u_char);
5502cdf4d2Sdsl static int	checkOS(u_char *, char *);
5602cdf4d2Sdsl static int	checkLang(u_char *, char *);
5702cdf4d2Sdsl static int	checkKbdLang(u_char *, char *);
5802cdf4d2Sdsl static int	checkInt(u_char *, char *, int, int);
5902cdf4d2Sdsl static int 	checkDateFmt(u_char *, char *);
6002cdf4d2Sdsl static void 	checkDateSep(u_char *, char *);
6102cdf4d2Sdsl static int 	checkColours(u_char *, char *);
62ce735c34Sleo 
63ce735c34Sleo #define SET_OS		0x001
64ce735c34Sleo #define SET_LANG	0x002
65ce735c34Sleo #define SET_KBDLANG	0x004
66ce735c34Sleo #define SET_HOSTID	0x008
67ce735c34Sleo #define SET_DATIME	0x010
68ce735c34Sleo #define SET_DATESEP	0x020
69ce735c34Sleo #define SET_BOOTDLY	0x040
70ce735c34Sleo #define SET_VID1	0x080
71ce735c34Sleo #define SET_VID2	0x100
72ce735c34Sleo 
73ce735c34Sleo #define ARRAY_OS	0
74ce735c34Sleo #define ARRAY_LANG	1
75ce735c34Sleo #define ARRAY_KBDLANG	2
76ce735c34Sleo #define ARRAY_HOSTID	3
77ce735c34Sleo #define ARRAY_DATIME	4
78ce735c34Sleo #define ARRAY_DATESEP	5
79ce735c34Sleo #define ARRAY_BOOTDLY	6
80ce735c34Sleo #define ARRAY_VID1	7
81ce735c34Sleo #define ARRAY_VID2	8
82ce735c34Sleo 
83ce735c34Sleo static const char	nvrdev[] = PATH_NVRAM;
84ce735c34Sleo 
85ce735c34Sleo int
main(int argc,char * argv[])8682357f6dSdsl main (int argc, char *argv[])
87ce735c34Sleo {
88ce735c34Sleo 	int	c, set = 0, verbose = 0;
89ce735c34Sleo 	int	fd;
90ce735c34Sleo 	u_char	bootpref[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
91ce735c34Sleo 	u_char	check_hour = 0, check_video1 = 0, check_video2 = 0;
92ce735c34Sleo 
93ce735c34Sleo 	fd = openNVRAM ();
94ce735c34Sleo 	bootpref[ARRAY_VID2] = readNVRAM (fd, NVRAM_VID2);
95ce735c34Sleo 	bootpref[ARRAY_VID1] = readNVRAM (fd, NVRAM_VID1);
96ce735c34Sleo 	/* parse options */
97ce735c34Sleo 	while ((c = getopt (argc, argv, "Vb:d:k:l:s:f:12e:c:nptv48oOxXiI")) != -1) {
98ce735c34Sleo 		switch (c) {
99ce735c34Sleo 		case 'V':
100ce735c34Sleo 			verbose = 1;
101ce735c34Sleo 			break;
102ce735c34Sleo 		case 'b':
103ce735c34Sleo 			if (checkOS (&bootpref[ARRAY_OS], optarg))
104ce735c34Sleo 				set |= SET_OS;
105ce735c34Sleo 			else
106ce735c34Sleo 				usage ();
107ce735c34Sleo 			break;
108ce735c34Sleo 		case 'd':
109ce735c34Sleo 			if (checkInt (&bootpref[ARRAY_BOOTDLY], optarg,
110ce735c34Sleo 			   0, 255))
111ce735c34Sleo 				set |= SET_BOOTDLY;
112ce735c34Sleo 			else
113ce735c34Sleo 				usage ();
114ce735c34Sleo 			break;
115ce735c34Sleo 		case 'k':
116ce735c34Sleo 			if (checkKbdLang (&bootpref[ARRAY_KBDLANG], optarg))
117ce735c34Sleo 				set |= SET_KBDLANG;
118ce735c34Sleo 			else
119ce735c34Sleo 				usage ();
120ce735c34Sleo 			break;
121ce735c34Sleo 		case 'l':
122ce735c34Sleo 			if (checkLang (&bootpref[ARRAY_LANG], optarg))
123ce735c34Sleo 				set |= SET_LANG;
124ce735c34Sleo 			else
125ce735c34Sleo 				usage ();
126ce735c34Sleo 			break;
127ce735c34Sleo 		case 's':
128ce735c34Sleo 			if (checkInt (&bootpref[ARRAY_HOSTID], optarg,
129ce735c34Sleo 			    0, 7))
130ce735c34Sleo 				set |= SET_HOSTID;
131ce735c34Sleo 			else
132ce735c34Sleo 				usage ();
133ce735c34Sleo 			break;
134ce735c34Sleo 		case 'f':
135ce735c34Sleo 			if (checkDateFmt (&bootpref[ARRAY_DATIME], optarg))
136ce735c34Sleo 				set |= SET_DATIME;
137ce735c34Sleo 			else
138ce735c34Sleo 				usage ();
139ce735c34Sleo 			break;
140ce735c34Sleo 		case '1':
141ce735c34Sleo 			if (check_hour & DATIME_24H) {
142ce735c34Sleo 				usage();
143ce735c34Sleo 			} else {
144ce735c34Sleo 				bootpref[ARRAY_DATIME] &= ~DATIME_24H;
145ce735c34Sleo 				set |= SET_DATIME;
146ce735c34Sleo 				check_hour |= DATIME_24H;
147ce735c34Sleo 			}
148ce735c34Sleo 			break;
149ce735c34Sleo 		case '2':
150ce735c34Sleo 			if (check_hour & DATIME_24H) {
151ce735c34Sleo 				usage();
152ce735c34Sleo 			} else {
153ce735c34Sleo 				bootpref[ARRAY_DATIME] |= DATIME_24H;
154ce735c34Sleo 				set |= SET_DATIME;
155ce735c34Sleo 				check_hour |= DATIME_24H;
156ce735c34Sleo 			}
157ce735c34Sleo 			break;
158ce735c34Sleo 		case 'e':
159ce735c34Sleo 			checkDateSep (&bootpref[ARRAY_DATESEP], optarg);
160ce735c34Sleo 			set |= SET_DATESEP;
161ce735c34Sleo 			break;
162ce735c34Sleo 		case 'c':
163ce735c34Sleo 			if (checkColours (&bootpref[ARRAY_VID2], optarg))
164ce735c34Sleo 				set |= SET_VID2;
165ce735c34Sleo 			else
166ce735c34Sleo 				usage ();
167ce735c34Sleo 			break;
168ce735c34Sleo 		case 'n':
169ce735c34Sleo 			if (check_video2 & VID2_PAL) {
170ce735c34Sleo 				usage();
171ce735c34Sleo 			} else {
172ce735c34Sleo 				bootpref[ARRAY_VID2] &= ~VID2_PAL;
173ce735c34Sleo 				set |= SET_VID2;
174ce735c34Sleo 				check_video2 |= VID2_PAL;
175ce735c34Sleo 			}
176ce735c34Sleo 			break;
177ce735c34Sleo 		case 'p':
178ce735c34Sleo 			if (check_video2 & VID2_PAL) {
179ce735c34Sleo 				usage();
180ce735c34Sleo 			} else {
181ce735c34Sleo 				bootpref[ARRAY_VID2] |= VID2_PAL;
182ce735c34Sleo 				set |= SET_VID2;
183ce735c34Sleo 				check_video2 |= VID2_PAL;
184ce735c34Sleo 			}
185ce735c34Sleo 			break;
186ce735c34Sleo 		case 't':
187ce735c34Sleo 			if (check_video2 & VID2_VGA) {
188ce735c34Sleo 				usage();
189ce735c34Sleo 			} else {
190ce735c34Sleo 				bootpref[ARRAY_VID2] &= ~VID2_VGA;
191ce735c34Sleo 				set |= SET_VID2;
192ce735c34Sleo 				check_video2 |= VID2_VGA;
193ce735c34Sleo 			}
194ce735c34Sleo 			break;
195ce735c34Sleo 		case 'v':
196ce735c34Sleo 			if (check_video2 & VID2_VGA) {
197ce735c34Sleo 				usage();
198ce735c34Sleo 			} else {
199ce735c34Sleo 				bootpref[ARRAY_VID2] |= VID2_VGA;
200ce735c34Sleo 				set |= SET_VID2;
201ce735c34Sleo 				check_video2 |= VID2_VGA;
202ce735c34Sleo 			}
203ce735c34Sleo 			break;
204ce735c34Sleo 		case '4':
205ce735c34Sleo 			if (check_video2 & VID2_80CLM) {
206ce735c34Sleo 				usage();
207ce735c34Sleo 			} else {
208ce735c34Sleo 				bootpref[ARRAY_VID2] &= ~VID2_80CLM;
209ce735c34Sleo 				set |= SET_VID2;
210ce735c34Sleo 				check_video2 |= VID2_80CLM;
211ce735c34Sleo 			}
212ce735c34Sleo 			break;
213ce735c34Sleo 		case '8':
214ce735c34Sleo 			if (check_video2 & VID2_80CLM) {
215ce735c34Sleo 				usage();
216ce735c34Sleo 			} else {
217ce735c34Sleo 				bootpref[ARRAY_VID2] |= VID2_80CLM;
218ce735c34Sleo 				set |= SET_VID2;
219ce735c34Sleo 				check_video2 |= VID2_80CLM;
220ce735c34Sleo 			}
221ce735c34Sleo 			break;
222ce735c34Sleo 		case 'o':
223ce735c34Sleo 			if (check_video2 & VID2_OVERSCAN) {
224ce735c34Sleo 				usage();
225ce735c34Sleo 			} else {
226ce735c34Sleo 				bootpref[ARRAY_VID2] |= VID2_OVERSCAN;
227ce735c34Sleo 				set |= SET_VID2;
228ce735c34Sleo 				check_video2 |= VID2_OVERSCAN;
229ce735c34Sleo 			}
230ce735c34Sleo 			break;
231ce735c34Sleo 		case 'O':
232ce735c34Sleo 			if (check_video2 & VID2_OVERSCAN) {
233ce735c34Sleo 				usage();
234ce735c34Sleo 			} else {
235ce735c34Sleo 				bootpref[ARRAY_VID2] &= ~VID2_OVERSCAN;
236ce735c34Sleo 				set |= SET_VID2;
237ce735c34Sleo 				check_video2 |= VID2_OVERSCAN;
238ce735c34Sleo 			}
239ce735c34Sleo 			break;
240ce735c34Sleo 		case 'x':
241ce735c34Sleo 			if (check_video2 & VID2_COMPAT) {
242ce735c34Sleo 				usage();
243ce735c34Sleo 			} else {
244ce735c34Sleo 				bootpref[ARRAY_VID2] |= VID2_COMPAT;
245ce735c34Sleo 				set |= SET_VID2;
246ce735c34Sleo 				check_video2 |= VID2_COMPAT;
247ce735c34Sleo 			}
248ce735c34Sleo 			break;
249ce735c34Sleo 		case 'X':
250ce735c34Sleo 			if (check_video2 & VID2_COMPAT) {
251ce735c34Sleo 				usage();
252ce735c34Sleo 			} else {
253ce735c34Sleo 				bootpref[ARRAY_VID2] &= ~VID2_COMPAT;
254ce735c34Sleo 				set |= SET_VID2;
255ce735c34Sleo 				check_video2 |= VID2_COMPAT;
256ce735c34Sleo 			}
257ce735c34Sleo 			break;
258ce735c34Sleo 		case 'i':
259ce735c34Sleo 			if (check_video1 & VID1_INTERLACE) {
260ce735c34Sleo 				usage();
261ce735c34Sleo 			} else {
262ce735c34Sleo 				bootpref[ARRAY_VID1] |= VID1_INTERLACE;
263ce735c34Sleo 				set |= SET_VID1;
264ce735c34Sleo 				check_video1 |= VID1_INTERLACE;
265ce735c34Sleo 			}
266ce735c34Sleo 			break;
267ce735c34Sleo 		case 'I':
268ce735c34Sleo 			if (check_video1 & VID1_INTERLACE) {
269ce735c34Sleo 				usage();
270ce735c34Sleo 			} else {
271ce735c34Sleo 				bootpref[ARRAY_VID1] &= ~VID1_INTERLACE;
272ce735c34Sleo 				set |= SET_VID1;
273ce735c34Sleo 				check_video1 |= VID1_INTERLACE;
274ce735c34Sleo 			}
275ce735c34Sleo 			break;
276ce735c34Sleo 		default:
277ce735c34Sleo 			usage ();
278ce735c34Sleo 		}
279ce735c34Sleo 	}
280ce735c34Sleo 	if (optind != argc) {
281ce735c34Sleo 		usage ();
282ce735c34Sleo 	}
283ce735c34Sleo 	if (set) {
284ce735c34Sleo 		setNVpref (fd, bootpref, set, verbose);
285ce735c34Sleo 	} else {
286ce735c34Sleo 		getNVpref (fd, bootpref);
287ce735c34Sleo 	}
288ce735c34Sleo 	closeNVRAM (fd);
289ce735c34Sleo 	return (EXIT_SUCCESS);
290ce735c34Sleo }
291ce735c34Sleo 
292ce735c34Sleo static void
usage(void)293ce735c34Sleo usage (void)
294ce735c34Sleo {
295ce735c34Sleo 	fprintf (stderr,
296ce735c34Sleo 		"usage: bootpref [-V] [-b os] [-d delay] [-k kbd] [-l lang] "
297ce735c34Sleo 		"[-s id]\n"
298ce735c34Sleo 		"\t[-f fmt] [-1] [-2] [-e sep]\n"
299ce735c34Sleo 		"\t[-c colours] [-n] [-p] [-t] [-v] [-4] [-8]\n"
300ce735c34Sleo 		"\t[-o] [-O] [-x] [-X] [-i] [-I]\n");
301ce735c34Sleo 	exit (EXIT_FAILURE);
302ce735c34Sleo }
303ce735c34Sleo 
304ce735c34Sleo static int
openNVRAM()305ce735c34Sleo openNVRAM ()
306ce735c34Sleo {
307ce735c34Sleo 	int fd;
308ce735c34Sleo 
309ce735c34Sleo 	if ((fd = open (nvrdev, O_RDWR)) < 0) {
310ce735c34Sleo 		err (EXIT_FAILURE, "%s", nvrdev);
311ce735c34Sleo 	}
312ce735c34Sleo 	return (fd);
313ce735c34Sleo }
314ce735c34Sleo 
315ce735c34Sleo static void
closeNVRAM(int fd)31682357f6dSdsl closeNVRAM (int fd)
317ce735c34Sleo {
318ce735c34Sleo 	if (close (fd) < 0) {
319ce735c34Sleo 		err (EXIT_FAILURE, "%s", nvrdev);
320ce735c34Sleo 	}
321ce735c34Sleo }
322ce735c34Sleo 
323ce735c34Sleo static u_char
readNVRAM(int fd,int pos)32482357f6dSdsl readNVRAM (int fd, int pos)
325ce735c34Sleo {
326ce735c34Sleo 	u_char val;
327ce735c34Sleo 
328ce735c34Sleo 	if (lseek(fd, (off_t)pos, SEEK_SET) != pos) {
329ce735c34Sleo 		err(EXIT_FAILURE, "%s", nvrdev);
330ce735c34Sleo 	}
331ce735c34Sleo 	if (read (fd, &val, (size_t)1) != 1) {
332ce735c34Sleo 		err(EXIT_FAILURE, "%s", nvrdev);
333ce735c34Sleo 	}
334ce735c34Sleo 	return (val);
335ce735c34Sleo }
336ce735c34Sleo 
337ce735c34Sleo static void
writeNVRAM(int fd,int pos,u_char val)33882357f6dSdsl writeNVRAM (int fd, int pos, u_char val)
339ce735c34Sleo {
340ce735c34Sleo 	if (lseek(fd, (off_t)pos, SEEK_SET) != pos) {
341ce735c34Sleo 		err(EXIT_FAILURE, "%s", nvrdev);
342ce735c34Sleo 	}
343ce735c34Sleo 	if (write (fd, &val, (size_t)1) != 1) {
344ce735c34Sleo 		err(EXIT_FAILURE, "%s", nvrdev);
345ce735c34Sleo 	}
346ce735c34Sleo }
347ce735c34Sleo 
348ce735c34Sleo static void
getNVpref(int fd,u_char bootpref[])34982357f6dSdsl getNVpref (int fd, u_char bootpref[])
350ce735c34Sleo {
351ce735c34Sleo 	/* Boot OS */
352ce735c34Sleo 	printf ("Boot OS is ");
353ce735c34Sleo 	showOS (readNVRAM (fd, NVRAM_BOOTPREF));
354ce735c34Sleo 	/* Boot Delay */
355ce735c34Sleo 	printf ("Boot delay is %d seconds\n", readNVRAM (fd, NVRAM_BOOTDLY));
356ce735c34Sleo 	/* TOS Language */
357ce735c34Sleo 	printf ("Language is ");
358ce735c34Sleo 	showLang (readNVRAM (fd, NVRAM_LANG));
359ce735c34Sleo 	/* Keyboard Language */
360ce735c34Sleo 	printf ("Keyboard is ");
361ce735c34Sleo 	showKbdLang (readNVRAM (fd, NVRAM_KBDLANG));
362ce735c34Sleo 	/* SCSI Host ID */
363ce735c34Sleo 	printf ("SCSI host ID is ");
364ce735c34Sleo 	if (readNVRAM (fd, NVRAM_HOSTID) & HOSTID_VALID) {
365ce735c34Sleo 		printf ("%d\n", readNVRAM (fd, NVRAM_HOSTID) ^ HOSTID_VALID);
366ce735c34Sleo 	} else {
367ce735c34Sleo 		printf ("invalid");
368ce735c34Sleo 	}
369ce735c34Sleo 	/* Date format/separator */
370ce735c34Sleo 	printf ("Date format is ");
371ce735c34Sleo 	showDateFmt (readNVRAM (fd, NVRAM_DATIME));
372ce735c34Sleo 	printf ("Date separator is ");
373ce735c34Sleo 	showDateSep (readNVRAM (fd, NVRAM_DATESEP));
374ce735c34Sleo 	/* Video */
375ce735c34Sleo 	printf ("Video is (0x%02x, 0x%02x) :\n", readNVRAM (fd, NVRAM_VID2),
376ce735c34Sleo 	    readNVRAM (fd, NVRAM_VID1));
377ce735c34Sleo 	showVideo2 (readNVRAM (fd, NVRAM_VID2));
378ce735c34Sleo 	showVideo1 (readNVRAM (fd, NVRAM_VID1), readNVRAM (fd, NVRAM_VID2));
379ce735c34Sleo }
380ce735c34Sleo 
381ce735c34Sleo static void
setNVpref(int fd,u_char bootpref[],int set,int verbose)382*62f5486cShe setNVpref (int fd, u_char bootpref[], int set, int verbose)
383ce735c34Sleo {
384ce735c34Sleo 	/* Boot OS */
385ce735c34Sleo 	if (set & SET_OS) {
386ce735c34Sleo 		writeNVRAM (fd, NVRAM_BOOTPREF, bootpref[ARRAY_OS]);
387ce735c34Sleo 		if (verbose) {
388ce735c34Sleo 			printf ("Boot OS set to ");
389ce735c34Sleo 			showOS (readNVRAM (fd, NVRAM_BOOTPREF));
390ce735c34Sleo 		}
391ce735c34Sleo 	}
392ce735c34Sleo 	/* Boot Delay */
393ce735c34Sleo 	if (set & SET_BOOTDLY) {
394ce735c34Sleo 		writeNVRAM (fd, NVRAM_BOOTDLY, bootpref[ARRAY_BOOTDLY]);
395ce735c34Sleo 		if (verbose) {
396ce735c34Sleo 			printf ("Boot delay set to %d seconds\n", readNVRAM (fd,
397ce735c34Sleo 			    NVRAM_BOOTDLY));
398ce735c34Sleo 		}
399ce735c34Sleo 	}
400ce735c34Sleo 	/* TOS Language */
401ce735c34Sleo 	if (set & SET_LANG) {
402ce735c34Sleo 		writeNVRAM (fd, NVRAM_LANG, bootpref[ARRAY_LANG]);
403ce735c34Sleo 		if (verbose) {
404ce735c34Sleo 			printf ("Language set to ");
405ce735c34Sleo 			showLang (readNVRAM (fd, NVRAM_LANG));
406ce735c34Sleo 		}
407ce735c34Sleo 	}
408ce735c34Sleo 	/* Keyboard Language */
409ce735c34Sleo 	if (set & SET_KBDLANG) {
410ce735c34Sleo 		writeNVRAM (fd, NVRAM_KBDLANG, bootpref[ARRAY_KBDLANG]);
411ce735c34Sleo 		if (verbose) {
412ce735c34Sleo 			printf ("Keyboard set to ");
413ce735c34Sleo 			showKbdLang (readNVRAM (fd, NVRAM_KBDLANG));
414ce735c34Sleo 		}
415ce735c34Sleo 	}
416ce735c34Sleo 	/* SCSI Host ID */
417ce735c34Sleo 	if (set & SET_HOSTID) {
418ce735c34Sleo 		writeNVRAM (fd, NVRAM_HOSTID, bootpref[ARRAY_HOSTID] |
419ce735c34Sleo 		    HOSTID_VALID);
420ce735c34Sleo 		if (verbose) {
421ce735c34Sleo 			printf ("SCSI host ID set to ");
422ce735c34Sleo 			printf ("%d\n", readNVRAM (fd, NVRAM_HOSTID) ^
423ce735c34Sleo 				HOSTID_VALID);
424ce735c34Sleo 		}
425ce735c34Sleo 	}
426ce735c34Sleo 	/* Date format/separator */
427ce735c34Sleo 	if (set & SET_DATIME) {
428ce735c34Sleo 		writeNVRAM (fd, NVRAM_DATIME, bootpref[ARRAY_DATIME]);
429ce735c34Sleo 		if (verbose) {
430ce735c34Sleo 			printf ("Date format set to ");
431ce735c34Sleo 			showDateFmt (readNVRAM (fd, NVRAM_DATIME));
432ce735c34Sleo 			printf ("\n");
433ce735c34Sleo 		}
434ce735c34Sleo 	}
435ce735c34Sleo 	if (set & SET_DATESEP) {
436ce735c34Sleo 		writeNVRAM (fd, NVRAM_DATESEP, bootpref[ARRAY_DATESEP]);
437ce735c34Sleo 		if (verbose) {
438ce735c34Sleo 			printf ("Date separator set to ");
439ce735c34Sleo 			showDateSep (readNVRAM (fd, NVRAM_DATESEP));
440ce735c34Sleo 		}
441ce735c34Sleo 	}
442ce735c34Sleo 	/* Video */
443ce735c34Sleo 	if ((set & SET_VID2) || (set & SET_VID1)) {
444ce735c34Sleo 		if (set & SET_VID2) {
445ce735c34Sleo 			writeNVRAM (fd, NVRAM_VID2, bootpref[ARRAY_VID2]);
446ce735c34Sleo 		}
447ce735c34Sleo 		if (set & SET_VID1) {
448ce735c34Sleo 			writeNVRAM (fd, NVRAM_VID1, bootpref[ARRAY_VID1]);
449ce735c34Sleo 		}
450ce735c34Sleo 		if (verbose) {
451ce735c34Sleo 			printf ("Video set to (0x%02x, 0x%02x) :\n",
452ce735c34Sleo 			    readNVRAM (fd, NVRAM_VID2),
453ce735c34Sleo 			    readNVRAM (fd, NVRAM_VID1));
454ce735c34Sleo 			showVideo2 (readNVRAM (fd, NVRAM_VID2));
455ce735c34Sleo 			showVideo1 (readNVRAM (fd, NVRAM_VID1),
456ce735c34Sleo 			    readNVRAM (fd, NVRAM_VID2));
457ce735c34Sleo 		}
458ce735c34Sleo 	}
459ce735c34Sleo }
460ce735c34Sleo 
461ce735c34Sleo static void
showOS(u_char bootos)46282357f6dSdsl showOS (u_char bootos)
463ce735c34Sleo {
464ce735c34Sleo 	switch (bootos) {
465ce735c34Sleo 	case BOOTPREF_NETBSD:
466ce735c34Sleo 		printf ("NetBSD");
467ce735c34Sleo 		break;
468ce735c34Sleo 	case BOOTPREF_TOS:
469ce735c34Sleo 		printf ("TOS");
470ce735c34Sleo 		break;
471ce735c34Sleo 	case BOOTPREF_MAGIC:
472ce735c34Sleo 		printf ("MAGIC");
473ce735c34Sleo 		break;
474ce735c34Sleo 	case BOOTPREF_LINUX:
475ce735c34Sleo 		printf ("Linux");
476ce735c34Sleo 		break;
477ce735c34Sleo 	case BOOTPREF_SYSV:
478ce735c34Sleo 		printf ("System V");
479ce735c34Sleo 		break;
480ce735c34Sleo 	case BOOTPREF_NONE:
481ce735c34Sleo 		printf ("none");
482ce735c34Sleo 		break;
483ce735c34Sleo 	default:
484ce735c34Sleo 		printf ("unknown");
485ce735c34Sleo 		break;
486ce735c34Sleo 	}
487ce735c34Sleo 	printf (" (0x%x).\n", bootos);
488ce735c34Sleo }
489ce735c34Sleo 
490ce735c34Sleo static void
showLang(u_char lang)49182357f6dSdsl showLang (u_char lang)
492ce735c34Sleo {
493ce735c34Sleo 	switch (lang) {
494bbf43dfbSleo 	case LANG_USA:
495ce735c34Sleo 	case LANG_GB:
496ce735c34Sleo 		printf ("English");
497ce735c34Sleo 		break;
498ce735c34Sleo 	case LANG_D:
499ce735c34Sleo 		printf ("German");
500ce735c34Sleo 		break;
501ce735c34Sleo 	case LANG_FR:
502ce735c34Sleo 		printf ("French");
503ce735c34Sleo 		break;
504ce735c34Sleo 	case LANG_ESP:
505ce735c34Sleo 		printf ("Spanish");
506ce735c34Sleo 		break;
507ce735c34Sleo 	case LANG_I:
508ce735c34Sleo 		printf ("Italian");
509ce735c34Sleo 		break;
510ce735c34Sleo 	default:
511ce735c34Sleo 		printf ("unknown");
512ce735c34Sleo 		break;
513ce735c34Sleo 	}
514ce735c34Sleo 	printf (" (0x%x).\n", lang);
515ce735c34Sleo }
516ce735c34Sleo 
517ce735c34Sleo static void
showKbdLang(u_char lang)51882357f6dSdsl showKbdLang (u_char lang)
519ce735c34Sleo {
520ce735c34Sleo 	switch (lang) {
521ce735c34Sleo 	case KBDLANG_USA:
522ce735c34Sleo 		printf ("American");
523ce735c34Sleo 		break;
524ce735c34Sleo 	case KBDLANG_D:
525ce735c34Sleo 		printf ("German");
526ce735c34Sleo 		break;
527ce735c34Sleo 	case KBDLANG_FR:
528ce735c34Sleo 		printf ("French");
529ce735c34Sleo 		break;
530ce735c34Sleo 	case KBDLANG_GB:
531ce735c34Sleo 		printf ("British");
532ce735c34Sleo 		break;
533ce735c34Sleo 	case KBDLANG_ESP:
534ce735c34Sleo 		printf ("Spanish");
535ce735c34Sleo 		break;
536ce735c34Sleo 	case KBDLANG_I:
537ce735c34Sleo 		printf ("Italian");
538ce735c34Sleo 		break;
539ce735c34Sleo 	case KBDLANG_CHF:
540ce735c34Sleo 		printf ("Swiss (French)");
541ce735c34Sleo 		break;
542ce735c34Sleo 	case KBDLANG_CHD:
543ce735c34Sleo 		printf ("Swiss (German)");
544ce735c34Sleo 		break;
545ce735c34Sleo 	default:
546ce735c34Sleo 		printf ("unknown");
547ce735c34Sleo 		break;
548ce735c34Sleo 	}
549ce735c34Sleo 	printf (" (0x%x).\n", lang);
550ce735c34Sleo }
551ce735c34Sleo 
552ce735c34Sleo static void
showDateFmt(u_char fmt)55382357f6dSdsl showDateFmt (u_char fmt)
554ce735c34Sleo {
555ce735c34Sleo 	if (fmt & DATIME_24H) {
556ce735c34Sleo 		printf ("24 hour clock, ");
557ce735c34Sleo 	} else {
558ce735c34Sleo 		printf ("12 hour clock, ");
559ce735c34Sleo 	}
560ce735c34Sleo 	switch (fmt & ~DATIME_24H) {
561ce735c34Sleo 	case DATIME_MMDDYY:
562ce735c34Sleo 		printf ("MMDDYY");
563ce735c34Sleo 		break;
564ce735c34Sleo 	case DATIME_DDMMYY:
565ce735c34Sleo 		printf ("DDMMYY");
566ce735c34Sleo 		break;
567ce735c34Sleo 	case DATIME_YYMMDD:
568ce735c34Sleo 		printf ("YYMMDD");
569ce735c34Sleo 		break;
570ce735c34Sleo 	case DATIME_YYDDMM:
571ce735c34Sleo 		printf ("YYDDMM");
572ce735c34Sleo 		break;
573ce735c34Sleo 	default:
574ce735c34Sleo 		printf ("unknown");
575ce735c34Sleo 		break;
576ce735c34Sleo 	}
577ce735c34Sleo 	printf (" (0x%02x)\n", fmt);
578ce735c34Sleo }
579ce735c34Sleo 
580ce735c34Sleo static void
showDateSep(u_char sep)58182357f6dSdsl showDateSep (u_char sep)
582ce735c34Sleo {
583ce735c34Sleo 	if (sep) {
584ce735c34Sleo 		if (sep >= 0x20) {
585ce735c34Sleo 			printf ("\"%c\" ", sep);
586ce735c34Sleo 		}
587ce735c34Sleo 	} else {
588ce735c34Sleo 		printf ("\"/\" ");
589ce735c34Sleo 	}
590ce735c34Sleo 	printf ("(0x%02x)\n", sep);
591ce735c34Sleo }
592ce735c34Sleo 
593ce735c34Sleo static void
showVideo2(u_char vid2)59482357f6dSdsl showVideo2 (u_char vid2)
595ce735c34Sleo {
596ce735c34Sleo 	u_char colours;
597ce735c34Sleo 
598ce735c34Sleo 	colours = vid2 & 0x07;
599ce735c34Sleo 	printf ("\t");
600ce735c34Sleo 	switch (colours) {
601ce735c34Sleo 	case VID2_2COL:
602ce735c34Sleo 		printf ("2");
603ce735c34Sleo 		break;
604ce735c34Sleo 	case VID2_4COL:
605ce735c34Sleo 		printf ("4");
606ce735c34Sleo 		break;
607ce735c34Sleo 	case VID2_16COL:
608ce735c34Sleo 		printf ("16");
609ce735c34Sleo 		break;
610ce735c34Sleo 	case VID2_256COL:
611ce735c34Sleo 		printf ("256");
612ce735c34Sleo 		break;
613ce735c34Sleo 	case VID2_65535COL:
614ce735c34Sleo 		printf ("65535");
615ce735c34Sleo 		break;
616ce735c34Sleo 	}
617ce735c34Sleo 	printf (" colours, ");
618ce735c34Sleo 	if (vid2 & VID2_80CLM) {
619ce735c34Sleo 		printf ("80");
620ce735c34Sleo 	} else {
621ce735c34Sleo 		printf ("40");
622ce735c34Sleo 	}
623ce735c34Sleo 	printf (" column, ");
624ce735c34Sleo 	if (vid2 & VID2_VGA) {
625ce735c34Sleo 		printf ("VGA");
626ce735c34Sleo 	} else {
627ce735c34Sleo 		printf ("TV");
628ce735c34Sleo 	}
629ce735c34Sleo 	printf (", ");
630ce735c34Sleo 	if (vid2 & VID2_PAL) {
631ce735c34Sleo 		printf ("PAL\n");
632ce735c34Sleo 	} else {
633ce735c34Sleo 		printf ("NTSC\n");
634ce735c34Sleo 	}
635ce735c34Sleo 	printf ("\tOverscan ");
636ce735c34Sleo 	if (vid2 & VID2_OVERSCAN) {
637ce735c34Sleo 		printf ("on\n");
638ce735c34Sleo 	} else {
639ce735c34Sleo 		printf ("off\n");
640ce735c34Sleo 	}
641ce735c34Sleo 	printf ("\tST compatibility ");
642ce735c34Sleo 	if (vid2 & VID2_COMPAT) {
643ce735c34Sleo 		printf ("on\n");
644ce735c34Sleo 	} else {
645ce735c34Sleo 		printf ("off\n");
646ce735c34Sleo 	}
647ce735c34Sleo }
648ce735c34Sleo 
649ce735c34Sleo static void
showVideo1(u_char vid1,u_char vid2)65082357f6dSdsl showVideo1 (u_char vid1, u_char vid2)
651ce735c34Sleo {
652ce735c34Sleo 	if (vid2 & VID2_VGA) {
653ce735c34Sleo 		printf ("\tDouble line ");
654ce735c34Sleo 		if (vid1 & VID1_INTERLACE) {
655ce735c34Sleo 			printf ("on");
656ce735c34Sleo 		} else {
657ce735c34Sleo 			printf ("off");
658ce735c34Sleo 		}
659ce735c34Sleo 	} else {
660ce735c34Sleo 		printf ("\tInterlace ");
661ce735c34Sleo 		if (vid1 & VID1_INTERLACE) {
662ce735c34Sleo 			printf ("on");
663ce735c34Sleo 		} else {
664ce735c34Sleo 			printf ("off");
665ce735c34Sleo 		}
666ce735c34Sleo 	}
667ce735c34Sleo 	printf ("\n");
668ce735c34Sleo }
669ce735c34Sleo 
670ce735c34Sleo static int
checkOS(u_char * val,char * str)67182357f6dSdsl checkOS (u_char *val, char *str)
672ce735c34Sleo {
673ce735c34Sleo 	if (!strncasecmp (str, "ne", 2)) {
674ce735c34Sleo 		*val = BOOTPREF_NETBSD;
675ce735c34Sleo 		return (1);
676ce735c34Sleo 	}
677ce735c34Sleo 	if (!strncasecmp (str, "t", 1)) {
678ce735c34Sleo 		*val = BOOTPREF_TOS;
679ce735c34Sleo 		return (1);
680ce735c34Sleo 	}
681ce735c34Sleo 	if (!strncasecmp (str, "m", 1)) {
682ce735c34Sleo 		*val = BOOTPREF_MAGIC;
683ce735c34Sleo 		return (1);
684ce735c34Sleo 	}
685ce735c34Sleo 	if (!strncasecmp (str, "l", 1)) {
686ce735c34Sleo 		*val = BOOTPREF_LINUX;
687ce735c34Sleo 		return (1);
688ce735c34Sleo 	}
689ce735c34Sleo 	if (!strncasecmp (str, "s", 1)) {
690ce735c34Sleo 		*val = BOOTPREF_SYSV;
691ce735c34Sleo 		return (1);
692ce735c34Sleo 	}
693ce735c34Sleo 	if (!strncasecmp (str, "no", 2)) {
694ce735c34Sleo 		*val = BOOTPREF_NONE;
695ce735c34Sleo 		return (1);
696ce735c34Sleo 	}
697ce735c34Sleo 	return (0);
698ce735c34Sleo }
699ce735c34Sleo 
700ce735c34Sleo static int
checkLang(u_char * val,char * str)70182357f6dSdsl checkLang (u_char *val, char *str)
702ce735c34Sleo {
703ce735c34Sleo 	if (!strncasecmp (str, "e", 1)) {
704ce735c34Sleo 		*val = LANG_GB;
705ce735c34Sleo 		return (1);
706ce735c34Sleo 	}
707ce735c34Sleo 	if (!strncasecmp (str, "g", 1)) {
708ce735c34Sleo 		*val = LANG_D;
709ce735c34Sleo 		return (1);
710ce735c34Sleo 	}
711ce735c34Sleo 	if (!strncasecmp (str, "f", 1)) {
712ce735c34Sleo 		*val = LANG_FR;
713ce735c34Sleo 		return (1);
714ce735c34Sleo 	}
715ce735c34Sleo 	if (!strncasecmp (str, "s", 1)) {
716ce735c34Sleo 		*val = LANG_ESP;
717ce735c34Sleo 		return (1);
718ce735c34Sleo 	}
719ce735c34Sleo 	if (!strncasecmp (str, "i", 1)) {
720ce735c34Sleo 		*val = LANG_I;
721ce735c34Sleo 		return (1);
722ce735c34Sleo 	}
723ce735c34Sleo 	return (0);
724ce735c34Sleo }
725ce735c34Sleo 
726ce735c34Sleo static int
checkKbdLang(u_char * val,char * str)72782357f6dSdsl checkKbdLang (u_char *val, char *str)
728ce735c34Sleo {
729ce735c34Sleo 	if (!strncasecmp (str, "a", 1)) {
730ce735c34Sleo 		*val = KBDLANG_USA;
731ce735c34Sleo 		return (1);
732ce735c34Sleo 	}
733ce735c34Sleo 	if (!strncasecmp (str, "g", 1)) {
734ce735c34Sleo 		*val = KBDLANG_D;
735ce735c34Sleo 		return (1);
736ce735c34Sleo 	}
737ce735c34Sleo 	if (!strncasecmp (str, "f", 1)) {
738ce735c34Sleo 		*val = KBDLANG_FR;
739ce735c34Sleo 		return (1);
740ce735c34Sleo 	}
741ce735c34Sleo 	if (!strncasecmp (str, "b", 1)) {
742ce735c34Sleo 		*val = KBDLANG_GB;
743ce735c34Sleo 		return (1);
744ce735c34Sleo 	}
745ce735c34Sleo 	if (!strncasecmp (str, "sp", 2)) {
746ce735c34Sleo 		*val = KBDLANG_ESP;
747ce735c34Sleo 		return (1);
748ce735c34Sleo 	}
749ce735c34Sleo 	if (!strncasecmp (str, "i", 1)) {
750ce735c34Sleo 		*val = KBDLANG_I;
751ce735c34Sleo 		return (1);
752ce735c34Sleo 	}
753ce735c34Sleo 	if (!strncasecmp (str, "swiss f", 7) || !strncasecmp (str, "sw f", 4)) {
754ce735c34Sleo 		*val = KBDLANG_CHF;
755ce735c34Sleo 		return (1);
756ce735c34Sleo 	}
757ce735c34Sleo 	if (!strncasecmp (str, "swiss g", 7) || !strncasecmp (str, "sw g", 4)) {
758ce735c34Sleo 		*val = KBDLANG_CHD;
759ce735c34Sleo 		return (1);
760ce735c34Sleo 	}
761ce735c34Sleo 	return (0);
762ce735c34Sleo }
763ce735c34Sleo 
764ce735c34Sleo static int
checkInt(u_char * val,char * str,int min,int max)76582357f6dSdsl checkInt (u_char *val, char *str, int min, int max)
766ce735c34Sleo {
767ce735c34Sleo 	int num;
768ce735c34Sleo 	if (1 == sscanf (str, "%d", &num) && num >= min && num <= max) {
769ce735c34Sleo 		*val = num;
770ce735c34Sleo 		return (1);
771ce735c34Sleo 	}
772ce735c34Sleo 	return (0);
773ce735c34Sleo }
774ce735c34Sleo 
775ce735c34Sleo static int
checkDateFmt(u_char * val,char * str)77682357f6dSdsl checkDateFmt (u_char *val, char *str)
777ce735c34Sleo {
778ce735c34Sleo 	if (!strncasecmp (str, "m", 1)) {
779ce735c34Sleo 		*val |= DATIME_MMDDYY;
780ce735c34Sleo 		return (1);
781ce735c34Sleo 	}
782ce735c34Sleo 	if (!strncasecmp (str, "d", 1)) {
783ce735c34Sleo 		*val |= DATIME_DDMMYY;
784ce735c34Sleo 		return (1);
785ce735c34Sleo 	}
786ce735c34Sleo 	if (!strncasecmp (str, "yym", 3)) {
787ce735c34Sleo 		*val |= DATIME_YYMMDD;
788ce735c34Sleo 		return (1);
789ce735c34Sleo 	}
790ce735c34Sleo 	if (!strncasecmp (str, "yyd", 3)) {
791ce735c34Sleo 		*val |= DATIME_YYDDMM;
792ce735c34Sleo 		return (1);
793ce735c34Sleo 	}
794ce735c34Sleo 	return (0);
795ce735c34Sleo }
796ce735c34Sleo 
797ce735c34Sleo static void
checkDateSep(u_char * val,char * str)79882357f6dSdsl checkDateSep (u_char *val, char *str)
799ce735c34Sleo {
800ce735c34Sleo 	if (str[0] == '/') {
801ce735c34Sleo 		*val = 0;
802ce735c34Sleo 	} else {
803ce735c34Sleo 		*val = str[0];
804ce735c34Sleo 	}
805ce735c34Sleo }
806ce735c34Sleo 
807ce735c34Sleo static int
checkColours(u_char * val,char * str)80882357f6dSdsl checkColours (u_char *val, char *str)
809ce735c34Sleo {
810ce735c34Sleo 	*val &= ~0x07;
811ce735c34Sleo 	if (!strncasecmp (str, "6", 1)) {
812ce735c34Sleo 		*val |= VID2_65535COL;
813ce735c34Sleo 		return (1);
814ce735c34Sleo 	}
815ce735c34Sleo 	if (!strncasecmp (str, "25", 2)) {
816ce735c34Sleo 		*val |= VID2_256COL;
817ce735c34Sleo 		return (1);
818ce735c34Sleo 	}
819ce735c34Sleo 	if (!strncasecmp (str, "1", 1)) {
820ce735c34Sleo 		*val |= VID2_16COL;
821ce735c34Sleo 		return (1);
822ce735c34Sleo 	}
823ce735c34Sleo 	if (!strncasecmp (str, "4", 1)) {
824ce735c34Sleo 		*val |= VID2_4COL;
825ce735c34Sleo 		return (1);
826ce735c34Sleo 	}
827ce735c34Sleo 	if (!strncasecmp (str, "2", 1)) {
828ce735c34Sleo 		*val |= VID2_2COL;
829ce735c34Sleo 		return (1);
830ce735c34Sleo 	}
831ce735c34Sleo 	return (0);
832ce735c34Sleo }
833