vgabios: Fix screen attrs on cga scroll.
[seabios.git] / vgasrc / vgafb.c
index 71a57196c0f611b77fe2a8b06024115a377625e3..a75bc81eb296c2e6d396cce4691aa623013f01d3 100644 (file)
@@ -5,9 +5,9 @@
 //
 // This file may be distributed under the terms of the GNU LGPLv3 license.
 
+#include "vgabios.h" // vgafb_scroll
 #include "biosvar.h" // GET_BDA
 #include "util.h" // memset_far
-#include "vgahw.h" // vgahw_find_mode
 #include "stdvga.h" // stdvga_planar4_plane
 
 
@@ -93,6 +93,10 @@ scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr
     }
     if (attr < 0)
         attr = 0;
+    if (cwidth == 1)
+        attr = (attr&1) | ((attr&1)<<1);
+    attr &= 3;
+    attr |= (attr<<2) | (attr<<4) | (attr<<6);
     int cols = lr.x - ul.x + 1;
     int rows = lr.y - ul.y + 1;
     if (nblines < rows) {
@@ -171,7 +175,7 @@ void
 vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr)
 {
     // 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;
 
@@ -253,40 +257,23 @@ write_gfx_char_cga(struct vgamode_s *vmode_g
         u8 *dest_far = (void*)(addr + (i >> 1) * 80);
         if (i & 1)
             dest_far += 0x2000;
-        u8 mask = 0x80;
         if (bpp == 1) {
-            u8 data = 0;
+            u8 colors = (ca.attr & 0x01) ? 0xff : 0x00;
+            u8 pixels = colors & GET_GLOBAL(fdata_g[src + i]);
             if (ca.attr & 0x80)
-                data = GET_FARVAR(SEG_CTEXT, *dest_far);
-            u8 j;
-            for (j = 0; j < 8; j++) {
-                if (GET_GLOBAL(fdata_g[src + i]) & mask) {
-                    if (ca.attr & 0x80)
-                        data ^= (ca.attr & 0x01) << (7 - j);
-                    else
-                        data |= (ca.attr & 0x01) << (7 - j);
-                }
-                mask >>= 1;
-            }
-            SET_FARVAR(SEG_CTEXT, *dest_far, data);
+                pixels ^= GET_FARVAR(SEG_GRAPH, *dest_far);
+            SET_FARVAR(SEG_CTEXT, *dest_far, pixels);
         } else {
-            while (mask > 0) {
-                u8 data = 0;
-                if (ca.attr & 0x80)
-                    data = GET_FARVAR(SEG_CTEXT, *dest_far);
-                u8 j;
-                for (j = 0; j < 4; j++) {
-                    if (GET_GLOBAL(fdata_g[src + i]) & mask) {
-                        if (ca.attr & 0x80)
-                            data ^= (ca.attr & 0x03) << ((3 - j) * 2);
-                        else
-                            data |= (ca.attr & 0x03) << ((3 - j) * 2);
-                    }
-                    mask >>= 1;
-                }
-                SET_FARVAR(SEG_CTEXT, *dest_far, data);
-                dest_far += 1;
-            }
+            u16 pixels = 0;
+            u8 fontline = GET_GLOBAL(fdata_g[src + i]);
+            int j;
+            for (j = 0; j < 8; j++)
+                if (fontline & (1<<j))
+                    pixels |= (ca.attr & 0x03) << (j*2);
+            pixels = htons(pixels);
+            if (ca.attr & 0x80)
+                pixels ^= GET_FARVAR(SEG_GRAPH, *(u16*)dest_far);
+            SET_FARVAR(SEG_CTEXT, *(u16*)dest_far, pixels);
         }
     }
 }
@@ -306,14 +293,11 @@ write_gfx_char_lin(struct vgamode_s *vmode_g
     u8 i;
     for (i = 0; i < 8; i++) {
         u8 *dest_far = (void*)(addr + i * nbcols * 8);
-        u8 mask = 0x80;
+        u8 fontline = GET_GLOBAL(fdata_g[src + i]);
         u8 j;
         for (j = 0; j < 8; j++) {
-            u8 data = 0x00;
-            if (GET_GLOBAL(fdata_g[src + i]) & mask)
-                data = ca.attr;
-            SET_FARVAR(SEG_GRAPH, dest_far[j], data);
-            mask >>= 1;
+            u8 pixel = (fontline & (0x80>>j)) ? ca.attr : 0x00;
+            SET_FARVAR(SEG_GRAPH, dest_far[j], pixel);
         }
     }
 }
@@ -339,7 +323,7 @@ void
 vgafb_write_char(struct cursorpos cp, struct carattr ca)
 {
     // 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;
 
@@ -365,7 +349,7 @@ struct carattr
 vgafb_read_char(struct cursorpos cp)
 {
     // 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)
         goto fail;
 
@@ -397,7 +381,7 @@ void
 vgafb_write_pixel(u8 color, u16 x, u16 y)
 {
     // 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;
 
@@ -453,7 +437,7 @@ u8
 vgafb_read_pixel(u16 x, u16 y)
 {
     // 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 0;