Page 1 of 1

VGA Driver Programming

Posted: Thu Feb 12, 2009 9:14 am
by freakxnet
Hi guys, im new in this forum but i read here for a while.
So i'm from germany, sorry for errors in my english.

So here is my problem or ignorance.

I user GRUB as bootloader and to switch for me in pm mode. I have written a bit of code and reporgrammed some functions like printf,io routines (outportb,inportb), convertsion functions like itoa, dec2hex, detecting floppy drives,setup systemtime, memory management and so on.

Now i would like to setup a simple VGA Driver in Mode 13h (at first simple 320x200@16 Colors). I read several documentations about the registers and all the stuff.
I think i know the basics behind them. But i have a general problem with the setup of the graphics mode. I don't understand the prozess of setup. I mean i have read a list of steps but in fact that says me not enough what i have to code to get the graphics mode.

For information im not a newby at programming and asm (not so good like C but i understand asm code). I have no code that i can paste here because i deleted all in front of frustration to code it new and ask here for help.

If anybody think that he has time to help me with usefull facts then i would be very thankful.

Regards

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 9:48 am
by clange
Hi

If you just want to set the graphics mode you can use this code as a starting point: http://files.osdev.org/mirrors/geezer/o ... cs/modes.c. It is not my code, but I have used it myself.

The easiest mode will be mode 13h as you mention, but 256 colors - not 16 colors. The memory layout of 320x200x256 is the simplest of all VGA modes.

clange

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 9:51 am
by Combuster
See VGA Hardware - it should have everything you need to get a VGA driver going.

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 10:16 am
by freakxnet
Ok thanks for the really fast answers. I will try to write the driver with the both information.
I post my current source when i'm hang and write my problems.

Regards

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 11:05 am
by freakxnet
Ok here is the first thing that i dont understand.

unsigned char g_320x200x256[] =
{
/* MISC */
0x63,
/* SEQ */
0x03, 0x01, 0x0F, 0x00, 0x0E,
/* CRTC */
0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
0xFF,
/* GC */
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
0xFF,
/* AC */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x41, 0x00, 0x0F, 0x00, 0x00
};

From where i know the data that are written to the registers? I mean why is written 0x63 to the misc out register?
In fact that is main question why i'm hang so on vga programming. Where i know all the values that have to write?

Regards

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 11:14 am
by Combuster
Where i know all the values that have to write?
That's why these listings exist - to get you started. You don't have to memorize all registers initially and what they mean, that's something that needs to grow.

Start with loading that dump into video memory, then read the wiki page (focused on usage) and freevga (focused on individual registers) to see what each does, then try to put that to practice. Most likely you don't need to know all this by hard anyway.

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 11:43 am
by freakxnet
Ok the first thing the of misc out register is now relative clear, i think.

7 6 5 4 3 2 1 0
VSP HSP - - CS ERAM IOS

- : Set to 0, Undefined on Read
VSP : Vertical Sync Polarity
HSP : Horizontal Sync Polarity
CS : Clock Select
ERAM : Enable RAM
IOS : I/O Address Select

0x63=01100011

1 1 0 0 0 1 1 0
7 6 5 4 3 2 1 0

So if i see that right then means that bits 7,6 set the 480 vertical lines, bits 5,4 are zero, bits 3,2 is set the clock to 28.322 MHz, bit 1 one enables the ram and bit 0 set to zero that port 3D4 is mapped to 3B4 . Is that right?

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 5:31 pm
by freakxnet
Ok its done. I've setted up the mode 13 and i can clear the screen by direct accessing the video memory.
Not bad. But now it seems to be that i have a problem with the palettes. When i plot a pixel on screen on this way

VGA_address[VGA_width*y+x]=0x0f;

then is the color not white. What i get is a color that is not white, more violett. Here is my code.

Code: Select all

