here is the mode switching and writing to video memory
Code:
void port_3c0_write(uint8_t index, uint8_t data) {
inb(0x3da); // read to clear index/data status
outb(0x3c0, index); //send index
outb(0x3c0, data); //send index
}
uint8_t port_3c0_read(uint8_t index) {
uint8_t retval;
inb(0x3da); // read to clear index/data status
outb(0x3c0, index); //send index
retval = inb(0x3C1);
inb(0x3da); // read to clear index/data status
return retval;
}
void port_3c4_write(uint8_t index, uint8_t data) {
outb(0x3c4, index);
outb(0x3c5, data);
}
void port_3ce_write(uint8_t index, uint8_t data) {
outb(0x3ce, index);
outb(0x3cf, data);
}
void port_3d4_write(uint8_t index, uint8_t data) {
outb(0x3d4, index);
outb(0x3d5, data);
}
uint8_t port_3d4_read(uint8_t index) {
outb(0x3d4, index);
return inb(0x3d5);
}
void do_switch(void) {
// now let's try to switch to mode 13h 320x200x256 linear
// dont know if the order makes a difference
/*MISC*/
outb(0x3c2, 0x63); //Miscellaneous Output Register
/*sequencer*/
port_3c4_write(0x00, 0x03); // ?
port_3c4_write(0x01, 0x01); // clock mode register
port_3c4_write(0x02, 0x05);
port_3c4_write(0x03, 0x00); // character select
port_3c4_write(0x04, 0x0e); // memory mode register
// unlock the crtc regs
uint8_t temp = port_3d4_read(0x03);
port_3d4_write(0x03, temp | 80); // ors against f000 0000
temp = port_3d4_read(0x11);
port_3d4_write(0x11, temp & ~80); // ands against 0fff ffff
/*CRTC*/
port_3d4_write(0x00, 0x5f); // horizontal total
port_3d4_write(0x01, 0x4f); // horizontal display enable end
port_3d4_write(0x02, 0x50); // Horizontal Blank Start
port_3d4_write(0x03, 0x82); // horizontal blank end
port_3d4_write(0x04, 0x54); // horizontal retrace start
port_3d4_write(0x05, 0x80); // horizontal retrace end
port_3d4_write(0x06, 0xbf); // horizontal vertical total
port_3d4_write(0x07, 0x1f); // horizontal overflow register
port_3d4_write(0x08, 0x00); // horizontal preset row scan
port_3d4_write(0x09, 0x41); // maximum scan line
port_3d4_write(0x0A, 0x00); // ?
port_3d4_write(0x0B, 0x00); // ?
port_3d4_write(0x0C, 0x00); // ?
port_3d4_write(0x0D, 0x00); // ?
port_3d4_write(0x0E, 0x00); // ?
port_3d4_write(0x0F, 0x00); // ?
port_3d4_write(0x10, 0x9c); // vertical retrace start
port_3d4_write(0x11, 0x8e); // vertical retrace end vga_hardware page has 8e doesnt seem to make a difference
port_3d4_write(0x12, 0x8f); // vertical display enable end
port_3d4_write(0x13, 0x28); // logical width
port_3d4_write(0x14, 0x40); // unsderline location
port_3d4_write(0x15, 0x96); // vertical blank start
port_3d4_write(0x16, 0xb9); // vertical blank end
port_3d4_write(0x17, 0xa3); // mode control
port_3d4_write(0x18, 0xff); // ?
/*Graphics Controller*/
port_3ce_write(0x00, 0x00); // ?
port_3ce_write(0x01, 0x00); // ?
port_3ce_write(0x02, 0x00); // ?
port_3ce_write(0x03, 0x00); // ?
port_3ce_write(0x04, 0x00); // ?
port_3ce_write(0x05, 0x40); // mode register
port_3ce_write(0x06, 0x05); // misc register
port_3ce_write(0x07, 0x0f); // ?
port_3ce_write(0x08, 0xff); // ?
/*attribute controller*/
port_3c0_write(0x00, 0x00); // ?
port_3c0_write(0x01, 0x01); // ?
port_3c0_write(0x02, 0x02); // ?
port_3c0_write(0x03, 0x03); // ?
port_3c0_write(0x04, 0x04); // ?
port_3c0_write(0x05, 0x05); // ?
port_3c0_write(0x06, 0x06); // ?
port_3c0_write(0x07, 0x07); // ?
port_3c0_write(0x08, 0x08); // ?
port_3c0_write(0x09, 0x09); // ?
port_3c0_write(0x0A, 0x0a); // ?
port_3c0_write(0x0B, 0x0b); // ?
port_3c0_write(0x0C, 0x0c); // ?
port_3c0_write(0x0D, 0x0d); // ?
port_3c0_write(0x0E, 0x0e); // ?
port_3c0_write(0x0F, 0x0f); // ?
port_3c0_write(0x10, 0x41); //mode control
port_3c0_write(0x11, 0x00); //Overscan register
port_3c0_write(0x12, 0x0f); //Color Plane Enable
port_3c0_write(0x13, 0x00); //Horizontal panning
port_3c0_write(0x14, 0x00); //color select
// lock color palette
inb(0x3da); // read to clear index/data status
outb(0x3c0, 0x20); //send index, switches here everything turns to ffff
video_ram = (uint8_t*) 0xa0000;
while (video_ram < (uint8_t*) 0xAFA00) {
*video_ram = (uint8_t) 0b00000001;
video_ram++;
}
}