Note on this tutorial

I wrote this tutorial many years ago (2001-2002). Because of the large number of links pointing to it I've left it up. However, I no longer support it. Please do not contact me asking for help with QBASIC, ASM, or other programming issues. Also, please do not contact me about minor errors in the text: the text of this tutorial is mostly unedited, and only the presentation and markup have been significantly updated (to valid XHTML 1.0 strict). If there are major errors which significantly interfere with readability, though, please feel free to bring them to my attention - Billy Wenge-Murphy
This tutorial is (c) 2001-2007 Billy Wenge-Murphy. All rights reserved. It may not be copied, reproduced, or redistributed in any form without permission. If you wish to share it, please link to it instead of reposting it.

4.5 - The palette

Mode 13h is called a 'paletted' graphics mode. That is, you can use 256 colors at once but there's something like 4 million possible colors (4,144,959 actually). When you write a byte to the screen, you're only telling which number of the palette that pixel is, not what the pixel actually looks like. What the color looks like is something saved in the palette.

So, how do you tell what a pixel/color looks like. Well, you mix 3 basic colors: Red, blue, and green. Things which emit their own light such as the electron gun in a TV or monitor have base colors red, green and blue, while other natural [reflected?] light has red, blue, and yellow. That's just how it happens. So, you can think of defining the look of a color as mixing colors, much like you probably did early in school with paint or something.

So, it's quite easy. But you must be familiar with yet another command: OUT. This command puts a byte out to a 'port' in your computer. We need this because your video card, which has control over the palette, has many different ports you must interface with from time to time. You can't just write bytes to them since they're ports, you have to use OUT (and to get stuff from a port, use IN)

But, why must we even use the palette at all? Well, sometimes the default palette doesn't have the exact shade of color you want, which there's a good chance of since there's only 256 in it. So, you just mix your own values of red, blue, and green and make the exact color you want.

The sprite in our last program was saved as an image file through windows, then i saved it in the file we used which has no junk in it like a "bitmap" does. Just the pure bytes that make the image. The problem is, the colors in that image didn't look the same as the original bitmap, since MS Paint in windows uses one palette, and our DOS based program uses another.
However, I did happen to save the palette and put it in a file. This way, we can make the colors in our program look the same as the original image, so that it's loaded correctly.
Before diving into the big main program, let's go over some simple palette stuff:
For simplicity's sake, let's just change the look of one color. We'll change color 0 (by default, completely black) to white. This is just a couple of out commands:

.MODEL MEDIUM
.STACK 200H
.CODE
START:

mov ax, 0013h
int 10h

xor al, al
mov dx, 3c8h
out dx, al

inc dx
mov al, 63
out dx, al
out dx, al
out dx, al

mov ax, 0100h
int 21h
mov ax, 4c00h
int 21h

end start

To use OUT we give it a port and a value. The port can be in DX, and the value in al - no other registers will work. They don't have to be in registers though. To write to the palette, first we send a byte to port 3c8h telling it which color we want to change. We did xor al,al because we want to change black, color 0. Then, it takes the next 3 values at port 3c9h. So we just INCed dx. The 3 values you give it are the amounts of red, green, and blue your new color will contain. Each one has a value from 0 to 63. Giving it 3 0's would result in black, and at the opposite extreme, 3 63's results in pure white. So, we just do mov al,63 and put it out to port 3c9h 3 times. The result should be the black screen changing to white. Don't be confused though - every byte in the screen's memory was 0 before, and it still is. We just changed what color 0 looks like.

So, we can now load the palette in our program before, making all the colors look right.

Yep, the tutorial ends abruptly right here. It was never finished and never will be. Sorry!
Mascot: Billy's Weird Cat Thing