Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / pcvt / vgaio / vgaio.y
1 %{
2 /*
3  * Copyright (c) 1994 Joerg Wunsch
4  *
5  * All rights reserved.
6  *
7  * This program is free software.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Joerg Wunsch
20  * 4. The name of the developer may not be used to endorse or promote
21  *    products derived from this software without specific prior written
22  *    permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #ident "$FreeBSD: src/usr.sbin/pcvt/vgaio/vgaio.y,v 1.5 1999/09/06 07:39:30 peter Exp $"
37
38 /*
39  * $Log: vgaio.y,v $
40  * Revision 1.1  1994/03/29  02:47:27  mycroft
41  * pcvt 3.0, with some performance enhancements by Joerg Wunsch and me.
42  *
43  * Revision 1.2  1994/01/08  17:42:58  j
44  * cleanup
45  * made multiple commands per line work
46  * wrote man page
47  *
48  * Revision 1.3  21.12.1994 -hm
49  * Added mi command for accessing the misc out register
50  * hex values shown as 2 fixed chars, added binary output
51  */
52
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <sys/fcntl.h>
56 #include <machine/cpufunc.h>
57 #include <machine/pcvt_ioctl.h>
58
59 #ifdef __NetBSD__
60 #include <machine/pio.h>
61 #endif
62
63 #include "vgaio.h"
64
65 void setreg(struct reg r, int val);
66 void getreg(struct reg r);
67 void yyerror(const char *msg);
68
69 #define YYDEBUG 1
70
71 unsigned short vgabase;
72
73 %}
74
75 %union {
76         int num;
77         struct reg reg;
78 }
79
80 %token MI GR CR SR AR NEWLINE
81 %token <num> NUM
82
83 %type <num> reggroup
84 %type <reg> register
85
86 %%
87
88 interpret:      lines ;
89
90 lines:          line
91                 | lines line
92                 ;
93
94 line:           statements NEWLINE
95                 | NEWLINE
96                 | error NEWLINE         { fprintf(stderr, "bing!\n"); }
97                 ;
98
99 statements:     statement
100                 | statements ';' statement
101                 ;
102
103 statement:      register '?'            { getreg($1); }
104                 | register '=' NUM      { setreg($1, $3); }
105                 | /* lambda */
106                 ;
107
108 register:       reggroup NUM            { $$.num = $2; $$.group = $1; }
109                 ;
110
111 reggroup:       GR              { $$ = GR; }
112                 | CR            { $$ = CR; }
113                 | SR            { $$ = SR; }
114                 | AR            { $$ = AR; }
115                 | MI            { $$ = MI; }
116                 ;
117
118 %%
119
120 static struct {
121         int id;
122         const char *name;
123 } regnames[] = {
124         {GR, "gr"}, {CR, "cr"}, {SR, "sr"}, {AR, "ar"}, {MI, "mi"},
125         {0, 0}
126 };
127
128 const char *getname(struct reg r) {
129         int idx;
130         for(idx = 0; regnames[idx].id; idx++)
131                 if(regnames[idx].id == r.group)
132                         return regnames[idx].name;
133         return "??";
134 }       
135
136 /*---------------------------------------------------------------------------*
137  *      return ptr to string of 1's and 0's for value
138  *---------------------------------------------------------------------------*/
139 char *
140 bin_str(unsigned long val, int length)
141 {
142         static char buffer[80];
143         int i = 0;
144
145         if (length > 32)
146                 length = 32;
147
148         val = val << (32 - length);
149
150         while (length--)
151         {
152                 if (val & 0x80000000)
153                         buffer[i++] = '1';
154                 else
155                         buffer[i++] = '0';
156                 if ((length % 4) == 0 && length)
157                         buffer[i++] = '.';
158                 val = val << 1;
159         }
160         return (buffer);
161 }
162
163 void getreg(struct reg r) {
164         int val;                        /* FreeBSD gcc ONLY accepts an int !! */
165
166         switch(r.group) {
167         case GR:
168                 outb(0x3ce, r.num);
169                 val = inb(0x3cf);
170                 break;
171
172         case AR:
173                 r.num &= 0x1f;
174                 (void)inb(vgabase + 0x0a);
175                 outb(0x3c0, r.num + 0x20);
176                 val = inb(0x3c1);
177                 break;
178
179         case CR:
180                 outb(vgabase + 4, r.num);
181                 val = inb(vgabase + 5);
182                 break;
183
184         case SR:
185                 outb(0x3c4, r.num);
186                 val = inb(0x3c5);
187                 break;
188
189         case MI:
190                 val = inb(0x3cc);
191                 break;
192         }
193                 
194         printf("%s%02x = 0x%02x = %s (bin)\n", getname(r), r.num, val, bin_str(val,8));
195 }
196
197 void setreg(struct reg r, int val) {
198         switch(r.group) {
199         case GR:
200                 outb(0x3ce, r.num);
201                 outb(0x3cf, val);
202                 break;
203
204         case AR:
205                 r.num &= 0x1f;
206                 (void)inb(vgabase + 0x0a);
207                 outb(0x3c0, r.num);
208                 outb(0x3c0, val);
209                 outb(0x3c0, r.num + 0x20);
210                 break;
211
212         case CR:
213                 outb(vgabase + 4, r.num);
214                 outb(vgabase + 5, val);
215                 break;
216
217         case SR:
218                 outb(0x3c4, r.num);
219                 outb(0x3c5, val);
220                 break;
221
222         case MI:
223                 outb(0x3c2, val);
224                 break;
225         }
226                 
227         printf("%s%02x set to 0x%02x = %s (bin) now\n", getname(r), r.num, val, bin_str(val,8));
228 }
229
230 void yyerror(const char *msg) {
231         fprintf(stderr, "yyerror: %s\n", msg);
232 }
233
234 int main(int argc, char **argv) {
235         int fd;
236
237         if(argc > 1) yydebug = 1;
238
239         if((fd = open("/dev/console", O_RDONLY)) < 0)
240                 fd = 0;
241
242         if(ioctl(fd, KDENABIO, 0) < 0) {
243                 perror("ioctl(KDENABIO)");
244                 return 1;
245         }
246         vgabase = (inb(0x3cc) & 1)? 0x3d0: 0x3b0;
247         yyparse();
248
249         (void)ioctl(fd, KDDISABIO, 0);
250         return 0;
251 }