#include "vgabios.h" // struct vbe_modeinfo
-#include "vbe.h" // VBE_MODE_VESA_DEFINED
+#include "vbe.h" // VBE_CAPABILITY_8BIT_DAC
#include "bochsvga.h" // bochsvga_set_mode
#include "util.h" // dprintf
#include "config.h" // CONFIG_*
-#include "biosvar.h" // SET_BDA
+#include "biosvar.h" // GET_GLOBAL
#include "stdvga.h" // VGAREG_SEQU_ADDRESS
#include "pci.h" // pci_config_readl
#include "pci_regs.h" // PCI_BASE_ADDRESS_0
{ 0x18c, { MM_DIRECT, 2560, 1600, 32, 8, 16, SEG_GRAPH } },
};
+static int is_bochsvga_mode(struct vgamode_s *vmode_g)
+{
+ return (vmode_g >= &bochsvga_modes[0].info
+ && vmode_g <= &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)-1].info);
+}
+
static u16 dispi_get_max_xres(void)
{
u16 en;
}
int
-bochsvga_set_mode(int mode, int flags)
+bochsvga_set_mode(struct vgamode_s *vmode_g, int flags)
{
- if (!(mode & VBE_MODE_VESA_DEFINED)) {
- dprintf(1, "set VGA mode %x\n", mode);
-
- SET_BDA(vbe_mode, 0);
+ if (! is_bochsvga_mode(vmode_g)) {
bochsvga_hires_enable(0);
- return stdvga_set_mode(mode, flags);
+ return stdvga_set_mode(vmode_g, flags);
}
- struct vgamode_s *vmode_g = bochsvga_find_mode(mode);
- if (!vmode_g) {
- dprintf(1, "VBE mode %x not found\n", mode);
- return VBE_RETURN_STATUS_FAILED;
- }
bochsvga_hires_enable(1);
u8 depth = GET_GLOBAL(vmode_g->depth);
if (depth == 4)
- stdvga_set_mode(0x6a, 0);
+ stdvga_set_mode(stdvga_find_mode(0x6a), 0);
if (depth == 8)
// XXX load_dac_palette(3);
;
stdvga_grdc_mask(0x05, 0x20, 0x40);
}
- SET_BDA(vbe_mode, mode | flags);
-
if (flags & MF_LINEARFB) {
/* Linear frame buffer */
/* XXX: ??? */
}
- if (!(mode & MF_NOCLEARMEM)) {
+ if (!(flags & MF_NOCLEARMEM)) {
bochsvga_clear_scr();
}
int bochsvga_init(void);
void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last);
struct vgamode_s *bochsvga_find_mode(int mode);
-int bochsvga_set_mode(int mode, int flags);
+int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags);
#endif // bochsvga.h
#include "biosvar.h" // GET_GLOBAL
#include "util.h" // dprintf
#include "bregs.h" // struct bregs
-#include "vbe.h" // struct vbe_info
#include "stdvga.h" // VGAREG_SEQU_ADDRESS
#include "pci.h" // pci_config_readl
#include "pci_regs.h" // PCI_BASE_ADDRESS_0
* helper functions
****************************************************************/
+int
+is_cirrus_mode(struct vgamode_s *vmode_g)
+{
+ return (vmode_g >= &cirrus_modes[0].info
+ && vmode_g <= &cirrus_modes[ARRAY_SIZE(cirrus_modes)-1].info);
+}
+
static u16
cirrus_vesamode_to_mode(u16 vesamode)
{
}
int
-clext_set_mode(int mode, int flags)
+clext_set_mode(struct vgamode_s *vmode_g, int flags)
{
- dprintf(1, "cirrus mode %x\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 (!(flags & MF_LINEARFB))
- cirrus_enable_16k_granularity();
- if (!(flags & MF_NOCLEARMEM))
- cirrus_clear_vram(0);
- SET_BDA(video_mode, mode);
- SET_BDA(vbe_mode, mode | flags);
- return 0;
+ if (!is_cirrus_mode(vmode_g)) {
+ cirrus_switch_mode(&mode_switchback);
+ dprintf(1, "cirrus mode switch regular\n");
+ return stdvga_set_mode(vmode_g, flags);
}
- cirrus_switch_mode(&mode_switchback);
- dprintf(1, "cirrus mode switch regular\n");
- return stdvga_set_mode(mode, flags);
+ struct cirrus_mode_s *table_g = container_of(
+ vmode_g, struct cirrus_mode_s, info);
+ cirrus_switch_mode(table_g);
+ if (!(flags & MF_LINEARFB))
+ cirrus_enable_16k_granularity();
+ if (!(flags & MF_NOCLEARMEM))
+ cirrus_clear_vram(0);
+ return 0;
}
static int
#include "types.h" // u16
struct vgamode_s *clext_find_mode(int mode);
-int clext_set_mode(int mode, int flags);
+int clext_set_mode(struct vgamode_s *vmode_g, int flags);
void clext_list_modes(u16 seg, u16 *dest, u16 *last);
int clext_init(void);
struct bregs;
#include "farptr.h" // SET_FARVAR
#include "biosvar.h" // GET_GLOBAL
#include "util.h" // memcpy_far
-#include "vbe.h" // VBE_RETURN_STATUS_FAILED
/****************************************************************
}
int
-stdvga_set_mode(int mode, int flags)
+stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
{
- // find the entry in the video modes
- struct vgamode_s *vmode_g = stdvga_find_mode(mode);
- dprintf(1, "mode search %02x found %p\n", mode, vmode_g);
- if (!vmode_g)
- return VBE_RETURN_STATUS_FAILED;
+ if (! stdvga_is_mode(vmode_g)) {
+ warn_internalerror();
+ return -1;
+ }
struct stdvga_mode_s *stdmode_g = container_of(
vmode_g, struct stdvga_mode_s, info);
if (memmodel == MM_TEXT)
stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
- // Setup BDA variables
- modeswitch_set_bda(mode, flags, vmode_g);
-
return 0;
}
// stdvgamodes.c
struct vgamode_s *stdvga_find_mode(int mode);
+int stdvga_is_mode(struct vgamode_s *vmode_g);
void stdvga_build_video_param(void);
void stdvga_override_crtc(int mode, u8 *crtc);
u16 stdvga_get_vde(void);
void stdvga_save_state(u16 seg, struct saveVideoHardware *info);
void stdvga_restore_state(u16 seg, struct saveVideoHardware *info);
-int stdvga_set_mode(int mode, int flags);
+int stdvga_set_mode(struct vgamode_s *vmode_g, int flags);
void stdvga_enable_video_addressing(u8 disable);
void stdvga_list_modes(u16 seg, u16 *dest, u16 *last);
int stdvga_init(void);
* Mode functions
****************************************************************/
+int
+stdvga_is_mode(struct vgamode_s *vmode_g)
+{
+ return (vmode_g >= &vga_modes[0].info
+ && vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
+}
+
struct vgamode_s *
stdvga_find_mode(int mode)
{
{
dprintf(1, "VBE mode set: %x\n", regs->bx);
- int mode = regs->bx & 0x1ff;
- int flags = regs->bx & (MF_CUSTOMCRTC|MF_LINEARFB|MF_NOCLEARMEM);
- int ret = vgahw_set_mode(mode, flags);
+ int mode = regs->bx & ~MF_VBEFLAGS;
+ int flags = regs->bx & MF_VBEFLAGS;
+ int ret = vga_set_mode(mode, flags);
regs->ah = ret;
regs->al = 0x4f;
static void
vbe_104f03(struct bregs *regs)
{
- u16 mode = GET_BDA(vbe_mode);
- if (!mode)
- regs->bx = GET_BDA(video_mode);
-
+ regs->bx = GET_BDA(vbe_mode);
dprintf(1, "VBE current mode=%x\n", regs->bx);
-
regs->ax = 0x004f;
}
#include "stdvga.h" // stdvga_set_cursor_shape
#include "clext.h" // clext_1012
#include "vgahw.h" // vgahw_set_mode
+#include "vbe.h" // VBE_RETURN_STATUS_FAILED
#include "pci.h" // pci_config_readw
#include "pci_regs.h" // PCI_VENDOR_ID
static void
restore_bda_state(u16 seg, struct saveBDAstate *info)
{
- SET_BDA(video_mode, GET_FARVAR(seg, info->video_mode));
+ u16 mode = GET_FARVAR(seg, info->video_mode);
+ SET_BDA(video_mode, mode);
+ SET_BDA(vbe_mode, mode);
SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols));
SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize));
SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address));
struct vgamode_s *
get_current_mode(void)
{
- return vgahw_find_mode(GET_BDA(video_mode));
+ return vgahw_find_mode(GET_BDA(vbe_mode) & ~MF_VBEFLAGS);
}
// Setup BDA after a mode switch.
-void
-modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g)
+int
+vga_set_mode(int mode, int flags)
{
+ dprintf(1, "set VGA mode %x\n", mode);
+ struct vgamode_s *vmode_g = vgahw_find_mode(mode);
+ if (!vmode_g)
+ return VBE_RETURN_STATUS_FAILED;
+
+ int ret = vgahw_set_mode(vmode_g, flags);
+ if (ret)
+ return ret;
+
// Set the BIOS mem
int width = GET_GLOBAL(vmode_g->width);
int height = GET_GLOBAL(vmode_g->height);
u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
int cheight = GET_GLOBAL(vmode_g->cheight);
- SET_BDA(video_mode, mode);
+ if (mode < 0x100)
+ SET_BDA(video_mode, mode);
+ else
+ SET_BDA(video_mode, 0xff);
+ SET_BDA(vbe_mode, mode | (flags & MF_VBEFLAGS));
if (memmodel == MM_TEXT) {
SET_BDA(video_cols, width);
SET_BDA(video_rows, height-1);
SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
break;
}
+
+ return 0;
}
if (regs->al & 0x80)
flags |= MF_NOCLEARMEM;
- vgahw_set_mode(mode, flags);
+ vga_set_mode(mode, flags);
}
static void
#define MF_CUSTOMCRTC 0x0800
#define MF_LINEARFB 0x4000
#define MF_NOCLEARMEM 0x8000
+#define MF_VBEFLAGS 0xfe00
// Memory model types
#define MM_TEXT 0x00
};
u16 calc_page_size(u8 memmodel, u16 width, u16 height);
struct vgamode_s *get_current_mode(void);
-void modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g);
+int vga_set_mode(int mode, int flags);
// vgafb.c
void vgafb_scroll(int nblines, int attr
return stdvga_find_mode(mode);
}
-static inline int vgahw_set_mode(int mode, int flags) {
+static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) {
if (CONFIG_VGA_CIRRUS)
- return clext_set_mode(mode, flags);
+ return clext_set_mode(vmode_g, flags);
if (CONFIG_VGA_BOCHS)
- return bochsvga_set_mode(mode, flags);
- return stdvga_set_mode(mode, flags);
+ return bochsvga_set_mode(vmode_g, flags);
+ return stdvga_set_mode(vmode_g, flags);
}
static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) {