//define the ports , taken from http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c
#define	VGA_AC_INDEX		0x3C0
#define	VGA_AC_WRITE		0x3C0
#define	VGA_AC_READ			0x3C1
#define	VGA_MISC_WRITE		0x3C2
#define VGA_SEQ_INDEX		0x3C4
#define VGA_SEQ_DATA		0x3C5
#define	VGA_DAC_READ_INDEX	0x3C7
#define	VGA_DAC_WRITE_INDEX	0x3C8
#define	VGA_DAC_DATA		0x3C9
#define	VGA_MISC_READ		0x3CC
#define VGA_GC_INDEX 		0x3CE
#define VGA_GC_DATA 		0x3CF
#define VGA_CRTC_INDEX		0x3D4		/* 0x3B4 */
#define VGA_CRTC_DATA		0x3D5		/* 0x3B5 */
#define	VGA_INSTAT_READ		0x3DA
#define	VGA_NUM_SEQ_REGS	5
#define	VGA_NUM_CRTC_REGS	25
#define	VGA_NUM_GC_REGS		9
#define	VGA_NUM_AC_REGS		21
#define	VGA_NUM_REGS		(1+VGA_NUM_SEQ_REGS+VGA_NUM_CRTC_REGS+VGA_NUM_GC_REGS+VGA_NUM_AC_REGS)

//the vga identifiers
unsigned int VGA_width;
unsigned int VGA_height;
unsigned int VGA_bpp;
unsigned char *VGA_address;

/**
 * CREATE THE REGISTER ARRAY TAKEN FROM http://wiki.osdev.org/VGA_Hardware
 */
unsigned char mode_320_200_256[]={
	/* MISC
	 *
	 * 0x63 => 01100011
	 * 7 6 5 4 3 2 1 0
	 * 1 1 0 0 0 1 1 0
	 * VSP HSP - - CS CS ERAM IOS
	 * 7,6 - 480 lines
	 * 5,4 - free
	 * 3,2 - 28,322 MHZ Clock
	 * 1 - Enable Ram
	 * 0 - Map 0x3d4 to 0x3b4
	 */
	0x63,
	/* SEQ */
	/**
	 * index 0x00 - Reset
	 * 0x03 = 11
	 * Bits 1,0 Synchronous reset
	 */
	0x03,
	/**
	 * index 0x01
	 * Clocking mode register
	 * 8/9 Dot Clocks
	 */
	0x01,
	/**
	 * Map Mask Register, 0x02
	 * 0x0F = 1111
	 * Enable all 4 Maps Bits 0-3
	 * chain 4 mode
	 */
	0x0F,
	/**
	 * map select register, 0x03
	 * no character map enabled
	 */
	0x00,
	/**
	 * memory mode register 0x04
	 * enables ch4,odd/even,extended memory
	 */
	0x0E,
	/* CRTC */
	0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
	0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x9C, 0x0E, 0x8F, 0x28,	0x40, 0x96, 0xB9, 0xA3,
	0xFF,
	/* GC */
	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
	0xFF,
	/* AC */
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
	0x41, 0x00, 0x0F, 0x00,	0x00
};

