vgabios: Generate video_param_table at runtime.

Now that all the mode info is available in vga_modes, generate the
externally visible video_param_table data from it.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
diff --git a/vgasrc/vga.c b/vgasrc/vga.c
index e7b96ff..ba07584 100644
--- a/vgasrc/vga.c
+++ b/vgasrc/vga.c
@@ -23,7 +23,6 @@
 #define DEBUG_VGA_POST 1
 #define DEBUG_VGA_10 3
 
-#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val))
 
 /****************************************************************
  * PCI Data
@@ -1582,9 +1581,7 @@
 
     // XXX - clear screen and display info
 
-    // XXX: fill it
-    SET_VGA(video_save_pointer_table.videoparam
-            , SEGOFF(get_global_seg(), (u32)video_param_table));
+    build_video_param();
 
     // Fixup checksum
     extern u8 _rom_header_size, _rom_header_checksum;
diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c
index 10bcbcd..47395f2 100644
--- a/vgasrc/vgatables.c
+++ b/vgasrc/vgatables.c
@@ -7,241 +7,81 @@
 
 #include "vgatables.h" // struct VideoParamTableEntry_s
 #include "biosvar.h" // GET_GLOBAL
+#include "util.h" // memcpy_far
 
 
 /****************************************************************
  * Video parameter table
  ****************************************************************/
 
+// 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;
+
 struct VideoSavePointer_s video_save_pointer_table VAR16;
 
