I've got a bare bones kernel that I have added VGA support to. It works great, except that all colors beyond ~30-40 dont work. I'm not sure what's wrong, so I was hoping someone could help me. Here is the relevant code:
Code: Select all
static __inline__ void outb(unsigned short port, unsigned char val)
{
asm volatile("outb %0,%1"::"a"(val), "dN" (port));
}
static __inline__ unsigned char inb(unsigned short port)
{
unsigned char ret;
asm volatile ("inb %1,%0":"=a"(ret):"dN"(port));
return ret;
}
void mode13h() {
/*** CRT CONTROLLER REGISTERS ***/
unsigned char CRTCRegs[] = {
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
};
unsigned int CRTCRegsSize = 25;
/*** ATTRIBUTE CONTROLLER REGISTERS ***/
unsigned char ACRegs[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x41, 0x00, 0x0F, 0x00, 0x00
};
unsigned int ACRegsSize = 21;
/*** GRAPHICS CONTROLLER REGISTERS ***/
unsigned char GCRegs[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
0xFF
};
unsigned int GCRegsSize = 9;
/*** SEQUENCER REGISTERS ***/
unsigned char SEQRegs[] = {
0x03, 0x01, 0x0F, 0x00, 0x0E
};
unsigned int SEQRegsSize = 5;
/*** ******************* ***/
/*** ******************* ***/
unsigned int i, q;
outb(0x3C2, 0x63); // Misc register
for(i = 0; i < SEQRegsSize; i++) {
outb(0x3C4, i);
outb(0x3C5, SEQRegs[i]);
}
// Enable CRTC regs
outb(0x3D4, 0x03);
outb(0x3D5, inb(0x3D5) | 0x80);
outb(0x3D4, 0x11);
outb(0x3D5, inb(0x3D5) & ~0x80);
// make sure they stay enabled
CRTCRegs[0x03] |= 0x80;
CRTCRegs[0x11] &= ~0x80;
for(i = 0; i < CRTCRegsSize; i++) {
outb(0x3D4, i);
outb(0x3D5, CRTCRegs[i]);
}
for(i = 0; i < GCRegsSize; i++) {
outb(0x3CE, i);
outb(0x3CF, GCRegs[i]);
}
for(i = 0; i < ACRegsSize; i++) {
q = inb(0x3DA); q = q;
outb(0x3C0, i);
outb(0x3C0, ACRegs[i]);
}
q = inb(0x3DA); q = q;
outb(VGA_AC_INDEX, 0x20);
}
static inline void setp(int x, int y, unsigned char color) {
static unsigned char * vga_mem = (unsigned char *) 0xA0000;
if (x > 320 || x < 0 || y > 200 || y < 0) return;
vga_mem[320 * y + x] = color;
}
void vga_clear()
{
int x;
int y;
for(y=0;y<200;y++) {
for(x=0;x<320;x++) {
setp(x, y, 0);
}
}
}
void _kmain() {
mode13h();
vga_clear();
int x = 0;
int y = 0;
unsigned char color = 0;
// draw a simple line and go through each color.
while (1) {
color++;
if (color > 254) color = 0;
x += 1;
y += 1;
setp(x, y, color);
}
}
Here is a screenshot of what I get: http://i35.tinypic.com/258t9gy.png
I tried to make sure I was setting the right registers by referring to the VGA Hardware article on the wiki, and I'm pretty sure I am. Still, there is obviously an error somewhere.
Can anyone figure out what's wrong? (It's probably something really stupid I did <_<)