1 // VGA bios implementation
3 // Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2001-2008 the LGPL VGABios developers Team
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
10 // * introduce "struct vregs", or add ebp to struct bregs.
11 // * Integrate vga_modes/pallete?/line_to_vpti/dac_regs/video_param_table
12 // * define structs for save/restore state
13 // * review correctness of converted asm by comparing with RBIL
14 // * refactor redundant code into sub-functions
15 // * See if there is a method to the in/out stuff that can be encapsulated.
16 // * remove "biosfn" prefixes
17 // * don't hardcode 0xc000
18 // * add defs for 0xa000/0xb800
19 // * verify all funcs static
21 // * convert vbe/clext code
23 // * separate code into separate files
24 // * extract hw code from bios interfaces
26 #include "bregs.h" // struct bregs
27 #include "biosvar.h" // GET_BDA
28 #include "util.h" // memset
29 #include "vgatables.h" // vga_modes
33 #define CONFIG_CIRRUS 0
36 #define DEBUG_VGA_POST 1
37 #define DEBUG_VGA_10 3
39 #define SET_VGA(var, val) SET_FARVAR(0xc000, (var), (val))
42 // ===================================================================
46 // ===================================================================
48 // -------------------------------------------------------------------
50 find_vga_entry(u8 mode)
53 for (i = 0; i <= MODE_MAX; i++)
54 if (GET_GLOBAL(vga_modes[i].svgamode) == mode)
60 call16_vgaint(u32 eax, u32 ebx)
73 memcpy16_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len)
75 memcpy_far(d_seg, d_far, s_seg, s_far, len);
79 // ===================================================================
83 // ===================================================================
85 // -------------------------------------------------------------------
87 biosfn_perform_gray_scale_summing(u16 start, u16 count)
89 inb(VGAREG_ACTL_RESET);
90 outb(0x00, VGAREG_ACTL_ADDRESS);
93 for (i = start; i < start+count; i++) {
94 // set read address and switch to read mode
95 outb(i, VGAREG_DAC_READ_ADDRESS);
96 // get 6-bit wide RGB data values
97 u8 r = inb(VGAREG_DAC_DATA);
98 u8 g = inb(VGAREG_DAC_DATA);
99 u8 b = inb(VGAREG_DAC_DATA);
101 // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
102 u16 intensity = ((77 * r + 151 * g + 28 * b) + 0x80) >> 8;
104 if (intensity > 0x3f)
107 // set write address and switch to write mode
108 outb(i, VGAREG_DAC_WRITE_ADDRESS);
109 // write new intensity value
110 outb(intensity & 0xff, VGAREG_DAC_DATA);
111 outb(intensity & 0xff, VGAREG_DAC_DATA);
112 outb(intensity & 0xff, VGAREG_DAC_DATA);
114 inb(VGAREG_ACTL_RESET);
115 outb(0x20, VGAREG_ACTL_ADDRESS);
118 // -------------------------------------------------------------------
120 biosfn_set_cursor_shape(u8 CH, u8 CL)
125 u16 curs = (CH << 8) + CL;
126 SET_BDA(cursor_type, curs);
128 u8 modeset_ctl = GET_BDA(modeset_ctl);
129 u16 cheight = GET_BDA(char_height);
130 if ((modeset_ctl & 0x01) && (cheight > 8) && (CL < 8) && (CH < 0x20)) {
132 CH = ((CH + 1) * cheight / 8) - 1;
134 CH = ((CL + 1) * cheight / 8) - 2;
135 CL = ((CL + 1) * cheight / 8) - 1;
137 // CTRC regs 0x0a and 0x0b
138 u16 crtc_addr = GET_BDA(crtc_address);
139 outb(0x0a, crtc_addr);
140 outb(CH, crtc_addr + 1);
141 outb(0x0b, crtc_addr);
142 outb(CL, crtc_addr + 1);
145 // -------------------------------------------------------------------
147 biosfn_set_cursor_pos(u8 page, u16 cursor)
149 // Should not happen...
154 SET_BDA(cursor_pos[page], cursor);
156 // Set the hardware cursor
157 u8 current = GET_BDA(video_page);
161 // Get the dimensions
162 u16 nbcols = GET_BDA(video_cols);
163 u16 nbrows = GET_BDA(video_rows) + 1;
165 u8 xcurs = cursor & 0x00ff;
166 u8 ycurs = (cursor & 0xff00) >> 8;
168 // Calculate the address knowing nbcols nbrows and page num
169 u16 address = SCREEN_IO_START(nbcols, nbrows, page) + xcurs + ycurs * nbcols;
171 // CRTC regs 0x0e and 0x0f
172 u16 crtc_addr = GET_BDA(crtc_address);
173 outb(0x0e, crtc_addr);
174 outb((address & 0xff00) >> 8, crtc_addr + 1);
175 outb(0x0f, crtc_addr);
176 outb(address & 0x00ff, crtc_addr + 1);
179 // -------------------------------------------------------------------
181 biosfn_get_cursor_pos(u8 page, u16 *shape, u16 *pos)
189 // FIXME should handle VGA 14/16 lines
190 *shape = GET_BDA(cursor_type);
191 *pos = GET_BDA(cursor_pos[page]);
194 // -------------------------------------------------------------------
196 biosfn_set_active_page(u8 page)
202 u8 mode = GET_BDA(video_mode);
203 u8 line = find_vga_entry(mode);
207 // Get pos curs pos for the right page
209 biosfn_get_cursor_pos(page, &dummy, &cursor);
212 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
213 // Get the dimensions
214 u16 nbcols = GET_BDA(video_cols);
215 u16 nbrows = GET_BDA(video_rows) + 1;
217 // Calculate the address knowing nbcols nbrows and page num
218 address = SCREEN_MEM_START(nbcols, nbrows, page);
219 SET_BDA(video_pagestart, address);
222 address = SCREEN_IO_START(nbcols, nbrows, page);
224 address = page * GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].slength);
227 // CRTC regs 0x0c and 0x0d
228 u16 crtc_addr = GET_BDA(crtc_address);
229 outb(0x0c, crtc_addr);
230 outb((address & 0xff00) >> 8, crtc_addr + 1);
231 outb(0x0d, crtc_addr);
232 outb(address & 0x00ff, crtc_addr + 1);
234 // And change the BIOS page
235 SET_BDA(video_page, page);
237 dprintf(1, "Set active page %02x address %04x\n", page, address);
239 // Display the cursor, now the page is active
240 biosfn_set_cursor_pos(page, cursor);
244 biosfn_set_video_mode(u8 mode)
245 { // mode: Bit 7 is 1 if no clear screen
247 cirrus_set_video_mode(mode);
250 if (vbe_has_vbe_display())
251 dispi_set_enable(VBE_DISPI_DISABLED);
255 u8 noclearmem = mode & 0x80;
258 // find the entry in the video modes
259 u8 line = find_vga_entry(mode);
261 dprintf(1, "mode search %02x found line %02x\n", mode, line);
266 u8 vpti = GET_GLOBAL(line_to_vpti[line]);
267 u16 twidth = GET_GLOBAL(video_param_table[vpti].twidth);
268 u16 theightm1 = GET_GLOBAL(video_param_table[vpti].theightm1);
269 u16 cheight = GET_GLOBAL(video_param_table[vpti].cheight);
271 // Read the bios mode set control
272 u8 modeset_ctl = GET_BDA(modeset_ctl);
274 // Then we know the number of lines
277 // if palette loading (bit 3 of modeset ctl = 0)
278 if ((modeset_ctl & 0x08) == 0) { // Set the PEL mask
279 outb(GET_GLOBAL(vga_modes[line].pelmask), VGAREG_PEL_MASK);
281 // Set the whole dac always, from 0
282 outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
284 // From which palette
286 switch (GET_GLOBAL(vga_modes[line].dacmodel)) {
289 palette_g = palette0;
292 palette_g = palette1;
295 palette_g = palette2;
298 palette_g = palette3;
301 // Always 256*3 values
303 for (i = 0; i < 0x0100; i++) {
304 if (i <= GET_GLOBAL(dac_regs[GET_GLOBAL(vga_modes[line].dacmodel)])) {
305 outb(GET_GLOBAL(palette_g[(i * 3) + 0]), VGAREG_DAC_DATA);
306 outb(GET_GLOBAL(palette_g[(i * 3) + 1]), VGAREG_DAC_DATA);
307 outb(GET_GLOBAL(palette_g[(i * 3) + 2]), VGAREG_DAC_DATA);
309 outb(0, VGAREG_DAC_DATA);
310 outb(0, VGAREG_DAC_DATA);
311 outb(0, VGAREG_DAC_DATA);
314 if ((modeset_ctl & 0x02) == 0x02)
315 biosfn_perform_gray_scale_summing(0x00, 0x100);
317 // Reset Attribute Ctl flip-flop
318 inb(VGAREG_ACTL_RESET);
322 for (i = 0; i <= 0x13; i++) {
323 outb(i, VGAREG_ACTL_ADDRESS);
324 outb(GET_GLOBAL(video_param_table[vpti].actl_regs[i])
325 , VGAREG_ACTL_WRITE_DATA);
327 outb(0x14, VGAREG_ACTL_ADDRESS);
328 outb(0x00, VGAREG_ACTL_WRITE_DATA);
331 outb(0, VGAREG_SEQU_ADDRESS);
332 outb(0x03, VGAREG_SEQU_DATA);
333 for (i = 1; i <= 4; i++) {
334 outb(i, VGAREG_SEQU_ADDRESS);
335 outb(GET_GLOBAL(video_param_table[vpti].sequ_regs[i - 1])
340 for (i = 0; i <= 8; i++) {
341 outb(i, VGAREG_GRDC_ADDRESS);
342 outb(GET_GLOBAL(video_param_table[vpti].grdc_regs[i])
346 // Set CRTC address VGA or MDA
347 u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
348 if (GET_GLOBAL(vga_modes[line].memmodel) == MTEXT)
349 crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
351 // Disable CRTC write protection
352 outw(0x0011, crtc_addr);
354 for (i = 0; i <= 0x18; i++) {
356 outb(GET_GLOBAL(video_param_table[vpti].crtc_regs[i]), crtc_addr + 1);
359 // Set the misc register
360 outb(GET_GLOBAL(video_param_table[vpti].miscreg), VGAREG_WRITE_MISC_OUTPUT);
363 outb(0x20, VGAREG_ACTL_ADDRESS);
364 inb(VGAREG_ACTL_RESET);
366 if (noclearmem == 0x00) {
367 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
368 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
369 , 0, 0x0720, 32*1024);
372 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
373 , 0, 0x0000, 32*1024);
375 outb(0x02, VGAREG_SEQU_ADDRESS);
376 u8 mmask = inb(VGAREG_SEQU_DATA);
377 outb(0x0f, VGAREG_SEQU_DATA); // all planes
378 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
379 , 0, 0x0000, 64*1024);
380 outb(mmask, VGAREG_SEQU_DATA);
385 SET_BDA(video_mode, mode);
386 SET_BDA(video_cols, twidth);
387 SET_BDA(video_pagesize, GET_GLOBAL(video_param_table[vpti].slength));
388 SET_BDA(crtc_address, crtc_addr);
389 SET_BDA(video_rows, theightm1);
390 SET_BDA(char_height, cheight);
391 SET_BDA(video_ctl, (0x60 | noclearmem));
392 SET_BDA(video_switches, 0xF9);
393 SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f);
395 // FIXME We nearly have the good tables. to be reworked
396 SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now
397 SET_BDA(video_savetable_ptr, (u32)video_save_pointer_table);
398 SET_BDA(video_savetable_seg, 0xc000);
401 SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
402 SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
405 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
406 biosfn_set_cursor_shape(0x06, 0x07);
407 // Set cursor pos for page 0..7
408 for (i = 0; i < 8; i++)
409 biosfn_set_cursor_pos(i, 0x0000);
412 biosfn_set_active_page(0x00);
414 // Write the fonts in memory
415 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
416 call16_vgaint(0x1104, 0);
417 call16_vgaint(0x1103, 0);
419 // Set the ints 0x1F and 0x43
420 SET_IVT(0x1f, 0xC000, (u32)&vgafont8[128 * 8]);
424 SET_IVT(0x43, 0xC000, (u32)vgafont8);
427 SET_IVT(0x43, 0xC000, (u32)vgafont14);
430 SET_IVT(0x43, 0xC000, (u32)vgafont16);
435 // -------------------------------------------------------------------
437 vgamem_copy_pl4(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
440 u16 src = ysrc * cheight * nbcols + xstart;
441 u16 dest = ydest * cheight * nbcols + xstart;
442 outw(0x0105, VGAREG_GRDC_ADDRESS);
444 for (i = 0; i < cheight; i++)
445 memcpy_far(0xa000, (void*)(dest + i * nbcols)
446 , 0xa000, (void*)(src + i * nbcols), cols);
447 outw(0x0005, VGAREG_GRDC_ADDRESS);
450 // -------------------------------------------------------------------
452 vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
455 u16 dest = ystart * cheight * nbcols + xstart;
456 outw(0x0205, VGAREG_GRDC_ADDRESS);
458 for (i = 0; i < cheight; i++)
459 memset_far(0xa000, (void*)(dest + i * nbcols), attr, cols);
460 outw(0x0005, VGAREG_GRDC_ADDRESS);
463 // -------------------------------------------------------------------
465 vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
468 u16 src = ((ysrc * cheight * nbcols) >> 1) + xstart;
469 u16 dest = ((ydest * cheight * nbcols) >> 1) + xstart;
471 for (i = 0; i < cheight; i++)
473 memcpy_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
474 , 0xb800, (void*)(0x2000 + src + (i >> 1) * nbcols)
477 memcpy_far(0xb800, (void*)(dest + (i >> 1) * nbcols)
478 , 0xb800, (void*)(src + (i >> 1) * nbcols), cols);
481 // -------------------------------------------------------------------
483 vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
486 u16 dest = ((ystart * cheight * nbcols) >> 1) + xstart;
488 for (i = 0; i < cheight; i++)
490 memset_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
493 memset_far(0xb800, (void*)(dest + (i >> 1) * nbcols), attr, cols);
496 // -------------------------------------------------------------------
498 biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page,
501 // page == 0xFF if current
508 u8 mode = GET_BDA(video_mode);
509 u8 line = find_vga_entry(mode);
513 // Get the dimensions
514 u16 nbrows = GET_BDA(video_rows) + 1;
515 u16 nbcols = GET_BDA(video_cols);
517 // Get the current page
519 page = GET_BDA(video_page);
525 if (nblines > nbrows)
527 u8 cols = clr - cul + 1;
529 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
530 // Compute the address
531 void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page));
532 dprintf(3, "Scroll, address %p (%d %d %02x)\n"
533 , address, nbrows, nbcols, page);
535 if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
536 && clr == nbcols - 1) {
537 memset16_far(GET_GLOBAL(vga_modes[line].sstart), address
538 , (u16)attr * 0x100 + ' ', nbrows * nbcols * 2);
539 } else { // if Scroll up
540 if (dir == SCROLL_UP) {
542 for (i = rul; i <= rlr; i++)
543 if ((i + nblines > rlr) || (nblines == 0))
544 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
545 , address + (i * nbcols + cul) * 2
546 , (u16)attr * 0x100 + ' ', cols * 2);
548 memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
549 , address + (i * nbcols + cul) * 2
550 , GET_GLOBAL(vga_modes[line].sstart)
551 , (void*)(((i + nblines) * nbcols + cul) * 2)
555 for (i = rlr; i >= rul; i--) {
556 if ((i < rul + nblines) || (nblines == 0))
557 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
558 , address + (i * nbcols + cul) * 2
559 , (u16)attr * 0x100 + ' ', cols * 2);
561 memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
562 , address + (i * nbcols + cul) * 2
563 , GET_GLOBAL(vga_modes[line].sstart)
564 , (void*)(((i - nblines) * nbcols + cul) * 2)
574 // FIXME gfx mode not complete
575 u8 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
576 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
579 if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
580 && clr == nbcols - 1) {
581 outw(0x0205, VGAREG_GRDC_ADDRESS);
582 memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
583 nbrows * nbcols * cheight);
584 outw(0x0005, VGAREG_GRDC_ADDRESS);
585 } else { // if Scroll up
586 if (dir == SCROLL_UP) {
588 for (i = rul; i <= rlr; i++)
589 if ((i + nblines > rlr) || (nblines == 0))
590 vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
593 vgamem_copy_pl4(cul, i + nblines, i, cols,
597 for (i = rlr; i >= rul; i--) {
598 if ((i < rul + nblines) || (nblines == 0))
599 vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
602 vgamem_copy_pl4(cul, i, i - nblines, cols,
611 u8 bpp = GET_GLOBAL(vga_modes[line].pixbits);
612 if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
613 && clr == nbcols - 1) {
614 memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
615 nbrows * nbcols * cheight * bpp);
623 if (dir == SCROLL_UP) {
625 for (i = rul; i <= rlr; i++)
626 if ((i + nblines > rlr) || (nblines == 0))
627 vgamem_fill_cga(cul, i, cols, nbcols, cheight,
630 vgamem_copy_cga(cul, i + nblines, i, cols,
634 for (i = rlr; i >= rul; i--) {
635 if ((i < rul + nblines) || (nblines == 0))
636 vgamem_fill_cga(cul, i, cols, nbcols, cheight,
639 vgamem_copy_cga(cul, i, i - nblines, cols,
649 dprintf(1, "Scroll in graphics mode\n");
653 // -------------------------------------------------------------------
655 biosfn_read_char_attr(u8 page, u16 *car)
658 u8 mode = GET_BDA(video_mode);
659 u8 line = find_vga_entry(mode);
663 // Get the cursor pos for the page
665 biosfn_get_cursor_pos(page, &dummy, &cursor);
666 u8 xcurs = cursor & 0x00ff;
667 u8 ycurs = (cursor & 0xff00) >> 8;
669 // Get the dimensions
670 u16 nbrows = GET_BDA(video_rows) + 1;
671 u16 nbcols = GET_BDA(video_cols);
673 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
674 // Compute the address
675 u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
676 + (xcurs + ycurs * nbcols) * 2);
678 *car = GET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address_far);
681 dprintf(1, "Read char in graphics mode\n");
685 // -------------------------------------------------------------------
687 write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols,
701 u16 addr = xcurs + ycurs * cheight * nbcols;
702 u16 src = car * cheight;
703 outw(0x0f02, VGAREG_SEQU_ADDRESS);
704 outw(0x0205, VGAREG_GRDC_ADDRESS);
706 outw(0x1803, VGAREG_GRDC_ADDRESS);
708 outw(0x0003, VGAREG_GRDC_ADDRESS);
710 for (i = 0; i < cheight; i++) {
711 u8 *dest_far = (void*)(addr + i * nbcols);
713 for (j = 0; j < 8; j++) {
715 outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
716 GET_FARVAR(0xa000, *dest_far);
717 if (GET_GLOBAL(fdata_g[src + i]) & mask)
718 SET_FARVAR(0xa000, *dest_far, attr & 0x0f);
720 SET_FARVAR(0xa000, *dest_far, 0x00);
723 outw(0xff08, VGAREG_GRDC_ADDRESS);
724 outw(0x0005, VGAREG_GRDC_ADDRESS);
725 outw(0x0003, VGAREG_GRDC_ADDRESS);
728 // -------------------------------------------------------------------
730 write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
732 u8 *fdata_g = vgafont8;
733 u16 addr = (xcurs * bpp) + ycurs * 320;
736 for (i = 0; i < 8; i++) {
737 u8 *dest_far = (void*)(addr + (i >> 1) * 80);
744 data = GET_FARVAR(0xb800, *dest_far);
746 for (j = 0; j < 8; j++) {
747 if (GET_GLOBAL(fdata_g[src + i]) & mask) {
749 data ^= (attr & 0x01) << (7 - j);
751 data |= (attr & 0x01) << (7 - j);
755 SET_FARVAR(0xb800, *dest_far, data);
760 data = GET_FARVAR(0xb800, *dest_far);
762 for (j = 0; j < 4; j++) {
763 if (GET_GLOBAL(fdata_g[src + i]) & mask) {
765 data ^= (attr & 0x03) << ((3 - j) * 2);
767 data |= (attr & 0x03) << ((3 - j) * 2);
771 SET_FARVAR(0xb800, *dest_far, data);
778 // -------------------------------------------------------------------
780 write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols)
782 u8 *fdata_g = vgafont8;
783 u16 addr = xcurs * 8 + ycurs * nbcols * 64;
786 for (i = 0; i < 8; i++) {
787 u8 *dest_far = (void*)(addr + i * nbcols * 8);
790 for (j = 0; j < 8; j++) {
792 if (GET_GLOBAL(fdata_g[src + i]) & mask)
794 SET_FARVAR(0xa000, dest_far[j], data);
800 // -------------------------------------------------------------------
802 biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count)
805 u8 mode = GET_BDA(video_mode);
806 u8 line = find_vga_entry(mode);
810 // Get the cursor pos for the page
812 biosfn_get_cursor_pos(page, &dummy, &cursor);
813 u8 xcurs = cursor & 0x00ff;
814 u8 ycurs = (cursor & 0xff00) >> 8;
816 // Get the dimensions
817 u16 nbrows = GET_BDA(video_rows) + 1;
818 u16 nbcols = GET_BDA(video_cols);
820 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
821 // Compute the address
822 void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
823 + (xcurs + ycurs * nbcols) * 2);
825 dummy = ((u16)attr << 8) + car;
826 memset16_far(GET_GLOBAL(vga_modes[line].sstart), address, dummy
831 // FIXME gfx mode not complete
832 u8 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
833 u8 bpp = GET_GLOBAL(vga_modes[line].pixbits);
834 while ((count-- > 0) && (xcurs < nbcols)) {
835 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
838 write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
842 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
845 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
852 // -------------------------------------------------------------------
854 biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count)
857 u8 mode = GET_BDA(video_mode);
858 u8 line = find_vga_entry(mode);
862 // Get the cursor pos for the page
864 biosfn_get_cursor_pos(page, &dummy, &cursor);
865 u8 xcurs = cursor & 0x00ff;
866 u8 ycurs = (cursor & 0xff00) >> 8;
868 // Get the dimensions
869 u16 nbrows = GET_BDA(video_rows) + 1;
870 u16 nbcols = GET_BDA(video_cols);
872 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
873 // Compute the address
874 u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
875 + (xcurs + ycurs * nbcols) * 2);
876 while (count-- > 0) {
877 SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address_far, car);
883 // FIXME gfx mode not complete
884 u8 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
885 u8 bpp = GET_GLOBAL(vga_modes[line].pixbits);
886 while ((count-- > 0) && (xcurs < nbcols)) {
887 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
890 write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
894 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
897 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
904 // -------------------------------------------------------------------
906 biosfn_set_border_color(struct bregs *regs)
908 inb(VGAREG_ACTL_RESET);
909 outb(0x00, VGAREG_ACTL_ADDRESS);
910 u8 al = regs->bl & 0x0f;
913 outb(al, VGAREG_ACTL_WRITE_DATA);
914 u8 bl = regs->bl & 0x10;
917 for (i = 1; i < 4; i++) {
918 outb(i, VGAREG_ACTL_ADDRESS);
920 al = inb(VGAREG_ACTL_READ_DATA);
923 outb(al, VGAREG_ACTL_WRITE_DATA);
925 outb(0x20, VGAREG_ACTL_ADDRESS);
929 biosfn_set_palette(struct bregs *regs)
931 inb(VGAREG_ACTL_RESET);
932 u8 bl = regs->bl & 0x01;
934 for (i = 1; i < 4; i++) {
935 outb(i, VGAREG_ACTL_ADDRESS);
937 u8 al = inb(VGAREG_ACTL_READ_DATA);
940 outb(al, VGAREG_ACTL_WRITE_DATA);
942 outb(0x20, VGAREG_ACTL_ADDRESS);
945 // -------------------------------------------------------------------
947 biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX)
950 u8 mode = GET_BDA(video_mode);
951 u8 line = find_vga_entry(mode);
954 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
957 u8 *addr_far, mask, attr, data;
958 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
961 addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols));
962 mask = 0x80 >> (CX & 0x07);
963 outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
964 outw(0x0205, VGAREG_GRDC_ADDRESS);
965 data = GET_FARVAR(0xa000, *addr_far);
967 outw(0x1803, VGAREG_GRDC_ADDRESS);
968 SET_FARVAR(0xa000, *addr_far, AL);
969 outw(0xff08, VGAREG_GRDC_ADDRESS);
970 outw(0x0005, VGAREG_GRDC_ADDRESS);
971 outw(0x0003, VGAREG_GRDC_ADDRESS);
974 if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
975 addr_far = (void*)((CX >> 2) + (DX >> 1) * 80);
977 addr_far = (void*)((CX >> 3) + (DX >> 1) * 80);
980 data = GET_FARVAR(0xb800, *addr_far);
981 if (GET_GLOBAL(vga_modes[line].pixbits) == 2) {
982 attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
983 mask = 0x03 << ((3 - (CX & 0x03)) * 2);
985 attr = (AL & 0x01) << (7 - (CX & 0x07));
986 mask = 0x01 << (7 - (CX & 0x07));
994 SET_FARVAR(0xb800, *addr_far, data);
997 addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
998 SET_FARVAR(0xa000, *addr_far, AL);
1003 // -------------------------------------------------------------------
1005 biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
1008 u8 mode = GET_BDA(video_mode);
1009 u8 line = find_vga_entry(mode);
1012 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
1015 u8 *addr_far, mask, attr, data, i;
1016 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
1019 addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols));
1020 mask = 0x80 >> (CX & 0x07);
1022 for (i = 0; i < 4; i++) {
1023 outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS);
1024 data = GET_FARVAR(0xa000, *addr_far) & mask;
1026 attr |= (0x01 << i);
1030 addr_far = (void*)((CX >> 2) + (DX >> 1) * 80);
1033 data = GET_FARVAR(0xb800, *addr_far);
1034 if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
1035 attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
1037 attr = (data >> (7 - (CX & 0x07))) & 0x01;
1040 addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
1041 attr = GET_FARVAR(0xa000, *addr_far);
1044 *AX = (*AX & 0xff00) | attr;
1047 // -------------------------------------------------------------------
1049 biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
1050 { // flag = WITH_ATTR / NO_ATTR
1051 // special case if page is 0xff, use current page
1053 page = GET_BDA(video_page);
1056 u8 mode = GET_BDA(video_mode);
1057 u8 line = find_vga_entry(mode);
1061 // Get the cursor pos for the page
1063 biosfn_get_cursor_pos(page, &dummy, &cursor);
1064 u8 xcurs = cursor & 0x00ff;
1065 u8 ycurs = (cursor & 0xff00) >> 8;
1067 // Get the dimensions
1068 u16 nbrows = GET_BDA(video_rows) + 1;
1069 u16 nbcols = GET_BDA(video_cols);
1091 biosfn_write_teletype(' ', page, attr, flag);
1092 biosfn_get_cursor_pos(page, &dummy, &cursor);
1093 xcurs = cursor & 0x00ff;
1094 ycurs = (cursor & 0xff00) >> 8;
1095 } while (xcurs % 8 == 0);
1100 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
1101 // Compute the address
1102 u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
1103 + (xcurs + ycurs * nbcols) * 2);
1105 SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address_far[0], car);
1106 if (flag == WITH_ATTR)
1107 SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address_far[1]
1110 // FIXME gfx mode not complete
1111 u8 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
1112 u8 bpp = GET_GLOBAL(vga_modes[line].pixbits);
1113 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
1116 write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
1120 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
1123 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
1130 // Do we need to wrap ?
1131 if (xcurs == nbcols) {
1135 // Do we need to scroll ?
1136 if (ycurs == nbrows) {
1137 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
1138 biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
1141 biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, page,
1145 // Set the cursor for the page
1149 biosfn_set_cursor_pos(page, cursor);
1152 // -------------------------------------------------------------------
1154 biosfn_get_video_mode(struct bregs *regs)
1156 regs->bh = GET_BDA(video_page);
1157 regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
1158 regs->ah = GET_BDA(video_cols);
1161 // -------------------------------------------------------------------
1163 biosfn_set_overscan_border_color(struct bregs *regs)
1165 inb(VGAREG_ACTL_RESET);
1166 outb(0x11, VGAREG_ACTL_ADDRESS);
1167 outb(regs->bh, VGAREG_ACTL_WRITE_DATA);
1168 outb(0x20, VGAREG_ACTL_ADDRESS);
1171 // -------------------------------------------------------------------
1173 biosfn_set_all_palette_reg(struct bregs *regs)
1175 inb(VGAREG_ACTL_RESET);
1177 u8 *data_far = (u8*)(regs->dx + 0);
1179 for (i = 0; i < 0x10; i++) {
1180 outb(i, VGAREG_ACTL_ADDRESS);
1181 u8 val = GET_FARVAR(regs->es, *data_far);
1182 outb(val, VGAREG_ACTL_WRITE_DATA);
1185 outb(0x11, VGAREG_ACTL_ADDRESS);
1186 outb(GET_FARVAR(regs->es, *data_far), VGAREG_ACTL_WRITE_DATA);
1187 outb(0x20, VGAREG_ACTL_ADDRESS);
1190 // -------------------------------------------------------------------
1192 biosfn_toggle_intensity(struct bregs *regs)
1194 inb(VGAREG_ACTL_RESET);
1195 outb(0x10, VGAREG_ACTL_ADDRESS);
1196 u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3);
1197 outb(val, VGAREG_ACTL_WRITE_DATA);
1198 outb(0x20, VGAREG_ACTL_ADDRESS);
1201 // -------------------------------------------------------------------
1203 biosfn_set_single_palette_reg(u8 reg, u8 val)
1205 inb(VGAREG_ACTL_RESET);
1206 outb(reg, VGAREG_ACTL_ADDRESS);
1207 outb(val, VGAREG_ACTL_WRITE_DATA);
1208 outb(0x20, VGAREG_ACTL_ADDRESS);
1211 // -------------------------------------------------------------------
1213 biosfn_get_single_palette_reg(u8 reg)
1215 inb(VGAREG_ACTL_RESET);
1216 outb(reg, VGAREG_ACTL_ADDRESS);
1217 u8 v = inb(VGAREG_ACTL_READ_DATA);
1218 inb(VGAREG_ACTL_RESET);
1219 outb(0x20, VGAREG_ACTL_ADDRESS);
1223 // -------------------------------------------------------------------
1225 biosfn_read_overscan_border_color(struct bregs *regs)
1227 inb(VGAREG_ACTL_RESET);
1228 outb(0x11, VGAREG_ACTL_ADDRESS);
1229 regs->bh = inb(VGAREG_ACTL_READ_DATA);
1230 inb(VGAREG_ACTL_RESET);
1231 outb(0x20, VGAREG_ACTL_ADDRESS);
1234 // -------------------------------------------------------------------
1236 biosfn_get_all_palette_reg(struct bregs *regs)
1238 u8 *data_far = (u8*)(regs->dx + 0);
1240 for (i = 0; i < 0x10; i++) {
1241 inb(VGAREG_ACTL_RESET);
1242 outb(i, VGAREG_ACTL_ADDRESS);
1243 SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA));
1246 inb(VGAREG_ACTL_RESET);
1247 outb(0x11, VGAREG_ACTL_ADDRESS);
1248 SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA));
1249 inb(VGAREG_ACTL_RESET);
1250 outb(0x20, VGAREG_ACTL_ADDRESS);
1253 // -------------------------------------------------------------------
1255 biosfn_set_single_dac_reg(struct bregs *regs)
1257 outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
1258 outb(regs->dh, VGAREG_DAC_DATA);
1259 outb(regs->ch, VGAREG_DAC_DATA);
1260 outb(regs->cl, VGAREG_DAC_DATA);
1263 // -------------------------------------------------------------------
1265 biosfn_set_all_dac_reg(struct bregs *regs)
1267 outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
1268 u8 *data_far = (u8*)(regs->dx + 0);
1269 int count = regs->cx;
1271 outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
1273 outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
1275 outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
1281 // -------------------------------------------------------------------
1283 biosfn_select_video_dac_color_page(struct bregs *regs)
1285 inb(VGAREG_ACTL_RESET);
1286 outb(0x10, VGAREG_ACTL_ADDRESS);
1287 u8 val = inb(VGAREG_ACTL_READ_DATA);
1288 if (!(regs->bl & 0x01)) {
1289 val = (val & 0x7f) | (regs->bh << 7);
1290 outb(val, VGAREG_ACTL_WRITE_DATA);
1291 outb(0x20, VGAREG_ACTL_ADDRESS);
1294 inb(VGAREG_ACTL_RESET);
1295 outb(0x14, VGAREG_ACTL_ADDRESS);
1300 outb(bh, VGAREG_ACTL_WRITE_DATA);
1301 outb(0x20, VGAREG_ACTL_ADDRESS);
1304 // -------------------------------------------------------------------
1306 biosfn_read_single_dac_reg(struct bregs *regs)
1308 outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
1309 regs->dh = inb(VGAREG_DAC_DATA);
1310 regs->ch = inb(VGAREG_DAC_DATA);
1311 regs->cl = inb(VGAREG_DAC_DATA);
1314 // -------------------------------------------------------------------
1316 biosfn_read_all_dac_reg(struct bregs *regs)
1318 outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
1319 u8 *data_far = (u8*)(regs->dx + 0);
1320 int count = regs->cx;
1322 SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
1324 SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
1326 SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
1332 // -------------------------------------------------------------------
1334 biosfn_set_pel_mask(struct bregs *regs)
1336 outb(regs->bl, VGAREG_PEL_MASK);
1339 // -------------------------------------------------------------------
1341 biosfn_read_pel_mask(struct bregs *regs)
1343 regs->bl = inb(VGAREG_PEL_MASK);
1346 // -------------------------------------------------------------------
1348 biosfn_read_video_dac_state(struct bregs *regs)
1350 inb(VGAREG_ACTL_RESET);
1351 outb(0x10, VGAREG_ACTL_ADDRESS);
1352 u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7;
1354 inb(VGAREG_ACTL_RESET);
1355 outb(0x14, VGAREG_ACTL_ADDRESS);
1356 u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f;
1360 inb(VGAREG_ACTL_RESET);
1361 outb(0x20, VGAREG_ACTL_ADDRESS);
1367 // -------------------------------------------------------------------
1371 outw(0x0100, VGAREG_SEQU_ADDRESS);
1372 outw(0x0402, VGAREG_SEQU_ADDRESS);
1373 outw(0x0704, VGAREG_SEQU_ADDRESS);
1374 outw(0x0300, VGAREG_SEQU_ADDRESS);
1375 outw(0x0204, VGAREG_GRDC_ADDRESS);
1376 outw(0x0005, VGAREG_GRDC_ADDRESS);
1377 outw(0x0406, VGAREG_GRDC_ADDRESS);
1381 release_font_access()
1383 outw(0x0100, VGAREG_SEQU_ADDRESS);
1384 outw(0x0302, VGAREG_SEQU_ADDRESS);
1385 outw(0x0304, VGAREG_SEQU_ADDRESS);
1386 outw(0x0300, VGAREG_SEQU_ADDRESS);
1387 u16 v = inw(VGAREG_READ_MISC_OUTPUT);
1388 v = ((v & 0x01) << 10) | 0x0a06;
1389 outw(v, VGAREG_GRDC_ADDRESS);
1390 outw(0x0004, VGAREG_GRDC_ADDRESS);
1391 outw(0x1005, VGAREG_GRDC_ADDRESS);
1395 set_scan_lines(u8 lines)
1397 u16 crtc_addr = GET_BDA(crtc_address);
1398 outb(0x09, crtc_addr);
1399 u8 crtc_r9 = inb(crtc_addr + 1);
1400 crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
1401 outb(crtc_r9, crtc_addr + 1);
1403 biosfn_set_cursor_shape(0x06, 0x07);
1405 biosfn_set_cursor_shape(lines - 4, lines - 3);
1406 SET_BDA(char_height, lines);
1407 outb(0x12, crtc_addr);
1408 u16 vde = inb(crtc_addr + 1);
1409 outb(0x07, crtc_addr);
1410 u8 ovl = inb(crtc_addr + 1);
1411 vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
1412 u8 rows = vde / lines;
1413 SET_BDA(video_rows, rows - 1);
1414 u16 cols = GET_BDA(video_cols);
1415 SET_BDA(video_pagesize, rows * cols * 2);
1419 biosfn_load_text_user_pat(u8 AL, u16 ES, u16 BP, u16 CX, u16 DX, u8 BL,
1423 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1425 for (i = 0; i < CX; i++) {
1426 void *src = (void*)(BP + i * BH);
1427 void *dest = (void*)(blockaddr + (DX + i) * 32);
1428 memcpy_far(0xA000, dest, ES, src, BH);
1430 release_font_access();
1436 biosfn_load_text_8_14_pat(u8 AL, u8 BL)
1439 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1441 for (i = 0; i < 0x100; i++) {
1443 void *dest = (void*)(blockaddr + i * 32);
1444 memcpy_far(0xA000, dest, 0xC000, &vgafont14[src], 14);
1446 release_font_access();
1452 biosfn_load_text_8_8_pat(u8 AL, u8 BL)
1455 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1457 for (i = 0; i < 0x100; i++) {
1459 void *dest = (void*)(blockaddr + i * 32);
1460 memcpy_far(0xA000, dest, 0xC000, &vgafont8[src], 8);
1462 release_font_access();
1467 // -------------------------------------------------------------------
1469 biosfn_set_text_block_specifier(struct bregs *regs)
1471 outw((regs->bl << 8) | 0x03, VGAREG_SEQU_ADDRESS);
1474 // -------------------------------------------------------------------
1476 biosfn_load_text_8_16_pat(u8 AL, u8 BL)
1479 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1481 for (i = 0; i < 0x100; i++) {
1483 void *dest = (void*)(blockaddr + i * 32);
1484 memcpy_far(0xA000, dest, 0xC000, &vgafont16[src], 16);
1486 release_font_access();
1491 // -------------------------------------------------------------------
1493 biosfn_get_font_info(u8 BH, u16 *ES, u16 *BP, u16 *CX, u16 *DX)
1497 u32 segoff = GET_IVT(0x1f).segoff;
1503 u32 segoff = GET_IVT(0x43).segoff;
1510 *BP = (u32)vgafont14;
1514 *BP = (u32)vgafont8;
1518 *BP = (u32)vgafont8 + 128 * 8;
1522 *BP = (u32)vgafont14alt;
1526 *BP = (u32)vgafont16;
1530 *BP = (u32)vgafont16alt;
1533 dprintf(1, "Get font info BH(%02x) was discarded\n", BH);
1536 // Set byte/char of on screen font
1537 *CX = GET_BDA(char_height) & 0xff;
1539 // Set Highest char row
1540 *DX = GET_BDA(video_rows);
1543 // -------------------------------------------------------------------
1545 biosfn_get_ega_info(struct bregs *regs)
1547 regs->cx = GET_BDA(video_switches) & 0x0f;
1548 regs->ax = GET_BDA(crtc_address);
1549 if (regs->ax == VGAREG_MDA_CRTC_ADDRESS)
1555 // -------------------------------------------------------------------
1557 biosfn_select_vert_res(struct bregs *regs)
1559 u8 mctl = GET_BDA(modeset_ctl);
1560 u8 vswt = GET_BDA(video_switches);
1565 mctl = (mctl & ~0x10) | 0x80;
1566 vswt = (vswt & ~0x0f) | 0x08;
1571 vswt = (vswt & ~0x0f) | 0x09;
1575 mctl = (mctl & ~0x80) | 0x10;
1576 vswt = (vswt & ~0x0f) | 0x09;
1579 dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
1582 SET_BDA(modeset_ctl, mctl);
1583 SET_BDA(video_switches, vswt);
1588 biosfn_enable_default_palette_loading(struct bregs *regs)
1590 u8 v = (regs->al & 0x01) << 3;
1591 u8 mctl = GET_BDA(video_ctl) & ~0x08;
1592 SET_BDA(video_ctl, mctl | v);
1597 biosfn_enable_video_addressing(struct bregs *regs)
1599 u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
1600 u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02;
1601 outb(v | v2, VGAREG_WRITE_MISC_OUTPUT);
1607 biosfn_enable_grayscale_summing(struct bregs *regs)
1609 u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
1610 u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
1611 SET_BDA(modeset_ctl, v | v2);
1616 biosfn_enable_cursor_emulation(struct bregs *regs)
1618 u8 v = (regs->al & 0x01) ^ 0x01;
1619 u8 v2 = GET_BDA(modeset_ctl) & ~0x01;
1620 SET_BDA(modeset_ctl, v | v2);
1624 // -------------------------------------------------------------------
1626 biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
1627 u16 seg, u8 *offset_far)
1629 // Read curs info for the page
1631 biosfn_get_cursor_pos(page, &dummy, &oldcurs);
1633 // if row=0xff special case : use current cursor position
1635 col = oldcurs & 0x00ff;
1636 row = (oldcurs & 0xff00) >> 8;
1642 biosfn_set_cursor_pos(page, newcurs);
1644 while (count-- != 0) {
1645 u8 car = GET_FARVAR(seg, *offset_far);
1647 if ((flag & 0x02) != 0) {
1648 attr = GET_FARVAR(seg, *offset_far);
1652 biosfn_write_teletype(car, page, attr, WITH_ATTR);
1655 // Set back curs pos
1656 if ((flag & 0x01) == 0)
1657 biosfn_set_cursor_pos(page, oldcurs);
1660 // -------------------------------------------------------------------
1662 biosfn_read_display_code(struct bregs *regs)
1664 regs->bx = GET_BDA(dcc_index);
1669 biosfn_set_display_code(struct bregs *regs)
1671 SET_BDA(dcc_index, regs->bl);
1672 dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
1676 // -------------------------------------------------------------------
1678 biosfn_read_state_info(u16 BX, u16 ES, u16 DI)
1680 // Address of static functionality table
1681 SET_FARVAR(ES, *(u16*)(DI + 0x00), (u32)static_functionality);
1682 SET_FARVAR(ES, *(u16*)(DI + 0x02), 0xC000);
1684 // Hard coded copy from BIOS area. Should it be cleaner ?
1685 memcpy_far(ES, (void*)(DI + 0x04), SEG_BDA, (void*)0x49, 30);
1686 memcpy_far(ES, (void*)(DI + 0x22), SEG_BDA, (void*)0x84, 3);
1688 SET_FARVAR(ES, *(u8*)(DI + 0x25), GET_BDA(dcc_index));
1689 SET_FARVAR(ES, *(u8*)(DI + 0x26), 0);
1690 SET_FARVAR(ES, *(u8*)(DI + 0x27), 16);
1691 SET_FARVAR(ES, *(u8*)(DI + 0x28), 0);
1692 SET_FARVAR(ES, *(u8*)(DI + 0x29), 8);
1693 SET_FARVAR(ES, *(u8*)(DI + 0x2a), 2);
1694 SET_FARVAR(ES, *(u8*)(DI + 0x2b), 0);
1695 SET_FARVAR(ES, *(u8*)(DI + 0x2c), 0);
1696 SET_FARVAR(ES, *(u8*)(DI + 0x31), 3);
1697 SET_FARVAR(ES, *(u8*)(DI + 0x32), 0);
1699 memset_far(ES, (void*)(DI + 0x33), 0, 13);
1702 // -------------------------------------------------------------------
1703 // -------------------------------------------------------------------
1705 biosfn_read_video_state_size(u16 CX)
1711 size += (5 + 8 + 5) * 2 + 6;
1713 size += 3 + 256 * 3 + 1;
1718 biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
1720 u16 crtc_addr = GET_BDA(crtc_address);
1722 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_ADDRESS));
1724 SET_FARVAR(ES, *(u8*)(BX+0), inb(crtc_addr));
1726 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_ADDRESS));
1728 inb(VGAREG_ACTL_RESET);
1729 u16 ar_index = inb(VGAREG_ACTL_ADDRESS);
1730 SET_FARVAR(ES, *(u8*)(BX+0), ar_index);
1732 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_READ_FEATURE_CTL));
1736 for (i = 1; i <= 4; i++) {
1737 outb(i, VGAREG_SEQU_ADDRESS);
1738 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
1741 outb(0, VGAREG_SEQU_ADDRESS);
1742 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
1745 for (i = 0; i <= 0x18; i++) {
1747 SET_FARVAR(ES, *(u8*)(BX+0), inb(crtc_addr + 1));
1751 for (i = 0; i <= 0x13; i++) {
1752 inb(VGAREG_ACTL_RESET);
1753 outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
1754 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_ACTL_READ_DATA));
1757 inb(VGAREG_ACTL_RESET);
1759 for (i = 0; i <= 8; i++) {
1760 outb(i, VGAREG_GRDC_ADDRESS);
1761 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_DATA));
1765 SET_FARVAR(ES, *(u16*)(BX+0), crtc_addr);
1768 /* XXX: read plane latches */
1769 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1771 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1773 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1775 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1779 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_mode));
1781 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_cols));
1783 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_pagesize));
1785 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(crtc_address));
1787 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_rows));
1789 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(char_height));
1791 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_ctl));
1793 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_switches));
1795 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(modeset_ctl));
1797 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_type));
1800 for (i = 0; i < 8; i++) {
1801 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_pos[i]));
1804 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_pagestart));
1806 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_page));
1809 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4)));
1811 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4 + 2)));
1813 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4)));
1815 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4 + 2)));
1819 /* XXX: check this */
1820 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_STATE));
1821 BX++; /* read/write mode dac */
1822 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_WRITE_ADDRESS));
1823 BX++; /* pix address */
1824 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_PEL_MASK));
1826 // Set the whole dac always, from 0
1827 outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
1829 for (i = 0; i < 256 * 3; i++) {
1830 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_DATA));
1833 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1834 BX++; /* color select register */
1840 biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
1843 // Reset Attribute Ctl flip-flop
1844 inb(VGAREG_ACTL_RESET);
1846 u16 crtc_addr = GET_FARVAR(ES, *(u16*)(BX + 0x40));
1851 for (i = 1; i <= 4; i++) {
1852 outb(i, VGAREG_SEQU_ADDRESS);
1853 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
1856 outb(0, VGAREG_SEQU_ADDRESS);
1857 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
1860 // Disable CRTC write protection
1861 outw(0x0011, crtc_addr);
1863 for (i = 0; i <= 0x18; i++) {
1866 outb(GET_FARVAR(ES, *(u8*)(BX+0)), crtc_addr + 1);
1870 // select crtc base address
1871 u16 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
1872 if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS)
1874 outb(v, VGAREG_WRITE_MISC_OUTPUT);
1876 // enable write protection if needed
1877 outb(0x11, crtc_addr);
1878 outb(GET_FARVAR(ES, *(u8*)(BX - 0x18 + 0x11)), crtc_addr + 1);
1880 // Set Attribute Ctl
1881 u16 ar_index = GET_FARVAR(ES, *(u8*)(addr1 + 0x03));
1882 inb(VGAREG_ACTL_RESET);
1883 for (i = 0; i <= 0x13; i++) {
1884 outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
1885 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_ACTL_WRITE_DATA);
1888 outb(ar_index, VGAREG_ACTL_ADDRESS);
1889 inb(VGAREG_ACTL_RESET);
1891 for (i = 0; i <= 8; i++) {
1892 outb(i, VGAREG_GRDC_ADDRESS);
1893 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_GRDC_DATA);
1896 BX += 2; /* crtc_addr */
1897 BX += 4; /* plane latches */
1899 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), VGAREG_SEQU_ADDRESS);
1901 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), crtc_addr);
1903 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), VGAREG_GRDC_ADDRESS);
1906 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), crtc_addr - 0x4 + 0xa);
1910 SET_BDA(video_mode, GET_FARVAR(ES, *(u8*)(BX+0)));
1912 SET_BDA(video_cols, GET_FARVAR(ES, *(u16*)(BX+0)));
1914 SET_BDA(video_pagesize, GET_FARVAR(ES, *(u16*)(BX+0)));
1916 SET_BDA(crtc_address, GET_FARVAR(ES, *(u16*)(BX+0)));
1918 SET_BDA(video_rows, GET_FARVAR(ES, *(u8*)(BX+0)));
1920 SET_BDA(char_height, GET_FARVAR(ES, *(u16*)(BX+0)));
1922 SET_BDA(video_ctl, GET_FARVAR(ES, *(u8*)(BX+0)));
1924 SET_BDA(video_switches, GET_FARVAR(ES, *(u8*)(BX+0)));
1926 SET_BDA(modeset_ctl, GET_FARVAR(ES, *(u8*)(BX+0)));
1928 SET_BDA(cursor_type, GET_FARVAR(ES, *(u16*)(BX+0)));
1931 for (i = 0; i < 8; i++) {
1932 SET_BDA(cursor_pos[i], GET_FARVAR(ES, *(u16*)(BX+0)));
1935 SET_BDA(video_pagestart, GET_FARVAR(ES, *(u16*)(BX+0)));
1937 SET_BDA(video_page, GET_FARVAR(ES, *(u8*)(BX+0)));
1940 SET_IVT(0x1f, GET_FARVAR(ES, *(u16*)(BX+2)), GET_FARVAR(ES, *(u16*)(BX+0)));
1942 SET_IVT(0x43, GET_FARVAR(ES, *(u16*)(BX+2)), GET_FARVAR(ES, *(u16*)(BX+0)));
1947 u16 v = GET_FARVAR(ES, *(u8*)(BX+0));
1949 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_PEL_MASK);
1951 // Set the whole dac always, from 0
1952 outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
1954 for (i = 0; i < 256 * 3; i++) {
1955 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_DAC_DATA);
1959 outb(v, VGAREG_DAC_WRITE_ADDRESS);
1965 /****************************************************************
1966 * VGA int 10 handler
1967 ****************************************************************/
1970 handle_1000(struct bregs *regs)
1973 biosfn_set_video_mode(regs->al);
1974 switch(regs->al & 0x7F) {
1993 handle_1001(struct bregs *regs)
1995 biosfn_set_cursor_shape(regs->ch, regs->cl);
1999 handle_1002(struct bregs *regs)
2001 biosfn_set_cursor_pos(regs->bh, regs->dx);
2005 handle_1003(struct bregs *regs)
2007 biosfn_get_cursor_pos(regs->bh, ®s->cx, ®s->dx);
2010 // Read light pen pos (unimplemented)
2012 handle_1004(struct bregs *regs)
2015 regs->ax = regs->bx = regs->cx = regs->dx = 0;
2019 handle_1005(struct bregs *regs)
2021 biosfn_set_active_page(regs->al);
2025 handle_1006(struct bregs *regs)
2027 biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl
2032 handle_1007(struct bregs *regs)
2034 biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl
2035 , 0xFF, SCROLL_DOWN);
2039 handle_1008(struct bregs *regs)
2042 biosfn_read_char_attr(regs->bh, ®s->ax);
2046 handle_1009(struct bregs *regs)
2049 biosfn_write_char_attr(regs->al, regs->bh, regs->bl, regs->cx);
2053 handle_100a(struct bregs *regs)
2056 biosfn_write_char_only(regs->al, regs->bh, regs->bl, regs->cx);
2061 handle_100b00(struct bregs *regs)
2064 biosfn_set_border_color(regs);
2068 handle_100b01(struct bregs *regs)
2071 biosfn_set_palette(regs);
2075 handle_100bXX(struct bregs *regs)
2081 handle_100b(struct bregs *regs)
2084 case 0x00: handle_100b00(regs); break;
2085 case 0x01: handle_100b01(regs); break;
2086 default: handle_100bXX(regs); break;
2092 handle_100c(struct bregs *regs)
2095 biosfn_write_pixel(regs->bh, regs->al, regs->cx, regs->dx);
2099 handle_100d(struct bregs *regs)
2102 biosfn_read_pixel(regs->bh, regs->cx, regs->dx, ®s->ax);
2106 handle_100e(struct bregs *regs)
2108 // Ralf Brown Interrupt list is WRONG on bh(page)
2109 // We do output only on the current page !
2110 biosfn_write_teletype(regs->al, 0xff, regs->bl, NO_ATTR);
2114 handle_100f(struct bregs *regs)
2117 biosfn_get_video_mode(regs);
2122 handle_101000(struct bregs *regs)
2124 if (regs->bl > 0x14)
2126 biosfn_set_single_palette_reg(regs->bl, regs->bh);
2130 handle_101001(struct bregs *regs)
2133 biosfn_set_overscan_border_color(regs);
2137 handle_101002(struct bregs *regs)
2140 biosfn_set_all_palette_reg(regs);
2144 handle_101003(struct bregs *regs)
2147 biosfn_toggle_intensity(regs);
2151 handle_101007(struct bregs *regs)
2153 if (regs->bl > 0x14)
2155 regs->bh = biosfn_get_single_palette_reg(regs->bl);
2159 handle_101008(struct bregs *regs)
2162 biosfn_read_overscan_border_color(regs);
2166 handle_101009(struct bregs *regs)
2169 biosfn_get_all_palette_reg(regs);
2173 handle_101010(struct bregs *regs)
2176 biosfn_set_single_dac_reg(regs);
2180 handle_101012(struct bregs *regs)
2183 biosfn_set_all_dac_reg(regs);
2187 handle_101013(struct bregs *regs)
2190 biosfn_select_video_dac_color_page(regs);
2194 handle_101015(struct bregs *regs)
2197 biosfn_read_single_dac_reg(regs);
2201 handle_101017(struct bregs *regs)
2204 biosfn_read_all_dac_reg(regs);
2208 handle_101018(struct bregs *regs)
2211 biosfn_set_pel_mask(regs);
2215 handle_101019(struct bregs *regs)
2218 biosfn_read_pel_mask(regs);
2222 handle_10101a(struct bregs *regs)
2225 biosfn_read_video_dac_state(regs);
2229 handle_10101b(struct bregs *regs)
2231 biosfn_perform_gray_scale_summing(regs->bx, regs->cx);
2235 handle_1010XX(struct bregs *regs)
2241 handle_1010(struct bregs *regs)
2244 case 0x00: handle_101000(regs); break;
2245 case 0x01: handle_101001(regs); break;
2246 case 0x02: handle_101002(regs); break;
2247 case 0x03: handle_101003(regs); break;
2248 case 0x07: handle_101007(regs); break;
2249 case 0x08: handle_101008(regs); break;
2250 case 0x09: handle_101009(regs); break;
2251 case 0x10: handle_101010(regs); break;
2252 case 0x12: handle_101012(regs); break;
2253 case 0x13: handle_101013(regs); break;
2254 case 0x15: handle_101015(regs); break;
2255 case 0x17: handle_101017(regs); break;
2256 case 0x18: handle_101018(regs); break;
2257 case 0x19: handle_101019(regs); break;
2258 case 0x1a: handle_10101a(regs); break;
2259 case 0x1b: handle_10101b(regs); break;
2260 default: handle_1010XX(regs); break;
2266 handle_101100(struct bregs *regs)
2269 biosfn_load_text_user_pat(regs->al, regs->es, 0 // XXX - regs->bp
2270 , regs->cx, regs->dx, regs->bl, regs->bh);
2274 handle_101101(struct bregs *regs)
2277 biosfn_load_text_8_14_pat(regs->al, regs->bl);
2281 handle_101102(struct bregs *regs)
2284 biosfn_load_text_8_8_pat(regs->al, regs->bl);
2288 handle_101103(struct bregs *regs)
2291 biosfn_set_text_block_specifier(regs);
2295 handle_101104(struct bregs *regs)
2298 biosfn_load_text_8_16_pat(regs->al, regs->bl);
2302 handle_101110(struct bregs *regs)
2304 handle_101100(regs);
2308 handle_101111(struct bregs *regs)
2310 handle_101101(regs);
2314 handle_101112(struct bregs *regs)
2316 handle_101102(regs);
2320 handle_101114(struct bregs *regs)
2322 handle_101104(regs);
2326 handle_101130(struct bregs *regs)
2329 biosfn_get_font_info(regs->bh, ®s->es, 0 // ®s->bp
2330 , ®s->cx, ®s->dx);
2334 handle_1011XX(struct bregs *regs)
2340 handle_1011(struct bregs *regs)
2343 case 0x00: handle_101100(regs); break;
2344 case 0x01: handle_101101(regs); break;
2345 case 0x02: handle_101102(regs); break;
2346 case 0x03: handle_101103(regs); break;
2347 case 0x04: handle_101104(regs); break;
2348 case 0x10: handle_101110(regs); break;
2349 case 0x11: handle_101111(regs); break;
2350 case 0x12: handle_101112(regs); break;
2351 case 0x14: handle_101114(regs); break;
2352 case 0x30: handle_101130(regs); break;
2353 default: handle_1011XX(regs); break;
2359 handle_101210(struct bregs *regs)
2362 biosfn_get_ega_info(regs);
2366 handle_101230(struct bregs *regs)
2369 biosfn_select_vert_res(regs);
2373 handle_101231(struct bregs *regs)
2376 biosfn_enable_default_palette_loading(regs);
2380 handle_101232(struct bregs *regs)
2383 biosfn_enable_video_addressing(regs);
2387 handle_101233(struct bregs *regs)
2390 biosfn_enable_grayscale_summing(regs);
2394 handle_101234(struct bregs *regs)
2397 biosfn_enable_cursor_emulation(regs);
2401 handle_101235(struct bregs *regs)
2408 handle_101236(struct bregs *regs)
2415 handle_1012XX(struct bregs *regs)
2421 handle_1012(struct bregs *regs)
2424 case 0x10: handle_101210(regs); break;
2425 case 0x30: handle_101230(regs); break;
2426 case 0x31: handle_101231(regs); break;
2427 case 0x32: handle_101232(regs); break;
2428 case 0x33: handle_101233(regs); break;
2429 case 0x34: handle_101234(regs); break;
2430 case 0x35: handle_101235(regs); break;
2431 case 0x36: handle_101236(regs); break;
2432 default: handle_1012XX(regs); break;
2435 // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae
2440 handle_1013(struct bregs *regs)
2443 biosfn_write_string(regs->al, regs->bh, regs->bl, regs->cx
2444 , regs->dh, regs->dl, regs->es, 0); // regs->bp);
2449 handle_101a00(struct bregs *regs)
2452 biosfn_read_display_code(regs);
2456 handle_101a01(struct bregs *regs)
2459 biosfn_set_display_code(regs);
2463 handle_101aXX(struct bregs *regs)
2469 handle_101a(struct bregs *regs)
2472 case 0x00: handle_101a00(regs); break;
2473 case 0x01: handle_101a01(regs); break;
2474 default: handle_101aXX(regs); break;
2480 handle_101b(struct bregs *regs)
2483 biosfn_read_state_info(regs->bx, regs->es, regs->di);
2489 handle_101c00(struct bregs *regs)
2492 regs->bx = biosfn_read_video_state_size(regs->cx);
2496 handle_101c01(struct bregs *regs)
2499 biosfn_save_video_state(regs->cx, regs->es, regs->bx);
2503 handle_101c02(struct bregs *regs)
2506 biosfn_restore_video_state(regs->cx, regs->es, regs->bx);
2510 handle_101cXX(struct bregs *regs)
2516 handle_101c(struct bregs *regs)
2519 case 0x00: handle_101c00(regs); break;
2520 case 0x01: handle_101c01(regs); break;
2521 case 0x02: handle_101c02(regs); break;
2522 default: handle_101cXX(regs); break;
2528 handle_104f00(struct bregs *regs)
2530 // XXX - vbe_biosfn_return_controller_information(&AX,ES,DI);
2531 // XXX - OR cirrus_vesa_00h
2535 handle_104f01(struct bregs *regs)
2537 // XXX - vbe_biosfn_return_mode_information(&AX,CX,ES,DI);
2538 // XXX - OR cirrus_vesa_01h
2542 handle_104f02(struct bregs *regs)
2544 // XXX - vbe_biosfn_set_mode(&AX,BX,ES,DI);
2545 // XXX - OR cirrus_vesa_02h
2549 handle_104f03(struct bregs *regs)
2551 // XXX - vbe_biosfn_return_current_mode
2552 // XXX - OR cirrus_vesa_03h
2556 handle_104f04(struct bregs *regs)
2558 // XXX - vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
2562 handle_104f05(struct bregs *regs)
2564 // XXX - vbe_biosfn_display_window_control
2565 // XXX - OR cirrus_vesa_05h
2569 handle_104f06(struct bregs *regs)
2571 // XXX - vbe_biosfn_set_get_logical_scan_line_length
2572 // XXX - OR cirrus_vesa_06h
2576 handle_104f07(struct bregs *regs)
2578 // XXX - vbe_biosfn_set_get_display_start
2579 // XXX - OR cirrus_vesa_07h
2583 handle_104f08(struct bregs *regs)
2585 // XXX - vbe_biosfn_set_get_dac_palette_format
2589 handle_104f0a(struct bregs *regs)
2591 // XXX - vbe_biosfn_return_protected_mode_interface
2595 handle_104fXX(struct bregs *regs)
2602 handle_104f(struct bregs *regs)
2605 handle_104fXX(regs);
2609 // XXX - check vbe_has_vbe_display()?
2612 case 0x00: handle_104f00(regs); break;
2613 case 0x01: handle_104f01(regs); break;
2614 case 0x02: handle_104f02(regs); break;
2615 case 0x03: handle_104f03(regs); break;
2616 case 0x04: handle_104f04(regs); break;
2617 case 0x05: handle_104f05(regs); break;
2618 case 0x06: handle_104f06(regs); break;
2619 case 0x07: handle_104f07(regs); break;
2620 case 0x08: handle_104f08(regs); break;
2621 case 0x0a: handle_104f0a(regs); break;
2622 default: handle_104fXX(regs); break;
2628 handle_10XX(struct bregs *regs)
2633 // INT 10h Video Support Service Entry Point
2635 handle_10(struct bregs *regs)
2637 debug_enter(regs, DEBUG_VGA_10);
2639 case 0x00: handle_1000(regs); break;
2640 case 0x01: handle_1001(regs); break;
2641 case 0x02: handle_1002(regs); break;
2642 case 0x03: handle_1003(regs); break;
2643 case 0x04: handle_1004(regs); break;
2644 case 0x05: handle_1005(regs); break;
2645 case 0x06: handle_1006(regs); break;
2646 case 0x07: handle_1007(regs); break;
2647 case 0x08: handle_1008(regs); break;
2648 case 0x09: handle_1009(regs); break;
2649 case 0x0a: handle_100a(regs); break;
2650 case 0x0b: handle_100b(regs); break;
2651 case 0x0c: handle_100c(regs); break;
2652 case 0x0d: handle_100d(regs); break;
2653 case 0x0e: handle_100e(regs); break;
2654 case 0x0f: handle_100f(regs); break;
2655 case 0x10: handle_1010(regs); break;
2656 case 0x11: handle_1011(regs); break;
2657 case 0x12: handle_1012(regs); break;
2658 case 0x13: handle_1013(regs); break;
2659 case 0x1a: handle_101a(regs); break;
2660 case 0x1b: handle_101b(regs); break;
2661 case 0x1c: handle_101c(regs); break;
2662 case 0x4f: handle_104f(regs); break;
2663 default: handle_10XX(regs); break;
2668 /****************************************************************
2670 ****************************************************************/
2675 // init detected hardware BIOS Area
2676 // set 80x25 color (not clear from RBIL but usual)
2677 u16 eqf = GET_BDA(equipment_list_flags);
2678 SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20);
2680 // Just for the first int10 find its children
2682 // the default char height
2683 SET_BDA(char_height, 0x10);
2686 SET_BDA(video_ctl, 0x60);
2688 // Set the basic screen we have
2689 SET_BDA(video_switches, 0xf9);
2691 // Set the basic modeset options
2692 SET_BDA(modeset_ctl, 0x51);
2694 // Set the default MSR
2695 SET_BDA(video_msr, 0x09);
2701 // switch to color mode and enable CPU access 480 lines
2702 outb(0xc3, VGAREG_WRITE_MISC_OUTPUT);
2703 // more than 64k 3C4/04
2704 outb(0x04, VGAREG_SEQU_ADDRESS);
2705 outb(0x02, VGAREG_SEQU_DATA);
2709 vga_post(struct bregs *regs)
2711 debug_enter(regs, DEBUG_VGA_POST);
2719 extern void entry_10(void);
2720 SET_IVT(0x10, 0xC000, (u32)entry_10);
2725 // XXX - clear screen and display info
2728 SET_VGA(video_save_pointer_table[0], (u32)video_param_table);
2729 SET_VGA(video_save_pointer_table[1], 0xC000);
2732 extern u8 _rom_header_size, _rom_header_checksum;
2733 SET_VGA(_rom_header_checksum, 0);
2734 u8 sum = -checksum_far(0xC000, 0, _rom_header_size * 512);
2735 SET_VGA(_rom_header_checksum, sum);