From 821d6b410e02897f84c4b732f3678f64e396c9cf Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sat, 31 Dec 2011 18:19:22 -0500 Subject: [PATCH] vgabios: Refactor vga_set_mode and stdvga_set_mode. Split out the BDA setup part of vga_set_mode to new function modeswitch_set_bda. Move the remaining parts (palette loading, screen clearing, font loading) of vga_set_mode into stdvga_set_mode. Add new mode switching flags and pass them to stdvga_set_mode, so it does not need to inspect modeset_ctl directly. Move code needed by stdvga_set_mode (perform_gray_scale_summing, clear_screen) to stdvga.c. Signed-off-by: Kevin O'Connor --- vgasrc/bochsvga.c | 2 +- vgasrc/stdvga.c | 82 +++++++++++++++++++++++++++++++++++++++++-- vgasrc/stdvga.h | 5 ++- vgasrc/vbe.c | 3 +- vgasrc/vgabios.c | 89 +++++++++-------------------------------------- vgasrc/vgabios.h | 10 ++++-- vgasrc/vgafb.c | 18 ---------- 7 files changed, 108 insertions(+), 101 deletions(-) diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 3b5c711..4ba6611 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -263,7 +263,7 @@ void bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info) { if (info->depth == 4) - vga_set_mode(0x6a, 0); + stdvga_set_mode(0x6a, 0); if (info->depth == 8) // XXX load_dac_palette(3); ; diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index f40c172..b756f59 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 "vgabios.h" // find_vga_entry // 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,9 +522,53 @@ stdvga_restore_state(u16 seg, struct saveVideoHardware *info) outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa); } +static void +clear_screen(struct vgamode_s *vmode_g) +{ + switch (GET_GLOBAL(vmode_g->memmodel)) { + case CTEXT: + case MTEXT: + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); + break; + case 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); + } +} + void -stdvga_set_mode(struct vgamode_s *vmode_g) +stdvga_set_mode(int mode, int flags) { + // find the entry in the video modes + struct vgamode_s *vmode_g = find_vga_entry(mode); + dprintf(1, "mode search %02x found %p\n", mode, vmode_g); + if (!vmode_g) + return; + + // if palette loading (bit 3 of modeset ctl = 0) + if (!(flags & MF_NOPALETTE)) { // Set the PEL mask + stdvga_set_pel_mask(GET_GLOBAL(vmode_g->pelmask)); + + // From which palette + u8 *palette_g = GET_GLOBAL(vmode_g->dac); + u16 palsize = GET_GLOBAL(vmode_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); @@ -555,6 +619,18 @@ 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 & TEXT) + stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16); + + // Setup BDA variables + modeswitch_set_bda(mode, flags, vmode_g); } diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index fb98304..ac5dea4 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -105,8 +105,6 @@ struct saveDACcolors { u8 color_select; }; -void stdvga_screen_disable(void); -void stdvga_screen_enable(void); void stdvga_set_border_color(u8 color); void stdvga_set_overscan_border_color(u8 color); u8 stdvga_get_overscan_border_color(void); @@ -124,6 +122,7 @@ void stdvga_set_pel_mask(u8 val); u8 stdvga_get_pel_mask(void); void stdvga_save_dac_state(u16 seg, struct saveDACcolors *info); void stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info); +void stdvga_perform_gray_scale_summing(u16 start, u16 count); void stdvga_sequ_write(u8 index, u8 value); void stdvga_grdc_write(u8 index, u8 value); void stdvga_set_text_block_specifier(u8 spec); @@ -137,7 +136,7 @@ void stdvga_set_scan_lines(u8 lines); u16 stdvga_get_vde(void); void stdvga_save_state(u16 seg, struct saveVideoHardware *info); void stdvga_restore_state(u16 seg, struct saveVideoHardware *info); -void stdvga_set_mode(struct vgamode_s *vmode_g); +void stdvga_set_mode(int mode, int flags); void stdvga_enable_video_addressing(u8 disable); void stdvga_init(void); diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index f598921..df95148 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -12,6 +12,7 @@ #include "util.h" // dprintf #include "biosvar.h" // get_global_set #include "bochsvga.h" // bochsvga_set_mode +#include "stdvga.h" // stdvga_set_mode static void vbe_104f00(struct bregs *regs) @@ -189,7 +190,7 @@ vbe_104f02(struct bregs *regs) dprintf(1, "set VGA mode %x\n", mode); bochsvga_hires_enable(0); - vga_set_mode(mode, 0); + stdvga_set_mode(mode, 0); } else { /* VBE */ rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); if (rc) { diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index cb8793e..d7c559a 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -17,7 +17,7 @@ #include "vgabios.h" // find_vga_entry #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* -#include "stdvga.h" // stdvga_screen_disable +#include "stdvga.h" // stdvga_set_mode #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init @@ -46,25 +46,6 @@ struct pci_data rom_pci_data VAR16VISIBLE = { * Helper functions ****************************************************************/ -static void -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(); -} - static void set_cursor_shape(u8 start, u8 end) { @@ -341,57 +322,10 @@ restore_bda_state(u16 seg, struct saveBDAstate *info) SET_IVT(0x43, GET_FARVAR(seg, info->font1)); } - -/**************************************************************** - * VGA int 10 handler - ****************************************************************/ - -// set video mode +// Setup BDA after a mode switch. void -vga_set_mode(u8 mode, u8 noclearmem) +modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) { - // find the entry in the video modes - struct vgamode_s *vmode_g = find_vga_entry(mode); - dprintf(1, "mode search %02x found %p\n", mode, vmode_g); - if (!vmode_g) - return; - - // Read the bios mode set control - u8 modeset_ctl = GET_BDA(modeset_ctl); - - // Then we know the number of lines -// FIXME - - // if palette loading (bit 3 of modeset ctl = 0) - if ((modeset_ctl & 0x08) == 0) { // Set the PEL mask - stdvga_set_pel_mask(GET_GLOBAL(vmode_g->pelmask)); - - // From which palette - u8 *palette_g = GET_GLOBAL(vmode_g->dac); - u16 palsize = GET_GLOBAL(vmode_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 ((modeset_ctl & 0x02) == 0x02) - perform_gray_scale_summing(0x00, 0x100); - } - - stdvga_set_mode(vmode_g); - - if (noclearmem == 0x00) - clear_screen(vmode_g); - - // Write the fonts in memory - u8 memmodel = GET_GLOBAL(vmode_g->memmodel); - if (memmodel & TEXT) - stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16); - // Set the BIOS mem u16 cheight = GET_GLOBAL(vmode_g->cheight); SET_BDA(video_mode, mode); @@ -400,10 +334,10 @@ vga_set_mode(u8 mode, u8 noclearmem) SET_BDA(crtc_address, stdvga_get_crtc()); SET_BDA(video_rows, GET_GLOBAL(vmode_g->theight)-1); SET_BDA(char_height, cheight); - SET_BDA(video_ctl, (0x60 | noclearmem)); + SET_BDA(video_ctl, 0x60 | (flags & MF_NOCLEARMEM ? 0x80 : 0x00)); SET_BDA(video_switches, 0xF9); SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); - SET_BDA(cursor_type, memmodel & TEXT ? 0x0607 : 0x0000); + SET_BDA(cursor_type, GET_GLOBAL(vmode_g->memmodel) & TEXT ? 0x0607 : 0x0000); int i; for (i=0; i<8; i++) SET_BDA(cursor_pos[i], 0x0000); @@ -435,6 +369,11 @@ vga_set_mode(u8 mode, u8 noclearmem) } } + +/**************************************************************** + * VGA int 10 handler + ****************************************************************/ + static void handle_1000(struct bregs *regs) { @@ -458,7 +397,11 @@ handle_1000(struct bregs *regs) if (bochsvga_enabled()) bochsvga_hires_enable(0); - vga_set_mode(mode, noclearmem); + int flags = GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM); + if (noclearmem) + flags |= MF_NOCLEARMEM; + + stdvga_set_mode(mode, flags); } static void @@ -731,7 +674,7 @@ handle_10101a(struct bregs *regs) static void handle_10101b(struct bregs *regs) { - perform_gray_scale_summing(regs->bx, regs->cx); + stdvga_perform_gray_scale_summing(regs->bx, regs->cx); } static void diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index d31161e..0371f8c 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -26,6 +26,13 @@ struct saveBDAstate { struct segoff_s font1; }; +// Mode flags +#define MF_GRAYSUM 0x0002 +#define MF_NOPALETTE 0x0008 +#define MF_CUSTOMCRTC 0x0800 +#define MF_LINEARFB 0x4000 +#define MF_NOCLEARMEM 0x8000 + // vgatables.c struct vgamode_s; struct vgamode_s *find_vga_entry(u8 mode); @@ -48,10 +55,9 @@ struct carattr { struct cursorpos { u8 x, y, page; }; -void vga_set_mode(u8 mode, u8 noclearmem); +void modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g); // vgafb.c -void clear_screen(struct vgamode_s *vmode_g); void vgafb_scroll(int nblines, int attr , struct cursorpos ul, struct cursorpos lr); void vgafb_write_char(struct cursorpos cp, struct carattr ca); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 19ab1df..38ed070 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -158,24 +158,6 @@ vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr) } } -void -clear_screen(struct vgamode_s *vmode_g) -{ - switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); - break; - case 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); - } -} - /**************************************************************** * Read/write characters to screen -- 2.25.1