VGA: Remove references to 'struct bregs' from vgaio.c code.
[seabios.git] / vgasrc / vgaio.c
1 // VGA io port access
2 //
3 // Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2001-2008 the LGPL VGABios developers Team
5 //
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
7
8 #include "ioport.h" // outb
9 #include "farptr.h" // SET_FARVAR
10 #include "vgatables.h" // VGAREG_*
11
12
13 /****************************************************************
14  * Attribute control
15  ****************************************************************/
16
17 void
18 vgahw_set_border_color(u8 color)
19 {
20     inb(VGAREG_ACTL_RESET);
21     outb(0x00, VGAREG_ACTL_ADDRESS);
22     u8 v1 = color & 0x0f;
23     if (v1 & 0x08)
24         v1 += 0x08;
25     outb(v1, VGAREG_ACTL_WRITE_DATA);
26
27     u8 v2 = color & 0x10;
28     int i;
29     for (i = 1; i < 4; i++) {
30         outb(i, VGAREG_ACTL_ADDRESS);
31
32         u8 cur = inb(VGAREG_ACTL_READ_DATA);
33         cur &= 0xef;
34         cur |= v2;
35         outb(cur, VGAREG_ACTL_WRITE_DATA);
36     }
37     outb(0x20, VGAREG_ACTL_ADDRESS);
38 }
39
40 void
41 vgahw_set_overscan_border_color(u8 color)
42 {
43     inb(VGAREG_ACTL_RESET);
44     outb(0x11, VGAREG_ACTL_ADDRESS);
45     outb(color, VGAREG_ACTL_WRITE_DATA);
46     outb(0x20, VGAREG_ACTL_ADDRESS);
47 }
48
49 u8
50 vgahw_get_overscan_border_color()
51 {
52     inb(VGAREG_ACTL_RESET);
53     outb(0x11, VGAREG_ACTL_ADDRESS);
54     u8 v = inb(VGAREG_ACTL_READ_DATA);
55     inb(VGAREG_ACTL_RESET);
56     outb(0x20, VGAREG_ACTL_ADDRESS);
57     return v;
58 }
59
60 void
61 vgahw_set_palette(u8 palid)
62 {
63     inb(VGAREG_ACTL_RESET);
64     palid &= 0x01;
65     int i;
66     for (i = 1; i < 4; i++) {
67         outb(i, VGAREG_ACTL_ADDRESS);
68
69         u8 v = inb(VGAREG_ACTL_READ_DATA);
70         v &= 0xfe;
71         v |= palid;
72         outb(v, VGAREG_ACTL_WRITE_DATA);
73     }
74     outb(0x20, VGAREG_ACTL_ADDRESS);
75 }
76
77 void
78 vgahw_set_single_palette_reg(u8 reg, u8 val)
79 {
80     inb(VGAREG_ACTL_RESET);
81     outb(reg, VGAREG_ACTL_ADDRESS);
82     outb(val, VGAREG_ACTL_WRITE_DATA);
83     outb(0x20, VGAREG_ACTL_ADDRESS);
84 }
85
86 u8
87 vgahw_get_single_palette_reg(u8 reg)
88 {
89     inb(VGAREG_ACTL_RESET);
90     outb(reg, VGAREG_ACTL_ADDRESS);
91     u8 v = inb(VGAREG_ACTL_READ_DATA);
92     inb(VGAREG_ACTL_RESET);
93     outb(0x20, VGAREG_ACTL_ADDRESS);
94     return v;
95 }
96
97 void
98 vgahw_set_all_palette_reg(u16 seg, u8 *data_far)
99 {
100     inb(VGAREG_ACTL_RESET);
101     int i;
102     for (i = 0; i < 0x10; i++) {
103         outb(i, VGAREG_ACTL_ADDRESS);
104         u8 val = GET_FARVAR(seg, *data_far);
105         outb(val, VGAREG_ACTL_WRITE_DATA);
106         data_far++;
107     }
108     outb(0x11, VGAREG_ACTL_ADDRESS);
109     outb(GET_FARVAR(seg, *data_far), VGAREG_ACTL_WRITE_DATA);
110     outb(0x20, VGAREG_ACTL_ADDRESS);
111 }
112
113 void
114 vgahw_get_all_palette_reg(u16 seg, u8 *data_far)
115 {
116     int i;
117     for (i = 0; i < 0x10; i++) {
118         inb(VGAREG_ACTL_RESET);
119         outb(i, VGAREG_ACTL_ADDRESS);
120         SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA));
121         data_far++;
122     }
123     inb(VGAREG_ACTL_RESET);
124     outb(0x11, VGAREG_ACTL_ADDRESS);
125     SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA));
126     inb(VGAREG_ACTL_RESET);
127     outb(0x20, VGAREG_ACTL_ADDRESS);
128 }
129
130 void
131 vgahw_toggle_intensity(u8 flag)
132 {
133     inb(VGAREG_ACTL_RESET);
134     outb(0x10, VGAREG_ACTL_ADDRESS);
135     u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0xf7) | ((flag & 0x01) << 3);
136     outb(val, VGAREG_ACTL_WRITE_DATA);
137     outb(0x20, VGAREG_ACTL_ADDRESS);
138 }
139
140 void
141 vgahw_select_video_dac_color_page(u8 flag, u8 data)
142 {
143     inb(VGAREG_ACTL_RESET);
144     outb(0x10, VGAREG_ACTL_ADDRESS);
145     u8 val = inb(VGAREG_ACTL_READ_DATA);
146     if (!(flag & 0x01)) {
147         // select paging mode
148         val = (val & 0x7f) | (data << 7);
149         outb(val, VGAREG_ACTL_WRITE_DATA);
150         outb(0x20, VGAREG_ACTL_ADDRESS);
151         return;
152     }
153     // select page
154     inb(VGAREG_ACTL_RESET);
155     outb(0x14, VGAREG_ACTL_ADDRESS);
156     if (!(val & 0x80))
157         data <<= 2;
158     data &= 0x0f;
159     outb(data, VGAREG_ACTL_WRITE_DATA);
160     outb(0x20, VGAREG_ACTL_ADDRESS);
161 }
162
163 void
164 vgahw_read_video_dac_state(u8 *pmode, u8 *curpage)
165 {
166     inb(VGAREG_ACTL_RESET);
167     outb(0x10, VGAREG_ACTL_ADDRESS);
168     u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7;
169
170     inb(VGAREG_ACTL_RESET);
171     outb(0x14, VGAREG_ACTL_ADDRESS);
172     u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f;
173     if (!(val1 & 0x01))
174         val2 >>= 2;
175
176     inb(VGAREG_ACTL_RESET);
177     outb(0x20, VGAREG_ACTL_ADDRESS);
178
179     *pmode = val1;
180     *curpage = val2;
181 }
182
183
184 /****************************************************************
185  * DAC control
186  ****************************************************************/
187
188 void
189 vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count)
190 {
191     outb(start, VGAREG_DAC_WRITE_ADDRESS);
192     while (count) {
193         outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
194         data_far++;
195         outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
196         data_far++;
197         outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
198         data_far++;
199         count--;
200     }
201 }
202
203 void
204 vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count)
205 {
206     outb(start, VGAREG_DAC_READ_ADDRESS);
207     while (count) {
208         SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
209         data_far++;
210         SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
211         data_far++;
212         SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
213         data_far++;
214         count--;
215     }
216 }
217
218 void
219 vgahw_set_pel_mask(u8 val)
220 {
221     outb(val, VGAREG_PEL_MASK);
222 }
223
224 u8
225 vgahw_get_pel_mask()
226 {
227     return inb(VGAREG_PEL_MASK);
228 }
229
230
231 /****************************************************************
232  * Memory control
233  ****************************************************************/
234
235 void
236 vgahw_set_text_block_specifier(u8 spec)
237 {
238     outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS);
239 }
240
241 void
242 get_font_access()
243 {
244     outw(0x0100, VGAREG_SEQU_ADDRESS);
245     outw(0x0402, VGAREG_SEQU_ADDRESS);
246     outw(0x0704, VGAREG_SEQU_ADDRESS);
247     outw(0x0300, VGAREG_SEQU_ADDRESS);
248     outw(0x0204, VGAREG_GRDC_ADDRESS);
249     outw(0x0005, VGAREG_GRDC_ADDRESS);
250     outw(0x0406, VGAREG_GRDC_ADDRESS);
251 }
252
253 void
254 release_font_access()
255 {
256     outw(0x0100, VGAREG_SEQU_ADDRESS);
257     outw(0x0302, VGAREG_SEQU_ADDRESS);
258     outw(0x0304, VGAREG_SEQU_ADDRESS);
259     outw(0x0300, VGAREG_SEQU_ADDRESS);
260     u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a;
261     outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS);
262     outw(0x0004, VGAREG_GRDC_ADDRESS);
263     outw(0x1005, VGAREG_GRDC_ADDRESS);
264 }
265
266
267 /****************************************************************
268  * Misc
269  ****************************************************************/
270
271 void
272 vgahw_enable_video_addressing(u8 disable)
273 {
274     u8 v = (disable & 1) ? 0x00 : 0x02;
275     u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02;
276     outb(v | v2, VGAREG_WRITE_MISC_OUTPUT);
277 }
278
279 void
280 vgahw_init()
281 {
282     // switch to color mode and enable CPU access 480 lines
283     outb(0xc3, VGAREG_WRITE_MISC_OUTPUT);
284     // more than 64k 3C4/04
285     outb(0x04, VGAREG_SEQU_ADDRESS);
286     outb(0x02, VGAREG_SEQU_DATA);
287 }