vga graphic mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

vga graphic mode

Post by kenneth_phough »

how does one change the vga graphic mode from pmode? I was thinking of implementing a virtual realmode and use BIOS interrupts but is there a more efficient way?

Thanks,
Kenneth
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

This question has probably been asked a billions times, searching the forum might help..

But IIRC, VBE3 has a protected mode interface to change video modes.. Although with VBE2 you have to change modes in realmode or v86.

I don't think you have any/many more options.. :?

The OSDev Wiki might be able to help you...
http://www.osdev.org/wiki/
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Some info can be found on bubach's site :
http://bos.asmhackers.net/docs/vga_without_bios/
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

Post by GLneo »

try this for mode 13h:

Code: Select all

static const unsigned short h[] = {0xbf06, 0x1f07, 0x4109, 0x9c10, 0x8e11, 0x8f12,
0x9615, 0xb916};
static const unsigned short w[] = {0x5f00, 0x4f01, 0x5002, 0x8203, 0x5404, 0x8005,
0x2813};

void set_video_mode_13h()
{
    int temp, a;
    outportb(0x3C2, 0x63);
    outportw(0x3D4,0x0E11);
    for(a = 0; a < 7; ++a) 
        outportw(0x3D4, w[a]);
    for(a = 0; a < 8; ++a)
        outportw(0x3D4, h[a]);
    outportw(0x3D4,0x0008);
    outportw(0x3D4,0x4014);
    outportw(0x3D4,0xa317);
    outportw(0x3C4,0x0e04);
    outportw(0x3C4,0x0101);
    outportw(0x3C4,0x0f02);
    outportw(0x3Ce,0x4005);
    outportw(0x3Ce,0x0506);
    inportb(0x3DA);
    outportb(0x3C0,0x30); 
    outportb(0x3C0,0x41);
    outportb(0x3C0,0x33); 
    outportb(0x3C0,0x00);
    for(temp = 0; temp < 16; temp++) 
    {
        outportb(0x3C0, (unsigned char)temp);
        outportb(0x3C0, (unsigned char)temp);
    }
    outportb(0x3C0, 0x20);
}
majo
Posts: 5
Joined: Wed Apr 05, 2006 11:00 pm

Post by majo »

I used some public domain code for my own os which sets the VGA registers for different modes out of arrays containing all the necessary values.

I have attached my modified version.

Don't ask me what all the registers are for, I don't know.
Attachments
vga_definitions.inc.c
(44.74 KiB) Downloaded 100 times
vga_modes.inc.c
(4.88 KiB) Downloaded 99 times
vga.c
(9.93 KiB) Downloaded 113 times
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

vga protected mode no bios

Post by Kevin McGuire »

I can tell you a little to help you along if you are a do it you're selfer.

There are five major functionality blocks present on a VGA card. These are the Cathode Ray Tube Block, Sequencer Block, Attribute Block, Extension Block, Digital To Analog Block, and the Graphics Block. Each block is accessed using a two or three registers.

The extension registers help configure the card as a whole, and allow proprietary functionality to become enabled such as SVGA IIRC. They also can change the DOT clock which is used to set the resolution among using many other registers in the following blocks.

The Cathode Ray Tube registers are going to help you format the output from the final stages onto the monitor by setting the number of scan lines for the horizontal and vertical screen along with niffy little settings that can divide the DOT clock and memory clocks independently to enable higher resolutions in the 1024x1024 range using four and eight bits per pixel IIRC.

Graphics registers are going to help you do a little mapping of video memory to the RAM which is access by your software. The graphics registers have different modes which some are used for special things such as clearing the entire or sections of the screen using methods that are faster than just writing a solid color to all pixels.

The sequencer registers are going to control the sequencer block which comes after the graphics block and they also help control the mapping of RAM address to video memory. They also support some more advanced mapping mechanisms like masking certain planes for writing and reading.

The attribute registers seem to contain things primarily relevant to text mode, but do contain some very important things such as the palette which is used as a table into the Digital To Analog converter.

The Digital To Analog controller registers contain settings to modify the circuit that converts the digital colors values into analog signals that the monitor understands. This is where you can store up to two-hundred-fifty-fix colors and depending on the mode you can use all or switch between sets of them.

Here are some helpful macro functions to enable accessing the registers in a easier way.

Code: Select all

