Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 21 +++++++++++++++++++++ vgasrc/bochsvga.h | 2 ++ vgasrc/stdvga.c | 12 ++++++++++++ vgasrc/stdvga.h | 2 ++ vgasrc/vbe.c | 25 +++++++++++++++++++++++-- vgasrc/vgahw.h | 12 ++++++++++++ 6 files changed, 72 insertions(+), 2 deletions(-)
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 @@ bochsvga_set_displaystart(struct vgamode_s *vmode_g, int val) 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_get_linelength(struct vgamode_s *vmode_g); 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 @@ stdvga_set_displaystart(struct vgamode_s *vmode_g, int val) 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_get_linelength(struct vgamode_s *vmode_g); 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 @@ fail: 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 @@ static inline int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val) { 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