From: Kevin O'Connor Date: Wed, 21 Dec 2011 04:56:14 +0000 (-0500) Subject: Updates to vgabios cirrus code. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=seabios.git;a=commitdiff_plain;h=e48a53795452212a259a34e685e05f38d823cafe Updates to vgabios cirrus code. Work in progress updates to cirrus vgabios code. --- diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 36ccad3..ed6d507 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -9,6 +9,11 @@ #include "biosvar.h" // GET_GLOBAL #include "util.h" // dprintf + +/**************************************************************** + * tables + ****************************************************************/ + struct cirrus_mode_s { /* + 0 */ u16 mode; @@ -289,6 +294,11 @@ static struct cirrus_mode_s cirrus_modes[] VAR16 = { 0xff,0,0,0,0,0,0,0,0}, }; + +/**************************************************************** + * helper functions + ****************************************************************/ + static struct cirrus_mode_s * cirrus_get_modeentry(u8 mode) { @@ -348,19 +358,61 @@ cirrus_switch_mode(struct cirrus_mode_s *table) vgahw_set_single_palette_reg(0x10, v); } -void -cirrus_set_video_mode(u8 mode) +static u8 +cirrus_get_memsize(void) +{ + // get DRAM band width + outb(0x0f, VGAREG_SEQU_ADDRESS); + u8 v = inb(VGAREG_SEQU_DATA); + u8 x = (v >> 3) & 0x03; + if (x == 0x03) { + if (v & 0x80) + // 4MB + return 0x40; + // 2MB + return 0x20; + } + return 0x04 << x; +} + +static void +cirrus_enable_16k_granularity(void) +{ + outb(0x0b, VGAREG_GRDC_ADDRESS); + u8 v = inb(VGAREG_GRDC_DATA); + outb(v | 0x20, VGAREG_GRDC_DATA); +} + +static void +cirrus_clear_vram(u16 param) +{ + cirrus_enable_16k_granularity(); + u8 count = cirrus_get_memsize() * 4; + u8 i; + for (i=0; iax = 0x0032; + else if (v == 0xb8) + // 5446 + regs->ax = 0x0039; + else + regs->ax = 0x00ff; + regs->bx = 0x00; + return; +} + +static void +cirrus_extbios_81h(struct bregs *regs) +{ + // XXX + regs->ax = 0x0100; +} + +static void +cirrus_extbios_82h(struct bregs *regs) +{ + u16 crtc_addr = cirrus_get_crtc(); + outb(0x27, crtc_addr); + regs->al = inb(crtc_addr + 1) & 0x03; + regs->ah = 0xAF; +} + +static void +cirrus_extbios_85h(struct bregs *regs) +{ + regs->al = cirrus_get_memsize(); +} + +static void +cirrus_extbios_9Ah(struct bregs *regs) +{ + regs->ax = 0x4060; + regs->cx = 0x1132; +} + +extern void a0h_callback(void); +ASM16( + // fatal: not implemented yet + "a0h_callback:" + "cli\n" + "hlt\n" + "retf"); + +static void +cirrus_extbios_A0h(struct bregs *regs) +{ + struct cirrus_mode_s *table_g = cirrus_get_modeentry(regs->al & 0x7f); + regs->ah = (table_g ? 1 : 0); + regs->si = 0xffff; + regs->di = regs->ds = regs->es = regs->bx = (u32)a0h_callback; +} + +static void +cirrus_extbios_A1h(struct bregs *regs) +{ + regs->bx = 0x0e00; // IBM 8512/8513, color +} + +static void +cirrus_extbios_A2h(struct bregs *regs) +{ + regs->al = 0x07; // HSync 31.5 - 64.0 kHz +} + +static void +cirrus_extbios_AEh(struct bregs *regs) +{ + regs->al = 0x01; // High Refresh 75Hz +} + +void +cirrus_extbios(struct bregs *regs) +{ + // XXX - regs->bl < 0x80 or > 0xaf call regular handlers. + switch (regs->bl) { + case 0x80: cirrus_extbios_80h(regs); break; + case 0x81: cirrus_extbios_81h(regs); break; + case 0x82: cirrus_extbios_82h(regs); break; + case 0x85: cirrus_extbios_85h(regs); break; + case 0x9a: cirrus_extbios_9Ah(regs); break; + case 0xa0: cirrus_extbios_A0h(regs); break; + case 0xa1: cirrus_extbios_A1h(regs); break; + case 0xa2: cirrus_extbios_A2h(regs); break; + case 0xae: cirrus_extbios_AEh(regs); break; + default: break; + } +} + + +/**************************************************************** + * vesa calls + ****************************************************************/ + +#if 0 +static u16 +cirrus_vesamode_to_mode(u16 vesamode) +{ + // XXX - convert assembler + return 0; +} + +static u8 +cirrus_get_bpp_bytes(void) +{ + // XXX - convert assembler + return 0; +} + +static void +cirrus_set_line_offset(u16 new_line_offset) +{ + // XXX - convert assembler +} + +static u16 +cirrus_get_line_offset(void) +{ + // XXX - convert assembler + return 0; +} + +static u16 +cirrus_get_line_offset_entry(void *table) +{ + // XXX - convert assembler + return 0; +} + +static void +cirrus_set_start_addr(void *addr) +{ + // XXX - convert assembler +} + +static void * +cirrus_get_start_addr(void) +{ + // XXX - convert assembler + return NULL; +} +#endif + +static void +cirrus_vesa_00h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_01h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_02h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_03h(struct bregs *regs) +{ + // XXX - convert assembler +} + +// XXX - add cirrus_vesa_05h_farentry to vgaentry.S + +static void +cirrus_vesa_05h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_06h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_07h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_10h(struct bregs *regs) +{ + // XXX - convert assembler +} + +static void +cirrus_vesa_not_handled(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x014f; +} + +void +cirrus_vesa(struct bregs *regs) +{ + switch (regs->al) { + case 0x00: cirrus_vesa_00h(regs); break; + case 0x01: cirrus_vesa_01h(regs); break; + case 0x02: cirrus_vesa_02h(regs); break; + case 0x03: cirrus_vesa_03h(regs); break; + case 0x05: cirrus_vesa_05h(regs); break; + case 0x06: cirrus_vesa_06h(regs); break; + case 0x07: cirrus_vesa_07h(regs); break; + case 0x10: cirrus_vesa_10h(regs); break; + default: cirrus_vesa_not_handled(regs); break; + } +} + + +/**************************************************************** + * init + ****************************************************************/ + void cirrus_init(void) { diff --git a/vgasrc/vga.c b/vgasrc/vga.c index 26f70ce..d1de5cc 100644 --- a/vgasrc/vga.c +++ b/vgasrc/vga.c @@ -474,8 +474,11 @@ handle_1000(struct bregs *regs) else regs->al = 0x30; - if (CONFIG_VGA_CIRRUS) - cirrus_set_video_mode(mode); + if (CONFIG_VGA_CIRRUS) { + int ret = cirrus_set_video_mode(mode, noclearmem); + if (ret) + return; + } if (vbe_enabled()) vbe_hires_enable(0); diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h index 5c0f3bf..d2fad8c 100644 --- a/vgasrc/vgatables.h +++ b/vgasrc/vgatables.h @@ -206,7 +206,7 @@ void vgahw_enable_video_addressing(u8 disable); void vgahw_init(void); // clext.c -void cirrus_set_video_mode(u8 mode); +int cirrus_set_video_mode(u8 mode, u8 noclearmem); void cirrus_init(void); // vbe.c