blob: 1b552db6affb68321ddd789da07f1de2b5fc9ec3 [file] [log] [blame]
Kevin O'Connor3471fdb2012-01-14 19:02:43 -05001// Standard VGA driver code
Kevin O'Connorc0c7df62009-05-17 18:11:33 -04002//
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
Kevin O'Connorf98bbf02012-01-27 23:09:02 -05008#include "vgabios.h" // struct vgamode_s
Kevin O'Connor88ca7412011-12-31 04:24:20 -05009#include "stdvga.h" // stdvga_init
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040010#include "ioport.h" // outb
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040011#include "farptr.h" // SET_FARVAR
Kevin O'Connorc990f272011-12-31 16:00:54 -050012#include "biosvar.h" // GET_GLOBAL
Kevin O'Connor2bec7d62011-12-31 04:31:16 -050013#include "util.h" // memcpy_far
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040014
15
16/****************************************************************
17 * Attribute control
18 ****************************************************************/
19
Kevin O'Connora0ecb052009-05-18 23:34:00 -040020void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050021stdvga_set_border_color(u8 color)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040022{
Kevin O'Connor8bc059e2009-05-17 21:19:36 -040023 u8 v1 = color & 0x0f;
24 if (v1 & 0x08)
25 v1 += 0x08;
Kevin O'Connor86d2e002012-01-14 22:17:07 -050026 stdvga_attr_write(0x00, v1);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040027
28 int i;
Kevin O'Connor86d2e002012-01-14 22:17:07 -050029 for (i = 1; i < 4; i++)
30 stdvga_attr_mask(i, 0x10, color & 0x10);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040031}
32
33void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050034stdvga_set_overscan_border_color(u8 color)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040035{
Kevin O'Connor86d2e002012-01-14 22:17:07 -050036 stdvga_attr_write(0x11, color);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040037}
38
Kevin O'Connor8bc059e2009-05-17 21:19:36 -040039u8
Kevin O'Connor88ca7412011-12-31 04:24:20 -050040stdvga_get_overscan_border_color(void)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040041{
Kevin O'Connor86d2e002012-01-14 22:17:07 -050042 return stdvga_attr_read(0x11);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040043}
44
45void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050046stdvga_set_palette(u8 palid)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040047{
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040048 int i;
Kevin O'Connor86d2e002012-01-14 22:17:07 -050049 for (i = 1; i < 4; i++)
50 stdvga_attr_mask(i, 0x01, palid & 0x01);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040051}
52
53void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050054stdvga_set_all_palette_reg(u16 seg, u8 *data_far)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040055{
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040056 int i;
57 for (i = 0; i < 0x10; i++) {
Kevin O'Connor86d2e002012-01-14 22:17:07 -050058 stdvga_attr_write(i, GET_FARVAR(seg, *data_far));
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040059 data_far++;
60 }
Kevin O'Connor86d2e002012-01-14 22:17:07 -050061 stdvga_attr_write(0x11, GET_FARVAR(seg, *data_far));
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040062}
63
64void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050065stdvga_get_all_palette_reg(u16 seg, u8 *data_far)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040066{
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040067 int i;
68 for (i = 0; i < 0x10; i++) {
Kevin O'Connor86d2e002012-01-14 22:17:07 -050069 SET_FARVAR(seg, *data_far, stdvga_attr_read(i));
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040070 data_far++;
71 }
Kevin O'Connor86d2e002012-01-14 22:17:07 -050072 SET_FARVAR(seg, *data_far, stdvga_attr_read(0x11));
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040073}
74
75void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050076stdvga_toggle_intensity(u8 flag)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040077{
Kevin O'Connor86d2e002012-01-14 22:17:07 -050078 stdvga_attr_mask(0x10, 0x08, (flag & 0x01) << 3);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040079}
80
81void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050082stdvga_select_video_dac_color_page(u8 flag, u8 data)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040083{
Kevin O'Connor8bc059e2009-05-17 21:19:36 -040084 if (!(flag & 0x01)) {
85 // select paging mode
Kevin O'Connor86d2e002012-01-14 22:17:07 -050086 stdvga_attr_mask(0x10, 0x80, data << 7);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040087 return;
88 }
Kevin O'Connor8bc059e2009-05-17 21:19:36 -040089 // select page
Kevin O'Connor86d2e002012-01-14 22:17:07 -050090 u8 val = stdvga_attr_read(0x10);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040091 if (!(val & 0x80))
Kevin O'Connor8bc059e2009-05-17 21:19:36 -040092 data <<= 2;
93 data &= 0x0f;
Kevin O'Connor86d2e002012-01-14 22:17:07 -050094 stdvga_attr_write(0x14, data);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040095}
96
97void
Kevin O'Connor88ca7412011-12-31 04:24:20 -050098stdvga_read_video_dac_state(u8 *pmode, u8 *curpage)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -040099{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500100 u8 val1 = stdvga_attr_read(0x10) >> 7;
101 u8 val2 = stdvga_attr_read(0x14) & 0x0f;
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400102 if (!(val1 & 0x01))
103 val2 >>= 2;
Kevin O'Connor8bc059e2009-05-17 21:19:36 -0400104 *pmode = val1;
105 *curpage = val2;
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400106}
107
108
109/****************************************************************
110 * DAC control
111 ****************************************************************/
112
113void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500114stdvga_save_dac_state(u16 seg, struct saveDACcolors *info)
Kevin O'Connorca668642009-05-21 23:06:08 -0400115{
116 /* XXX: check this */
117 SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE));
118 SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS));
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500119 SET_FARVAR(seg, info->pelmask, stdvga_pelmask_read());
Kevin O'Connor3471fdb2012-01-14 19:02:43 -0500120 stdvga_dac_read(seg, info->dac, 0, 256);
Kevin O'Connorca668642009-05-21 23:06:08 -0400121 SET_FARVAR(seg, info->color_select, 0);
122}
123
124void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500125stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info)
Kevin O'Connorca668642009-05-21 23:06:08 -0400126{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500127 stdvga_pelmask_write(GET_FARVAR(seg, info->pelmask));
Kevin O'Connor3471fdb2012-01-14 19:02:43 -0500128 stdvga_dac_write(seg, info->dac, 0, 256);
Kevin O'Connorca668642009-05-21 23:06:08 -0400129 outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS);
130}
131
Kevin O'Connor821d6b42011-12-31 18:19:22 -0500132void
133stdvga_perform_gray_scale_summing(u16 start, u16 count)
134{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500135 stdvga_attrindex_write(0x00);
Kevin O'Connor821d6b42011-12-31 18:19:22 -0500136 int i;
137 for (i = start; i < start+count; i++) {
138 u8 rgb[3];
Kevin O'Connor3471fdb2012-01-14 19:02:43 -0500139 stdvga_dac_read(GET_SEG(SS), rgb, i, 1);
Kevin O'Connor821d6b42011-12-31 18:19:22 -0500140
141 // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
142 u16 intensity = ((77 * rgb[0] + 151 * rgb[1] + 28 * rgb[2]) + 0x80) >> 8;
143 if (intensity > 0x3f)
144 intensity = 0x3f;
145
Kevin O'Connor3471fdb2012-01-14 19:02:43 -0500146 stdvga_dac_write(GET_SEG(SS), rgb, i, 1);
Kevin O'Connor821d6b42011-12-31 18:19:22 -0500147 }
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500148 stdvga_attrindex_write(0x20);
Kevin O'Connor821d6b42011-12-31 18:19:22 -0500149}
150
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400151
152/****************************************************************
153 * Memory control
154 ****************************************************************/
155
156void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500157stdvga_set_text_block_specifier(u8 spec)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400158{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500159 stdvga_sequ_write(0x03, spec);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400160}
161
Kevin O'Connor160d34a2012-01-16 18:48:26 -0500162// Enable reads and writes to the given "plane" when in planar4 mode.
163void
164stdvga_planar4_plane(int plane)
165{
166 if (plane < 0) {
167 // Return to default mode (read plane0, write all planes)
168 stdvga_sequ_write(0x02, 0x0f);
169 stdvga_grdc_write(0x04, 0);
170 } else {
171 stdvga_sequ_write(0x02, 1<<plane);
172 stdvga_grdc_write(0x04, plane);
173 }
174}
175
Kevin O'Connor2bec7d62011-12-31 04:31:16 -0500176
177/****************************************************************
178 * Font loading
179 ****************************************************************/
180
181static void
Kevin O'Connor1ca05b02010-01-03 17:43:37 -0500182get_font_access(void)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400183{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500184 stdvga_sequ_write(0x00, 0x01);
185 stdvga_sequ_write(0x02, 0x04);
186 stdvga_sequ_write(0x04, 0x07);
187 stdvga_sequ_write(0x00, 0x03);
188 stdvga_grdc_write(0x04, 0x02);
189 stdvga_grdc_write(0x05, 0x00);
190 stdvga_grdc_write(0x06, 0x04);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400191}
192
Kevin O'Connor2bec7d62011-12-31 04:31:16 -0500193static void
Kevin O'Connor1ca05b02010-01-03 17:43:37 -0500194release_font_access(void)
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400195{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500196 stdvga_sequ_write(0x00, 0x01);
197 stdvga_sequ_write(0x02, 0x03);
198 stdvga_sequ_write(0x04, 0x03);
199 stdvga_sequ_write(0x00, 0x03);
200 u16 v = (stdvga_misc_read() & 0x01) ? 0x0e : 0x0a;
201 stdvga_grdc_write(0x06, v);
202 stdvga_grdc_write(0x04, 0x00);
203 stdvga_grdc_write(0x05, 0x10);
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400204}
205
Kevin O'Connor2bec7d62011-12-31 04:31:16 -0500206void
207stdvga_load_font(u16 seg, void *src_far, u16 count
208 , u16 start, u8 destflags, u8 fontsize)
209{
210 get_font_access();
211 u16 blockaddr = ((destflags & 0x03) << 14) + ((destflags & 0x04) << 11);
212 void *dest_far = (void*)(blockaddr + start*32);
213 u16 i;
214 for (i = 0; i < count; i++)
215 memcpy_far(SEG_GRAPH, dest_far + i*32
216 , seg, src_far + i*fontsize, fontsize);
217 release_font_access();
218}
219
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400220
221/****************************************************************
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400222 * CRTC registers
223 ****************************************************************/
224
Kevin O'Connorc990f272011-12-31 16:00:54 -0500225u16
226stdvga_get_crtc(void)
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400227{
Kevin O'Connor3471fdb2012-01-14 19:02:43 -0500228 if (stdvga_misc_read() & 1)
Kevin O'Connorc990f272011-12-31 16:00:54 -0500229 return VGAREG_VGA_CRTC_ADDRESS;
230 return VGAREG_MDA_CRTC_ADDRESS;
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400231}
232
Kevin O'Connor3876b532012-01-24 00:07:44 -0500233// Return the multiplication factor needed for the vga offset register.
234int
235stdvga_bpp_factor(struct vgamode_s *vmode_g)
236{
237 switch (GET_GLOBAL(vmode_g->memmodel)) {
238 case MM_TEXT:
239 return 2;
240 case MM_CGA:
241 return GET_GLOBAL(vmode_g->depth);
242 case MM_PLANAR:
243 return 1;
244 default:
245 return 4;
246 }
247}
248
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400249void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500250stdvga_set_cursor_shape(u8 start, u8 end)
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400251{
Kevin O'Connorc990f272011-12-31 16:00:54 -0500252 u16 crtc_addr = stdvga_get_crtc();
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500253 stdvga_crtc_write(crtc_addr, 0x0a, start);
254 stdvga_crtc_write(crtc_addr, 0x0b, end);
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400255}
256
257void
Kevin O'Connor16920072012-01-27 22:59:46 -0500258stdvga_set_cursor_pos(int address)
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400259{
Kevin O'Connorc990f272011-12-31 16:00:54 -0500260 u16 crtc_addr = stdvga_get_crtc();
Kevin O'Connor16920072012-01-27 22:59:46 -0500261 address /= 2; // Assume we're in text mode.
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500262 stdvga_crtc_write(crtc_addr, 0x0e, address >> 8);
263 stdvga_crtc_write(crtc_addr, 0x0f, address);
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400264}
265
266void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500267stdvga_set_scan_lines(u8 lines)
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400268{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500269 stdvga_crtc_mask(stdvga_get_crtc(), 0x09, 0x1f, lines - 1);
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400270}
271
272// Get vertical display end
273u16
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500274stdvga_get_vde(void)
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400275{
Kevin O'Connorc990f272011-12-31 16:00:54 -0500276 u16 crtc_addr = stdvga_get_crtc();
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500277 u16 vde = stdvga_crtc_read(crtc_addr, 0x12);
278 u8 ovl = stdvga_crtc_read(crtc_addr, 0x07);
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400279 vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
280 return vde;
281}
282
Kevin O'Connor9961f992012-01-21 11:53:44 -0500283int
284stdvga_get_window(struct vgamode_s *vmode_g, int window)
285{
286 return -1;
287}
288
289int
290stdvga_set_window(struct vgamode_s *vmode_g, int window, int val)
291{
292 return -1;
293}
294
Kevin O'Connor3876b532012-01-24 00:07:44 -0500295int
296stdvga_get_linelength(struct vgamode_s *vmode_g)
297{
298 u8 val = stdvga_crtc_read(stdvga_get_crtc(), 0x13);
299 return val * stdvga_bpp_factor(vmode_g) * 2;
300}
301
302int
303stdvga_set_linelength(struct vgamode_s *vmode_g, int val)
304{
305 int factor = stdvga_bpp_factor(vmode_g) * 2;
306 stdvga_crtc_write(stdvga_get_crtc(), 0x13, DIV_ROUND_UP(val, factor));
307 return 0;
308}
309
Kevin O'Connord61fc532012-01-27 20:37:45 -0500310int
311stdvga_get_displaystart(struct vgamode_s *vmode_g)
312{
313 u16 crtc_addr = stdvga_get_crtc();
314 int addr = (stdvga_crtc_read(crtc_addr, 0x0c) << 8
315 | stdvga_crtc_read(crtc_addr, 0x0d));
316 return addr * stdvga_bpp_factor(vmode_g);
317}
318
319int
320stdvga_set_displaystart(struct vgamode_s *vmode_g, int val)
321{
322 u16 crtc_addr = stdvga_get_crtc();
323 val /= stdvga_bpp_factor(vmode_g);
324 stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
325 stdvga_crtc_write(crtc_addr, 0x0d, val);
326 return 0;
327}
328
Kevin O'Connore737b172012-02-04 11:08:39 -0500329int
330stdvga_get_dacformat(struct vgamode_s *vmode_g)
331{
332 return -1;
333}
334
335int
336stdvga_set_dacformat(struct vgamode_s *vmode_g, int val)
337{
338 return -1;
339}
340
Kevin O'Connora0ecb052009-05-18 23:34:00 -0400341
342/****************************************************************
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500343 * Save/Restore state
Kevin O'Connorc0c7df62009-05-17 18:11:33 -0400344 ****************************************************************/
345
346void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500347stdvga_save_state(u16 seg, struct saveVideoHardware *info)
Kevin O'Connorca668642009-05-21 23:06:08 -0400348{
Kevin O'Connorc990f272011-12-31 16:00:54 -0500349 u16 crtc_addr = stdvga_get_crtc();
Kevin O'Connorca668642009-05-21 23:06:08 -0400350 SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS));
351 SET_FARVAR(seg, info->crtc_index, inb(crtc_addr));
352 SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS));
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500353 SET_FARVAR(seg, info->actl_index, stdvga_attrindex_read());
Kevin O'Connorca668642009-05-21 23:06:08 -0400354 SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL));
355
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500356 int i;
357 for (i=0; i<4; i++)
358 SET_FARVAR(seg, info->sequ_regs[i], stdvga_sequ_read(i+1));
359 SET_FARVAR(seg, info->sequ0, stdvga_sequ_read(0));
Kevin O'Connorca668642009-05-21 23:06:08 -0400360
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500361 for (i=0; i<25; i++)
362 SET_FARVAR(seg, info->crtc_regs[i], stdvga_crtc_read(crtc_addr, i));
Kevin O'Connorca668642009-05-21 23:06:08 -0400363
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500364 for (i=0; i<20; i++)
365 SET_FARVAR(seg, info->actl_regs[i], stdvga_attr_read(i));
Kevin O'Connorca668642009-05-21 23:06:08 -0400366
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500367 for (i=0; i<9; i++)
368 SET_FARVAR(seg, info->grdc_regs[i], stdvga_grdc_read(i));
Kevin O'Connorca668642009-05-21 23:06:08 -0400369
370 SET_FARVAR(seg, info->crtc_addr, crtc_addr);
371
372 /* XXX: read plane latches */
373 for (i=0; i<4; i++)
374 SET_FARVAR(seg, info->plane_latch[i], 0);
375}
376
377void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500378stdvga_restore_state(u16 seg, struct saveVideoHardware *info)
Kevin O'Connorca668642009-05-21 23:06:08 -0400379{
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500380 int i;
381 for (i=0; i<4; i++)
382 stdvga_sequ_write(i+1, GET_FARVAR(seg, info->sequ_regs[i]));
383 stdvga_sequ_write(0x00, GET_FARVAR(seg, info->sequ0));
Kevin O'Connorca668642009-05-21 23:06:08 -0400384
385 // Disable CRTC write protection
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500386 u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr);
387 stdvga_crtc_write(crtc_addr, 0x11, 0x00);
Kevin O'Connorca668642009-05-21 23:06:08 -0400388 // Set CRTC regs
389 for (i=0; i<25; i++)
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500390 if (i != 0x11)
391 stdvga_crtc_write(crtc_addr, i, GET_FARVAR(seg, info->crtc_regs[i]));
Kevin O'Connorca668642009-05-21 23:06:08 -0400392 // select crtc base address
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500393 stdvga_misc_mask(0x01, crtc_addr == VGAREG_VGA_CRTC_ADDRESS ? 0x01 : 0x00);
Kevin O'Connorca668642009-05-21 23:06:08 -0400394
395 // enable write protection if needed
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500396 stdvga_crtc_write(crtc_addr, 0x11, GET_FARVAR(seg, info->crtc_regs[0x11]));
Kevin O'Connorca668642009-05-21 23:06:08 -0400397
398 // Set Attribute Ctl
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500399 for (i=0; i<20; i++)
400 stdvga_attr_write(i, GET_FARVAR(seg, info->actl_regs[i]));
401 stdvga_attrindex_write(GET_FARVAR(seg, info->actl_index));
Kevin O'Connorca668642009-05-21 23:06:08 -0400402
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500403 for (i=0; i<9; i++)
404 stdvga_grdc_write(i, GET_FARVAR(seg, info->grdc_regs[i]));
Kevin O'Connorca668642009-05-21 23:06:08 -0400405
406 outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS);
407 outb(GET_FARVAR(seg, info->crtc_index), crtc_addr);
408 outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS);
409 outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa);
410}
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400411
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400412
413/****************************************************************
414 * Misc
415 ****************************************************************/
416
417void
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500418stdvga_enable_video_addressing(u8 disable)
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400419{
420 u8 v = (disable & 1) ? 0x00 : 0x02;
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500421 stdvga_misc_mask(0x02, v);
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400422}
423
Kevin O'Connor161d2012011-12-31 19:42:21 -0500424int
Kevin O'Connor88ca7412011-12-31 04:24:20 -0500425stdvga_init(void)
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400426{
427 // switch to color mode and enable CPU access 480 lines
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500428 stdvga_misc_write(0xc3);
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400429 // more than 64k 3C4/04
Kevin O'Connor86d2e002012-01-14 22:17:07 -0500430 stdvga_sequ_write(0x04, 0x02);
Kevin O'Connor161d2012011-12-31 19:42:21 -0500431
432 return 0;
Kevin O'Connor124b6f72009-05-25 00:44:29 -0400433}