OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Sep 17, 2019 2:50 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: VGA colors in 80x25 text mode?
PostPosted: Sun Jun 19, 2011 11:10 am 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
Hi, I was writing an extension for my kernel which would change the 16 VGA colors (for 80x25 text mode). I tried following Brackeen's tutorial on 256-color 0x13 mode, because in my old kernel (which I abandoned), I was able to set colors in 80x25 text mode in the exact same way. Now, the thing that goes wrong is that color 0 changes OK, but color 15 doesn't. I haven't tried other colors, but does anyone know how I should implement this correctly? Here's my extension:

Code:
/*

vgacol.h
Custom VGA colors kernel extension

This extension is "always enable". When it is
"disabled" (default ;)), it is only used to make
sure all colors are displayed appropriately on all
VGA screens (BIOS-independent).

Bibliography:
http://www.brackeen.com/vga/basics.html
http://www.brackeen.com/vga/bitmaps.html

*/

#ifndef _VGACOL_H
#define _VGACOL_H

#include <atom/kernel.h>

typedef struct color_struct
{
   u8int      red;
   u8int      green;
   u8int      blue;
} __attribute__ ((packed)) color_t;

color_t colors[16] = {
   {1,   1,   1},      /* black */
   {1,   1,   32},      /* blue */
   {1,   32,   1},      /* green */
   {1,   32,   32},      /* cyan */
   {32,   1,   1},      /* red */
   {32,   1,   32},      /* magenta */
   {16,   16,   1},      /* brown */
   {32,   32,   32},      /* light gray */
   {16,   16,   16},      /* dark gray */
   {1,   1,   63},      /* light blue */
   {1,   63,   1},      /* light green */
   {1,   63,   63},      /* light cyan */
   {63,   1,   1},      /* light red */
   {63,   1,   63},      /* light magenta */
   {63,   63,   1},      /* yellow */
   {63,   63,   63}      /* white */
};

void vgacol()
{
   /* write VGA colors */
   while ((inb(0x03DA) & 0x08));
   while (!(inb(0x03DA) & 0x08));
   int i=0;
   for (i=0; i<16; i++)
   {
      //outb(0x03C8, i);
      printdec(colors[i].red); printk(" ");
      printdec(colors[i].green); printk(" ");
      printdec(colors[i].blue); printk("\n");
      outb(0x03C9, colors[i].red);
      outb(0x03C9, colors[i].green);
      outb(0x03C9, colors[i].blue);
   };
   while (1);
};

#endif


When I change white and black, only black changes (to magenta) on the screen. The prindec()s print out the palette correctly.

And yes, I know that the palette I put there is exactly the same as VGA's original one, but when I change color 15 I don't see the effect, and that's why I'm asking. Is there something I'm doing wrong?

P.S. changing light red doesn't seem to work either... only color 0 is changing...

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Sun Jun 19, 2011 12:16 pm 
Offline
Member
Member
User avatar

Joined: Fri Jun 13, 2008 3:21 pm
Posts: 1700
Location: Cambridge, United Kingdom
Is there a reason why the write to - what is I assume, anyway (my VGA memory is hazy) - the palette index port is commented out?


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Sun Jun 19, 2011 2:25 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9284
Location: On the balcony, watching the Swedish Chef
Not writing the DAC address is one bug (though it might just happen to work because the bios loads the entire DAC after which the address ends up being 0 again). It should however increment automatically after each three DAC data writes, so you only need to write it once, before the loop.

The bigger problem is the EGA palette. Since you are in 16-colour mode, the 4 colour bits are mapped through the EGA palette to 6 bits, selecting colours from a grand choice of 64. Worse, the default setting makes sure that colours 0..15 do not map to DAC entries 0..15, but rather go all over that choice of 64.

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Mon Jun 20, 2011 12:35 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

Combuster wrote:
The bigger problem is the EGA palette. Since you are in 16-colour mode, the 4 colour bits are mapped through the EGA palette to 6 bits, selecting colours from a grand choice of 64. Worse, the default setting makes sure that colours 0..15 do not map to DAC entries 0..15, but rather go all over that choice of 64.


My book ("Programmer's Guide to the EGA, VGA and Super VGA Cards") explains it like this..

For EGA cards, the 4-bit colour is used as an index into a 16-entry palette to select one of 64 possible colours (where the 64 possible colours are "2-bit red, 2-bit green and 2-bit blue").

For VGA cards, the 4-bit colour is used as an index into a 16-entry EGA palette to select a 6-bit value, and then this 6-bit value is used as an index in the VGA palette to select one of 262144 possible colours (where the 262144 possible colours are "6-bit red, 6-bit green and 6-bit blue").

