[SeaBIOS] [PATCH 05/10] vgabios: Add support for vesa get/set window function.
Kevin O'Connor
kevin at koconnor.net
Sat Jan 28 05:28:44 CET 2012
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
vgasrc/bochsvga.c | 19 +++++++++++++++++++
vgasrc/bochsvga.h | 2 ++
vgasrc/clext.c | 38 +++++++++++++++-----------------------
vgasrc/clext.h | 2 ++
vgasrc/stdvga.c | 12 ++++++++++++
vgasrc/stdvga.h | 2 ++
vgasrc/vbe.c | 30 +++++++++++++++++++++++++++---
vgasrc/vgaentry.S | 5 +++++
vgasrc/vgahw.h | 17 +++++++++++++++++
9 files changed, 101 insertions(+), 26 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c
index 6cbbf9c..74da887 100644
--- a/vgasrc/bochsvga.c
+++ b/vgasrc/bochsvga.c
@@ -198,6 +198,25 @@ bochsvga_hires_enable(int enable)
dispi_write(VBE_DISPI_INDEX_ENABLE, flags);
}
+int
+bochsvga_get_window(struct vgamode_s *vmode_g, int window)
+{
+ if (window != 0)
+ return -1;
+ return dispi_read(VBE_DISPI_INDEX_BANK);
+}
+
+int
+bochsvga_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ if (window != 0)
+ return -1;
+ dispi_write(VBE_DISPI_INDEX_BANK, val);
+ if (dispi_read(VBE_DISPI_INDEX_BANK) != val)
+ return -1;
+ return 0;
+}
+
static void
bochsvga_clear_scr(void)
{
diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h
index 1eaa91a..26a82e0 100644
--- a/vgasrc/bochsvga.h
+++ b/vgasrc/bochsvga.h
@@ -55,6 +55,8 @@ static inline void dispi_write(u16 reg, u16 val)
int bochsvga_init(void);
void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last);
struct vgamode_s *bochsvga_find_mode(int mode);
+int bochsvga_get_window(struct vgamode_s *vmode_g, int window);
+int bochsvga_set_window(struct vgamode_s *vmode_g, int window, int val);
int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags);
#endif // bochsvga.h
diff --git a/vgasrc/clext.c b/vgasrc/clext.c
index 363ef5d..ee39c5e 100644
--- a/vgasrc/clext.c
+++ b/vgasrc/clext.c
@@ -400,6 +400,21 @@ cirrus_get_memsize(void)
return 0x04 << x;
}
+int
+clext_get_window(struct vgamode_s *vmode_g, int window)
+{
+ return stdvga_grdc_read(window + 9);
+}
+
+int
+clext_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ if (val >= 0x100)
+ return -1;
+ stdvga_grdc_write(window + 9, val);
+ return 0;
+}
+
static void
cirrus_enable_16k_granularity(void)
{
@@ -620,28 +635,6 @@ cirrus_get_start_addr(void)
}
static void
-cirrus_vesa_05h(struct bregs *regs)
-{
- if (regs->bl > 1)
- goto fail;
- if (regs->bh == 0) {
- // set mempage
- if (regs->dx >= 0x100)
- goto fail;
- stdvga_grdc_write(regs->bl + 9, regs->dx);
- } else if (regs->bh == 1) {
- // get mempage
- regs->dx = stdvga_grdc_read(regs->bl + 9);
- } else
- goto fail;
-
- regs->ax = 0x004f;
- return;
-fail:
- regs->ax = 0x014f;
-}
-
-static void
cirrus_vesa_06h(struct bregs *regs)
{
if (regs->bl > 2) {
@@ -714,7 +707,6 @@ void
cirrus_vesa(struct bregs *regs)
{
switch (regs->al) {
- case 0x05: cirrus_vesa_05h(regs); break;
case 0x06: cirrus_vesa_06h(regs); break;
case 0x07: cirrus_vesa_07h(regs); break;
case 0x10: cirrus_vesa_10h(regs); break;
diff --git a/vgasrc/clext.h b/vgasrc/clext.h
index 718b756..b300cf4 100644
--- a/vgasrc/clext.h
+++ b/vgasrc/clext.h
@@ -4,6 +4,8 @@
#include "types.h" // u16
struct vgamode_s *clext_find_mode(int mode);
+int clext_get_window(struct vgamode_s *vmode_g, int window);
+int clext_set_window(struct vgamode_s *vmode_g, int window, int val);
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);
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c
index b7def32..9c0cba9 100644
--- a/vgasrc/stdvga.c
+++ b/vgasrc/stdvga.c
@@ -270,6 +270,18 @@ stdvga_get_vde(void)
return vde;
}
+int
+stdvga_get_window(struct vgamode_s *vmode_g, int window)
+{
+ return -1;
+}
+
+int
+stdvga_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ return -1;
+}
+
/****************************************************************
* Save/Restore/Set state
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h
index cc93f0d..05f2bf5 100644
--- a/vgasrc/stdvga.h
+++ b/vgasrc/stdvga.h
@@ -134,6 +134,8 @@ void stdvga_set_active_page(u16 address);
void stdvga_set_cursor_pos(u16 address);
void stdvga_set_scan_lines(u8 lines);
u16 stdvga_get_vde(void);
+int stdvga_get_window(struct vgamode_s *vmode_g, int window);
+int stdvga_set_window(struct vgamode_s *vmode_g, int window, int val);
void stdvga_save_state(u16 seg, struct saveVideoHardware *info);
void stdvga_restore_state(u16 seg, struct saveVideoHardware *info);
int stdvga_set_mode(struct vgamode_s *vmode_g, int flags);
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c
index b6ffb97..7e84794 100644
--- a/vgasrc/vbe.c
+++ b/vgasrc/vbe.c
@@ -102,7 +102,9 @@ vbe_104f01(struct bregs *regs)
SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */
SET_FARVAR(seg, info->winA_seg, GET_GLOBAL(vmode_g->sstart));
SET_FARVAR(seg, info->winB_seg, 0x0);
- SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0);
+ extern void entry_104f05(void);
+ SET_FARVAR(seg, info->win_func_ptr
+ , SEGOFF(get_global_seg(), (u32)entry_104f05));
int width = GET_GLOBAL(vmode_g->width);
int height = GET_GLOBAL(vmode_g->height);
int linesize = width * DIV_ROUND_UP(depth, 8);
@@ -207,10 +209,32 @@ vbe_104f04(struct bregs *regs)
regs->ax = 0x0100;
}
-static void
+void VISIBLE16
vbe_104f05(struct bregs *regs)
{
- debug_stub(regs);
+ if (regs->bh > 1 || regs->bl > 1)
+ goto fail;
+ if (GET_BDA(vbe_mode) & MF_LINEARFB) {
+ regs->ah = VBE_RETURN_STATUS_INVALID;
+ return;
+ }
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (! vmode_g)
+ goto fail;
+ if (regs->bh) {
+ int ret = vgahw_get_window(vmode_g, regs->bl);
+ if (ret < 0)
+ goto fail;
+ regs->dx = ret;
+ regs->ax = 0x004f;
+ return;
+ }
+ int ret = vgahw_set_window(vmode_g, regs->bl, regs->dx);
+ if (ret)
+ goto fail;
+ regs->ax = 0x004f;
+ return;
+fail:
regs->ax = 0x0100;
}
diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S
index 112857b..785d91f 100644
--- a/vgasrc/vgaentry.S
+++ b/vgasrc/vgaentry.S
@@ -50,6 +50,11 @@ _rom_header_signature:
* Entry points
****************************************************************/
+ DECLFUNC entry_104f05
+entry_104f05:
+ ENTRY_ARG vbe_104f05
+ lretw
+
DECLFUNC _optionrom_entry
_optionrom_entry:
ENTRY_ARG vga_post
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index bb5112a..ca8798c 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -44,4 +44,21 @@ static inline int vgahw_init(void) {
return stdvga_init();
}
+static inline int vgahw_get_window(struct vgamode_s *vmode_g, int window) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_get_window(vmode_g, window);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_get_window(vmode_g, window);
+ return stdvga_get_window(vmode_g, window);
+}
+
+static inline int vgahw_set_window(struct vgamode_s *vmode_g, int window
+ , int val) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_set_window(vmode_g, window, val);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_set_window(vmode_g, window, val);
+ return stdvga_set_window(vmode_g, window, val);
+}
+
#endif // vgahw.h
--
1.7.6.4
More information about the SeaBIOS
mailing list