vgabios: Add support for VBE get/set dac palette format (func 08).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c
index 9210004..0a36afc 100644
--- a/vgasrc/bochsvga.c
+++ b/vgasrc/bochsvga.c
@@ -180,6 +180,27 @@
     return 0;
 }
 
+int
+bochsvga_get_dacformat(struct vgamode_s *vmode_g)
+{
+    u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+    return (en & VBE_DISPI_8BIT_DAC) ? 8 : 6;
+}
+
+int
+bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val)
+{
+    u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+    if (val == 6)
+        en &= ~VBE_DISPI_8BIT_DAC;
+    else if (val == 8)
+        en |= VBE_DISPI_8BIT_DAC;
+    else
+        return -1;
+    dispi_write(VBE_DISPI_INDEX_ENABLE, en);
+    return 0;
+}
+
 
 /****************************************************************
  * Mode setting
diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h
index 57b2b69..78a9e0a 100644
--- a/vgasrc/bochsvga.h
+++ b/vgasrc/bochsvga.h
@@ -60,6 +60,8 @@
 int bochsvga_set_linelength(struct vgamode_s *vmode_g, int val);
 int bochsvga_get_displaystart(struct vgamode_s *vmode_g);
 int bochsvga_set_displaystart(struct vgamode_s *vmode_g, int val);
+int bochsvga_get_dacformat(struct vgamode_s *vmode_g);
+int bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val);
 int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags);
 int bochsvga_init(void);
 
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c
index dcc51a8..1b552db 100644
--- a/vgasrc/stdvga.c
+++ b/vgasrc/stdvga.c
@@ -326,6 +326,18 @@
     return 0;
 }
 
+int
+stdvga_get_dacformat(struct vgamode_s *vmode_g)
+{
+    return -1;
+}
+
+int
+stdvga_set_dacformat(struct vgamode_s *vmode_g, int val)
+{
+    return -1;
+}
+
 
 /****************************************************************
  * Save/Restore state
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h
index 4933723..000a097 100644
--- a/vgasrc/stdvga.h
+++ b/vgasrc/stdvga.h
@@ -126,6 +126,8 @@
 int stdvga_set_linelength(struct vgamode_s *vmode_g, int val);
 int stdvga_get_displaystart(struct vgamode_s *vmode_g);
 int stdvga_set_displaystart(struct vgamode_s *vmode_g, int val);
+int stdvga_get_dacformat(struct vgamode_s *vmode_g);
+int stdvga_set_dacformat(struct vgamode_s *vmode_g, int val);
 void stdvga_save_state(u16 seg, struct saveVideoHardware *info);
 void stdvga_restore_state(u16 seg, struct saveVideoHardware *info);
 void stdvga_enable_video_addressing(u8 disable);
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c
index 77b0934..0ee69b4 100644
--- a/vgasrc/vbe.c
+++ b/vgasrc/vbe.c
@@ -305,8 +305,29 @@
 static void
 vbe_104f08(struct bregs *regs)
 {
-    debug_stub(regs);
-    regs->ax = 0x0100;
+    struct vgamode_s *vmode_g = get_current_mode();
+    if (! vmode_g)
+        goto fail;
+    u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+    if (memmodel == MM_DIRECT || memmodel == MM_YUV) {
+        regs->ax = 0x034f;
+        return;
+    }
+    if (regs->bl > 1)
+        goto fail;
+    if (regs->bl == 0) {
+        int ret = vgahw_set_dacformat(vmode_g, regs->bh);
+        if (ret < 0)
+            goto fail;
+    }
+    int ret = vgahw_get_dacformat(vmode_g);
+    if (ret < 0)
+        goto fail;
+    regs->bh = ret;
+    regs->ax = 0x004f;
+    return;
+fail:
+    regs->ax = 0x014f;
 }
 
 static void
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index af6b068..585ae3d 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -93,4 +93,16 @@
     return stdvga_set_displaystart(vmode_g, val);
 }
 
+static inline int vgahw_get_dacformat(struct vgamode_s *vmode_g) {
+    if (CONFIG_VGA_BOCHS)
+        return bochsvga_get_dacformat(vmode_g);
+    return stdvga_get_dacformat(vmode_g);
+}
+
+static inline int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val) {
+    if (CONFIG_VGA_BOCHS)
+        return bochsvga_set_dacformat(vmode_g, val);
+    return stdvga_set_dacformat(vmode_g, val);
+}
+
 #endif // vgahw.h