aboutsummaryrefslogtreecommitdiffstats
path: root/vgasrc/bochsvga.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2012-02-04 12:40:02 -0500
committerKevin O'Connor <kevin@koconnor.net>2012-02-04 12:41:13 -0500
commit2469f89528a7da83eb608dfc86fda5fc780b8f92 (patch)
tree38d975f9367476700be9ee8e9742b55287d128e2 /vgasrc/bochsvga.c
parent9f857fc97c0cdfa6f18a43d1548cd91014766c26 (diff)
downloadseabios-2469f89528a7da83eb608dfc86fda5fc780b8f92.tar.gz
vgabios: Implement VBE save/restore state function (func 04).
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'vgasrc/bochsvga.c')
-rw-r--r--vgasrc/bochsvga.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c
index 0a36afc5..957bde29 100644
--- a/vgasrc/bochsvga.c
+++ b/vgasrc/bochsvga.c
@@ -201,6 +201,71 @@ bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val)
return 0;
}
+int
+bochsvga_size_state(int states)
+{
+ int size = stdvga_size_state(states);
+ if (size < 0)
+ return size;
+ if (states & 8)
+ size += (VBE_DISPI_INDEX_Y_OFFSET-VBE_DISPI_INDEX_XRES+1)*sizeof(u16);
+ return size;
+}
+
+int
+bochsvga_save_state(u16 seg, void *data, int states)
+{
+ int ret = stdvga_save_state(seg, data, states);
+ if (ret < 0)
+ return ret;
+
+ if (!(states & 8))
+ return 0;
+
+ u16 *info = (data + stdvga_size_state(states));
+ u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+ SET_FARVAR(seg, *info, en);
+ info++;
+ if (!(en & VBE_DISPI_ENABLED))
+ return 0;
+ int i;
+ for (i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++)
+ if (i != VBE_DISPI_INDEX_ENABLE) {
+ u16 v = dispi_read(i);
+ SET_FARVAR(seg, *info, v);
+ info++;
+ }
+ return 0;
+}
+
+int
+bochsvga_restore_state(u16 seg, void *data, int states)
+{
+ int ret = stdvga_restore_state(seg, data, states);
+ if (ret < 0)
+ return ret;
+
+ if (!(states & 8))
+ return 0;
+
+ u16 *info = (data + stdvga_size_state(states));
+ u16 en = GET_FARVAR(seg, *info);
+ info++;
+ if (!(en & VBE_DISPI_ENABLED)) {
+ dispi_write(VBE_DISPI_INDEX_ENABLE, en);
+ return 0;
+ }
+ int i;
+ for (i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++)
+ if (i == VBE_DISPI_INDEX_ENABLE) {
+ dispi_write(i, en);
+ } else {
+ dispi_write(i, GET_FARVAR(seg, *info));
+ info++;
+ }
+ return 0;
+}
+
/****************************************************************
* Mode setting