On Fri, May 15, 2020 at 05:03:30PM -0700, [email protected] wrote:
> One of the first things I noticed when I tried OpenBSD in VirtualBox
> was that doing ctrl-alt-2, then ctrl-alt-1 to switch back and forth
> between virtual screens left the text mode background a dim red
> color instead of black.
> 
> Here is someone else noting it, ten years ago:
> http://daemonforums.org/showthread.php?t=4704
> 
> It doesn't happen on a real (nvidia) VGA, but unexpected behavior on
> a virtual machine can be a sign that code is doing undefined things
> on the hardware, which is worth investigating.
> 
> The call to vga_enable() at the end of vga_restore_palette() is what
> triggers the behavior.
> 
> This appears to be truly ancient code, but I don't think it was ever
> correct.
> 
> #define       vga_enable(vh) \
>       vga_raw_write(vh, 0, 0x20);
> 
> After resetting the attribute flip-flop, this is just setting the VGA
> attribute index to an illegal register value -- there aren't 32
> attribute registers.

bits 0-4 are the index register, bit 5 is some kind of an enable bit.

To quote Abrash

"bit 5 of the AC Index register should be set to 1 whenever palette RAM
is not being set (which is to say, all the time in your code, because
palette RAM should normally be set via the BIOS). When bit 5 is 0, video
data from display memory is no longer sent to palette RAM, and the
screen becomes a solid color—not normally a desirable state of affairs."

from
http://www.jagregory.com/abrash-black-book/#notes-on-setting-and-reading-registers

The Matrox G400 datasheet describes bit 5 as

"This bit controls use of the internal palette. If pas = 0, the host
CPU can read and write the palette, and the display is forced to the
overscan color. If pas = 1, the palette is used normally by the video
stream to translate color indices (CPU writes are inhibited and reads
return all `1's). Normally, the internal palette is loaded during the
blank time, since loading inhibits video translation."

from
http://www.bitsavers.org/pdf/matrox/G400SPEC_Jun1999.PDF
3-289 -> 3-290

> 
> The palette code doesn't even touch the attributes, so it doesn't
> have to reset the flip-flop, either.
> 
> The vga_enable() was also used, along with another unnecessary flip
> flop reset (it toggles between address and data, so after writing
> an address and data, it is back where it started), in the
> vga_attr_read and write functions.
> 
> Removing all this appears to work fine on both VirtualBox and Nvidia.
> 
> Perhaps there was errant code that wrote to the io port register at
> some point, and having it dissapear into an "invalid" register hid
> another bug?
> 
> Index: vga.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/vga.c,v
> retrieving revision 1.69
> diff -u -p -r1.69 vga.c
> --- vga.c     17 Jun 2017 19:20:30 -0000      1.69
> +++ vga.c     15 May 2020 23:38:32 -0000
> @@ -1213,8 +1213,6 @@ vga_save_palette(struct vga_config *vc)
>       vga_raw_write(vh, VGA_DAC_READ, 0x00);
>       for (i = 0; i < 3 * 256; i++)
>               *palette++ = vga_raw_read(vh, VGA_DAC_DATA);
> -
> -     vga_raw_read(vh, 0x0a);                 /* reset flip/flop */
>  }
>  
>  void
> @@ -1231,10 +1229,6 @@ vga_restore_palette(struct vga_config *v
>       vga_raw_write(vh, VGA_DAC_WRITE, 0x00);
>       for (i = 0; i < 3 * 256; i++)
>               vga_raw_write(vh, VGA_DAC_DATA, *palette++);
> -
> -     vga_raw_read(vh, 0x0a);                 /* reset flip/flop */
> -
> -     vga_enable(vh);
>  }
>  
>  void
> Index: vgavar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/vgavar.h,v
> retrieving revision 1.13
> diff -u -p -r1.13 vgavar.h
> --- vgavar.h  26 Jul 2015 03:17:07 -0000      1.13
> +++ vgavar.h  15 May 2020 23:38:32 -0000
> @@ -96,9 +96,6 @@ static inline void _vga_gdc_write(struct
>  #define      vga_raw_write(vh, reg, value) \
>       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, reg, value)
>  
> -#define      vga_enable(vh) \
> -     vga_raw_write(vh, 0, 0x20);
> -
>  static inline u_int8_t
>  _vga_attr_read(struct vga_handle *vh, int reg)
>  {
> @@ -110,11 +107,6 @@ _vga_attr_read(struct vga_handle *vh, in
>       vga_raw_write(vh, VGA_ATC_INDEX, reg);
>       res = vga_raw_read(vh, VGA_ATC_DATAR);
>  
> -     /* reset state XXX unneeded? */
> -     (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
> -
> -     vga_enable(vh);
> -
>       return (res);
>  }
>  
> @@ -126,11 +118,6 @@ _vga_attr_write(struct vga_handle *vh, i
>  
>       vga_raw_write(vh, VGA_ATC_INDEX, reg);
>       vga_raw_write(vh, VGA_ATC_DATAW, val);
> -
> -     /* reset state XXX unneeded? */
> -     (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
> -
> -     vga_enable(vh);
>  }
>  
>  static inline u_int8_t
> 
> 
> 

Reply via email to