-struct VideoParam_s video_param_table[] VAR16 = {
-    // index=0x00 no mode defined
-    {},
-    // index=0x01 no mode defined
-    {},
-    // index=0x02 no mode defined
-    {},
-    // index=0x03 no mode defined
-    {},
-    // index=0x04 vga mode 0x04
-    { 40, 24, 8, 0x0800,      /* tw, th-1, ch, slength */
-      { 0x09, 0x03, 0x00, 0x02 },    /* sequ_regs */
-      0x63,                      /* miscreg */
-      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
-        0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x01, 0x00, 0x03, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff }, /* grdc_regs */
-    },
-    /* index=0x05 vga mode 0x05 */
-    { 40, 24, 8, 0x0800,     /* tw, th-1, ch, slength */
-      { 0x09, 0x03, 0x00, 0x02 },    /* sequ_regs */
-      0x63,                      /* miscreg */
-      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
-        0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x01, 0x00, 0x03, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff }, /* grdc_regs */
-    },
-    /* index=0x06 vga mode 0x06 */
-    { 80, 24, 8, 0x1000,     /* tw, th-1, ch, slength */
-      { 0x01, 0x01, 0x00, 0x06 },    /* sequ_regs */
-      0x63,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-        0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-        0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-        0x01, 0x00, 0x01, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x07 vga mode 0x07 */
-    { 80, 24, 16, 0x1000,    /* tw, th-1, ch, slength */
-      { 0x00, 0x03, 0x00, 0x02 },    /* sequ_regs */
-      0x66,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-        0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-        0x0e, 0x00, 0x0f, 0x08 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x08 no mode defined */
-    {},
-    /* index=0x09 no mode defined */
-    {},
-    /* index=0x0a no mode defined */
-    {},
-    /* index=0x0b no mode defined */
-    {},
-    /* index=0x0c no mode defined */
-    {},
-    /* index=0x0d vga mode 0x0d */
-    { 40, 24, 8, 0x2000,     /* tw, th-1, ch, slength */
-      { 0x09, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0x63,                      /* miscreg */
-      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
-        0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x0e vga mode 0x0e */
-    { 80, 24, 8, 0x4000,     /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0x63,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-        0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x0f no mode defined */
-    {},
-    /* index=0x10 no mode defined */
-    {},
-    /* index=0x11 vga mode 0x0f */
-    { 80, 24, 14, 0x8000,    /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0xa3,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
-        0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
-        0x01, 0x00, 0x01, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x12 vga mode 0x10 */
-    { 80, 24, 14, 0x8000,    /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0xa3,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x13 no mode defined */
-    {},
-    /* index=0x14 no mode defined */
-    {},
-    /* index=0x15 no mode defined */
-    {},
-    /* index=0x16 no mode defined */
-    {},
-    /* index=0x17 vga mode 0x01 */
-    { 40, 24, 16, 0x0800,    /* tw, th-1, ch, slength */
-      { 0x08, 0x03, 0x00, 0x02 },    /* sequ_regs */
-      0x67,                      /* miscreg */
-      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-        0x0c, 0x00, 0x0f, 0x08 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff }, /* grdc_regs */
-    },
-    /* index=0x18 vga mode 0x03 */
-    { 80, 24, 16, 0x1000,    /* tw, th-1, ch, slength */
-      { 0x00, 0x03, 0x00, 0x02 },    /* sequ_regs */
-      0x67,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-        0x0c, 0x00, 0x0f, 0x08 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x19 vga mode 0x07 */
-    { 80, 24, 16, 0x1000,    /* tw, th-1, ch, slength */
-      { 0x00, 0x03, 0x00, 0x02 },    /* sequ_regs */
-      0x66,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-        0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-        0x0e, 0x00, 0x0f, 0x08 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff }, /* grdc_regs */
-    },
-    /* index=0x1a vga mode 0x11 */
-    { 80, 29, 16, 0x0000,    /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0xe3,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
-        0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
-        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-    },
-    /* index=0x1b vga mode 0x12 */
-    { 80, 29, 16, 0x0000,    /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0xe3,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x1c vga mode 0x13 */
-    { 40, 24, 8, 0x0000,     /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x0e },    /* sequ_regs */
-      0x63,                      /* miscreg */
-      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-        0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-        0x41, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-    /* index=0x1d vga mode 0x6a */
-    { 100, 36, 16, 0x0000,   /* tw, th-1, ch, slength */
-      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
-      0xe3,                      /* miscreg */
-      { 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
-        0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
-        0xff },                      /* crtc_regs */
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
-      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
-     },
-};
+// standard BIOS Video Parameter Table
+struct VideoParam_s {
+    u8 twidth;
+    u8 theightm1;
+    u8 cheight;
+    u16 slength;
+    u8 sequ_regs[4];
+    u8 miscreg;
+    u8 crtc_regs[25];
+    u8 actl_regs[20];
+    u8 grdc_regs[9];
+} PACKED;
+
+struct VideoParam_s video_param_table[29] VAR16;
+
+void
+build_video_param(void)
+{
+    static u8 parammodes[ARRAY_SIZE(video_param_table)] VAR16 = {
+        0, 0, 0, 0, 0x04, 0x05, 0x06, 0x07,
+        0, 0, 0, 0, 0, 0x0d, 0x0e, 0,
+        0, 0x0f, 0x10, 0, 0, 0, 0, 0x01,
+        0x03, 0x07, 0x11, 0x12, 0x13
+    };
+
+    int i;
+    for (i=0; i<ARRAY_SIZE(parammodes); i++) {
+        u8 mode = GET_GLOBAL(parammodes[i]);
+        if (! mode)
+            continue;
+        struct VideoParam_s *vparam_g = &video_param_table[i];
+        struct vgamode_s *vmode_g = find_vga_entry(mode);
+        if (!vmode_g)
+            continue;
+        SET_VGA(vparam_g->twidth, GET_GLOBAL(vmode_g->twidth));
+        SET_VGA(vparam_g->theightm1, GET_GLOBAL(vmode_g->theight)-1);
+        SET_VGA(vparam_g->cheight, GET_GLOBAL(vmode_g->cheight));
+        SET_VGA(vparam_g->slength, GET_GLOBAL(vmode_g->slength));
+        memcpy_far(get_global_seg(), vparam_g->sequ_regs
+                   , get_global_seg(), GET_GLOBAL(vmode_g->sequ_regs)
+                   , ARRAY_SIZE(vparam_g->sequ_regs));
+        SET_VGA(vparam_g->miscreg, GET_GLOBAL(vmode_g->miscreg));
+        memcpy_far(get_global_seg(), vparam_g->crtc_regs
+                   , get_global_seg(), GET_GLOBAL(vmode_g->crtc_regs)
+                   , ARRAY_SIZE(vparam_g->crtc_regs));
+        memcpy_far(get_global_seg(), vparam_g->actl_regs
+                   , get_global_seg(), GET_GLOBAL(vmode_g->actl_regs)
+                   , ARRAY_SIZE(vparam_g->actl_regs));
+        memcpy_far(get_global_seg(), vparam_g->grdc_regs
+                   , get_global_seg(), GET_GLOBAL(vmode_g->grdc_regs)
+                   , ARRAY_SIZE(vparam_g->grdc_regs));
+    }
+
+    SET_VGA(video_save_pointer_table.videoparam
+            , SEGOFF(get_global_seg(), (u32)video_param_table));
+}
 
 
 /****************************************************************
diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h
index f31595e..5a90174 100644
--- a/vgasrc/vgatables.h
+++ b/vgasrc/vgatables.h
@@ -70,29 +70,6 @@
 #define SCREEN_IO_START(x,y,p) (((((x)*(y)) | 0x00ff) + 1) * (p))
 #define SCREEN_MEM_START(x,y,p) SCREEN_IO_START(((x)*2),(y),(p))
 
-// 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;
-
-/* standard BIOS Video Parameter Table */
-struct VideoParam_s {
-    u8 twidth;
-    u8 theightm1;
-    u8 cheight;
-    u16 slength;
-    u8 sequ_regs[4];
-    u8 miscreg;
-    u8 crtc_regs[25];
-    u8 actl_regs[20];
-    u8 grdc_regs[9];
-} PACKED;
-
 struct vgamode_s {
     u8 svgamode;
     u8 memmodel;    /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */
@@ -157,8 +134,8 @@
 
 // vgatables.c
 struct vgamode_s *find_vga_entry(u8 mode);
+void build_video_param(void);
 extern struct VideoSavePointer_s video_save_pointer_table;
-extern struct VideoParam_s video_param_table[];
 extern u8 static_functionality[];
 
 // vgafonts.c
@@ -169,6 +146,7 @@
 extern u8 vgafont16alt[];
 
 // vga.c
+#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val))
 struct carattr {
     u8 car, attr, use_attr;
 };