For VGA cards, the EGA palette is meant to be like this (as default):
Code:
EGA   VGA
0x0   0x00  Black
0x1   0x01  Blue
0x2   0x02  Green
0x3   0x03  Cyan
0x4   0x04  Red
0x5   0x05  Magenta
0x6   0x14  Brown
0x7   0x07  Light Gray
0x8   0x38  Gray
0x9   0x39  Light Blue
0xA   0x3A  Light Green
0xB   0x3B  Light Cyan
0xC   0x3C  Light Red
0xD   0x3D  Light Magenta
0xE   0x3E  Light Yellow
0xF   0x3F  White

Where "EGA" is the 4-bit original data value, and "VGA" is the 6-bit value used in the VGA palette to find the final colour. Notice how they're not sequential (and that brown is strange).

A while ago I did some experiments with the palette for 16-colour graphics modes (using BIOS functions to set the palette/s). I wanted to setup 16-colour graphics modes as "1-bit red, 2-bit green and 1-bit blue" to make my dithering code (which converts "8-bit blue, 8-bit red, 8-bit green" source data) simpler and faster. I found that:
  • some modern (Super VGA) video cards do it right (as described above) and some don't
  • there's no combination (of EGA and VGA palette values) that works correctly on all modern video cards
  • there's no way to determine if the video card does it right or not (at least not without a huge blacklist/whitelist with an entry for each video card)

In the end I couldn't get it to work reliably on all video cards (only about 75% of them) and gave up. I'd assume that the way palettes are used for 16-colour text modes is the same as 16-colour graphics modes, and that you'll have the same problem.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Mon Jun 20, 2011 5:15 am 
Offline
Member
Member

Joined: Fri Nov 16, 2007 1:59 pm
Posts: 612
Sorry, I think it will be correctly to write that the second column contains EGA colors/VGA indexes in DAC.

Now I don't have compatibility with EGA therefore I initialize "Attribute Controller" with 0-15 and load only first 16 DAC triplexes when update palette. Default palette (0) is compatible with EGA by colors but not by values stored in "Attribute Controller".

_________________
If you have seen bad English in my words, tell me what's wrong, please.


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Mon Jun 20, 2011 12:55 pm 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
Thanks, it works now. In my code I added a map of "EGA -> VGA" palette indexes as posted by Brendan, and it's working :) I just look up the table and insert the right value into the palette index port, and so on. And everything is fine!

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Mon Jun 20, 2011 8:05 pm 
Offline
Member
Member
User avatar

Joined: Mon Jul 28, 2008 9:46 am
Posts: 310
Location: Ontario, Canada
Thanks Brendan!

I had no idea why color 0x6 was not being set properly when I updated the palette. Now I find out that it is really 0x14 that needs to be set thus fixing the bug.

http://code.google.com/p/baremetal/sour ... nit_64.asm

_________________
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Wed Jun 22, 2011 2:02 am 
Offline
Member
Member

Joined: Fri Nov 16, 2007 1:59 pm
Posts: 612
The values 0-15 are correct for palette registers of "Attribute Controller" in VGA compatible cards and more simple. They are just indexes in DAC (4 or 6 low-significant bits of indexes). Total initialization of VGA register set gives good result with this values. Here is my default palette that compatible with EGA colors 0...5, 0x14, 7, 0x38... (see attach). And here is the code to initialize DAC with this palette.

Code:
  mov dl,VIDEO_DACMR and 0xFF
  mov al,0x0F ; mask to use only first 16 triplexes
  out dx,al
  mov dl,VIDEO_DACAWMR and 0xFF
  mov al,0 ; base index
  out dx,al
  mov dl,VIDEO_DACDR and 0xFF
  mov ecx,16*3 ; count of bytes to write
  rep outsb


Attachments:
cgapal.zip [148 Bytes]
Downloaded 35 times

_________________
If you have seen bad English in my words, tell me what's wrong, please.
Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Wed Jun 22, 2011 11:02 am 
Offline
Member
Member
User avatar

Joined: Mon Jul 28, 2008 9:46 am
Posts: 310
Location: Ontario, Canada
What is VIDEO_DACMR and why are you only setting DL?

This is my old code (That did not set color 6 or the high colors properly)
Code:
   xor eax, eax
   mov dx, 0x03C8      ; DAC Address Write Mode Register
   out dx, al
   mov dx, 0x03C9      ; DAC Data Register
   mov rcx, 16      ; 16 colors
   mov rsi, palette
nexttritone:
   lodsb
   out dx, al
   lodsb
   out dx, al
   lodsb
   out dx, al
   dec rcx
   cmp rcx, 0
   jne nexttritone

_________________
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Wed Jun 22, 2011 12:16 pm 
Offline
Member
Member

Joined: Fri Nov 16, 2007 1:59 pm
Posts: 612
Code:
VIDEO_DACMR equ 0x3C6 ; I think it's DAC Mask Register
...
VIDEO_ISR1 equ 0x3DA
...

  mov edx,VIDEO_ISR1 ; set address for first i/o operation (dh=3)
  ...
  mov dl,VIDEO_DACMR and 0xFF
  ...

