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
vga graphic mode
- kenneth_phough
- Member
- Posts: 106
- Joined: Sun Sep 18, 2005 11:00 pm
- Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
- Contact:
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
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/
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/
Some info can be found on bubach's site :
http://bos.asmhackers.net/docs/vga_without_bios/
http://bos.asmhackers.net/docs/vga_without_bios/
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);
}
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.
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 99 times
-
- vga_modes.inc.c
- (4.88 KiB) Downloaded 99 times
-
- vga.c
- (9.93 KiB) Downloaded 113 times
- Kevin McGuire
- Member
- Posts: 843
- Joined: Tue Nov 09, 2004 12:00 am
- Location: United States
- Contact:
vga protected mode no bios
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.
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.
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
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;
}
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;
}
http://www.osdever.net/FreeVGA/home.htm#vga