#define VGA_GFX_ADDR 0x3CE
#define VGA_GFX_DATA 0x3CF
#define VGA_SEQ_ADDR 0x3C4
#define VGA_SEQ_DATA 0x3C5
#define VGA_DAC_WADDR 0x3C8
#define VGA_DAC_RADDR 0x3C7
#define VGA_DAC_DATA  0x3C9
#define VGA_DAC_STATE 0x3C7
#define VGA_CRT_ADDR  0x3D4
#define VGA_CRT_DATA  0x3D5
#define VGA_ATR_ADDRDATA  0x3C0
#define VGA_ATR_READ  	  0x3C1
#define CLK_25 0x00
#define CLK_28 0x04
#define CLK_U0 0x08
#define CLK_U1 0x0C

inline void vga_atr_w_ip(u16 index, u8 data){
	inb(0x3da);
	outb(index, VGA_ATR_ADDRDATA);
	outb(data, VGA_ATR_ADDRDATA);
	return;
}
inline void vga_atr_w(u16 index, u8 data){
	inb(0x3da);
	outb(index|0x20, VGA_ATR_ADDRDATA);
	outb(data, VGA_ATR_ADDRDATA);
	return;
}
inline u8 vga_atr_r_ip(u16 index){
	inb(0x3da);
	outb(index, VGA_ATR_ADDRDATA);
	return inb(VGA_ATR_READ);
}
inline u8 vga_atr_r(u16 index){
	inb(0x3da);
	outb(index|0x20, VGA_ATR_ADDRDATA);
	return inb(VGA_ATR_READ);
}
inline u8 vga_seq_r(u16 index){
	outb(index, VGA_SEQ_ADDR);
	return inb(VGA_SEQ_DATA);
}
inline u8 vga_gfx_r(u16 index){
	outb(index, VGA_GFX_ADDR);
	return inb(VGA_GFX_DATA);
}
inline u8 vga_dac_r(u16 index){
	return inb(index);
}
inline u8 vga_crt_r(u16 index){
	outb(index, VGA_CRT_ADDR);
	return inb(VGA_CRT_DATA);
}
inline void vga_crt_w(u16 index, u8 data){
	outb(index, VGA_CRT_ADDR);
	outb(data, VGA_CRT_DATA);
	return;
}
inline void vga_dac_w(u16 index, u8 data){
	outb(data, index);
	return;
}
inline void vga_seq_w(u8 index, u8 data){
	outb(index, VGA_SEQ_ADDR);
	outb(data, VGA_SEQ_DATA);
	return;
}
inline void vga_gfx_w(u8 index, u8 data){
	outb(index, VGA_GFX_ADDR);
	outb(data, VGA_GFX_DATA);
	return;
}
A lot of times a driver will contain a structure that holds a value for each index in each register block so that when a mode switch occurs the entire register set is just simply dumped into the VGA card. One of the posters used such a method and works quite well actually. In a lot of cases the function will look like this.

Code: Select all

static inline void vga_setmode(struct tvmode *mode){
	u32 x;
	// write extension registers
	outb(mode->extReg[0], 0x3C2);
	// write crt registers
	vga_crt_w(0x11, 0x0);
	for(x = 0; x < CRTCOUNT; ++x){
		vga_crt_w(x, mode->crtReg[x]);
	}
	// write sequencer registers
	for(x = 0; x < SEQCOUNT; ++x){
		vga_seq_w(x, mode->seqReg[x]);
	}
	// write graphic registers
	for(x = 0; x < GFXCOUNT; ++x){
		vga_gfx_w(x, mode->gfxReg[x]);
	}
	// reset palette flip-flop
	inb(0x3da);
	// write attribute palette
	for(x = 0; x < 0xF; ++x){
		vga_atr_w_ip(x, mode->atrReg[x]);
	}
	// enable access to attribute palette
	outb(0x20, VGA_ATR_ADDRDATA);
	// reset palette flip-flop
	inb(0x3da);
	// write remaining attribute registers
	for(; x < ATRCOUNT; ++x){
		vga_atr_w(x, mode->atrReg[x]);
	}
	return;
}
This is a excellent resource for VGA programming. I made a functional VGA driver using this documentation, and it took many hours to do so but it is very possible.
http://www.osdever.net/FreeVGA/home.htm#vga
Post Reply