vgabios: Extract out current mode finding into new function.
[seabios.git] / vgasrc / vgabios.c
index f35110787b5a470f0daa15f1aa8d62345bf095fa..62b09b45caad464c3e9d8014a75d4f0f4b1d9e72 100644 (file)
 #include "optionroms.h" // struct pci_data
 #include "config.h" // CONFIG_*
 #include "stdvga.h" // stdvga_set_cursor_shape
-#include "geodevga.h" // geodevga_init
-#include "bochsvga.h" // bochsvga_init
-#include "clext.h" // clext_init
+#include "clext.h" // clext_1012
 #include "vgahw.h" // vgahw_set_mode
+#include "pci.h" // pci_config_readw
+#include "pci_regs.h" // PCI_VENDOR_ID
 
 // XXX
 #define DEBUG_VGA_POST 1
 #define DEBUG_VGA_10 3
 
+// Standard Video Save Pointer Table
+struct VideoSavePointer_s {
+    struct segoff_s videoparam;
+    struct segoff_s paramdynamicsave;
+    struct segoff_s textcharset;
+    struct segoff_s graphcharset;
+    struct segoff_s secsavepointer;
+    u8 reserved[8];
+} PACKED;
+
+static struct VideoSavePointer_s video_save_pointer_table VAR16;
+
+struct VideoParam_s video_param_table[29] VAR16;
+
 
 /****************************************************************
  * PCI Data
@@ -137,7 +151,7 @@ set_active_page(u8 page)
         return;
 
     // Get the mode
-    struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode));
+    struct vgamode_s *vmode_g = get_current_mode();
     if (!vmode_g)
         return;
 
@@ -322,6 +336,17 @@ restore_bda_state(u16 seg, struct saveBDAstate *info)
     SET_IVT(0x43, GET_FARVAR(seg, info->font1));
 }
 
+
+/****************************************************************
+ * Mode setting
+ ****************************************************************/
+
+struct vgamode_s *
+get_current_mode(void)
+{
+    return vgahw_find_mode(GET_BDA(video_mode));
+}
+
 // Setup BDA after a mode switch.
 void
 modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g)
@@ -577,7 +602,7 @@ handle_101000(struct bregs *regs)
 {
     if (regs->bl > 0x14)
         return;
-    stdvga_set_single_palette_reg(regs->bl, regs->bh);
+    stdvga_attr_write(regs->bl, regs->bh);
 }
 
 static void
@@ -603,7 +628,7 @@ handle_101007(struct bregs *regs)
 {
     if (regs->bl > 0x14)
         return;
-    regs->bh = stdvga_get_single_palette_reg(regs->bl);
+    regs->bh = stdvga_attr_read(regs->bl);
 }
 
 static void
@@ -622,13 +647,13 @@ static void noinline
 handle_101010(struct bregs *regs)
 {
     u8 rgb[3] = {regs->dh, regs->ch, regs->cl};
-    stdvga_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1);
+    stdvga_dac_write(GET_SEG(SS), rgb, regs->bx, 1);
 }
 
 static void
 handle_101012(struct bregs *regs)
 {
-    stdvga_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
+    stdvga_dac_write(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
 }
 
 static void
@@ -641,7 +666,7 @@ static void noinline
 handle_101015(struct bregs *regs)
 {
     u8 rgb[3];
-    stdvga_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1);
+    stdvga_dac_read(GET_SEG(SS), rgb, regs->bx, 1);
     regs->dh = rgb[0];
     regs->ch = rgb[1];
     regs->cl = rgb[2];
@@ -650,19 +675,19 @@ handle_101015(struct bregs *regs)
 static void
 handle_101017(struct bregs *regs)
 {
-    stdvga_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
+    stdvga_dac_read(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
 }
 
 static void
 handle_101018(struct bregs *regs)
 {
-    stdvga_set_pel_mask(regs->bl);
+    stdvga_pelmask_write(regs->bl);
 }
 
 static void
 handle_101019(struct bregs *regs)
 {
-    regs->bl = stdvga_get_pel_mask();
+    regs->bl = stdvga_pelmask_read();
 }
 
 static void
@@ -942,6 +967,11 @@ handle_1012XX(struct bregs *regs)
 static void
 handle_1012(struct bregs *regs)
 {
+    if (CONFIG_VGA_CIRRUS && regs->bl >= 0x80) {
+        clext_1012(regs);
+        return;
+    }
+
     switch (regs->bl) {
     case 0x10: handle_101210(regs); break;
     case 0x30: handle_101230(regs); break;
@@ -953,8 +983,6 @@ handle_1012(struct bregs *regs)
     case 0x36: handle_101236(regs); break;
     default:   handle_1012XX(regs); break;
     }
-
-    // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae
 }
 
 
@@ -1009,6 +1037,22 @@ handle_101a(struct bregs *regs)
 }
 
 
+static u8 static_functionality[0x10] VAR16 = {
+ /* 0 */ 0xff,  // All modes supported #1
+ /* 1 */ 0xe0,  // All modes supported #2
+ /* 2 */ 0x0f,  // All modes supported #3
+ /* 3 */ 0x00, 0x00, 0x00, 0x00,  // reserved
+ /* 7 */ 0x07,  // 200, 350, 400 scan lines
+ /* 8 */ 0x02,  // mamimum number of visible charsets in text mode
+ /* 9 */ 0x08,  // total number of charset blocks in text mode
+ /* a */ 0xe7,  // Change to add new functions
+ /* b */ 0x0c,  // Change to add new functions
+ /* c */ 0x00,  // reserved
+ /* d */ 0x00,  // reserved
+ /* e */ 0x00,  // Change to add new functions
+ /* f */ 0x00   // reserved
+};
+
 struct funcInfo {
     struct segoff_s static_functionality;
     u8 bda_0x49[30];
@@ -1195,14 +1239,19 @@ init_bios_area(void)
     SET_BDA(video_msr, 0x09);
 }
 
-u16 VgaBDF VAR16;
+int VgaBDF VAR16 = -1;
 
 void VISIBLE16
 vga_post(struct bregs *regs)
 {
     debug_enter(regs, DEBUG_VGA_POST);
 
-    SET_VGA(VgaBDF, regs->ax);
+    if (CONFIG_VGA_PCI) {
+        u16 bdf = regs->ax;
+        if (pci_config_readw(bdf, PCI_VENDOR_ID) == CONFIG_VGA_VID
+            && pci_config_readw(bdf, PCI_DEVICE_ID) == CONFIG_VGA_DID)
+            SET_VGA(VgaBDF, bdf);
+    }
 
     int ret = vgahw_init();
     if (ret) {
@@ -1212,7 +1261,9 @@ vga_post(struct bregs *regs)
 
     init_bios_area();
 
-    build_video_param();
+    SET_VGA(video_save_pointer_table.videoparam
+            , SEGOFF(get_global_seg(), (u32)video_param_table));
+    stdvga_build_video_param();
 
     extern void entry_10(void);
     SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));