diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2011-12-20 23:56:14 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2011-12-20 23:56:14 -0500 |
commit | e48a53795452212a259a34e685e05f38d823cafe (patch) | |
tree | d01578677264fb8728b2ddb5aef20a7d1c38466b /vgasrc | |
parent | 8bd766f40cf8afe9e408c0a283f6ac40dfffd6c6 (diff) | |
download | seabios-hppa-e48a53795452212a259a34e685e05f38d823cafe.zip seabios-hppa-e48a53795452212a259a34e685e05f38d823cafe.tar.gz seabios-hppa-e48a53795452212a259a34e685e05f38d823cafe.tar.bz2 |
Updates to vgabios cirrus code.
Work in progress updates to cirrus vgabios code.
Diffstat (limited to 'vgasrc')
-rw-r--r-- | vgasrc/clext.c | 299 | ||||
-rw-r--r-- | vgasrc/vga.c | 7 | ||||
-rw-r--r-- | vgasrc/vgatables.h | 2 |
3 files changed, 300 insertions, 8 deletions
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; i<count; i++) { + outw((i<<8) | 0x09, VGAREG_GRDC_ADDRESS); + memset16_far(SEG_GRAPH, 0, param, 16 * 1024); + } + outw(0x0009, VGAREG_GRDC_ADDRESS); +} + +int +cirrus_set_video_mode(u8 mode, u8 noclearmem) { dprintf(1, "cirrus mode %d\n", mode); SET_BDA(vbe_mode, 0); - struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode & 0x7f); + struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); if (table_g) { - //XXX - cirrus_set_video_mode_extended(table); - return; + cirrus_switch_mode(table_g); + if (!noclearmem) + cirrus_clear_vram(0xffff); + SET_BDA(video_mode, mode); + return 1; } table_g = cirrus_get_modeentry(0xfe); cirrus_switch_mode(table_g); dprintf(1, "cirrus mode switch regular\n"); + return 0; } static int @@ -370,6 +422,243 @@ cirrus_check(void) return inb(VGAREG_SEQU_DATA) == 0x12; } + +/**************************************************************** + * extbios + ****************************************************************/ + +static void +cirrus_extbios_80h(struct bregs *regs) +{ + u16 crtc_addr = cirrus_get_crtc(); + outb(0x27, crtc_addr); + u8 v = inb(crtc_addr + 1); + if (v == 0xa0) + // 5430 + regs->ax = 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 |