void write_registers(unsigned char *regs){
	unsigned i;

	/* write MISCELLANEOUS reg */
	outportb(VGA_MISC_WRITE, *regs);
	regs++;
	/* write SEQUENCER regs */
	for(i = 0; i < VGA_NUM_SEQ_REGS; i++)
	{
		outportb(VGA_SEQ_INDEX, i);
		outportb(VGA_SEQ_DATA, *regs);
		regs++;
	}
	/* unlock CRTC registers */
	outportb(VGA_CRTC_INDEX, 0x03);
	outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) | 0x80);
	outportb(VGA_CRTC_INDEX, 0x11);
	outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) & ~0x80);
	/* make sure they remain unlocked */
	regs[0x03] |= 0x80;
	regs[0x11] &= ~0x80;
	/* write CRTC regs */
	for(i = 0; i < VGA_NUM_CRTC_REGS; i++)
	{
		outportb(VGA_CRTC_INDEX, i);
		outportb(VGA_CRTC_DATA, *regs);
		regs++;
	}
	/* write GRAPHICS CONTROLLER regs */
	for(i = 0; i < VGA_NUM_GC_REGS; i++)
	{
		outportb(VGA_GC_INDEX, i);
		outportb(VGA_GC_DATA, *regs);
		regs++;
	}
	/* write ATTRIBUTE CONTROLLER regs */
	for(i = 0; i < VGA_NUM_AC_REGS; i++)
	{
		(void)inportb(VGA_INSTAT_READ);
		outportb(VGA_AC_INDEX, i);
		outportb(VGA_AC_WRITE, *regs);
		regs++;
	}
	
	/* lock 16-color palette and unblank display */
	(void)inportb(VGA_INSTAT_READ);
	outportb(VGA_AC_INDEX, 0x20);
}

/**
 * Clears the VGA screen
 */
void VGA_clear_screen(){
	unsigned int x=0;
	unsigned int y=0;

	for(y=0; y<VGA_height; y++){
		for(x=0; x<VGA_width; x++){
			VGA_address[VGA_width*y+x]=0x0f;
		}
	}
}

/**
 * Note here the vga struct must have the width 320 and height of 200
 * color mode is 256
 */
void VGA_init(int width, int height, int bpp){
	//setup the vga struct
	VGA_width=(unsigned int)width;
	VGA_height=(unsigned int)height;
	VGA_bpp=bpp;
	VGA_address=0xA0000;

	//enables the mode 13 state
	write_registers(mode_320_200_256);

	//clears the screen
	VGA_clear_screen();
}
Have i forgott something?

Regards

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 5:38 pm
by Combuster
The DAC is still in an undefined state. If you want to have a guaranteed set of colors, you should plug them into the DAC registers instead of relying what the bios put in there previously.

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 5:53 pm
by freakxnet
Ok thanks. I solved the problem with that code, here i mapped on index 0x00 the
color 0x3f,0x3f,0x3f

outportb(0x3c8,0x00);
outportb(0x3c9,0x3f);
outportb(0x3c9,0x3f);
outportb(0x3c9,0x3f);

When i call the clear screen function the the screen takes the color white.

Regards

Re: VGA Driver Programming

Posted: Thu Feb 12, 2009 7:58 pm
by freakxnet
Ok so its all nice. Now my next step is to implement higher resolutions like 1024x768@16bpp or 32bpp.
I use grub as bootloader. I searched for information about but i dont really found information yet.
What i know is that the VGA Driver i have written this cannot do in any cases. So i think about Vesa i read that they can support such things.

Have anybody a tip where i can start my search for information to support such modes in use with grub and Qemu?

Regards

Re: VGA Driver Programming

Posted: Fri Feb 13, 2009 12:23 am
by eddyb
freakxnet wrote:Ok so its all nice. Now my next step is to implement higher resolutions like 1024x768@16bpp or 32bpp.
I use grub as bootloader. I searched for information about but i dont really found information yet.
What i know is that the VGA Driver i have written this cannot do in any cases. So i think about Vesa i read that they can support such things.

Have anybody a tip where i can start my search for information to support such modes in use with grub and Qemu?

Regards
VGA can't do that, so yeah, you're right, you need VBE.
After googling less than a minute, i found http://www.smk.co.za/software/vbe-grub/ .
there are 2 patches for 2 version of grub. you have to download the grub source and the patch, to apply the patch and to compile it. that will give you the possibility of putting a command in the menu.lst file that will set the VBE mode for you.

Re: VGA Driver Programming

Posted: Fri Feb 13, 2009 12:32 pm
by Dex
I have coded a vesa demo, that is fully self contained (eg: self booting), that may help http://dex4u.com/demos/VesaDemo.zip