Use the same function signature for cirrus, bochsvga, and stdvga set_mode code.
Make both the int1000 interface and the VBE 104f02 interface use the same set_mode function.
Where clext and bochsvga need to fallback to the standard vga mode switching, have them call vgastd_mode_switch directly.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 35 ++++++++++++++++++++++++++++++----- vgasrc/bochsvga.h | 2 +- vgasrc/clext.c | 8 ++++---- vgasrc/clext.h | 2 +- vgasrc/stdvga.c | 7 +++++-- vgasrc/stdvga.h | 2 +- vgasrc/vbe.c | 42 ++++++++---------------------------------- vgasrc/vgabios.c | 17 ++++------------- vgasrc/vgahw.h | 19 +++++++++++++++++++ 9 files changed, 73 insertions(+), 61 deletions(-) create mode 100644 vgasrc/vgahw.h
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 4ba6611..c64919f 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -1,7 +1,7 @@ #include "vgabios.h" // struct vbe_modeinfo -#include "vbe.h" -#include "bochsvga.h" -#include "util.h" +#include "vbe.h" // VBE_MODE_VESA_DEFINED +#include "bochsvga.h" // bochsvga_set_mode +#include "util.h" // dprintf #include "config.h" // CONFIG_* #include "biosvar.h" // SET_BDA #include "stdvga.h" // VGAREG_SEQU_ADDRESS @@ -259,9 +259,24 @@ bochsvga_hires_enable(int enable) dispi_write(VBE_DISPI_INDEX_ENABLE, flags); }
-void -bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info) +int +bochsvga_set_mode(int mode, int flags) { + if (!(mode & VBE_MODE_VESA_DEFINED)) { + dprintf(1, "set VGA mode %x\n", mode); + + bochsvga_hires_enable(0); + return stdvga_set_mode(mode, flags); + } + + struct vbe_modeinfo modeinfo, *info = &modeinfo; + int ret = bochsvga_mode_info(mode, &modeinfo); + if (ret) { + dprintf(1, "VBE mode %x not found\n", mode); + return VBE_RETURN_STATUS_FAILED; + } + bochsvga_hires_enable(1); + if (info->depth == 4) stdvga_set_mode(0x6a, 0); if (info->depth == 8) @@ -315,6 +330,16 @@ bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info) }
SET_BDA(vbe_mode, mode); + + if (flags & MF_LINEARFB) { + /* Linear frame buffer */ + /* XXX: ??? */ + } + if (!(mode & MF_NOCLEARMEM)) { + bochsvga_clear_scr(); + } + + return 0; }
void diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index f0263d7..af60503 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -59,7 +59,7 @@ int bochsvga_list_modes(u16 seg, u16 ptr); struct vbe_modeinfo; int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info); void bochsvga_hires_enable(int enable); -void bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info); +int bochsvga_set_mode(int mode, int flags); void bochsvga_clear_scr(void); int bochsvga_hires_enabled(void); u16 bochsvga_curr_mode(void); diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 7071749..f468002 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -393,22 +393,22 @@ cirrus_clear_vram(u16 param) }
int -clext_set_video_mode(u8 mode, u8 noclearmem) +clext_set_mode(int mode, int flags) { dprintf(1, "cirrus mode %d\n", mode); SET_BDA(vbe_mode, 0); struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); if (table_g) { cirrus_switch_mode(table_g); - if (!noclearmem) + if (!(flags & MF_NOCLEARMEM)) cirrus_clear_vram(0xffff); SET_BDA(video_mode, mode); - return 1; + return 0; } table_g = cirrus_get_modeentry(0xfe); cirrus_switch_mode(table_g); dprintf(1, "cirrus mode switch regular\n"); - return 0; + return stdvga_set_mode(mode, flags); }
static int diff --git a/vgasrc/clext.h b/vgasrc/clext.h index 7d486a3..537cbea 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -3,7 +3,7 @@
#include "types.h" // u8
-int clext_set_video_mode(u8 mode, u8 noclearmem); +int clext_set_mode(int mode, int flags); void clext_init(void);
#endif // clext.h diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index b756f59..e55f8fa 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -10,6 +10,7 @@ #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_GLOBAL #include "util.h" // memcpy_far +#include "vbe.h" // VBE_RETURN_STATUS_FAILED #include "vgabios.h" // find_vga_entry
// TODO @@ -540,14 +541,14 @@ clear_screen(struct vgamode_s *vmode_g) } }
-void +int stdvga_set_mode(int mode, int flags) { // find the entry in the video modes struct vgamode_s *vmode_g = find_vga_entry(mode); dprintf(1, "mode search %02x found %p\n", mode, vmode_g); if (!vmode_g) - return; + return VBE_RETURN_STATUS_FAILED;
// if palette loading (bit 3 of modeset ctl = 0) if (!(flags & MF_NOPALETTE)) { // Set the PEL mask @@ -631,6 +632,8 @@ stdvga_set_mode(int mode, int flags)
// Setup BDA variables modeswitch_set_bda(mode, flags, vmode_g); + + return 0; }
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index ac5dea4..c260ae0 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -136,7 +136,7 @@ void stdvga_set_scan_lines(u8 lines); u16 stdvga_get_vde(void); void stdvga_save_state(u16 seg, struct saveVideoHardware *info); void stdvga_restore_state(u16 seg, struct saveVideoHardware *info); -void stdvga_set_mode(int mode, int flags); +int stdvga_set_mode(int mode, int flags); void stdvga_enable_video_addressing(u8 disable); void stdvga_init(void);
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index df95148..8256cae 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -11,8 +11,8 @@ #include "vbe.h" // struct vbe_info #include "util.h" // dprintf #include "biosvar.h" // get_global_set -#include "bochsvga.h" // bochsvga_set_mode -#include "stdvga.h" // stdvga_set_mode +#include "bochsvga.h" // bochsvga_hires_enabled +#include "vgahw.h" // vgahw_set_mode
static void vbe_104f00(struct bregs *regs) @@ -178,40 +178,14 @@ vbe_104f01(struct bregs *regs) static void vbe_104f02(struct bregs *regs) { - //u16 seg = regs->es; - //struct vbe_crtc_info *crtc_info = (void*)(regs->di+0); - u16 mode = regs->bx; - struct vbe_modeinfo modeinfo; - int rc; + dprintf(1, "VBE mode set: %x\n", regs->bx);
- dprintf(1, "VBE mode set: %x\n", mode); - - if (mode < 0x100) { /* VGA */ - dprintf(1, "set VGA mode %x\n", mode); - - bochsvga_hires_enable(0); - stdvga_set_mode(mode, 0); - } else { /* VBE */ - rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); - if (rc) { - dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); - regs->ax = 0x100; - return; - } - bochsvga_hires_enable(1); - bochsvga_set_mode(mode & 0x1ff, &modeinfo); - - if (mode & 0x4000) { - /* Linear frame buffer */ - /* XXX: ??? */ - } - if (!(mode & 0x8000)) { - bochsvga_clear_scr(); - } - } + int mode = regs->bx & 0x1ff; + int flags = regs->bx & (MF_CUSTOMCRTC|MF_LINEARFB|MF_NOCLEARMEM); + int ret = vgahw_set_mode(mode, flags);
- regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ + regs->ah = ret; + regs->al = 0x4f; }
static void diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 203a394..9e8863a 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -21,6 +21,7 @@ #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init #include "clext.h" // clext_init +#include "vgahw.h" // vgahw_set_mode
// XXX #define DEBUG_VGA_POST 1 @@ -378,8 +379,7 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) static void handle_1000(struct bregs *regs) { - u8 noclearmem = regs->al & 0x80; - u8 mode = regs->al & 0x7f; + int mode = regs->al & 0x7f;
// Set regs->al if (mode > 7) @@ -389,20 +389,11 @@ handle_1000(struct bregs *regs) else regs->al = 0x30;
- if (CONFIG_VGA_CIRRUS) { - int ret = clext_set_video_mode(mode, noclearmem); - if (ret) - return; - } - - if (bochsvga_enabled()) - bochsvga_hires_enable(0); - int flags = GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM); - if (noclearmem) + if (regs->al & 0x80) flags |= MF_NOCLEARMEM;
- stdvga_set_mode(mode, flags); + vgahw_set_mode(mode, flags); }
static void diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h new file mode 100644 index 0000000..57e41c3 --- /dev/null +++ b/vgasrc/vgahw.h @@ -0,0 +1,19 @@ +#ifndef __VGAHW_H +#define __VGAHW_H + +#include "types.h" // u8 +#include "config.h" // CONFIG_* + +#include "clext.h" // clext_set_mode +#include "bochsvga.h" // bochsvga_set_mode +#include "stdvga.h" // stdvga_set_mode + +static inline int vgahw_set_mode(int mode, int flags) { + if (CONFIG_VGA_CIRRUS) + return clext_set_mode(mode, flags); + if (CONFIG_VGA_BOCHS) + return bochsvga_set_mode(mode, flags); + return stdvga_set_mode(mode, flags); +} + +#endif // vgahw.h