X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=vgasrc%2Fstdvga.c;h=6998cd09268090a6b33e67c76264bbd935612573;hb=34203cdf8a89c747e221005850a4558252235360;hp=f40c172b6dc9ca20d831fb2a041930300206f123;hpb=c990f27298104d23a0a63fc340385310e598fe00;p=seabios.git diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index f40c172..6998cd0 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -10,6 +10,7 @@ #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_GLOBAL #include "util.h" // memcpy_far +#include "vbe.h" // VBE_RETURN_STATUS_FAILED // TODO // * replace direct in/out calls with wrapper functions @@ -19,14 +20,14 @@ * Attribute control ****************************************************************/ -void +static void stdvga_screen_disable(void) { inb(VGAREG_ACTL_RESET); outb(0x00, VGAREG_ACTL_ADDRESS); } -void +static void stdvga_screen_enable(void) { inb(VGAREG_ACTL_RESET); @@ -265,6 +266,25 @@ stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info) outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS); } +void +stdvga_perform_gray_scale_summing(u16 start, u16 count) +{ + stdvga_screen_disable(); + int i; + for (i = start; i < start+count; i++) { + u8 rgb[3]; + stdvga_get_dac_regs(GET_SEG(SS), rgb, i, 1); + + // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue ) + u16 intensity = ((77 * rgb[0] + 151 * rgb[1] + 28 * rgb[2]) + 0x80) >> 8; + if (intensity > 0x3f) + intensity = 0x3f; + + stdvga_set_dac_regs(GET_SEG(SS), rgb, i, 1); + } + stdvga_screen_enable(); +} + /**************************************************************** * Memory control @@ -502,14 +522,59 @@ stdvga_restore_state(u16 seg, struct saveVideoHardware *info) outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa); } -void -stdvga_set_mode(struct vgamode_s *vmode_g) +static void +clear_screen(struct vgamode_s *vmode_g) +{ + switch (GET_GLOBAL(vmode_g->memmodel)) { + case MM_TEXT: + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); + break; + case MM_CGA: + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); + break; + default: + // XXX - old code gets/sets/restores sequ register 2 to 0xf - + // but it should always be 0xf anyway. + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024); + } +} + +int +stdvga_set_mode(int mode, int flags) { + // find the entry in the video modes + struct vgamode_s *vmode_g = stdvga_find_mode(mode); + dprintf(1, "mode search %02x found %p\n", mode, vmode_g); + if (!vmode_g) + return VBE_RETURN_STATUS_FAILED; + struct stdvga_mode_s *stdmode_g = container_of( + vmode_g, struct stdvga_mode_s, info); + + // if palette loading (bit 3 of modeset ctl = 0) + if (!(flags & MF_NOPALETTE)) { // Set the PEL mask + stdvga_set_pel_mask(GET_GLOBAL(stdmode_g->pelmask)); + + // From which palette + u8 *palette_g = GET_GLOBAL(stdmode_g->dac); + u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3; + + // Always 256*3 values + stdvga_set_dac_regs(get_global_seg(), palette_g, 0, palsize); + u16 i; + for (i = palsize; i < 0x0100; i++) { + static u8 rgb[3] VAR16; + stdvga_set_dac_regs(get_global_seg(), rgb, i, 1); + } + + if (flags & MF_GRAYSUM) + stdvga_perform_gray_scale_summing(0x00, 0x100); + } + // Reset Attribute Ctl flip-flop inb(VGAREG_ACTL_RESET); // Set Attribute Ctl - u8 *regs = GET_GLOBAL(vmode_g->actl_regs); + u8 *regs = GET_GLOBAL(stdmode_g->actl_regs); u16 i; for (i = 0; i <= 0x13; i++) { outb(i, VGAREG_ACTL_ADDRESS); @@ -521,21 +586,21 @@ stdvga_set_mode(struct vgamode_s *vmode_g) // Set Sequencer Ctl outb(0, VGAREG_SEQU_ADDRESS); outb(0x03, VGAREG_SEQU_DATA); - regs = GET_GLOBAL(vmode_g->sequ_regs); + regs = GET_GLOBAL(stdmode_g->sequ_regs); for (i = 1; i <= 4; i++) { outb(i, VGAREG_SEQU_ADDRESS); outb(GET_GLOBAL(regs[i - 1]), VGAREG_SEQU_DATA); } // Set Grafx Ctl - regs = GET_GLOBAL(vmode_g->grdc_regs); + regs = GET_GLOBAL(stdmode_g->grdc_regs); for (i = 0; i <= 8; i++) { outb(i, VGAREG_GRDC_ADDRESS); outb(GET_GLOBAL(regs[i]), VGAREG_GRDC_DATA); } // Set CRTC address VGA or MDA - u8 miscreg = GET_GLOBAL(vmode_g->miscreg); + u8 miscreg = GET_GLOBAL(stdmode_g->miscreg); u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; if (!(miscreg & 1)) crtc_addr = VGAREG_MDA_CRTC_ADDRESS; @@ -543,7 +608,7 @@ stdvga_set_mode(struct vgamode_s *vmode_g) // Disable CRTC write protection outw(0x0011, crtc_addr); // Set CRTC regs - regs = GET_GLOBAL(vmode_g->crtc_regs); + regs = GET_GLOBAL(stdmode_g->crtc_regs); for (i = 0; i <= 0x18; i++) { outb(i, crtc_addr); outb(GET_GLOBAL(regs[i]), crtc_addr + 1); @@ -555,6 +620,20 @@ stdvga_set_mode(struct vgamode_s *vmode_g) // Enable video outb(0x20, VGAREG_ACTL_ADDRESS); inb(VGAREG_ACTL_RESET); + + // Clear screen + if (!(flags & MF_NOCLEARMEM)) + clear_screen(vmode_g); + + // Write the fonts in memory + u8 memmodel = GET_GLOBAL(vmode_g->memmodel); + if (memmodel == MM_TEXT) + stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16); + + // Setup BDA variables + modeswitch_set_bda(mode, flags, vmode_g); + + return 0; } @@ -562,6 +641,12 @@ stdvga_set_mode(struct vgamode_s *vmode_g) * Misc ****************************************************************/ +void +stdvga_list_modes(u16 seg, u16 *dest, u16 *last) +{ + SET_FARVAR(seg, *dest, 0xffff); +} + void stdvga_enable_video_addressing(u8 disable) { @@ -570,7 +655,7 @@ stdvga_enable_video_addressing(u8 disable) outb(v | v2, VGAREG_WRITE_MISC_OUTPUT); } -void +int stdvga_init(void) { // switch to color mode and enable CPU access 480 lines @@ -578,4 +663,6 @@ stdvga_init(void) // more than 64k 3C4/04 outb(0x04, VGAREG_SEQU_ADDRESS); outb(0x02, VGAREG_SEQU_DATA); + + return 0; }