_________________
If you have seen bad English in my words, tell me what's wrong, please.


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Wed Jun 22, 2011 3:33 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9284
Location: On the balcony, watching the Swedish Chef
in other words, its a poorly documented trick to optimize
o16 mov dx, register; out dx, al;
to
mov dh, 0x03 ; all vga registers take the form of 3xx; add three bytes here
(...)
mov dl, register; out dx, al; save two bytes for each of these

Using just the DAC mask however breaks the brown colour since PAL[6] & 0x0f = 4 and PAL[4] & 0x0f = 4, which means that brown becomes aliased to red. That said, brendan's table of DAC aliases correspond with the default values in the EGA palette, and on a true VGA they can be modified to a linear palette:
Code:
mov dx, 0x3da
in al, dx ; reset AC flipflop to "address"
mov dx, 0x3c0 ; AC register
mov al, 16
.loop:
dec al
out dx, al    ; index
out dx, al    ; data: pal[x] = x
jnz .loop
mov al, 0x20
out dx, al   ; enable screen again


What concerns me more is that Brendan mentioned poor implementations of PAL/DAC in 16-colour modes with the added conclusion that neither rewriting the PAL nor rewriting the DAC or any combination of the two gives guaranteed success. I already realized that I need two VGA drivers anyway: one for all the implementations that can do the standard stuff, i.e. either text, planar-16 w/o DAC, chain4-256 or Mode X with DAC and none of the fun stuff, and one that actually exposes all VGA features including but not limited to GRs, latches, EGA palette, splitscreens, linear 16-colour modes, 512-character text and freeform resolutions. The first driver would then be primarily for emulated hardware (which sucks in general) and possibly bad vga clones, while the second would be for actual VGAs and 100% compatibles.

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Fri Jun 24, 2011 9:11 am 
Offline
Member
Member

Joined: Fri Nov 16, 2007 1:59 pm
Posts: 612
Your code like mine:
Code:
  mov edx,VIDEO_ISR1

  cli
  in al,dx

  mov dl,VIDEO_AOR and 0xFF
  mov al,VIDEO_MAXATTR
@@:
  out dx,al
  outsb
  dec al
  cmp al,0x10
  jae @b
@@:
  out dx,al
  out dx,al
  sub al,1
  jnc @b

  mov al,0x20
  out dx,al


I have the second variant only (with advanced VGA features such as 512 different characters at once - normal and bold characters as alternative for 256 different characters with normal and bright colors, 16 background colors as alternative for 8 colors and blinking, fixed base address of video memory for all modes - 0xA0000, fixed "EGA palette" for all color palettes - 0-15, resolution 80x30 (720x 480) as alternative for resolution 80x25 (720x400) and so on). I use only first 16 DAC triplexes because it's simple and some emulators have no support for DAC palette splitting 16x16 and 4x64. The driver works fine on all hardware where I test it.

_________________
If you have seen bad English in my words, tell me what's wrong, please.


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Fri Jun 24, 2011 5:20 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9284
Location: On the balcony, watching the Swedish Chef
You do know that that code snippet lacks any form of documentation and does not, as your wording suggests, do what my snippet does?

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Sat Jun 25, 2011 2:40 am 
Offline
Member
Member

Joined: Fri Nov 16, 2007 1:59 pm
Posts: 612
Hmm, it does more than just initialize "EGA palette". And what kind of documentation do you want to see? Is it such comment as "reset flip-flop to write index" or "reset PAS bit for normal operation of the attribute controller"? Or anybody don't understand what is means VIDEO_AOR or VIDEO_MAXATTR? :D

_________________
If you have seen bad English in my words, tell me what's wrong, please.


Top
 Profile  
 
 Post subject: Re: VGA colors in 80x25 text mode?
PostPosted: Mon Jul 22, 2019 8:20 pm 
Offline
Member
Member

Joined: Tue Apr 24, 2018 9:46 pm
Posts: 56
Brendan wrote:
For VGA cards, the EGA palette is meant to be like this (as default):
Code:
EGA   VGA
0x0   0x00  Black
0x1   0x01  Blue
0x2   0x02  Green
0x3   0x03  Cyan
0x4   0x04  Red
0x5   0x05  Magenta
0x6   0x14  Brown
0x7   0x07  Light Gray
0x8   0x38  Gray
0x9   0x39  Light Blue
0xA   0x3A  Light Green
0xB   0x3B  Light Cyan
0xC   0x3C  Light Red
0xD   0x3D  Light Magenta
0xE   0x3E  Light Yellow
0xF   0x3F  White



=D> Thank you for this table! Was wondering why the colors no longer matched when switching from text mode to graphics mode then back to text mode. Why brown (0x6) now appeared as a shade of grey! The shade of grey is exactly the color at index 0x14, and so on... Maybe the reason this isn't so well documented is because once people leave text mode, they never look back.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group