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 // * eliminate unimplemented() calls
15 // * eliminate DEBUG defs
16 // * more syntax cleanups
17 // * refactor redundant code into sub-functions
18 // * See if there is a method to the in/out stuff that can be encapsulated.
19 // * remove "biosfn" prefixes
20 // * don't hardcode 0xc000
21 // * add defs for 0xa000/0xb800
22 // * verify all funcs static
24 // * separate code into separate files
25 // * extract hw code from bios interfaces
27 // * convert vbe/clext code
29 #include "bregs.h" // struct bregs
30 #include "biosvar.h" // GET_BDA
31 #include "util.h" // memset
32 #include "vgatables.h" // vga_modes
36 #define CONFIG_CIRRUS 0
39 #define DEBUG_VGA_POST 1
40 #define DEBUG_VGA_10 3
42 #define SET_VGA(var, val) SET_FARVAR(0xc000, (var), (val))
45 // ===================================================================
49 // ===================================================================
51 // -------------------------------------------------------------------
53 find_vga_entry(u8 mode)
56 for (i = 0; i <= MODE_MAX; i++)
57 if (GET_GLOBAL(vga_modes[i].svgamode) == mode)
63 call16_vgaint(u32 eax, u32 ebx)
76 memcpy16_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len)
78 memcpy_far(d_seg, d_far, s_seg, s_far, len);
82 // ===================================================================
86 // ===================================================================
88 // -------------------------------------------------------------------
90 biosfn_perform_gray_scale_summing(u16 start, u16 count)
96 inb(VGAREG_ACTL_RESET);
97 outb(0x00, VGAREG_ACTL_ADDRESS);
99 for (index = 0; index < count; index++) {
100 // set read address and switch to read mode
101 outb(start, VGAREG_DAC_READ_ADDRESS);
102 // get 6-bit wide RGB data values
103 r = inb(VGAREG_DAC_DATA);
104 g = inb(VGAREG_DAC_DATA);
105 b = inb(VGAREG_DAC_DATA);
107 // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
108 i = ((77 * r + 151 * g + 28 * b) + 0x80) >> 8;
113 // set write address and switch to write mode
114 outb(start, VGAREG_DAC_WRITE_ADDRESS);
115 // write new intensity value
116 outb(i & 0xff, VGAREG_DAC_DATA);
117 outb(i & 0xff, VGAREG_DAC_DATA);
118 outb(i & 0xff, VGAREG_DAC_DATA);
121 inb(VGAREG_ACTL_RESET);
122 outb(0x20, VGAREG_ACTL_ADDRESS);
125 // -------------------------------------------------------------------
127 biosfn_set_cursor_shape(u8 CH, u8 CL)
129 u16 cheight, curs, crtc_addr;
135 curs = (CH << 8) + CL;
136 SET_BDA(cursor_type, curs);
138 modeset_ctl = GET_BDA(modeset_ctl);
139 cheight = GET_BDA(char_height);
140 if ((modeset_ctl & 0x01) && (cheight > 8) && (CL < 8) && (CH < 0x20)) {
141 if (CL != (CH + 1)) {
142 CH = ((CH + 1) * cheight / 8) - 1;
144 CH = ((CL + 1) * cheight / 8) - 2;
146 CL = ((CL + 1) * cheight / 8) - 1;
148 // CTRC regs 0x0a and 0x0b
149 crtc_addr = GET_BDA(crtc_address);
150 outb(0x0a, crtc_addr);
151 outb(CH, crtc_addr + 1);
152 outb(0x0b, crtc_addr);
153 outb(CL, crtc_addr + 1);
156 // -------------------------------------------------------------------
158 biosfn_set_cursor_pos(u8 page, u16 cursor)
160 u8 xcurs, ycurs, current;
161 u16 nbcols, nbrows, address, crtc_addr;
163 // Should not happen...
168 SET_BDA(cursor_pos[page], cursor);
170 // Set the hardware cursor
171 current = GET_BDA(video_page);
172 if (page == current) {
173 // Get the dimensions
174 nbcols = GET_BDA(video_cols);
175 nbrows = GET_BDA(video_rows) + 1;
177 xcurs = cursor & 0x00ff;
178 ycurs = (cursor & 0xff00) >> 8;
180 // Calculate the address knowing nbcols nbrows and page num
182 SCREEN_IO_START(nbcols, nbrows, page) + xcurs + ycurs * nbcols;
184 // CRTC regs 0x0e and 0x0f
185 crtc_addr = GET_BDA(crtc_address);
186 outb(0x0e, crtc_addr);
187 outb((address & 0xff00) >> 8, crtc_addr + 1);
188 outb(0x0f, crtc_addr);
189 outb(address & 0x00ff, crtc_addr + 1);
193 // -------------------------------------------------------------------
195 biosfn_get_cursor_pos(u8 page, u16 *shape, u16 *pos)
203 // FIXME should handle VGA 14/16 lines
204 *shape = GET_BDA(cursor_type);
205 *pos = GET_BDA(cursor_pos[page]);
208 // -------------------------------------------------------------------
210 biosfn_set_active_page(u8 page)
212 u16 cursor, dummy, crtc_addr;
213 u16 nbcols, nbrows, address;
220 mode = GET_BDA(video_mode);
221 line = find_vga_entry(mode);
225 // Get pos curs pos for the right page
226 biosfn_get_cursor_pos(page, &dummy, &cursor);
228 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
229 // Get the dimensions
230 nbcols = GET_BDA(video_cols);
231 nbrows = GET_BDA(video_rows) + 1;
233 // Calculate the address knowing nbcols nbrows and page num
234 address = SCREEN_MEM_START(nbcols, nbrows, page);
235 SET_BDA(video_pagestart, address);
238 address = SCREEN_IO_START(nbcols, nbrows, page);
240 address = page * GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].slength);
243 // CRTC regs 0x0c and 0x0d
244 crtc_addr = GET_BDA(crtc_address);
245 outb(0x0c, crtc_addr);
246 outb((address & 0xff00) >> 8, crtc_addr + 1);
247 outb(0x0d, crtc_addr);
248 outb(address & 0x00ff, crtc_addr + 1);
250 // And change the BIOS page
251 SET_BDA(video_page, page);
253 dprintf(1, "Set active page %02x address %04x\n", page, address);
255 // Display the cursor, now the page is active
256 biosfn_set_cursor_pos(page, cursor);
260 biosfn_set_video_mode(u8 mode)
261 { // mode: Bit 7 is 1 if no clear screen
262 // Should we clear the screen ?
263 u8 noclearmem = mode & 0x80;
264 u8 line, mmask, *palette, vpti;
265 u16 i, twidth, theightm1, cheight;
266 u8 modeset_ctl, video_ctl, vga_switches;
269 cirrus_set_video_mode(mode);
272 if (vbe_has_vbe_display())
273 dispi_set_enable(VBE_DISPI_DISABLED);
279 // find the entry in the video modes
280 line = find_vga_entry(mode);
282 dprintf(1, "mode search %02x found line %02x\n", mode, line);
287 vpti = GET_GLOBAL(line_to_vpti[line]);
288 twidth = GET_GLOBAL(video_param_table[vpti].twidth);
289 theightm1 = GET_GLOBAL(video_param_table[vpti].theightm1);
290 cheight = GET_GLOBAL(video_param_table[vpti].cheight);
292 // Read the bios vga control
293 video_ctl = GET_BDA(video_ctl);
295 // Read the bios vga switches
296 vga_switches = GET_BDA(video_switches);
298 // Read the bios mode set control
299 modeset_ctl = GET_BDA(modeset_ctl);
301 // Then we know the number of lines
304 // if palette loading (bit 3 of modeset ctl = 0)
305 if ((modeset_ctl & 0x08) == 0) { // Set the PEL mask
306 outb(GET_GLOBAL(vga_modes[line].pelmask), VGAREG_PEL_MASK);
308 // Set the whole dac always, from 0
309 outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
311 // From which palette
312 switch (GET_GLOBAL(vga_modes[line].dacmodel)) {
327 // Always 256*3 values
328 for (i = 0; i < 0x0100; i++) {
329 if (i <= GET_GLOBAL(dac_regs[GET_GLOBAL(vga_modes[line].dacmodel)])) {
330 outb(GET_GLOBAL(palette[(i * 3) + 0]), VGAREG_DAC_DATA);
331 outb(GET_GLOBAL(palette[(i * 3) + 1]), VGAREG_DAC_DATA);
332 outb(GET_GLOBAL(palette[(i * 3) + 2]), VGAREG_DAC_DATA);
334 outb(0, VGAREG_DAC_DATA);
335 outb(0, VGAREG_DAC_DATA);
336 outb(0, VGAREG_DAC_DATA);
339 if ((modeset_ctl & 0x02) == 0x02)
340 biosfn_perform_gray_scale_summing(0x00, 0x100);
342 // Reset Attribute Ctl flip-flop
343 inb(VGAREG_ACTL_RESET);
346 for (i = 0; i <= 0x13; i++) {
347 outb(i, VGAREG_ACTL_ADDRESS);
348 outb(GET_GLOBAL(video_param_table[vpti].actl_regs[i])
349 , VGAREG_ACTL_WRITE_DATA);
351 outb(0x14, VGAREG_ACTL_ADDRESS);
352 outb(0x00, VGAREG_ACTL_WRITE_DATA);
355 outb(0, VGAREG_SEQU_ADDRESS);
356 outb(0x03, VGAREG_SEQU_DATA);
357 for (i = 1; i <= 4; i++) {
358 outb(i, VGAREG_SEQU_ADDRESS);
359 outb(GET_GLOBAL(video_param_table[vpti].sequ_regs[i - 1])
364 for (i = 0; i <= 8; i++) {
365 outb(i, VGAREG_GRDC_ADDRESS);
366 outb(GET_GLOBAL(video_param_table[vpti].grdc_regs[i])
370 // Set CRTC address VGA or MDA
371 u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
372 if (GET_GLOBAL(vga_modes[line].memmodel) == MTEXT)
373 crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
375 // Disable CRTC write protection
376 outw(0x0011, crtc_addr);
378 for (i = 0; i <= 0x18; i++) {
380 outb(GET_GLOBAL(video_param_table[vpti].crtc_regs[i]), crtc_addr + 1);
383 // Set the misc register
384 outb(GET_GLOBAL(video_param_table[vpti].miscreg), VGAREG_WRITE_MISC_OUTPUT);
387 outb(0x20, VGAREG_ACTL_ADDRESS);
388 inb(VGAREG_ACTL_RESET);
390 if (noclearmem == 0x00) {
391 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
392 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
393 , 0, 0x0720, 32*1024);
396 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
397 , 0, 0x0000, 32*1024);
399 outb(0x02, VGAREG_SEQU_ADDRESS);
400 mmask = inb(VGAREG_SEQU_DATA);
401 outb(0x0f, VGAREG_SEQU_DATA); // all planes
402 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
403 , 0, 0x0000, 64*1024);
404 outb(mmask, VGAREG_SEQU_DATA);
409 SET_BDA(video_mode, mode);
410 SET_BDA(video_cols, twidth);
411 SET_BDA(video_pagesize, GET_GLOBAL(video_param_table[vpti].slength));
412 SET_BDA(crtc_address, crtc_addr);
413 SET_BDA(video_rows, theightm1);
414 SET_BDA(char_height, cheight);
415 SET_BDA(video_ctl, (0x60 | noclearmem));
416 SET_BDA(video_switches, 0xF9);
417 SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f);
419 // FIXME We nearly have the good tables. to be reworked
420 SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now
421 SET_BDA(video_savetable_ptr, (u32)video_save_pointer_table);
422 SET_BDA(video_savetable_seg, 0xc000);
425 SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
426 SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
429 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
430 biosfn_set_cursor_shape(0x06, 0x07);
431 // Set cursor pos for page 0..7
432 for (i = 0; i < 8; i++)
433 biosfn_set_cursor_pos(i, 0x0000);
436 biosfn_set_active_page(0x00);
438 // Write the fonts in memory
439 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
440 call16_vgaint(0x1104, 0);
441 call16_vgaint(0x1103, 0);
443 // Set the ints 0x1F and 0x43
444 SET_IVT(0x1f, 0xC000, (u32)&vgafont8[128 * 8]);
448 SET_IVT(0x43, 0xC000, (u32)vgafont8);
451 SET_IVT(0x43, 0xC000, (u32)vgafont14);
454 SET_IVT(0x43, 0xC000, (u32)vgafont16);
459 // -------------------------------------------------------------------
461 vgamem_copy_pl4(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
464 u16 src = ysrc * cheight * nbcols + xstart;
465 u16 dest = ydest * cheight * nbcols + xstart;
466 outw(0x0105, VGAREG_GRDC_ADDRESS);
468 for (i = 0; i < cheight; i++)
469 memcpy_far(0xa000, (void*)(dest + i * nbcols)
470 , 0xa000, (void*)(src + i * nbcols), cols);
471 outw(0x0005, VGAREG_GRDC_ADDRESS);
474 // -------------------------------------------------------------------
476 vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
479 u16 dest = ystart * cheight * nbcols + xstart;
480 outw(0x0205, VGAREG_GRDC_ADDRESS);
482 for (i = 0; i < cheight; i++)
483 memset_far(0xa000, (void*)(dest + i * nbcols), attr, cols);
484 outw(0x0005, VGAREG_GRDC_ADDRESS);
487 // -------------------------------------------------------------------
489 vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
492 u16 src = ((ysrc * cheight * nbcols) >> 1) + xstart;
493 u16 dest = ((ydest * cheight * nbcols) >> 1) + xstart;
495 for (i = 0; i < cheight; i++)
497 memcpy_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
498 , 0xb800, (void*)(0x2000 + src + (i >> 1) * nbcols)
501 memcpy_far(0xb800, (void*)(dest + (i >> 1) * nbcols)
502 , 0xb800, (void*)(src + (i >> 1) * nbcols), cols);
505 // -------------------------------------------------------------------
507 vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
510 u16 dest = ((ystart * cheight * nbcols) >> 1) + xstart;
512 for (i = 0; i < cheight; i++)
514 memset_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
517 memset_far(0xb800, (void*)(dest + (i >> 1) * nbcols), attr, cols);
520 // -------------------------------------------------------------------
522 biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page,
525 // page == 0xFF if current
527 u8 mode, line, cheight, bpp, cols;
528 u16 nbcols, nbrows, i;
536 mode = GET_BDA(video_mode);
537 line = find_vga_entry(mode);
541 // Get the dimensions
542 nbrows = GET_BDA(video_rows) + 1;
543 nbcols = GET_BDA(video_cols);
545 // Get the current page
547 page = GET_BDA(video_page);
553 if (nblines > nbrows)
555 cols = clr - cul + 1;
557 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
558 // Compute the address
559 void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page));
560 dprintf(3, "Scroll, address %p (%d %d %02x)\n"
561 , address, nbrows, nbcols, page);
563 if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
564 && clr == nbcols - 1) {
565 memset16_far(GET_GLOBAL(vga_modes[line].sstart), address
566 , (u16)attr * 0x100 + ' ', nbrows * nbcols * 2);
567 } else { // if Scroll up
568 if (dir == SCROLL_UP) {
569 for (i = rul; i <= rlr; i++) {
570 if ((i + nblines > rlr) || (nblines == 0))
571 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
572 , address + (i * nbcols + cul) * 2
573 , (u16)attr * 0x100 + ' ', cols * 2);
575 memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
576 , address + (i * nbcols + cul) * 2
577 , GET_GLOBAL(vga_modes[line].sstart)
578 , (void*)(((i + nblines) * nbcols + cul) * 2)
582 for (i = rlr; i >= rul; i--) {
583 if ((i < rul + nblines) || (nblines == 0))
584 memset16_far(GET_GLOBAL(vga_modes[line].sstart)
585 , address + (i * nbcols + cul) * 2
586 , (u16)attr * 0x100 + ' ', cols * 2);
588 memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
589 , address + (i * nbcols + cul) * 2
590 , GET_GLOBAL(vga_modes[line].sstart)
591 , (void*)(((i - nblines) * nbcols + cul) * 2)
599 // FIXME gfx mode not complete
600 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
601 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
604 if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
605 && clr == nbcols - 1) {
606 outw(0x0205, VGAREG_GRDC_ADDRESS);
607 memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
608 nbrows * nbcols * cheight);
609 outw(0x0005, VGAREG_GRDC_ADDRESS);
610 } else { // if Scroll up
611 if (dir == SCROLL_UP) {
612 for (i = rul; i <= rlr; i++) {
613 if ((i + nblines > rlr) || (nblines == 0))
614 vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
617 vgamem_copy_pl4(cul, i + nblines, i, cols,
621 for (i = rlr; i >= rul; i--) {
622 if ((i < rul + nblines) || (nblines == 0))
623 vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
626 vgamem_copy_pl4(cul, i, i - nblines, cols,
635 bpp = GET_GLOBAL(vga_modes[line].pixbits);
636 if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
637 && clr == nbcols - 1) {
638 memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
639 nbrows * nbcols * cheight * bpp);
647 if (dir == SCROLL_UP) {
648 for (i = rul; i <= rlr; i++) {
649 if ((i + nblines > rlr) || (nblines == 0))
650 vgamem_fill_cga(cul, i, cols, nbcols, cheight,
653 vgamem_copy_cga(cul, i + nblines, i, cols,
657 for (i = rlr; i >= rul; i--) {
658 if ((i < rul + nblines) || (nblines == 0))
659 vgamem_fill_cga(cul, i, cols, nbcols, cheight,
662 vgamem_copy_cga(cul, i, i - nblines, cols,
671 dprintf(1, "Scroll in graphics mode\n");
679 // -------------------------------------------------------------------
681 biosfn_read_char_attr(u8 page, u16 *car)
683 u8 xcurs, ycurs, mode, line;
688 mode = GET_BDA(video_mode);
689 line = find_vga_entry(mode);
693 // Get the cursor pos for the page
694 biosfn_get_cursor_pos(page, &dummy, &cursor);
695 xcurs = cursor & 0x00ff;
696 ycurs = (cursor & 0xff00) >> 8;
698 // Get the dimensions
699 nbrows = GET_BDA(video_rows) + 1;
700 nbcols = GET_BDA(video_cols);
702 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
703 // Compute the address
704 u16 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
705 + (xcurs + ycurs * nbcols) * 2);
707 *car = GET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address);
716 // -------------------------------------------------------------------
718 write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols,
735 addr = xcurs + ycurs * cheight * nbcols;
737 outw(0x0f02, VGAREG_SEQU_ADDRESS);
738 outw(0x0205, VGAREG_GRDC_ADDRESS);
740 outw(0x1803, VGAREG_GRDC_ADDRESS);
742 outw(0x0003, VGAREG_GRDC_ADDRESS);
743 for (i = 0; i < cheight; i++) {
744 u8 *dest = (void*)(addr + i * nbcols);
745 for (j = 0; j < 8; j++) {
747 outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
748 GET_FARVAR(0xa000, *dest);
749 if (GET_GLOBAL(fdata[src + i]) & mask)
750 SET_FARVAR(0xa000, *dest, attr & 0x0f);
752 SET_FARVAR(0xa000, *dest, 0x00);
755 outw(0xff08, VGAREG_GRDC_ADDRESS);
756 outw(0x0005, VGAREG_GRDC_ADDRESS);
757 outw(0x0003, VGAREG_GRDC_ADDRESS);
760 // -------------------------------------------------------------------
762 write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
764 u8 *fdata = vgafont8;
765 u16 addr = (xcurs * bpp) + ycurs * 320;
768 for (i = 0; i < 8; i++) {
769 u8 *dest = (void*)(addr + (i >> 1) * 80);
776 data = GET_FARVAR(0xb800, *dest);
778 for (j = 0; j < 8; j++) {
779 if (GET_GLOBAL(fdata[src + i]) & mask) {
781 data ^= (attr & 0x01) << (7 - j);
783 data |= (attr & 0x01) << (7 - j);
787 SET_FARVAR(0xb800, *dest, data);
792 data = GET_FARVAR(0xb800, *dest);
794 for (j = 0; j < 4; j++) {
795 if (GET_GLOBAL(fdata[src + i]) & mask) {
797 data ^= (attr & 0x03) << ((3 - j) * 2);
799 data |= (attr & 0x03) << ((3 - j) * 2);
803 SET_FARVAR(0xb800, *dest, data);
810 // -------------------------------------------------------------------
812 write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols)
814 u8 *fdata = vgafont8;
815 u16 addr = xcurs * 8 + ycurs * nbcols * 64;
818 for (i = 0; i < 8; i++) {
819 u8 *dest = (void*)(addr + i * nbcols * 8);
822 for (j = 0; j < 8; j++) {
824 if (GET_GLOBAL(fdata[src + i]) & mask)
826 SET_FARVAR(0xa000, dest[j], data);
832 // -------------------------------------------------------------------
834 biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count)
836 u8 cheight, xcurs, ycurs, mode, line, bpp;
841 mode = GET_BDA(video_mode);
842 line = find_vga_entry(mode);
846 // Get the cursor pos for the page
847 biosfn_get_cursor_pos(page, &dummy, &cursor);
848 xcurs = cursor & 0x00ff;
849 ycurs = (cursor & 0xff00) >> 8;
851 // Get the dimensions
852 nbrows = GET_BDA(video_rows) + 1;
853 nbcols = GET_BDA(video_cols);
855 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
856 // Compute the address
857 void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
858 + (xcurs + ycurs * nbcols) * 2);
860 dummy = ((u16)attr << 8) + car;
861 memset16_far(GET_GLOBAL(vga_modes[line].sstart), address, dummy
864 // FIXME gfx mode not complete
865 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
866 bpp = GET_GLOBAL(vga_modes[line].pixbits);
867 while ((count-- > 0) && (xcurs < nbcols)) {
868 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
871 write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
875 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
878 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
890 // -------------------------------------------------------------------
892 biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count)
894 u8 cheight, xcurs, ycurs, mode, line, bpp;
899 mode = GET_BDA(video_mode);
900 line = find_vga_entry(mode);
904 // Get the cursor pos for the page
905 biosfn_get_cursor_pos(page, &dummy, &cursor);
906 xcurs = cursor & 0x00ff;
907 ycurs = (cursor & 0xff00) >> 8;
909 // Get the dimensions
910 nbrows = GET_BDA(video_rows) + 1;
911 nbcols = GET_BDA(video_cols);
913 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
914 // Compute the address
915 u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
916 + (xcurs + ycurs * nbcols) * 2);
917 while (count-- > 0) {
918 SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address, car);
922 // FIXME gfx mode not complete
923 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
924 bpp = GET_GLOBAL(vga_modes[line].pixbits);
925 while ((count-- > 0) && (xcurs < nbcols)) {
926 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
929 write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
933 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
936 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
950 // -------------------------------------------------------------------
952 biosfn_set_border_color(struct bregs *regs)
954 inb(VGAREG_ACTL_RESET);
955 outb(0x00, VGAREG_ACTL_ADDRESS);
956 u8 al = regs->bl & 0x0f;
959 outb(al, VGAREG_ACTL_WRITE_DATA);
960 u8 bl = regs->bl & 0x10;
963 for (i = 1; i < 4; i++) {
964 outb(i, VGAREG_ACTL_ADDRESS);
966 al = inb(VGAREG_ACTL_READ_DATA);
969 outb(al, VGAREG_ACTL_WRITE_DATA);
971 outb(0x20, VGAREG_ACTL_ADDRESS);
975 biosfn_set_palette(struct bregs *regs)
977 inb(VGAREG_ACTL_RESET);
978 u8 bl = regs->bl & 0x01;
980 for (i = 1; i < 4; i++) {
981 outb(i, VGAREG_ACTL_ADDRESS);
983 u8 al = inb(VGAREG_ACTL_READ_DATA);
986 outb(al, VGAREG_ACTL_WRITE_DATA);
988 outb(0x20, VGAREG_ACTL_ADDRESS);
991 // -------------------------------------------------------------------
993 biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX)
998 u8 mode = GET_BDA(video_mode);
999 u8 line = find_vga_entry(mode);
1002 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
1006 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
1009 addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
1010 mask = 0x80 >> (CX & 0x07);
1011 outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
1012 outw(0x0205, VGAREG_GRDC_ADDRESS);
1013 data = GET_FARVAR(0xa000, *addr);
1015 outw(0x1803, VGAREG_GRDC_ADDRESS);
1016 SET_FARVAR(0xa000, *addr, AL);
1017 outw(0xff08, VGAREG_GRDC_ADDRESS);
1018 outw(0x0005, VGAREG_GRDC_ADDRESS);
1019 outw(0x0003, VGAREG_GRDC_ADDRESS);
1022 if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
1023 addr = (void*)((CX >> 2) + (DX >> 1) * 80);
1025 addr = (void*)((CX >> 3) + (DX >> 1) * 80);
1028 data = GET_FARVAR(0xb800, *addr);
1029 if (GET_GLOBAL(vga_modes[line].pixbits) == 2) {
1030 attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
1031 mask = 0x03 << ((3 - (CX & 0x03)) * 2);
1033 attr = (AL & 0x01) << (7 - (CX & 0x07));
1034 mask = 0x01 << (7 - (CX & 0x07));
1042 SET_FARVAR(0xb800, *addr, data);
1045 addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
1046 SET_FARVAR(0xa000, *addr, AL);
1055 // -------------------------------------------------------------------
1057 biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
1059 u8 mode, line, mask, attr, data, i;
1062 mode = GET_BDA(video_mode);
1063 line = find_vga_entry(mode);
1066 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
1070 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
1073 addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
1074 mask = 0x80 >> (CX & 0x07);
1076 for (i = 0; i < 4; i++) {
1077 outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS);
1078 data = GET_FARVAR(0xa000, *addr) & mask;
1080 attr |= (0x01 << i);
1084 addr = (void*)((CX >> 2) + (DX >> 1) * 80);
1087 data = GET_FARVAR(0xb800, *addr);
1088 if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
1089 attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
1091 attr = (data >> (7 - (CX & 0x07))) & 0x01;
1094 addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
1095 attr = GET_FARVAR(0xa000, *addr);
1103 *AX = (*AX & 0xff00) | attr;
1106 // -------------------------------------------------------------------
1108 biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
1109 { // flag = WITH_ATTR / NO_ATTR
1110 u8 cheight, xcurs, ycurs, mode, line, bpp;
1114 // special case if page is 0xff, use current page
1116 page = GET_BDA(video_page);
1119 mode = GET_BDA(video_mode);
1120 line = find_vga_entry(mode);
1124 // Get the cursor pos for the page
1125 biosfn_get_cursor_pos(page, &dummy, &cursor);
1126 xcurs = cursor & 0x00ff;
1127 ycurs = (cursor & 0xff00) >> 8;
1129 // Get the dimensions
1130 nbrows = GET_BDA(video_rows) + 1;
1131 nbcols = GET_BDA(video_cols);
1153 biosfn_write_teletype(' ', page, attr, flag);
1154 biosfn_get_cursor_pos(page, &dummy, &cursor);
1155 xcurs = cursor & 0x00ff;
1156 ycurs = (cursor & 0xff00) >> 8;
1157 } while (xcurs % 8 == 0);
1162 if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
1163 // Compute the address
1164 u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
1165 + (xcurs + ycurs * nbcols) * 2);
1167 SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[0], car);
1168 if (flag == WITH_ATTR)
1169 SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[1], attr);
1171 // FIXME gfx mode not complete
1172 cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
1173 bpp = GET_GLOBAL(vga_modes[line].pixbits);
1174 switch (GET_GLOBAL(vga_modes[line].memmodel)) {
1177 write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
1181 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
1184 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
1195 // Do we need to wrap ?
1196 if (xcurs == nbcols) {
1200 // Do we need to scroll ?
1201 if (ycurs == nbrows) {
1202 if (GET_GLOBAL(vga_modes[line].class) == TEXT)
1203 biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
1206 biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, page,
1210 // Set the cursor for the page
1214 biosfn_set_cursor_pos(page, cursor);
1217 // -------------------------------------------------------------------
1219 biosfn_get_video_mode(struct bregs *regs)
1221 regs->bh = GET_BDA(video_page);
1222 regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
1223 regs->ah = GET_BDA(video_cols);
1226 // -------------------------------------------------------------------
1228 biosfn_set_overscan_border_color(struct bregs *regs)
1230 inb(VGAREG_ACTL_RESET);
1231 outb(0x11, VGAREG_ACTL_ADDRESS);
1232 outb(regs->bh, VGAREG_ACTL_WRITE_DATA);
1233 outb(0x20, VGAREG_ACTL_ADDRESS);
1236 // -------------------------------------------------------------------
1238 biosfn_set_all_palette_reg(struct bregs *regs)
1240 inb(VGAREG_ACTL_RESET);
1242 u8 *data = (u8*)(regs->dx + 0);
1244 for (i = 0; i < 0x10; i++) {
1245 outb(i, VGAREG_ACTL_ADDRESS);
1246 u8 val = GET_FARVAR(regs->es, *data);
1247 outb(val, VGAREG_ACTL_WRITE_DATA);
1250 outb(0x11, VGAREG_ACTL_ADDRESS);
1251 outb(GET_FARVAR(regs->es, *data), VGAREG_ACTL_WRITE_DATA);
1252 outb(0x20, VGAREG_ACTL_ADDRESS);
1255 // -------------------------------------------------------------------
1257 biosfn_toggle_intensity(struct bregs *regs)
1259 inb(VGAREG_ACTL_RESET);
1260 outb(0x10, VGAREG_ACTL_ADDRESS);
1261 u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3);
1262 outb(val, VGAREG_ACTL_WRITE_DATA);
1263 outb(0x20, VGAREG_ACTL_ADDRESS);
1266 // -------------------------------------------------------------------
1268 biosfn_set_single_palette_reg(u8 reg, u8 val)
1270 inb(VGAREG_ACTL_RESET);
1271 outb(reg, VGAREG_ACTL_ADDRESS);
1272 outb(val, VGAREG_ACTL_WRITE_DATA);
1273 outb(0x20, VGAREG_ACTL_ADDRESS);
1276 // -------------------------------------------------------------------
1278 biosfn_get_single_palette_reg(u8 reg)
1280 inb(VGAREG_ACTL_RESET);
1281 outb(reg, VGAREG_ACTL_ADDRESS);
1282 u8 v = inb(VGAREG_ACTL_READ_DATA);
1283 inb(VGAREG_ACTL_RESET);
1284 outb(0x20, VGAREG_ACTL_ADDRESS);
1288 // -------------------------------------------------------------------
1290 biosfn_read_overscan_border_color(struct bregs *regs)
1292 inb(VGAREG_ACTL_RESET);
1293 outb(0x11, VGAREG_ACTL_ADDRESS);
1294 regs->bh = inb(VGAREG_ACTL_READ_DATA);
1295 inb(VGAREG_ACTL_RESET);
1296 outb(0x20, VGAREG_ACTL_ADDRESS);
1299 // -------------------------------------------------------------------
1301 biosfn_get_all_palette_reg(struct bregs *regs)
1303 u8 *data = (u8*)(regs->dx + 0);
1305 for (i = 0; i < 0x10; i++) {
1306 inb(VGAREG_ACTL_RESET);
1307 outb(i, VGAREG_ACTL_ADDRESS);
1308 SET_FARVAR(regs->es, *data, inb(VGAREG_ACTL_READ_DATA));
1311 inb(VGAREG_ACTL_RESET);
1312 outb(0x11, VGAREG_ACTL_ADDRESS);
1313 SET_FARVAR(regs->es, *data, inb(VGAREG_ACTL_READ_DATA));
1314 inb(VGAREG_ACTL_RESET);
1315 outb(0x20, VGAREG_ACTL_ADDRESS);
1318 // -------------------------------------------------------------------
1320 biosfn_set_single_dac_reg(struct bregs *regs)
1322 outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
1323 outb(regs->dh, VGAREG_DAC_DATA);
1324 outb(regs->ch, VGAREG_DAC_DATA);
1325 outb(regs->cl, VGAREG_DAC_DATA);
1328 // -------------------------------------------------------------------
1330 biosfn_set_all_dac_reg(struct bregs *regs)
1332 outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
1333 u8 *data = (u8*)(regs->dx + 0);
1334 int count = regs->cx;
1336 outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
1338 outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
1340 outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
1346 // -------------------------------------------------------------------
1348 biosfn_select_video_dac_color_page(struct bregs *regs)
1350 inb(VGAREG_ACTL_RESET);
1351 outb(0x10, VGAREG_ACTL_ADDRESS);
1352 u8 val = inb(VGAREG_ACTL_READ_DATA);
1353 if (!(regs->bl & 0x01)) {
1354 val = (val & 0x7f) | (regs->bh << 7);
1355 outb(val, VGAREG_ACTL_WRITE_DATA);
1356 outb(0x20, VGAREG_ACTL_ADDRESS);
1359 inb(VGAREG_ACTL_RESET);
1360 outb(0x14, VGAREG_ACTL_ADDRESS);
1365 outb(bh, VGAREG_ACTL_WRITE_DATA);
1366 outb(0x20, VGAREG_ACTL_ADDRESS);
1369 // -------------------------------------------------------------------
1371 biosfn_read_single_dac_reg(struct bregs *regs)
1373 outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
1374 regs->dh = inb(VGAREG_DAC_DATA);
1375 regs->ch = inb(VGAREG_DAC_DATA);
1376 regs->cl = inb(VGAREG_DAC_DATA);
1379 // -------------------------------------------------------------------
1381 biosfn_read_all_dac_reg(struct bregs *regs)
1383 outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
1384 u8 *data = (u8*)(regs->dx + 0);
1385 int count = regs->cx;
1387 SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
1389 SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
1391 SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
1397 // -------------------------------------------------------------------
1399 biosfn_set_pel_mask(struct bregs *regs)
1401 outb(regs->bl, VGAREG_PEL_MASK);
1404 // -------------------------------------------------------------------
1406 biosfn_read_pel_mask(struct bregs *regs)
1408 regs->bl = inb(VGAREG_PEL_MASK);
1411 // -------------------------------------------------------------------
1413 biosfn_read_video_dac_state(struct bregs *regs)
1415 inb(VGAREG_ACTL_RESET);
1416 outb(0x10, VGAREG_ACTL_ADDRESS);
1417 u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7;
1419 inb(VGAREG_ACTL_RESET);
1420 outb(0x14, VGAREG_ACTL_ADDRESS);
1421 u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f;
1425 inb(VGAREG_ACTL_RESET);
1426 outb(0x20, VGAREG_ACTL_ADDRESS);
1432 // -------------------------------------------------------------------
1436 outw(0x0100, VGAREG_SEQU_ADDRESS);
1437 outw(0x0402, VGAREG_SEQU_ADDRESS);
1438 outw(0x0704, VGAREG_SEQU_ADDRESS);
1439 outw(0x0300, VGAREG_SEQU_ADDRESS);
1440 outw(0x0204, VGAREG_GRDC_ADDRESS);
1441 outw(0x0005, VGAREG_GRDC_ADDRESS);
1442 outw(0x0406, VGAREG_GRDC_ADDRESS);
1446 release_font_access()
1448 outw(0x0100, VGAREG_SEQU_ADDRESS);
1449 outw(0x0302, VGAREG_SEQU_ADDRESS);
1450 outw(0x0304, VGAREG_SEQU_ADDRESS);
1451 outw(0x0300, VGAREG_SEQU_ADDRESS);
1452 u16 v = inw(VGAREG_READ_MISC_OUTPUT);
1453 v = ((v & 0x01) << 10) | 0x0a06;
1454 outw(v, VGAREG_GRDC_ADDRESS);
1455 outw(0x0004, VGAREG_GRDC_ADDRESS);
1456 outw(0x1005, VGAREG_GRDC_ADDRESS);
1460 set_scan_lines(u8 lines)
1462 u16 crtc_addr, cols, vde;
1463 u8 crtc_r9, ovl, rows;
1465 crtc_addr = GET_BDA(crtc_address);
1466 outb(0x09, crtc_addr);
1467 crtc_r9 = inb(crtc_addr + 1);
1468 crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
1469 outb(crtc_r9, crtc_addr + 1);
1471 biosfn_set_cursor_shape(0x06, 0x07);
1473 biosfn_set_cursor_shape(lines - 4, lines - 3);
1474 SET_BDA(char_height, lines);
1475 outb(0x12, crtc_addr);
1476 vde = inb(crtc_addr + 1);
1477 outb(0x07, crtc_addr);
1478 ovl = inb(crtc_addr + 1);
1479 vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
1481 SET_BDA(video_rows, rows - 1);
1482 cols = GET_BDA(video_cols);
1483 SET_BDA(video_pagesize, rows * cols * 2);
1487 biosfn_load_text_user_pat(u8 AL, u16 ES, u16 BP, u16 CX, u16 DX, u8 BL,
1491 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1493 for (i = 0; i < CX; i++) {
1494 void *src = (void*)(BP + i * BH);
1495 void *dest = (void*)(blockaddr + (DX + i) * 32);
1496 memcpy_far(0xA000, dest, ES, src, BH);
1498 release_font_access();
1504 biosfn_load_text_8_14_pat(u8 AL, u8 BL)
1507 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1509 for (i = 0; i < 0x100; i++) {
1511 void *dest = (void*)(blockaddr + i * 32);
1512 memcpy_far(0xA000, dest, 0xC000, &vgafont14[src], 14);
1514 release_font_access();
1520 biosfn_load_text_8_8_pat(u8 AL, u8 BL)
1523 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1525 for (i = 0; i < 0x100; i++) {
1527 void *dest = (void*)(blockaddr + i * 32);
1528 memcpy_far(0xA000, dest, 0xC000, &vgafont8[src], 8);
1530 release_font_access();
1535 // -------------------------------------------------------------------
1537 biosfn_set_text_block_specifier(struct bregs *regs)
1539 outw((regs->bl << 8) | 0x03, VGAREG_SEQU_ADDRESS);
1542 // -------------------------------------------------------------------
1544 biosfn_load_text_8_16_pat(u8 AL, u8 BL)
1547 u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
1549 for (i = 0; i < 0x100; i++) {
1551 void *dest = (void*)(blockaddr + i * 32);
1552 memcpy_far(0xA000, dest, 0xC000, &vgafont16[src], 16);
1554 release_font_access();
1559 // -------------------------------------------------------------------
1561 biosfn_get_font_info(u8 BH, u16 *ES, u16 *BP, u16 *CX, u16 *DX)
1565 u32 segoff = GET_IVT(0x1f).segoff;
1571 u32 segoff = GET_IVT(0x43).segoff;
1578 *BP = (u32)vgafont14;
1582 *BP = (u32)vgafont8;
1586 *BP = (u32)vgafont8 + 128 * 8;
1590 *BP = (u32)vgafont14alt;
1594 *BP = (u32)vgafont16;
1598 *BP = (u32)vgafont16alt;
1601 dprintf(1, "Get font info BH(%02x) was discarded\n", BH);
1604 // Set byte/char of on screen font
1605 *CX = GET_BDA(char_height) & 0xff;
1607 // Set Highest char row
1608 *DX = GET_BDA(video_rows);
1611 // -------------------------------------------------------------------
1613 biosfn_get_ega_info(struct bregs *regs)
1615 regs->cx = GET_BDA(video_switches) & 0x0f;
1616 regs->ax = GET_BDA(crtc_address);
1617 if (regs->ax == VGAREG_MDA_CRTC_ADDRESS)
1623 // -------------------------------------------------------------------
1625 biosfn_select_vert_res(struct bregs *regs)
1627 u8 mctl = GET_BDA(modeset_ctl);
1628 u8 vswt = GET_BDA(video_switches);
1633 mctl = (mctl & ~0x10) | 0x80;
1634 vswt = (vswt & ~0x0f) | 0x08;
1639 vswt = (vswt & ~0x0f) | 0x09;
1643 mctl = (mctl & ~0x80) | 0x10;
1644 vswt = (vswt & ~0x0f) | 0x09;
1647 dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
1650 SET_BDA(modeset_ctl, mctl);
1651 SET_BDA(video_switches, vswt);
1656 biosfn_enable_default_palette_loading(struct bregs *regs)
1658 u8 v = (regs->al & 0x01) << 3;
1659 u8 mctl = GET_BDA(video_ctl) & ~0x08;
1660 SET_BDA(video_ctl, mctl | v);
1665 biosfn_enable_video_addressing(struct bregs *regs)
1667 u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
1668 u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02;
1669 outb(v | v2, VGAREG_WRITE_MISC_OUTPUT);
1675 biosfn_enable_grayscale_summing(struct bregs *regs)
1677 u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
1678 u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
1679 SET_BDA(modeset_ctl, v | v2);
1684 biosfn_enable_cursor_emulation(struct bregs *regs)
1686 u8 v = (regs->al & 0x01) ^ 0x01;
1687 u8 v2 = GET_BDA(modeset_ctl) & ~0x01;
1688 SET_BDA(modeset_ctl, v | v2);
1692 // -------------------------------------------------------------------
1694 biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
1695 u16 seg, u8 *offset)
1697 u16 newcurs, oldcurs, dummy;
1700 // Read curs info for the page
1701 biosfn_get_cursor_pos(page, &dummy, &oldcurs);
1703 // if row=0xff special case : use current cursor position
1705 col = oldcurs & 0x00ff;
1706 row = (oldcurs & 0xff00) >> 8;
1712 biosfn_set_cursor_pos(page, newcurs);
1714 while (count-- != 0) {
1715 car = GET_FARVAR(seg, *offset);
1717 if ((flag & 0x02) != 0) {
1718 attr = GET_FARVAR(seg, *offset);
1722 biosfn_write_teletype(car, page, attr, WITH_ATTR);
1725 // Set back curs pos
1726 if ((flag & 0x01) == 0)
1727 biosfn_set_cursor_pos(page, oldcurs);
1730 // -------------------------------------------------------------------
1732 biosfn_read_display_code(struct bregs *regs)
1734 regs->bx = GET_BDA(dcc_index);
1739 biosfn_set_display_code(struct bregs *regs)
1741 SET_BDA(dcc_index, regs->bl);
1742 dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
1746 // -------------------------------------------------------------------
1748 biosfn_read_state_info(u16 BX, u16 ES, u16 DI)
1750 // Address of static functionality table
1751 SET_FARVAR(ES, *(u16*)(DI + 0x00), (u32)static_functionality);
1752 SET_FARVAR(ES, *(u16*)(DI + 0x02), 0xC000);
1754 // Hard coded copy from BIOS area. Should it be cleaner ?
1755 memcpy_far(ES, (void*)(DI + 0x04), SEG_BDA, (void*)0x49, 30);
1756 memcpy_far(ES, (void*)(DI + 0x22), SEG_BDA, (void*)0x84, 3);
1758 SET_FARVAR(ES, *(u8*)(DI + 0x25), GET_BDA(dcc_index));
1759 SET_FARVAR(ES, *(u8*)(DI + 0x26), 0);
1760 SET_FARVAR(ES, *(u8*)(DI + 0x27), 16);
1761 SET_FARVAR(ES, *(u8*)(DI + 0x28), 0);
1762 SET_FARVAR(ES, *(u8*)(DI + 0x29), 8);
1763 SET_FARVAR(ES, *(u8*)(DI + 0x2a), 2);
1764 SET_FARVAR(ES, *(u8*)(DI + 0x2b), 0);
1765 SET_FARVAR(ES, *(u8*)(DI + 0x2c), 0);
1766 SET_FARVAR(ES, *(u8*)(DI + 0x31), 3);
1767 SET_FARVAR(ES, *(u8*)(DI + 0x32), 0);
1769 memset_far(ES, (void*)(DI + 0x33), 0, 13);
1772 // -------------------------------------------------------------------
1773 // -------------------------------------------------------------------
1775 biosfn_read_video_state_size(u16 CX)
1781 size += (5 + 8 + 5) * 2 + 6;
1783 size += 3 + 256 * 3 + 1;
1788 biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
1790 u16 i, crtc_addr, ar_index;
1792 crtc_addr = GET_BDA(crtc_address);
1794 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_ADDRESS));
1796 SET_FARVAR(ES, *(u8*)(BX+0), inb(crtc_addr));
1798 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_ADDRESS));
1800 inb(VGAREG_ACTL_RESET);
1801 ar_index = inb(VGAREG_ACTL_ADDRESS);
1802 SET_FARVAR(ES, *(u8*)(BX+0), ar_index);
1804 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_READ_FEATURE_CTL));
1807 for (i = 1; i <= 4; i++) {
1808 outb(i, VGAREG_SEQU_ADDRESS);
1809 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
1812 outb(0, VGAREG_SEQU_ADDRESS);
1813 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
1816 for (i = 0; i <= 0x18; i++) {
1818 SET_FARVAR(ES, *(u8*)(BX+0), inb(crtc_addr + 1));
1822 for (i = 0; i <= 0x13; i++) {
1823 inb(VGAREG_ACTL_RESET);
1824 outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
1825 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_ACTL_READ_DATA));
1828 inb(VGAREG_ACTL_RESET);
1830 for (i = 0; i <= 8; i++) {
1831 outb(i, VGAREG_GRDC_ADDRESS);
1832 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_DATA));
1836 SET_FARVAR(ES, *(u16*)(BX+0), crtc_addr);
1839 /* XXX: read plane latches */
1840 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1842 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1844 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1846 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1850 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_mode));
1852 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_cols));
1854 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_pagesize));
1856 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(crtc_address));
1858 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_rows));
1860 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(char_height));
1862 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_ctl));
1864 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_switches));
1866 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(modeset_ctl));
1868 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_type));
1870 for (i = 0; i < 8; i++) {
1871 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_pos[i]));
1874 SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_pagestart));
1876 SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_page));
1879 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4)));
1881 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4 + 2)));
1883 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4)));
1885 SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4 + 2)));
1889 /* XXX: check this */
1890 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_STATE));
1891 BX++; /* read/write mode dac */
1892 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_WRITE_ADDRESS));
1893 BX++; /* pix address */
1894 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_PEL_MASK));
1896 // Set the whole dac always, from 0
1897 outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
1898 for (i = 0; i < 256 * 3; i++) {
1899 SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_DATA));
1902 SET_FARVAR(ES, *(u8*)(BX+0), 0);
1903 BX++; /* color select register */
1909 biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
1911 u16 i, crtc_addr, v, addr1, ar_index;
1914 // Reset Attribute Ctl flip-flop
1915 inb(VGAREG_ACTL_RESET);
1917 crtc_addr = GET_FARVAR(ES, *(u16*)(BX + 0x40));
1921 for (i = 1; i <= 4; i++) {
1922 outb(i, VGAREG_SEQU_ADDRESS);
1923 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
1926 outb(0, VGAREG_SEQU_ADDRESS);
1927 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
1930 // Disable CRTC write protection
1931 outw(0x0011, crtc_addr);
1933 for (i = 0; i <= 0x18; i++) {
1936 outb(GET_FARVAR(ES, *(u8*)(BX+0)), crtc_addr + 1);
1940 // select crtc base address
1941 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
1942 if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS)
1944 outb(v, VGAREG_WRITE_MISC_OUTPUT);
1946 // enable write protection if needed
1947 outb(0x11, crtc_addr);
1948 outb(GET_FARVAR(ES, *(u8*)(BX - 0x18 + 0x11)), crtc_addr + 1);
1950 // Set Attribute Ctl
1951 ar_index = GET_FARVAR(ES, *(u8*)(addr1 + 0x03));
1952 inb(VGAREG_ACTL_RESET);
1953 for (i = 0; i <= 0x13; i++) {
1954 outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
1955 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_ACTL_WRITE_DATA);
1958 outb(ar_index, VGAREG_ACTL_ADDRESS);
1959 inb(VGAREG_ACTL_RESET);
1961 for (i = 0; i <= 8; i++) {
1962 outb(i, VGAREG_GRDC_ADDRESS);
1963 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_GRDC_DATA);
1966 BX += 2; /* crtc_addr */
1967 BX += 4; /* plane latches */
1969 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), VGAREG_SEQU_ADDRESS);
1971 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), crtc_addr);
1973 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), VGAREG_GRDC_ADDRESS);
1976 outb(GET_FARVAR(ES, *(u8*)(addr1+0)), crtc_addr - 0x4 + 0xa);
1980 SET_BDA(video_mode, GET_FARVAR(ES, *(u8*)(BX+0)));
1982 SET_BDA(video_cols, GET_FARVAR(ES, *(u16*)(BX+0)));
1984 SET_BDA(video_pagesize, GET_FARVAR(ES, *(u16*)(BX+0)));
1986 SET_BDA(crtc_address, GET_FARVAR(ES, *(u16*)(BX+0)));
1988 SET_BDA(video_rows, GET_FARVAR(ES, *(u8*)(BX+0)));
1990 SET_BDA(char_height, GET_FARVAR(ES, *(u16*)(BX+0)));
1992 SET_BDA(video_ctl, GET_FARVAR(ES, *(u8*)(BX+0)));
1994 SET_BDA(video_switches, GET_FARVAR(ES, *(u8*)(BX+0)));
1996 SET_BDA(modeset_ctl, GET_FARVAR(ES, *(u8*)(BX+0)));
1998 SET_BDA(cursor_type, GET_FARVAR(ES, *(u16*)(BX+0)));
2000 for (i = 0; i < 8; i++) {
2001 SET_BDA(cursor_pos[i], GET_FARVAR(ES, *(u16*)(BX+0)));
2004 SET_BDA(video_pagestart, GET_FARVAR(ES, *(u16*)(BX+0)));
2006 SET_BDA(video_page, GET_FARVAR(ES, *(u8*)(BX+0)));
2009 SET_IVT(0x1f, GET_FARVAR(ES, *(u16*)(BX+2)), GET_FARVAR(ES, *(u16*)(BX+0)));
2011 SET_IVT(0x43, GET_FARVAR(ES, *(u16*)(BX+2)), GET_FARVAR(ES, *(u16*)(BX+0)));
2016 v = GET_FARVAR(ES, *(u8*)(BX+0));
2018 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_PEL_MASK);
2020 // Set the whole dac always, from 0
2021 outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
2022 for (i = 0; i < 256 * 3; i++) {
2023 outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_DAC_DATA);
2027 outb(v, VGAREG_DAC_WRITE_ADDRESS);
2033 /****************************************************************
2034 * VGA int 10 handler
2035 ****************************************************************/
2038 handle_1000(struct bregs *regs)
2041 biosfn_set_video_mode(regs->al);
2042 switch(regs->al & 0x7F) {
2061 handle_1001(struct bregs *regs)
2063 biosfn_set_cursor_shape(regs->ch, regs->cl);
2067 handle_1002(struct bregs *regs)
2069 biosfn_set_cursor_pos(regs->bh, regs->dx);
2073 handle_1003(struct bregs *regs)
2075 biosfn_get_cursor_pos(regs->bh, ®s->cx, ®s->dx);
2078 // Read light pen pos (unimplemented)
2080 handle_1004(struct bregs *regs)
2083 regs->ax = regs->bx = regs->cx = regs->dx = 0;
2087 handle_1005(struct bregs *regs)
2089 biosfn_set_active_page(regs->al);
2093 handle_1006(struct bregs *regs)
2095 biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl
2100 handle_1007(struct bregs *regs)
2102 biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl
2103 , 0xFF, SCROLL_DOWN);
2107 handle_1008(struct bregs *regs)
2110 biosfn_read_char_attr(regs->bh, ®s->ax);
2114 handle_1009(struct bregs *regs)
2117 biosfn_write_char_attr(regs->al, regs->bh, regs->bl, regs->cx);
2121 handle_100a(struct bregs *regs)
2124 biosfn_write_char_only(regs->al, regs->bh, regs->bl, regs->cx);
2129 handle_100b00(struct bregs *regs)
2132 biosfn_set_border_color(regs);
2136 handle_100b01(struct bregs *regs)
2139 biosfn_set_palette(regs);
2143 handle_100bXX(struct bregs *regs)
2149 handle_100b(struct bregs *regs)
2152 case 0x00: handle_100b00(regs); break;
2153 case 0x01: handle_100b01(regs); break;
2154 default: handle_100bXX(regs); break;
2160 handle_100c(struct bregs *regs)
2163 biosfn_write_pixel(regs->bh, regs->al, regs->cx, regs->dx);
2167 handle_100d(struct bregs *regs)
2170 biosfn_read_pixel(regs->bh, regs->cx, regs->dx, ®s->ax);
2174 handle_100e(struct bregs *regs)
2176 // Ralf Brown Interrupt list is WRONG on bh(page)
2177 // We do output only on the current page !
2178 biosfn_write_teletype(regs->al, 0xff, regs->bl, NO_ATTR);
2182 handle_100f(struct bregs *regs)
2185 biosfn_get_video_mode(regs);
2190 handle_101000(struct bregs *regs)
2192 if (regs->bl > 0x14)
2194 biosfn_set_single_palette_reg(regs->bl, regs->bh);
2198 handle_101001(struct bregs *regs)
2201 biosfn_set_overscan_border_color(regs);
2205 handle_101002(struct bregs *regs)
2208 biosfn_set_all_palette_reg(regs);
2212 handle_101003(struct bregs *regs)
2215 biosfn_toggle_intensity(regs);
2219 handle_101007(struct bregs *regs)
2221 if (regs->bl > 0x14)
2223 regs->bh = biosfn_get_single_palette_reg(regs->bl);
2227 handle_101008(struct bregs *regs)
2230 biosfn_read_overscan_border_color(regs);
2234 handle_101009(struct bregs *regs)
2237 biosfn_get_all_palette_reg(regs);
2241 handle_101010(struct bregs *regs)
2244 biosfn_set_single_dac_reg(regs);
2248 handle_101012(struct bregs *regs)
2251 biosfn_set_all_dac_reg(regs);
2255 handle_101013(struct bregs *regs)
2258 biosfn_select_video_dac_color_page(regs);
2262 handle_101015(struct bregs *regs)
2265 biosfn_read_single_dac_reg(regs);
2269 handle_101017(struct bregs *regs)
2272 biosfn_read_all_dac_reg(regs);
2276 handle_101018(struct bregs *regs)
2279 biosfn_set_pel_mask(regs);
2283 handle_101019(struct bregs *regs)
2286 biosfn_read_pel_mask(regs);
2290 handle_10101a(struct bregs *regs)
2293 biosfn_read_video_dac_state(regs);
2297 handle_10101b(struct bregs *regs)
2299 biosfn_perform_gray_scale_summing(regs->bx, regs->cx);
2303 handle_1010XX(struct bregs *regs)
2309 handle_1010(struct bregs *regs)
2312 case 0x00: handle_101000(regs); break;
2313 case 0x01: handle_101001(regs); break;
2314 case 0x02: handle_101002(regs); break;
2315 case 0x03: handle_101003(regs); break;
2316 case 0x07: handle_101007(regs); break;
2317 case 0x08: handle_101008(regs); break;
2318 case 0x09: handle_101009(regs); break;
2319 case 0x10: handle_101010(regs); break;
2320 case 0x12: handle_101012(regs); break;
2321 case 0x13: handle_101013(regs); break;
2322 case 0x15: handle_101015(regs); break;
2323 case 0x17: handle_101017(regs); break;
2324 case 0x18: handle_101018(regs); break;
2325 case 0x19: handle_101019(regs); break;
2326 case 0x1a: handle_10101a(regs); break;
2327 case 0x1b: handle_10101b(regs); break;
2328 default: handle_1010XX(regs); break;
2334 handle_101100(struct bregs *regs)
2337 biosfn_load_text_user_pat(regs->al, regs->es, 0 // XXX - regs->bp
2338 , regs->cx, regs->dx, regs->bl, regs->bh);
2342 handle_101101(struct bregs *regs)
2345 biosfn_load_text_8_14_pat(regs->al, regs->bl);
2349 handle_101102(struct bregs *regs)
2352 biosfn_load_text_8_8_pat(regs->al, regs->bl);
2356 handle_101103(struct bregs *regs)
2359 biosfn_set_text_block_specifier(regs);
2363 handle_101104(struct bregs *regs)
2366 biosfn_load_text_8_16_pat(regs->al, regs->bl);
2370 handle_101110(struct bregs *regs)
2372 handle_101100(regs);
2376 handle_101111(struct bregs *regs)
2378 handle_101101(regs);
2382 handle_101112(struct bregs *regs)
2384 handle_101102(regs);
2388 handle_101114(struct bregs *regs)
2390 handle_101104(regs);
2394 handle_101130(struct bregs *regs)
2397 biosfn_get_font_info(regs->bh, ®s->es, 0 // ®s->bp
2398 , ®s->cx, ®s->dx);
2402 handle_1011XX(struct bregs *regs)
2408 handle_1011(struct bregs *regs)
2411 case 0x00: handle_101100(regs); break;
2412 case 0x01: handle_101101(regs); break;
2413 case 0x02: handle_101102(regs); break;
2414 case 0x03: handle_101103(regs); break;
2415 case 0x04: handle_101104(regs); break;
2416 case 0x10: handle_101110(regs); break;
2417 case 0x11: handle_101111(regs); break;
2418 case 0x12: handle_101112(regs); break;
2419 case 0x14: handle_101114(regs); break;
2420 case 0x30: handle_101130(regs); break;
2421 default: handle_1011XX(regs); break;
2427 handle_101210(struct bregs *regs)
2430 biosfn_get_ega_info(regs);
2434 handle_101230(struct bregs *regs)
2437 biosfn_select_vert_res(regs);
2441 handle_101231(struct bregs *regs)
2444 biosfn_enable_default_palette_loading(regs);
2448 handle_101232(struct bregs *regs)
2451 biosfn_enable_video_addressing(regs);
2455 handle_101233(struct bregs *regs)
2458 biosfn_enable_grayscale_summing(regs);
2462 handle_101234(struct bregs *regs)
2465 biosfn_enable_cursor_emulation(regs);
2469 handle_101235(struct bregs *regs)
2476 handle_101236(struct bregs *regs)
2483 handle_1012XX(struct bregs *regs)
2489 handle_1012(struct bregs *regs)
2492 case 0x10: handle_101210(regs); break;
2493 case 0x30: handle_101230(regs); break;
2494 case 0x31: handle_101231(regs); break;
2495 case 0x32: handle_101232(regs); break;
2496 case 0x33: handle_101233(regs); break;
2497 case 0x34: handle_101234(regs); break;
2498 case 0x35: handle_101235(regs); break;
2499 case 0x36: handle_101236(regs); break;
2500 default: handle_1012XX(regs); break;
2503 // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae
2508 handle_1013(struct bregs *regs)
2511 biosfn_write_string(regs->al, regs->bh, regs->bl, regs->cx
2512 , regs->dh, regs->dl, regs->es, 0); // regs->bp);
2517 handle_101a00(struct bregs *regs)
2520 biosfn_read_display_code(regs);
2524 handle_101a01(struct bregs *regs)
2527 biosfn_set_display_code(regs);
2531 handle_101aXX(struct bregs *regs)
2537 handle_101a(struct bregs *regs)
2540 case 0x00: handle_101a00(regs); break;
2541 case 0x01: handle_101a01(regs); break;
2542 default: handle_101aXX(regs); break;
2548 handle_101b(struct bregs *regs)
2551 biosfn_read_state_info(regs->bx, regs->es, regs->di);
2557 handle_101c00(struct bregs *regs)
2560 regs->bx = biosfn_read_video_state_size(regs->cx);
2564 handle_101c01(struct bregs *regs)
2567 biosfn_save_video_state(regs->cx, regs->es, regs->bx);
2571 handle_101c02(struct bregs *regs)
2574 biosfn_restore_video_state(regs->cx, regs->es, regs->bx);
2578 handle_101cXX(struct bregs *regs)
2584 handle_101c(struct bregs *regs)
2587 case 0x00: handle_101c00(regs); break;
2588 case 0x01: handle_101c01(regs); break;
2589 case 0x02: handle_101c02(regs); break;
2590 default: handle_101cXX(regs); break;
2596 handle_104f00(struct bregs *regs)
2598 // XXX - vbe_biosfn_return_controller_information(&AX,ES,DI);
2599 // XXX - OR cirrus_vesa_00h
2603 handle_104f01(struct bregs *regs)
2605 // XXX - vbe_biosfn_return_mode_information(&AX,CX,ES,DI);
2606 // XXX - OR cirrus_vesa_01h
2610 handle_104f02(struct bregs *regs)
2612 // XXX - vbe_biosfn_set_mode(&AX,BX,ES,DI);
2613 // XXX - OR cirrus_vesa_02h
2617 handle_104f03(struct bregs *regs)
2619 // XXX - vbe_biosfn_return_current_mode
2620 // XXX - OR cirrus_vesa_03h
2624 handle_104f04(struct bregs *regs)
2626 // XXX - vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
2630 handle_104f05(struct bregs *regs)
2632 // XXX - vbe_biosfn_display_window_control
2633 // XXX - OR cirrus_vesa_05h
2637 handle_104f06(struct bregs *regs)
2639 // XXX - vbe_biosfn_set_get_logical_scan_line_length
2640 // XXX - OR cirrus_vesa_06h
2644 handle_104f07(struct bregs *regs)
2646 // XXX - vbe_biosfn_set_get_display_start
2647 // XXX - OR cirrus_vesa_07h
2651 handle_104f08(struct bregs *regs)
2653 // XXX - vbe_biosfn_set_get_dac_palette_format
2657 handle_104f0a(struct bregs *regs)
2659 // XXX - vbe_biosfn_return_protected_mode_interface
2663 handle_104fXX(struct bregs *regs)
2670 handle_104f(struct bregs *regs)
2673 handle_104fXX(regs);
2677 // XXX - check vbe_has_vbe_display()?
2680 case 0x00: handle_104f00(regs); break;
2681 case 0x01: handle_104f01(regs); break;
2682 case 0x02: handle_104f02(regs); break;
2683 case 0x03: handle_104f03(regs); break;
2684 case 0x04: handle_104f04(regs); break;
2685 case 0x05: handle_104f05(regs); break;
2686 case 0x06: handle_104f06(regs); break;
2687 case 0x07: handle_104f07(regs); break;
2688 case 0x08: handle_104f08(regs); break;
2689 case 0x0a: handle_104f0a(regs); break;
2690 default: handle_104fXX(regs); break;
2696 handle_10XX(struct bregs *regs)
2701 // INT 10h Video Support Service Entry Point
2703 handle_10(struct bregs *regs)
2705 debug_enter(regs, DEBUG_VGA_10);
2707 case 0x00: handle_1000(regs); break;
2708 case 0x01: handle_1001(regs); break;
2709 case 0x02: handle_1002(regs); break;
2710 case 0x03: handle_1003(regs); break;
2711 case 0x04: handle_1004(regs); break;
2712 case 0x05: handle_1005(regs); break;
2713 case 0x06: handle_1006(regs); break;
2714 case 0x07: handle_1007(regs); break;
2715 case 0x08: handle_1008(regs); break;
2716 case 0x09: handle_1009(regs); break;
2717 case 0x0a: handle_100a(regs); break;
2718 case 0x0b: handle_100b(regs); break;
2719 case 0x0c: handle_100c(regs); break;
2720 case 0x0d: handle_100d(regs); break;
2721 case 0x0e: handle_100e(regs); break;
2722 case 0x0f: handle_100f(regs); break;
2723 case 0x10: handle_1010(regs); break;
2724 case 0x11: handle_1011(regs); break;
2725 case 0x12: handle_1012(regs); break;
2726 case 0x13: handle_1013(regs); break;
2727 case 0x1a: handle_101a(regs); break;
2728 case 0x1b: handle_101b(regs); break;
2729 case 0x1c: handle_101c(regs); break;
2730 case 0x4f: handle_104f(regs); break;
2731 default: handle_10XX(regs); break;
2736 /****************************************************************
2738 ****************************************************************/
2743 // init detected hardware BIOS Area
2744 // set 80x25 color (not clear from RBIL but usual)
2745 u16 eqf = GET_BDA(equipment_list_flags);
2746 SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20);
2748 // Just for the first int10 find its children
2750 // the default char height
2751 SET_BDA(char_height, 0x10);
2754 SET_BDA(video_ctl, 0x60);
2756 // Set the basic screen we have
2757 SET_BDA(video_switches, 0xf9);
2759 // Set the basic modeset options
2760 SET_BDA(modeset_ctl, 0x51);
2762 // Set the default MSR
2763 SET_BDA(video_msr, 0x09);
2769 // switch to color mode and enable CPU access 480 lines
2770 outb(0xc3, VGAREG_WRITE_MISC_OUTPUT);
2771 // more than 64k 3C4/04
2772 outb(0x04, VGAREG_SEQU_ADDRESS);
2773 outb(0x02, VGAREG_SEQU_DATA);
2777 vga_post(struct bregs *regs)
2779 debug_enter(regs, DEBUG_VGA_POST);
2787 extern void entry_10(void);
2788 SET_IVT(0x10, 0xC000, (u32)entry_10);
2793 // XXX - clear screen and display info
2796 SET_VGA(video_save_pointer_table[0], (u32)video_param_table);
2797 SET_VGA(video_save_pointer_table[1], 0xC000);
2800 extern u8 _rom_header_size, _rom_header_checksum;
2801 SET_VGA(_rom_header_checksum, 0);
2802 u8 sum = -checksum_far(0xC000, 0, _rom_header_size * 512);
2803 SET_VGA(_rom_header_checksum, sum);