vgabios: Minor - pass display address to stdvga_set_cursor_pos().
[seabios.git] / vgasrc / vgabios.c
index 5ce7c0c99c1be42ddca209e2f1be0c0eedd4de9a..2f24e7828c91a99e16a8ac0f414754c2dc034473 100644 (file)
@@ -20,6 +20,7 @@
 #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
 
@@ -62,6 +63,22 @@ struct pci_data rom_pci_data VAR16VISIBLE = {
  * Helper functions
  ****************************************************************/
 
+// Return the bits per pixel in system memory for a given mode.
+int
+vga_bpp(struct vgamode_s *vmode_g)
+{
+    switch (GET_GLOBAL(vmode_g->memmodel)) {
+    case MM_TEXT:
+        return 16;
+    case MM_PLANAR:
+        return 1;
+    }
+    u8 depth = GET_GLOBAL(vmode_g->depth);
+    if (depth > 8)
+        return ALIGN(depth, 8);
+    return depth;
+}
+
 u16
 calc_page_size(u8 memmodel, u16 width, u16 height)
 {
@@ -121,11 +138,9 @@ set_cursor_pos(struct cursorpos cp)
         return;
 
     // Calculate the memory address
-    u16 nbcols = GET_BDA(video_cols);
-    u16 address = (GET_BDA(video_pagesize) * cp.page
-                   + (cp.x + cp.y * nbcols) * 2);
-
-    stdvga_set_cursor_pos(address / 2);
+    int address = (GET_BDA(video_pagesize) * cp.page
+                   + (cp.x + cp.y * GET_BDA(video_cols)) * 2);
+    stdvga_set_cursor_pos(address);
 }
 
 static struct cursorpos
@@ -151,7 +166,7 @@ set_active_page(u8 page)
         return;
 
     // Get the mode
-    struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode));
+    struct vgamode_s *vmode_g = get_current_mode();
     if (!vmode_g)
         return;
 
@@ -159,9 +174,8 @@ set_active_page(u8 page)
     struct cursorpos cp = get_cursor_pos(page);
 
     // Calculate memory address of start of page
-    u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
-    u16 address = GET_BDA(video_pagesize) * page;
-    stdvga_set_active_page(memmodel == MM_TEXT ? address / 2 : address);
+    int address = GET_BDA(video_pagesize) * page;
+    vgahw_set_displaystart(vmode_g, address);
 
     // And change the BIOS page
     SET_BDA(video_pagestart, address);
@@ -316,7 +330,9 @@ save_bda_state(u16 seg, struct saveBDAstate *info)
 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));
@@ -336,16 +352,40 @@ restore_bda_state(u16 seg, struct saveBDAstate *info)
     SET_IVT(0x43, GET_FARVAR(seg, info->font1));
 }
 
+
+/****************************************************************
+ * Mode setting
+ ****************************************************************/
+
+struct vgamode_s *
+get_current_mode(void)
+{
+    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);
@@ -391,6 +431,8 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g)
         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
         break;
     }
+
+    return 0;
 }
 
 
@@ -415,7 +457,7 @@ handle_1000(struct bregs *regs)
     if (regs->al & 0x80)
         flags |= MF_NOCLEARMEM;
 
-    vgahw_set_mode(mode, flags);
+    vga_set_mode(mode, flags);
 }
 
 static void