[SeaBIOS] [PATCH 2/2] vgabios: implement read char in graphics mode

Kevin O'Connor kevin at koconnor.net
Fri Jan 2 17:16:41 CET 2015


On Fri, Jan 02, 2015 at 09:36:13AM +0100, Paolo Bonzini wrote:
> On 02/01/2015 04:40, Kevin O'Connor wrote:
> > > I couldn't find documentation for what to return as the attribute, but
> > > experimenting with DOSBox suggests 0 (and GWBasic accepts it).
> >
> > Just for reference, for the "cbvga" text mode emulation, I grab the
> > background attribute by assuming the lower right pixel of the cell is
> > the background, and then assume the foreground attribute is the
> > background attribute xor'd with 0x7 (see gfx_write_char()).  I'm not
> > sure if that hack applies here though.  :-)
> 
> No, it doesn't.  http://www.ctyme.com/intr/rb-0098.htm says AH is only
> defined in text mode, so it's probably safer to return zero.
> 
> Actually, it even says "only characters drawn with white foreground
> pixels are matched by the pattern-comparison routine".  I can tweak the
> patch to only match color (1 << vga_bpp) - 1, or to add a comment that
> we extend the behavior.

Curiosity got the better of me, so I added some test code to SeaBIOS
and ran it on machines with an ATI vgabios and Intel vgabios.  The
test code writes the letter 'A' with various foregrounds on various
backgrounds.

It looks to me that these vgabios look for just zero and non-zero
pixels (ie, they don't care what the foreground color is, they just
want a non-black foreground).  In the cases where there was a
non-black background on a non-black foreground (eg, blue 'A' on green
background) it treated the cell as character 0xdb (the font character
with all pixels on), and cases where there was black foreground on
non-black background (eg, black 'A' on green background) got treated
as an undetected character.

Cases where the entire cell was blank (eg, black 'A' on black
background) returned 0x00 instead of space (0x20).  So, no special
handling of that situation.

In many cases these vgabios did return an attribute in AH, but it's
not clear to me how it decided which attr to return.

-Kevin


On AMD:

Mode 0: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 1: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 2: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 3: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 4: 200,241,241,241,1db,0,1db,1db,1db,1db,0,1db,1db,1db,1db,0,
Mode 5: 200,241,241,241,1db,0,1db,1db,1db,1db,0,1db,1db,1db,1db,0,
Mode 6: 241,241,241,241,0,0,0,0,0,0,0,0,0,0,0,0,
Mode 7: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode d: 100,141,141,141,1db,0,1db,1db,1db,1db,0,1db,1db,1db,1db,0,
Mode e: 100,141,141,141,1db,0,1db,1db,1db,1db,0,1db,1db,1db,1db,0,
Mode f: 100,141,100,141,1db,0,1db,0,100,141,100,141,1db,0,1db,0,
Mode 10: 100,141,141,141,1db,0,1db,1db,1db,1db,0,1db,1db,1db,1db,0,
Mode 11: 141,141,141,141,0,0,0,0,0,0,0,0,0,0,0,0,
Mode 12: 100,141,141,141,1db,0,1db,1db,1db,1db,0,1db,1db,1db,1db,0,
Mode 13: 100,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
Mode 6a: 100,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,

On Intel:

Mode 0: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 1: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 2: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 3: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode 4: 0,41,41,41,db,6d38,db,db,db,db,6d38,db,db,db,db,6d38,
Mode 5: 0,41,41,41,db,6d38,db,db,db,db,6d38,db,db,db,db,6d38,
Mode 6: 41,41,41,41,6d38,6d38,6d38,6d38,6d38,6d38,6d38,6d38,6d38,6d38,6d38,6d38,
Mode 7: 741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
Mode d: 500,541,541,541,5db,500,5db,5db,5db,5db,500,5db,5db,5db,5db,500,
Mode e: 500,541,541,541,5db,500,5db,5db,5db,5db,500,5db,5db,5db,5db,500,
Mode f: 500,541,500,541,5db,500,5db,500,500,500,500,500,5db,500,5db,500,
Mode 10: 500,541,541,541,5db,500,5db,5db,5db,5db,500,5db,5db,5db,5db,500,
Mode 11: 500,541,500,541,5db,500,5db,500,500,541,500,541,5db,500,5db,500,
Mode 12: 500,541,541,541,5db,500,5db,5db,5db,5db,500,5db,5db,5db,5db,500,
Mode 13: 0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
Mode 6a: 0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,

SeaBIOS Patch:

diff --git a/src/bootsplash.c b/src/bootsplash.c
index c572685..5035124 100644
--- a/src/bootsplash.c
+++ b/src/bootsplash.c
@@ -36,6 +36,53 @@ call16_int10(struct bregs *br)
  * VGA text / graphics console
  ****************************************************************/
 
+static void
+testit(int mode)
+{
+    struct bregs br;
+    memset(&br, 0, sizeof(br));
+    br.ax = mode;
+    call16_int10(&br);
+
+    dprintf(1, "Mode %x: ", mode);
+    int i, j;
+    for (i=0; i<4; i++) {
+        memset(&br, 0, sizeof(br));
+        br.ah = 0x02;
+        br.dx = i<<8;
+        call16_int10(&br);
+
+        memset(&br, 0, sizeof(br));
+        br.ah = 0x0A;
+        br.al = 219;
+        br.bl = i;
+        br.cx = 4;
+        call16_int10(&br);
+
+        for (j=0; j<4; j++) {
+            memset(&br, 0, sizeof(br));
+            br.ah = 0x02;
+            br.dx = j | (i<<8);
+            call16_int10(&br);
+
+            memset(&br, 0, sizeof(br));
+            br.ah = 0x0A;
+            br.al = 'A';
+            br.bl = j | (i ? 0x80 : 0);
+            br.cx = 1;
+            call16_int10(&br);
+
+            memset(&br, 0, sizeof(br));
+            br.ah = 0x08;
+            call16_int10(&br);
+            dprintf(1, "%x,", br.ax);
+        }
+    }
+    dprintf(1, "\n");
+
+    msleep(8000);
+}
+
 void
 enable_vga_console(void)
 {
@@ -47,6 +94,15 @@ enable_vga_console(void)
     br.ax = 0x0003;
     call16_int10(&br);
 
+    int i;
+    for (i=0; i<=0x13; i++)
+        if (i <= 0x07 || i >= 0x0D)
+            testit(i);
+    testit(0x6A);
+
+    br.ax = 0x0003;
+    call16_int10(&br);
+
     // Write to screen.
     printf("SeaBIOS (version %s)\n", VERSION);
     display_uuid();



More information about the SeaBIOS mailing list