Assorted updates. Mostly framework changes to support better integration of the various hardware types (eg, cirrus/bochs). There are a few bug fixes in this series though.
-Kevin
Kevin O'Connor (20): vgabios: Minor fixes to struct vbe_info definition. vgabios: Continue port of clext.c. vgabios: Rename vbe.c to bochsvga.c. vgabios: Use bochsvga_ prefix for bochs vga functions. vgabios: Rename vga.c to vgabios.c. vgabios: Move vbe code from vgabios.c to new file vbe.c. vgabios: Rename vgaio.c to stdvga.c. vgabios: Rename vgahw_* functions to stdvga_*. vgabios: Move vgafb_load_font to stdvga.c. vgabios: Fix typo in release_font_access() - inb instead of inw. vgabios: Introduce stdvga_get_crtc() and use it consistently. vgabios: Don't call int10 during mode switch. vgabios: Change vga_set_mode() to directly setup BDA. vgabios: Refactor vga_set_mode and stdvga_set_mode. vgabios: Create clext.h and use "clext_" as prefix for exported funcs. vgabios: Unify X_set_mode() functions. vgabios: Unify X_init() functions. vgabios: Framebuffer fixes for CGA and planar graphics modes. vgabios: Minor - make FB scroll functions look similar. vgabios: Add scrolling for linear (packed pixel) graphics mode.
Makefile | 6 +- src/vbe.h | 6 +- vgasrc/bochsvga.c | 364 ++++++++++++ vgasrc/bochsvga.h | 67 +++ vgasrc/clext.c | 368 +++++++++++-- vgasrc/clext.h | 9 + vgasrc/dispi.h | 55 -- vgasrc/geodelx.c | 12 +- vgasrc/stdvga.c | 662 ++++++++++++++++++++++ vgasrc/stdvga.h | 143 +++++ vgasrc/vbe.c | 512 ++++++++---------- vgasrc/vga.c | 1595 ---------------------------------------------------- vgasrc/vgabios.c | 1219 +++++++++++++++++++++++++++++++++++++++ vgasrc/vgabios.h | 88 +++ vgasrc/vgafb.c | 177 +++--- vgasrc/vgafonts.c | 2 +- vgasrc/vgahw.h | 30 + vgasrc/vgaio.c | 559 ------------------ vgasrc/vgatables.c | 3 +- vgasrc/vgatables.h | 235 -------- 20 files changed, 3232 insertions(+), 2880 deletions(-) create mode 100644 vgasrc/bochsvga.c create mode 100644 vgasrc/bochsvga.h create mode 100644 vgasrc/clext.h delete mode 100644 vgasrc/dispi.h create mode 100644 vgasrc/stdvga.c create mode 100644 vgasrc/stdvga.h delete mode 100644 vgasrc/vga.c create mode 100644 vgasrc/vgabios.c create mode 100644 vgasrc/vgabios.h create mode 100644 vgasrc/vgahw.h delete mode 100644 vgasrc/vgaio.c delete mode 100644 vgasrc/vgatables.h
Although the VBE3 spec says there is 189 bytes of pad at the end of the vbe_info struct, the spec also says the total struct size should be 256 bytes. The VBE2 spec uses sufficient pad to get to 256 bytes. So, assume the spec was off by one and make the pad 190 bytes.
Also, use u32 for capabilities and 'struct segoff_s' for win_func_ptr.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/vbe.h | 6 +++--- vgasrc/vga.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/vbe.h b/src/vbe.h index bfcd6b4..386613c 100644 --- a/src/vbe.h +++ b/src/vbe.h @@ -11,7 +11,7 @@ struct vbe_info { u32 signature; u16 version; struct segoff_s oem_string; - u8 capabilities[4]; + u32 capabilities; struct segoff_s video_mode; u16 total_memory; u16 oem_revision; @@ -30,7 +30,7 @@ struct vbe_mode_info { u16 win_size; u16 winA_seg; u16 winB_seg; - u32 win_func_ptr; + struct segoff_s win_func_ptr; u16 bytes_per_scanline; /* VBE 1.2 */ u16 xres; @@ -71,7 +71,7 @@ struct vbe_mode_info { u8 linear_alpha_size; u8 linear_alpha_pos; u32 pixclock_max; - u8 reserved[189]; + u8 reserved[190]; } PACKED;
struct vbe_crtc_info { diff --git a/vgasrc/vga.c b/vgasrc/vga.c index 37f227c..539cd7a 100644 --- a/vgasrc/vga.c +++ b/vgasrc/vga.c @@ -1226,7 +1226,7 @@ handle_104f00(struct bregs *regs)
SET_FARVAR(seg, info->oem_string, SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); - SET_FARVAR(seg, info->capabilities[0], 0x1); /* 8BIT DAC */ + SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */
/* We generate our mode list in the reserved field of the info block */ SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34)); @@ -1284,7 +1284,7 @@ handle_104f01(struct bregs *regs) SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ SET_FARVAR(seg, info->winA_seg, 0xA000); SET_FARVAR(seg, info->winB_seg, 0x0); - SET_FARVAR(seg, info->win_func_ptr, 0x0); + SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); SET_FARVAR(seg, info->bytes_per_scanline, modeinfo.linesize); SET_FARVAR(seg, info->xres, modeinfo.width); SET_FARVAR(seg, info->yres, modeinfo.height);
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 326 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 302 insertions(+), 24 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 277246b..b2c59fb 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -9,6 +9,7 @@ #include "biosvar.h" // GET_GLOBAL #include "util.h" // dprintf #include "bregs.h" // struct bregs +#include "vbe.h" // struct vbe_info
/**************************************************************** @@ -533,77 +534,293 @@ cirrus_extbios(struct bregs *regs) * vesa calls ****************************************************************/
-#if 0 +static struct { + u16 vesamode, mode; +} cirrus_vesa_modelist[] VAR16 = { + // 640x480x8 + { 0x101, 0x5f }, + // 640x480x15 + { 0x110, 0x66 }, + // 640x480x16 + { 0x111, 0x64 }, + // 640x480x24 + { 0x112, 0x71 }, + // 800x600x8 + { 0x103, 0x5c }, + // 800x600x15 + { 0x113, 0x67 }, + // 800x600x16 + { 0x114, 0x65 }, + // 800x600x24 + { 0x115, 0x78 }, + // 1024x768x8 + { 0x105, 0x60 }, + // 1024x768x15 + { 0x116, 0x68 }, + // 1024x768x16 + { 0x117, 0x74 }, + // 1024x768x24 + { 0x118, 0x79 }, + // 1280x1024x8 + { 0x107, 0x6d }, + // 1280x1024x15 + { 0x119, 0x69 }, + // 1280x1024x16 + { 0x11a, 0x75 }, +}; + static u16 cirrus_vesamode_to_mode(u16 vesamode) { - // XXX - convert assembler + int i; + for (i=0; i<ARRAY_SIZE(cirrus_vesa_modelist); i++) + if (GET_GLOBAL(cirrus_vesa_modelist[i].vesamode) == vesamode) + return GET_GLOBAL(cirrus_vesa_modelist[i].mode); return 0; }
static u8 cirrus_get_bpp_bytes(void) { - // XXX - convert assembler - return 0; + outb(0x07, VGAREG_SEQU_ADDRESS); + u8 v = inb(VGAREG_SEQU_DATA) & 0x0e; + if (v == 0x06) + v &= 0x02; + v >>= 1; + if (v != 0x04) + v++; + return v; }
static void cirrus_set_line_offset(u16 new_line_offset) { - // XXX - convert assembler + u16 crtc_addr = cirrus_get_crtc(); + outb(0x13, crtc_addr); + outb(new_line_offset / 8, crtc_addr + 1); + + outb(0x1b, crtc_addr); + u8 v = inb(crtc_addr + 1); + outb((((new_line_offset / 8) & 0x100) >> 4) | (v & 0xef), crtc_addr + 1); }
static u16 cirrus_get_line_offset(void) { - // XXX - convert assembler - return 0; + u16 crtc_addr = cirrus_get_crtc(); + outb(0x13, crtc_addr); + u8 reg13 = inb(crtc_addr + 1); + outb(0x1b, crtc_addr); + u8 reg1b = inb(crtc_addr + 1); + + return (((reg1b << 4) & 0x100) + reg13) * 8; }
static u16 -cirrus_get_line_offset_entry(void *table) +cirrus_get_line_offset_entry(struct cirrus_mode_s *table_g) { - // XXX - convert assembler - return 0; + u16 *crtc = GET_GLOBAL(table_g->crtc); + + u16 *c = crtc; + u16 reg13; + for (;;) { + reg13 = GET_GLOBAL(*c); + if ((reg13 & 0xff) == 0x13) + break; + c++; + } + reg13 >>= 8; + + c = crtc; + u16 reg1b; + for (;;) { + reg1b = GET_GLOBAL(*c); + if ((reg1b & 0xff) == 0x1b) + break; + c++; + } + reg1b >>= 8; + + return (((reg1b << 4) & 0x100) + reg13) * 8; }
static void -cirrus_set_start_addr(void *addr) +cirrus_set_start_addr(u32 addr) { - // XXX - convert assembler + u16 crtc_addr = cirrus_get_crtc(); + outb(0x0d, crtc_addr); + outb(addr, crtc_addr + 1); + + outb(0x0c, crtc_addr); + outb(addr>>8, crtc_addr + 1); + + outb(0x1d, crtc_addr); + u8 v = inb(crtc_addr + 1); + outb(((addr & 0x0800) >> 4) | (v & 0x7f), crtc_addr + 1); + + outb(0x1b, crtc_addr); + v = inb(crtc_addr + 1); + outb(((addr & 0x0100) >> 8) | ((addr & 0x0600) >> 7) | (v & 0xf2) + , crtc_addr + 1); }
-static void * +static u32 cirrus_get_start_addr(void) { - // XXX - convert assembler - return NULL; + u16 crtc_addr = cirrus_get_crtc(); + outb(0x0c, crtc_addr); + u8 b2 = inb(crtc_addr + 1); + + outb(0x0d, crtc_addr); + u8 b1 = inb(crtc_addr + 1); + + outb(0x1b, crtc_addr); + u8 b3 = inb(crtc_addr + 1); + + outb(0x1d, crtc_addr); + u8 b4 = inb(crtc_addr + 1); + + return (b1 | (b2<<8) | ((b3 & 0x01) << 16) | ((b3 & 0x0c) << 15) + | ((b4 & 0x80) << 12)); } -#endif
static void cirrus_vesa_00h(struct bregs *regs) { - // XXX - convert assembler + u16 seg = regs->es; + struct vbe_info *info = (void*)(regs->di+0); + + if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { + SET_FARVAR(seg, info->oem_revision, 0x0100); + SET_FARVAR(seg, info->oem_vendor_string, + SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); + SET_FARVAR(seg, info->oem_product_string, + SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); + SET_FARVAR(seg, info->oem_revision_string, + SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); + } + SET_FARVAR(seg, info->signature, VESA_SIGNATURE); + + SET_FARVAR(seg, info->version, 0x0200); + + SET_FARVAR(seg, info->oem_string + , SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); + SET_FARVAR(seg, info->capabilities, 0); + SET_FARVAR(seg, info->total_memory, cirrus_get_memsize()); + + u16 *destmode = (void*)info->reserved; + SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode)); + int i; + for (i=0; i<ARRAY_SIZE(cirrus_vesa_modelist); i++) + SET_FARVAR(seg, destmode[i] + , GET_GLOBAL(cirrus_vesa_modelist[i].vesamode)); + SET_FARVAR(seg, destmode[i], 0xffff); + + regs->ax = 0x004f; }
+static u32 cirrus_lfb_addr VAR16; + static void cirrus_vesa_01h(struct bregs *regs) { - // XXX - convert assembler + u16 mode = cirrus_vesamode_to_mode(regs->cx & 0x3fff); + if (!mode) { + regs->ax = 0x014f; + return; + } + struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); + u32 lfb = GET_GLOBAL(cirrus_lfb_addr); // XXX + if ((regs->cx & 0x4000) && !lfb) { + regs->ax = 0x014f; + return; + } + + u16 seg = regs->es; + struct vbe_mode_info *info = (void*)(regs->di+0); + memset_far(seg, info, 0, sizeof(*info)); + + SET_FARVAR(seg, info->mode_attributes, lfb ? 0xbb : 0x3b); + SET_FARVAR(seg, info->winA_attributes, 0x07); + SET_FARVAR(seg, info->winB_attributes, 0); + SET_FARVAR(seg, info->win_granularity, 16); + SET_FARVAR(seg, info->win_size, 64); + SET_FARVAR(seg, info->winA_seg, SEG_GRAPH); + SET_FARVAR(seg, info->winB_seg, 0x0); + SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); // XXX + u16 linesize = cirrus_get_line_offset_entry(table_g); + SET_FARVAR(seg, info->bytes_per_scanline, linesize); + SET_FARVAR(seg, info->xres, GET_GLOBAL(table_g->width)); + u16 height = GET_GLOBAL(table_g->height); + SET_FARVAR(seg, info->yres, height); + SET_FARVAR(seg, info->xcharsize, 8); + SET_FARVAR(seg, info->ycharsize, 16); + SET_FARVAR(seg, info->planes, 1); + SET_FARVAR(seg, info->bits_per_pixel, GET_GLOBAL(table_g->depth)); + SET_FARVAR(seg, info->banks, 1); + SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->vesacolortype)); + SET_FARVAR(seg, info->bank_size, 0); + + int pages = (cirrus_get_memsize() * 64 * 1024) / (height * linesize); + SET_FARVAR(seg, info->pages, pages - 1); + SET_FARVAR(seg, info->reserved0, 0); + + SET_FARVAR(seg, info->red_size, GET_GLOBAL(table_g->vesaredmask)); + SET_FARVAR(seg, info->red_pos, GET_GLOBAL(table_g->vesaredpos)); + SET_FARVAR(seg, info->green_size, GET_GLOBAL(table_g->vesagreenmask)); + SET_FARVAR(seg, info->green_pos, GET_GLOBAL(table_g->vesagreenpos)); + SET_FARVAR(seg, info->blue_size, GET_GLOBAL(table_g->vesabluemask)); + SET_FARVAR(seg, info->blue_pos, GET_GLOBAL(table_g->vesabluepos)); + SET_FARVAR(seg, info->alpha_size, GET_GLOBAL(table_g->vesareservedmask)); + SET_FARVAR(seg, info->alpha_pos, GET_GLOBAL(table_g->vesareservedpos)); + u8 directcolor_info = GET_GLOBAL(table_g->bitsperpixel) <= 8; + SET_FARVAR(seg, info->directcolor_info, directcolor_info); + + SET_FARVAR(seg, info->phys_base, lfb); + + regs->ax = 0x004f; }
static void cirrus_vesa_02h(struct bregs *regs) { - // XXX - convert assembler + if (regs->bx & 0x3e00) { + regs->ax = 0x014f; + return; + } + if ((regs->bx & 0x1ff) < 0x100) { + // XXX - call legacy mode switch + regs->ax = 0x004f; + return; + } + + u16 mode = cirrus_vesamode_to_mode(regs->cx & 0x3fff); + if (!mode) { + regs->ax = 0x014f; + return; + } + struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); + cirrus_switch_mode(table_g); + + if (!(regs->bx & 0x4000)) + cirrus_enable_16k_granularity(); + if (!(regs->bx & 0x8000)) + cirrus_clear_vram(0); + SET_BDA(video_mode, mode); + SET_BDA(vbe_mode, regs->bx); + + regs->ax = 0x004f; }
static void cirrus_vesa_03h(struct bregs *regs) { - // XXX - convert assembler + u16 mode = GET_BDA(vbe_mode); + if (!mode) + mode = GET_BDA(video_mode); + regs->bx = mode; + + regs->ax = 0x004f; }
// XXX - add cirrus_vesa_05h_farentry to vgaentry.S @@ -611,25 +828,86 @@ cirrus_vesa_03h(struct bregs *regs) static void cirrus_vesa_05h(struct bregs *regs) { - // XXX - convert assembler + if (regs->bl > 1) + goto fail; + if (regs->bh == 0) { + // set mempage + if (regs->dx >= 0x100) + goto fail; + outw((regs->dx << 8) | (regs->bl + 9), VGAREG_GRDC_ADDRESS); + } else if (regs->bh == 1) { + // get mempage + outb(regs->bl + 9, VGAREG_GRDC_ADDRESS); + regs->dx = inb(VGAREG_GRDC_DATA); + } else + goto fail; + + regs->ax = 0x004f; + return; +fail: + regs->ax = 0x014f; }
static void cirrus_vesa_06h(struct bregs *regs) { - // XXX - convert assembler + if (regs->bl > 2) { + regs->ax = 0x0100; + return; + } + + if (regs->bl == 0x00) { + cirrus_set_line_offset(cirrus_get_bpp_bytes() * regs->cx); + } else if (regs->bl == 0x02) { + cirrus_set_line_offset(regs->cx); + } + + u32 v = cirrus_get_line_offset(); + regs->cx = v / cirrus_get_bpp_bytes(); + regs->bx = v; + regs->dx = (cirrus_get_memsize() * 64 * 1024) / v; + regs->ax = 0x004f; }
static void cirrus_vesa_07h(struct bregs *regs) { - // XXX - convert assembler + if (regs->bl == 0x80 || regs->bl == 0x00) { + u32 addr = (cirrus_get_bpp_bytes() * regs->cx + + cirrus_get_line_offset() * regs->dx); + cirrus_set_start_addr(addr / 4); + } else if (regs->bl == 0x01) { + u32 addr = cirrus_get_start_addr() * 4; + u32 linelength = cirrus_get_line_offset(); + regs->dx = addr / linelength; + regs->cx = (addr % linelength) / cirrus_get_bpp_bytes(); + } else { + regs->ax = 0x0100; + return; + } + + regs->ax = 0x004f; }
static void cirrus_vesa_10h(struct bregs *regs) { - // XXX - convert assembler + if (regs->bl == 0x00) { + regs->bx = 0x0f30; + regs->ax = 0x004f; + return; + } + if (regs->bl == 0x01) { + SET_BDA(vbe_flag, regs->bh); + regs->ax = 0x004f; + return; + } + if (regs->bl == 0x02) { + regs->bh = GET_BDA(vbe_flag); + regs->ax = 0x004f; + return; + } + regs->ax = 0x014f; }
static void
The code is specific to the Bochs "dispi" interface, not the vesa video bios extensions spec.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- vgasrc/bochsvga.c | 340 +++++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/bochsvga.h | 55 +++++++++ vgasrc/dispi.h | 55 --------- vgasrc/vbe.c | 340 ----------------------------------------------------- 5 files changed, 396 insertions(+), 396 deletions(-) create mode 100644 vgasrc/bochsvga.c create mode 100644 vgasrc/bochsvga.h delete mode 100644 vgasrc/dispi.h delete mode 100644 vgasrc/vbe.c
diff --git a/Makefile b/Makefile index da6999c..3d60b88 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py # VGA src files SRCVGA=src/output.c src/util.c vgasrc/vga.c vgasrc/vgafb.c vgasrc/vgaio.c \ vgasrc/vgatables.c vgasrc/vgafonts.c \ - vgasrc/clext.c vgasrc/vbe.c vgasrc/geodelx.c + vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodelx.c
CFLAGS16VGA = $(CFLAGS16INC) -g -Isrc
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c new file mode 100644 index 0000000..7ea1a1f --- /dev/null +++ b/vgasrc/bochsvga.c @@ -0,0 +1,340 @@ +#include "vgatables.h" +#include "vbe.h" +#include "bochsvga.h" +#include "util.h" +#include "config.h" // CONFIG_ +#include "biosvar.h" // SET_BDA + +struct mode +{ + u16 mode; + u16 width; + u16 height; + u8 depth; +} vbe_modes[] VAR16 = { + /* standard modes */ + { 0x100, 640, 400, 8 }, + { 0x101, 640, 480, 8 }, + { 0x102, 800, 600, 4 }, + { 0x103, 800, 600, 8 }, + { 0x104, 1024, 768, 4 }, + { 0x105, 1024, 768, 8 }, + { 0x106, 1280, 1024, 4 }, + { 0x107, 1280, 1024, 8 }, + { 0x10D, 320, 200, 15 }, + { 0x10E, 320, 200, 16 }, + { 0x10F, 320, 200, 24 }, + { 0x110, 640, 480, 15 }, + { 0x111, 640, 480, 16 }, + { 0x112, 640, 480, 24 }, + { 0x113, 800, 600, 15 }, + { 0x114, 800, 600, 16 }, + { 0x115, 800, 600, 24 }, + { 0x116, 1024, 768, 15 }, + { 0x117, 1024, 768, 16 }, + { 0x118, 1024, 768, 24 }, + { 0x119, 1280, 1024, 15 }, + { 0x11A, 1280, 1024, 16 }, + { 0x11B, 1280, 1024, 24 }, + { 0x11C, 1600, 1200, 8 }, + { 0x11D, 1600, 1200, 15 }, + { 0x11E, 1600, 1200, 16 }, + { 0x11F, 1600, 1200, 24 }, + /* BOCHS modes */ + { 0x140, 320, 200, 32 }, + { 0x141, 640, 400, 32 }, + { 0x142, 640, 480, 32 }, + { 0x143, 800, 600, 32 }, + { 0x144, 1024, 768, 32 }, + { 0x145, 1280, 1024, 32 }, + { 0x146, 320, 200, 8 }, + { 0x147, 1600, 1200, 32 }, + { 0x148, 1152, 864, 8 }, + { 0x149, 1152, 864, 15 }, + { 0x14a, 1152, 864, 16 }, + { 0x14b, 1152, 864, 24 }, + { 0x14c, 1152, 864, 32 }, + { 0x178, 1280, 800, 16 }, + { 0x179, 1280, 800, 24 }, + { 0x17a, 1280, 800, 32 }, + { 0x17b, 1280, 960, 16 }, + { 0x17c, 1280, 960, 24 }, + { 0x17d, 1280, 960, 32 }, + { 0x17e, 1440, 900, 16 }, + { 0x17f, 1440, 900, 24 }, + { 0x180, 1440, 900, 32 }, + { 0x181, 1400, 1050, 16 }, + { 0x182, 1400, 1050, 24 }, + { 0x183, 1400, 1050, 32 }, + { 0x184, 1680, 1050, 16 }, + { 0x185, 1680, 1050, 24 }, + { 0x186, 1680, 1050, 32 }, + { 0x187, 1920, 1200, 16 }, + { 0x188, 1920, 1200, 24 }, + { 0x189, 1920, 1200, 32 }, + { 0x18a, 2560, 1600, 16 }, + { 0x18b, 2560, 1600, 24 }, + { 0x18c, 2560, 1600, 32 }, + { 0, }, +}; + +#define BYTES_PER_PIXEL(m) ((GET_GLOBAL((m)->depth) + 7) / 8) + +u32 pci_lfb_addr VAR16; + +static inline u32 pci_config_readl(u8 bus, u8 devfn, u16 addr) +{ + int status; + u32 val; + u16 bdf = (bus << 16) | devfn; + + addr &= ~3; + + asm volatile( + "int $0x1a\n" + "cli\n" + "cld" + : "=a"(status), "=c"(val) + : "a"(0xb10a), "b"(bdf), "D"(addr) + : "cc", "memory"); + + if ((status >> 16)) + return (u32)-1; + + return val; +} + + +static u16 dispi_get_max_xres(void) +{ + u16 en; + u16 xres; + + en = dispi_read(VBE_DISPI_INDEX_ENABLE); + + dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS); + xres = dispi_read(VBE_DISPI_INDEX_XRES); + dispi_write(VBE_DISPI_INDEX_ENABLE, en); + + return xres; +} + +static u16 dispi_get_max_bpp(void) +{ + u16 en; + u16 bpp; + + en = dispi_read(VBE_DISPI_INDEX_ENABLE); + + dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS); + bpp = dispi_read(VBE_DISPI_INDEX_BPP); + dispi_write(VBE_DISPI_INDEX_ENABLE, en); + + return bpp; +} + +/* Called only during POST */ +int +vbe_init(u8 bus, u8 devfn) +{ + u32 lfb_addr; + + if (!CONFIG_VGA_BOCHS) + return -1; + + /* Sanity checks */ + dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID0); + if (dispi_read(VBE_DISPI_INDEX_ID) != VBE_DISPI_ID0) { + dprintf(1, "No VBE DISPI interface detected\n"); + return -1; + } + + SET_BDA(vbe_flag, 0x1); + dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5); + + if (CONFIG_VGA_PCI) + lfb_addr = pci_config_readl(bus, devfn, 0x10) & ~0xf; + else + lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS; + + SET_FARVAR(get_global_seg(), pci_lfb_addr, lfb_addr); + + dprintf(1, "VBE DISPI detected. lfb_addr=%x\n", GET_GLOBAL(pci_lfb_addr)); + + return 0; +} + +int +vbe_enabled(void) +{ + return GET_BDA(vbe_flag); +} + +u16 +vbe_total_mem(void) +{ + return dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K); +} + +static struct mode *find_mode_entry(u16 mode) +{ + struct mode *m; + + for (m = vbe_modes; GET_GLOBAL(m->mode); m++) { + if (GET_GLOBAL(m->mode) == mode) + return m; + } + + return NULL; +} + +static int mode_valid(struct mode *m) +{ + u16 max_xres = dispi_get_max_xres(); + u16 max_bpp = dispi_get_max_bpp(); + u32 max_mem = vbe_total_mem() * 64 * 1024; + + u32 mem = GET_GLOBAL(m->width) * GET_GLOBAL(m->height) * + BYTES_PER_PIXEL(m); + + if (GET_GLOBAL(m->width) > max_xres || + GET_GLOBAL(m->depth) > max_bpp || + mem > max_mem) + return 0; + + return 1; +} + +int +vbe_list_modes(u16 seg, u16 ptr) +{ + int count = 0; + u16 *dest = (u16 *)(u32)ptr; + struct mode *m; + + for (m = vbe_modes; GET_GLOBAL(m->mode); m++) { + if (!mode_valid(m)) + continue; + + dprintf(1, "VBE found mode %x valid.\n", GET_GLOBAL(m->mode)); + SET_FARVAR(seg, dest[count], GET_GLOBAL(m->mode)); + + count++; + } + + SET_FARVAR(seg, dest[count], 0xffff); /* End of list */ + + return count; +} + +int +vbe_mode_info(u16 mode, struct vbe_modeinfo *info) +{ + struct mode *m; + + m = find_mode_entry(mode); + if (!m || !mode_valid(m)) + return -1; + + info->width = GET_GLOBAL(m->width); + info->height = GET_GLOBAL(m->height); + info->depth = GET_GLOBAL(m->depth); + + info->linesize = info->width * ((info->depth + 7) / 8); + info->phys_base = GET_GLOBAL(pci_lfb_addr); + info->vram_size = vbe_total_mem() * 64 * 1024; + + return 0; +} + +void +vbe_hires_enable(int enable) +{ + u16 flags = enable ? + VBE_DISPI_ENABLED | + VBE_DISPI_LFB_ENABLED | + VBE_DISPI_NOCLEARMEM : 0; + + dispi_write(VBE_DISPI_INDEX_ENABLE, flags); +} + +void +vbe_set_mode(u16 mode, struct vbe_modeinfo *info) +{ + if (info->depth == 4) + vga_set_mode(0x6a, 0); + if (info->depth == 8) + // XXX load_dac_palette(3); + ; + + dispi_write(VBE_DISPI_INDEX_BPP, info->depth); + dispi_write(VBE_DISPI_INDEX_XRES, info->width); + dispi_write(VBE_DISPI_INDEX_YRES, info->height); + dispi_write(VBE_DISPI_INDEX_BANK, 0); + + /* VGA compat setup */ + //XXX: This probably needs some reverse engineering + u8 v; + outw(0x0011, VGAREG_VGA_CRTC_ADDRESS); + outw(((info->width * 4 - 1) << 8) | 0x1, VGAREG_VGA_CRTC_ADDRESS); + dispi_write(VBE_DISPI_INDEX_VIRT_WIDTH, info->width); + outw(((info->height - 1) << 8) | 0x12, VGAREG_VGA_CRTC_ADDRESS); + outw(((info->height - 1) & 0xff00) | 0x7, VGAREG_VGA_CRTC_ADDRESS); + v = inb(VGAREG_VGA_CRTC_DATA) & 0xbd; + if (v & 0x1) + v |= 0x2; + if (v & 0x2) + v |= 0x40; + outb(v, VGAREG_VGA_CRTC_DATA); + + outw(0x9, VGAREG_VGA_CRTC_ADDRESS); + outb(0x17, VGAREG_VGA_CRTC_ADDRESS); + outb(inb(VGAREG_VGA_CRTC_DATA) | 0x3, VGAREG_VGA_CRTC_DATA); + v = inb(VGAREG_ACTL_RESET); + outw(0x10, VGAREG_ACTL_ADDRESS); + v = inb(VGAREG_ACTL_READ_DATA) | 0x1; + outb(v, VGAREG_ACTL_ADDRESS); + outb(0x20, VGAREG_ACTL_ADDRESS); + outw(0x0506, VGAREG_GRDC_ADDRESS); + outw(0x0f02, VGAREG_SEQU_ADDRESS); + if (info->depth >= 8) { + outb(0x14, VGAREG_VGA_CRTC_ADDRESS); + outb(inb(VGAREG_VGA_CRTC_DATA) | 0x40, VGAREG_VGA_CRTC_DATA); + v = inb(VGAREG_ACTL_RESET); + outw(0x10, VGAREG_ACTL_ADDRESS); + v = inb(VGAREG_ACTL_READ_DATA) | 0x40; + outb(v, VGAREG_ACTL_ADDRESS); + outb(0x20, VGAREG_ACTL_ADDRESS); + outb(0x04, VGAREG_SEQU_ADDRESS); + v = inb(VGAREG_SEQU_DATA) | 0x08; + outb(v, VGAREG_SEQU_DATA); + outb(0x05, VGAREG_GRDC_ADDRESS); + v = inb(VGAREG_GRDC_DATA) & 0x9f; + outb(v | 0x40, VGAREG_GRDC_DATA); + } + + SET_BDA(vbe_mode, mode); +} + +void +vbe_clear_scr(void) +{ + u16 en; + + en = dispi_read(VBE_DISPI_INDEX_ENABLE); + en &= ~VBE_DISPI_NOCLEARMEM; + dispi_write(VBE_DISPI_INDEX_ENABLE, en); +} + +int +vbe_hires_enabled(void) +{ + return dispi_read(VBE_DISPI_INDEX_ENABLE) & VBE_DISPI_ENABLED; +} + +u16 +vbe_curr_mode(void) +{ + return GET_BDA(vbe_mode); +} + diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h new file mode 100644 index 0000000..963cb13 --- /dev/null +++ b/vgasrc/bochsvga.h @@ -0,0 +1,55 @@ +#ifndef __DISPI_H +#define __DISPI_H + +#include "types.h" // u8 +#include "ioport.h" // outb + +#define VBE_DISPI_BANK_ADDRESS 0xA0000 +#define VBE_DISPI_BANK_SIZE_KB 64 + +#define VBE_DISPI_MAX_XRES 2560 +#define VBE_DISPI_MAX_YRES 1600 + +#define VBE_DISPI_IOPORT_INDEX 0x01CE +#define VBE_DISPI_IOPORT_DATA 0x01CF + +#define VBE_DISPI_INDEX_ID 0x0 +#define VBE_DISPI_INDEX_XRES 0x1 +#define VBE_DISPI_INDEX_YRES 0x2 +#define VBE_DISPI_INDEX_BPP 0x3 +#define VBE_DISPI_INDEX_ENABLE 0x4 +#define VBE_DISPI_INDEX_BANK 0x5 +#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 +#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 +#define VBE_DISPI_INDEX_X_OFFSET 0x8 +#define VBE_DISPI_INDEX_Y_OFFSET 0x9 +#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa + +#define VBE_DISPI_ID0 0xB0C0 +#define VBE_DISPI_ID1 0xB0C1 +#define VBE_DISPI_ID2 0xB0C2 +#define VBE_DISPI_ID3 0xB0C3 +#define VBE_DISPI_ID4 0xB0C4 +#define VBE_DISPI_ID5 0xB0C5 + +#define VBE_DISPI_DISABLED 0x00 +#define VBE_DISPI_ENABLED 0x01 +#define VBE_DISPI_GETCAPS 0x02 +#define VBE_DISPI_8BIT_DAC 0x20 +#define VBE_DISPI_LFB_ENABLED 0x40 +#define VBE_DISPI_NOCLEARMEM 0x80 + +#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 + +static inline u16 dispi_read(u16 reg) +{ + outw(reg, VBE_DISPI_IOPORT_INDEX); + return inw(VBE_DISPI_IOPORT_DATA); +} +static inline void dispi_write(u16 reg, u16 val) +{ + outw(reg, VBE_DISPI_IOPORT_INDEX); + outw(val, VBE_DISPI_IOPORT_DATA); +} + +#endif diff --git a/vgasrc/dispi.h b/vgasrc/dispi.h deleted file mode 100644 index 963cb13..0000000 --- a/vgasrc/dispi.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __DISPI_H -#define __DISPI_H - -#include "types.h" // u8 -#include "ioport.h" // outb - -#define VBE_DISPI_BANK_ADDRESS 0xA0000 -#define VBE_DISPI_BANK_SIZE_KB 64 - -#define VBE_DISPI_MAX_XRES 2560 -#define VBE_DISPI_MAX_YRES 1600 - -#define VBE_DISPI_IOPORT_INDEX 0x01CE -#define VBE_DISPI_IOPORT_DATA 0x01CF - -#define VBE_DISPI_INDEX_ID 0x0 -#define VBE_DISPI_INDEX_XRES 0x1 -#define VBE_DISPI_INDEX_YRES 0x2 -#define VBE_DISPI_INDEX_BPP 0x3 -#define VBE_DISPI_INDEX_ENABLE 0x4 -#define VBE_DISPI_INDEX_BANK 0x5 -#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 -#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 -#define VBE_DISPI_INDEX_X_OFFSET 0x8 -#define VBE_DISPI_INDEX_Y_OFFSET 0x9 -#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa - -#define VBE_DISPI_ID0 0xB0C0 -#define VBE_DISPI_ID1 0xB0C1 -#define VBE_DISPI_ID2 0xB0C2 -#define VBE_DISPI_ID3 0xB0C3 -#define VBE_DISPI_ID4 0xB0C4 -#define VBE_DISPI_ID5 0xB0C5 - -#define VBE_DISPI_DISABLED 0x00 -#define VBE_DISPI_ENABLED 0x01 -#define VBE_DISPI_GETCAPS 0x02 -#define VBE_DISPI_8BIT_DAC 0x20 -#define VBE_DISPI_LFB_ENABLED 0x40 -#define VBE_DISPI_NOCLEARMEM 0x80 - -#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 - -static inline u16 dispi_read(u16 reg) -{ - outw(reg, VBE_DISPI_IOPORT_INDEX); - return inw(VBE_DISPI_IOPORT_DATA); -} -static inline void dispi_write(u16 reg, u16 val) -{ - outw(reg, VBE_DISPI_IOPORT_INDEX); - outw(val, VBE_DISPI_IOPORT_DATA); -} - -#endif diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c deleted file mode 100644 index 2a1e932..0000000 --- a/vgasrc/vbe.c +++ /dev/null @@ -1,340 +0,0 @@ -#include "vgatables.h" -#include "vbe.h" -#include "dispi.h" -#include "util.h" -#include "config.h" // CONFIG_ -#include "biosvar.h" // SET_BDA - -struct mode -{ - u16 mode; - u16 width; - u16 height; - u8 depth; -} vbe_modes[] VAR16 = { - /* standard modes */ - { 0x100, 640, 400, 8 }, - { 0x101, 640, 480, 8 }, - { 0x102, 800, 600, 4 }, - { 0x103, 800, 600, 8 }, - { 0x104, 1024, 768, 4 }, - { 0x105, 1024, 768, 8 }, - { 0x106, 1280, 1024, 4 }, - { 0x107, 1280, 1024, 8 }, - { 0x10D, 320, 200, 15 }, - { 0x10E, 320, 200, 16 }, - { 0x10F, 320, 200, 24 }, - { 0x110, 640, 480, 15 }, - { 0x111, 640, 480, 16 }, - { 0x112, 640, 480, 24 }, - { 0x113, 800, 600, 15 }, - { 0x114, 800, 600, 16 }, - { 0x115, 800, 600, 24 }, - { 0x116, 1024, 768, 15 }, - { 0x117, 1024, 768, 16 }, - { 0x118, 1024, 768, 24 }, - { 0x119, 1280, 1024, 15 }, - { 0x11A, 1280, 1024, 16 }, - { 0x11B, 1280, 1024, 24 }, - { 0x11C, 1600, 1200, 8 }, - { 0x11D, 1600, 1200, 15 }, - { 0x11E, 1600, 1200, 16 }, - { 0x11F, 1600, 1200, 24 }, - /* BOCHS modes */ - { 0x140, 320, 200, 32 }, - { 0x141, 640, 400, 32 }, - { 0x142, 640, 480, 32 }, - { 0x143, 800, 600, 32 }, - { 0x144, 1024, 768, 32 }, - { 0x145, 1280, 1024, 32 }, - { 0x146, 320, 200, 8 }, - { 0x147, 1600, 1200, 32 }, - { 0x148, 1152, 864, 8 }, - { 0x149, 1152, 864, 15 }, - { 0x14a, 1152, 864, 16 }, - { 0x14b, 1152, 864, 24 }, - { 0x14c, 1152, 864, 32 }, - { 0x178, 1280, 800, 16 }, - { 0x179, 1280, 800, 24 }, - { 0x17a, 1280, 800, 32 }, - { 0x17b, 1280, 960, 16 }, - { 0x17c, 1280, 960, 24 }, - { 0x17d, 1280, 960, 32 }, - { 0x17e, 1440, 900, 16 }, - { 0x17f, 1440, 900, 24 }, - { 0x180, 1440, 900, 32 }, - { 0x181, 1400, 1050, 16 }, - { 0x182, 1400, 1050, 24 }, - { 0x183, 1400, 1050, 32 }, - { 0x184, 1680, 1050, 16 }, - { 0x185, 1680, 1050, 24 }, - { 0x186, 1680, 1050, 32 }, - { 0x187, 1920, 1200, 16 }, - { 0x188, 1920, 1200, 24 }, - { 0x189, 1920, 1200, 32 }, - { 0x18a, 2560, 1600, 16 }, - { 0x18b, 2560, 1600, 24 }, - { 0x18c, 2560, 1600, 32 }, - { 0, }, -}; - -#define BYTES_PER_PIXEL(m) ((GET_GLOBAL((m)->depth) + 7) / 8) - -u32 pci_lfb_addr VAR16; - -static inline u32 pci_config_readl(u8 bus, u8 devfn, u16 addr) -{ - int status; - u32 val; - u16 bdf = (bus << 16) | devfn; - - addr &= ~3; - - asm volatile( - "int $0x1a\n" - "cli\n" - "cld" - : "=a"(status), "=c"(val) - : "a"(0xb10a), "b"(bdf), "D"(addr) - : "cc", "memory"); - - if ((status >> 16)) - return (u32)-1; - - return val; -} - - -static u16 dispi_get_max_xres(void) -{ - u16 en; - u16 xres; - - en = dispi_read(VBE_DISPI_INDEX_ENABLE); - - dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS); - xres = dispi_read(VBE_DISPI_INDEX_XRES); - dispi_write(VBE_DISPI_INDEX_ENABLE, en); - - return xres; -} - -static u16 dispi_get_max_bpp(void) -{ - u16 en; - u16 bpp; - - en = dispi_read(VBE_DISPI_INDEX_ENABLE); - - dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS); - bpp = dispi_read(VBE_DISPI_INDEX_BPP); - dispi_write(VBE_DISPI_INDEX_ENABLE, en); - - return bpp; -} - -/* Called only during POST */ -int -vbe_init(u8 bus, u8 devfn) -{ - u32 lfb_addr; - - if (!CONFIG_VGA_BOCHS) - return -1; - - /* Sanity checks */ - dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID0); - if (dispi_read(VBE_DISPI_INDEX_ID) != VBE_DISPI_ID0) { - dprintf(1, "No VBE DISPI interface detected\n"); - return -1; - } - - SET_BDA(vbe_flag, 0x1); - dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5); - - if (CONFIG_VGA_PCI) - lfb_addr = pci_config_readl(bus, devfn, 0x10) & ~0xf; - else - lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS; - - SET_FARVAR(get_global_seg(), pci_lfb_addr, lfb_addr); - - dprintf(1, "VBE DISPI detected. lfb_addr=%x\n", GET_GLOBAL(pci_lfb_addr)); - - return 0; -} - -int -vbe_enabled(void) -{ - return GET_BDA(vbe_flag); -} - -u16 -vbe_total_mem(void) -{ - return dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K); -} - -static struct mode *find_mode_entry(u16 mode) -{ - struct mode *m; - - for (m = vbe_modes; GET_GLOBAL(m->mode); m++) { - if (GET_GLOBAL(m->mode) == mode) - return m; - } - - return NULL; -} - -static int mode_valid(struct mode *m) -{ - u16 max_xres = dispi_get_max_xres(); - u16 max_bpp = dispi_get_max_bpp(); - u32 max_mem = vbe_total_mem() * 64 * 1024; - - u32 mem = GET_GLOBAL(m->width) * GET_GLOBAL(m->height) * - BYTES_PER_PIXEL(m); - - if (GET_GLOBAL(m->width) > max_xres || - GET_GLOBAL(m->depth) > max_bpp || - mem > max_mem) - return 0; - - return 1; -} - -int -vbe_list_modes(u16 seg, u16 ptr) -{ - int count = 0; - u16 *dest = (u16 *)(u32)ptr; - struct mode *m; - - for (m = vbe_modes; GET_GLOBAL(m->mode); m++) { - if (!mode_valid(m)) - continue; - - dprintf(1, "VBE found mode %x valid.\n", GET_GLOBAL(m->mode)); - SET_FARVAR(seg, dest[count], GET_GLOBAL(m->mode)); - - count++; - } - - SET_FARVAR(seg, dest[count], 0xffff); /* End of list */ - - return count; -} - -int -vbe_mode_info(u16 mode, struct vbe_modeinfo *info) -{ - struct mode *m; - - m = find_mode_entry(mode); - if (!m || !mode_valid(m)) - return -1; - - info->width = GET_GLOBAL(m->width); - info->height = GET_GLOBAL(m->height); - info->depth = GET_GLOBAL(m->depth); - - info->linesize = info->width * ((info->depth + 7) / 8); - info->phys_base = GET_GLOBAL(pci_lfb_addr); - info->vram_size = vbe_total_mem() * 64 * 1024; - - return 0; -} - -void -vbe_hires_enable(int enable) -{ - u16 flags = enable ? - VBE_DISPI_ENABLED | - VBE_DISPI_LFB_ENABLED | - VBE_DISPI_NOCLEARMEM : 0; - - dispi_write(VBE_DISPI_INDEX_ENABLE, flags); -} - -void -vbe_set_mode(u16 mode, struct vbe_modeinfo *info) -{ - if (info->depth == 4) - vga_set_mode(0x6a, 0); - if (info->depth == 8) - // XXX load_dac_palette(3); - ; - - dispi_write(VBE_DISPI_INDEX_BPP, info->depth); - dispi_write(VBE_DISPI_INDEX_XRES, info->width); - dispi_write(VBE_DISPI_INDEX_YRES, info->height); - dispi_write(VBE_DISPI_INDEX_BANK, 0); - - /* VGA compat setup */ - //XXX: This probably needs some reverse engineering - u8 v; - outw(0x0011, VGAREG_VGA_CRTC_ADDRESS); - outw(((info->width * 4 - 1) << 8) | 0x1, VGAREG_VGA_CRTC_ADDRESS); - dispi_write(VBE_DISPI_INDEX_VIRT_WIDTH, info->width); - outw(((info->height - 1) << 8) | 0x12, VGAREG_VGA_CRTC_ADDRESS); - outw(((info->height - 1) & 0xff00) | 0x7, VGAREG_VGA_CRTC_ADDRESS); - v = inb(VGAREG_VGA_CRTC_DATA) & 0xbd; - if (v & 0x1) - v |= 0x2; - if (v & 0x2) - v |= 0x40; - outb(v, VGAREG_VGA_CRTC_DATA); - - outw(0x9, VGAREG_VGA_CRTC_ADDRESS); - outb(0x17, VGAREG_VGA_CRTC_ADDRESS); - outb(inb(VGAREG_VGA_CRTC_DATA) | 0x3, VGAREG_VGA_CRTC_DATA); - v = inb(VGAREG_ACTL_RESET); - outw(0x10, VGAREG_ACTL_ADDRESS); - v = inb(VGAREG_ACTL_READ_DATA) | 0x1; - outb(v, VGAREG_ACTL_ADDRESS); - outb(0x20, VGAREG_ACTL_ADDRESS); - outw(0x0506, VGAREG_GRDC_ADDRESS); - outw(0x0f02, VGAREG_SEQU_ADDRESS); - if (info->depth >= 8) { - outb(0x14, VGAREG_VGA_CRTC_ADDRESS); - outb(inb(VGAREG_VGA_CRTC_DATA) | 0x40, VGAREG_VGA_CRTC_DATA); - v = inb(VGAREG_ACTL_RESET); - outw(0x10, VGAREG_ACTL_ADDRESS); - v = inb(VGAREG_ACTL_READ_DATA) | 0x40; - outb(v, VGAREG_ACTL_ADDRESS); - outb(0x20, VGAREG_ACTL_ADDRESS); - outb(0x04, VGAREG_SEQU_ADDRESS); - v = inb(VGAREG_SEQU_DATA) | 0x08; - outb(v, VGAREG_SEQU_DATA); - outb(0x05, VGAREG_GRDC_ADDRESS); - v = inb(VGAREG_GRDC_DATA) & 0x9f; - outb(v | 0x40, VGAREG_GRDC_DATA); - } - - SET_BDA(vbe_mode, mode); -} - -void -vbe_clear_scr(void) -{ - u16 en; - - en = dispi_read(VBE_DISPI_INDEX_ENABLE); - en &= ~VBE_DISPI_NOCLEARMEM; - dispi_write(VBE_DISPI_INDEX_ENABLE, en); -} - -int -vbe_hires_enabled(void) -{ - return dispi_read(VBE_DISPI_INDEX_ENABLE) & VBE_DISPI_ENABLED; -} - -u16 -vbe_curr_mode(void) -{ - return GET_BDA(vbe_mode); -} -
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 33 ++++++++++++++++----------------- vgasrc/bochsvga.h | 12 ++++++++++++ vgasrc/vga.c | 31 ++++++++++++++++--------------- vgasrc/vgatables.h | 10 ---------- 4 files changed, 44 insertions(+), 42 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 7ea1a1f..99d4041 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -5,13 +5,13 @@ #include "config.h" // CONFIG_ #include "biosvar.h" // SET_BDA
-struct mode +static struct mode { u16 mode; u16 width; u16 height; u8 depth; -} vbe_modes[] VAR16 = { +} bochsvga_modes[] VAR16 = { /* standard modes */ { 0x100, 640, 400, 8 }, { 0x101, 640, 480, 8 }, @@ -135,7 +135,7 @@ static u16 dispi_get_max_bpp(void)
/* Called only during POST */ int -vbe_init(u8 bus, u8 devfn) +bochsvga_init(u8 bus, u8 devfn) { u32 lfb_addr;
@@ -165,13 +165,13 @@ vbe_init(u8 bus, u8 devfn) }
int -vbe_enabled(void) +bochsvga_enabled(void) { return GET_BDA(vbe_flag); }
u16 -vbe_total_mem(void) +bochsvga_total_mem(void) { return dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K); } @@ -180,7 +180,7 @@ static struct mode *find_mode_entry(u16 mode) { struct mode *m;
- for (m = vbe_modes; GET_GLOBAL(m->mode); m++) { + for (m = bochsvga_modes; GET_GLOBAL(m->mode); m++) { if (GET_GLOBAL(m->mode) == mode) return m; } @@ -192,7 +192,7 @@ static int mode_valid(struct mode *m) { u16 max_xres = dispi_get_max_xres(); u16 max_bpp = dispi_get_max_bpp(); - u32 max_mem = vbe_total_mem() * 64 * 1024; + u32 max_mem = bochsvga_total_mem() * 64 * 1024;
u32 mem = GET_GLOBAL(m->width) * GET_GLOBAL(m->height) * BYTES_PER_PIXEL(m); @@ -206,13 +206,13 @@ static int mode_valid(struct mode *m) }
int -vbe_list_modes(u16 seg, u16 ptr) +bochsvga_list_modes(u16 seg, u16 ptr) { int count = 0; u16 *dest = (u16 *)(u32)ptr; struct mode *m;
- for (m = vbe_modes; GET_GLOBAL(m->mode); m++) { + for (m = bochsvga_modes; GET_GLOBAL(m->mode); m++) { if (!mode_valid(m)) continue;
@@ -228,7 +228,7 @@ vbe_list_modes(u16 seg, u16 ptr) }
int -vbe_mode_info(u16 mode, struct vbe_modeinfo *info) +bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info) { struct mode *m;
@@ -242,13 +242,13 @@ vbe_mode_info(u16 mode, struct vbe_modeinfo *info)
info->linesize = info->width * ((info->depth + 7) / 8); info->phys_base = GET_GLOBAL(pci_lfb_addr); - info->vram_size = vbe_total_mem() * 64 * 1024; + info->vram_size = bochsvga_total_mem() * 64 * 1024;
return 0; }
void -vbe_hires_enable(int enable) +bochsvga_hires_enable(int enable) { u16 flags = enable ? VBE_DISPI_ENABLED | @@ -259,7 +259,7 @@ vbe_hires_enable(int enable) }
void -vbe_set_mode(u16 mode, struct vbe_modeinfo *info) +bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info) { if (info->depth == 4) vga_set_mode(0x6a, 0); @@ -317,7 +317,7 @@ vbe_set_mode(u16 mode, struct vbe_modeinfo *info) }
void -vbe_clear_scr(void) +bochsvga_clear_scr(void) { u16 en;
@@ -327,14 +327,13 @@ vbe_clear_scr(void) }
int -vbe_hires_enabled(void) +bochsvga_hires_enabled(void) { return dispi_read(VBE_DISPI_INDEX_ENABLE) & VBE_DISPI_ENABLED; }
u16 -vbe_curr_mode(void) +bochsvga_curr_mode(void) { return GET_BDA(vbe_mode); } - diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index 963cb13..aaa3a97 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -52,4 +52,16 @@ static inline void dispi_write(u16 reg, u16 val) outw(val, VBE_DISPI_IOPORT_DATA); }
+int bochsvga_init(u8 bus, u8 devfn); +int bochsvga_enabled(void); +u16 bochsvga_total_mem(void); +int bochsvga_list_modes(u16 seg, u16 ptr); +struct vbe_modeinfo; +int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info); +void bochsvga_hires_enable(int enable); +void bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info); +void bochsvga_clear_scr(void); +int bochsvga_hires_enabled(void); +u16 bochsvga_curr_mode(void); + #endif diff --git a/vgasrc/vga.c b/vgasrc/vga.c index 539cd7a..9e5884b 100644 --- a/vgasrc/vga.c +++ b/vgasrc/vga.c @@ -17,8 +17,9 @@ #include "vgatables.h" // find_vga_entry #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* -#include "vbe.h" // vbe_* +#include "vbe.h" // struct vbe_info #include "geodelx.h" // geodelx_init +#include "bochsvga.h" // bochsvga_init
// XXX #define DEBUG_VGA_POST 1 @@ -478,8 +479,8 @@ handle_1000(struct bregs *regs) return; }
- if (vbe_enabled()) - vbe_hires_enable(0); + if (bochsvga_enabled()) + bochsvga_hires_enable(0);
vga_set_mode(mode, noclearmem); } @@ -1232,7 +1233,7 @@ handle_104f00(struct bregs *regs) SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34));
/* Total memory (in 64 blocks) */ - SET_FARVAR(seg, info->total_memory, vbe_total_mem()); + SET_FARVAR(seg, info->total_memory, bochsvga_total_mem());
SET_FARVAR(seg, info->oem_vendor_string, SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); @@ -1242,7 +1243,7 @@ handle_104f00(struct bregs *regs) SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING));
/* Fill list of modes */ - vbe_list_modes(seg, regs->di + 32); + bochsvga_list_modes(seg, regs->di + 32);
regs->al = regs->ah; /* 0x4F, Function supported */ regs->ah = 0x0; /* 0x0, Function call successful */ @@ -1259,7 +1260,7 @@ handle_104f01(struct bregs *regs)
dprintf(1, "VBE mode info request: %x\n", mode);
- rc = vbe_mode_info(mode, &modeinfo); + rc = bochsvga_mode_info(mode, &modeinfo); if (rc) { dprintf(1, "VBE mode %x not found\n", mode); regs->ax = 0x100; @@ -1379,24 +1380,24 @@ handle_104f02(struct bregs *regs) if (mode < 0x100) { /* VGA */ dprintf(1, "set VGA mode %x\n", mode);
- vbe_hires_enable(0); + bochsvga_hires_enable(0); vga_set_mode(mode, 0); } else { /* VBE */ - rc = vbe_mode_info(mode & 0x1ff, &modeinfo); + rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); if (rc) { dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); regs->ax = 0x100; return; } - vbe_hires_enable(1); - vbe_set_mode(mode & 0x1ff, &modeinfo); + bochsvga_hires_enable(1); + bochsvga_set_mode(mode & 0x1ff, &modeinfo);
if (mode & 0x4000) { /* Linear frame buffer */ /* XXX: ??? */ } if (!(mode & 0x8000)) { - vbe_clear_scr(); + bochsvga_clear_scr(); } }
@@ -1407,10 +1408,10 @@ handle_104f02(struct bregs *regs) static void handle_104f03(struct bregs *regs) { - if (!vbe_hires_enabled()) { + if (!bochsvga_hires_enabled()) { regs->bx = GET_BDA(video_mode); } else { - regs->bx = vbe_curr_mode(); + regs->bx = bochsvga_curr_mode(); }
dprintf(1, "VBE current mode=%x\n", regs->bx); @@ -1471,7 +1472,7 @@ handle_104fXX(struct bregs *regs) static void handle_104f(struct bregs *regs) { - if (!vbe_enabled()) { + if (!bochsvga_enabled()) { handle_104fXX(regs); return; } @@ -1575,7 +1576,7 @@ vga_post(struct bregs *regs)
init_bios_area();
- vbe_init(regs->ah, regs->al); + bochsvga_init(regs->ah, regs->al);
extern void entry_10(void); SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10)); diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h index 5a90174..e0d61c9 100644 --- a/vgasrc/vgatables.h +++ b/vgasrc/vgatables.h @@ -221,15 +221,5 @@ struct vbe_modeinfo u32 phys_base; u32 vram_size; }; -int vbe_init(u8 bus, u8 devfn); -int vbe_enabled(void); -u16 vbe_total_mem(void); -int vbe_list_modes(u16 seg, u16 ptr); -int vbe_mode_info(u16 mode, struct vbe_modeinfo *info); -void vbe_hires_enable(int enable); -void vbe_set_mode(u16 mode, struct vbe_modeinfo *info); -void vbe_clear_scr(void); -int vbe_hires_enabled(void); -u16 vbe_curr_mode(void);
#endif // vgatables.h
Also, rename vgatables.h to vgabios.h.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- vgasrc/bochsvga.c | 4 +- vgasrc/bochsvga.h | 6 +- vgasrc/clext.c | 2 +- vgasrc/geodelx.c | 2 +- vgasrc/vga.c | 1596 ---------------------------------------------------- vgasrc/vgabios.c | 1596 ++++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/vgabios.h | 225 ++++++++ vgasrc/vgafb.c | 2 +- vgasrc/vgafonts.c | 2 +- vgasrc/vgaio.c | 2 +- vgasrc/vgatables.c | 2 +- vgasrc/vgatables.h | 225 -------- 13 files changed, 1833 insertions(+), 1833 deletions(-) delete mode 100644 vgasrc/vga.c create mode 100644 vgasrc/vgabios.c create mode 100644 vgasrc/vgabios.h delete mode 100644 vgasrc/vgatables.h
diff --git a/Makefile b/Makefile index 3d60b88..2346ee3 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,7 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py ################ VGA build rules
# VGA src files -SRCVGA=src/output.c src/util.c vgasrc/vga.c vgasrc/vgafb.c vgasrc/vgaio.c \ +SRCVGA=src/output.c src/util.c vgasrc/vgabios.c vgasrc/vgafb.c vgasrc/vgaio.c \ vgasrc/vgatables.c vgasrc/vgafonts.c \ vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodelx.c
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 99d4041..9dd142b 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -1,8 +1,8 @@ -#include "vgatables.h" +#include "vgabios.h" // struct vbe_modeinfo #include "vbe.h" #include "bochsvga.h" #include "util.h" -#include "config.h" // CONFIG_ +#include "config.h" // CONFIG_* #include "biosvar.h" // SET_BDA
static struct mode diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index aaa3a97..f0263d7 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -1,5 +1,5 @@ -#ifndef __DISPI_H -#define __DISPI_H +#ifndef __BOCHSVGA_H +#define __BOCHSVGA_H
#include "types.h" // u8 #include "ioport.h" // outb @@ -64,4 +64,4 @@ void bochsvga_clear_scr(void); int bochsvga_hires_enabled(void); u16 bochsvga_curr_mode(void);
-#endif +#endif // bochsvga.h diff --git a/vgasrc/clext.c b/vgasrc/clext.c index b2c59fb..40447ff 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -5,7 +5,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "vgatables.h" // cirrus_init +#include "vgabios.h" // cirrus_init #include "biosvar.h" // GET_GLOBAL #include "util.h" // dprintf #include "bregs.h" // struct bregs diff --git a/vgasrc/geodelx.c b/vgasrc/geodelx.c index 6c0f838..1d58be0 100644 --- a/vgasrc/geodelx.c +++ b/vgasrc/geodelx.c @@ -10,7 +10,7 @@ #include "ioport.h" // outb #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_BDA -#include "vgatables.h" // VGAREG_* +#include "vgabios.h" // VGAREG_* #include "util.h" // memset #include "config.h" #include "types.h" diff --git a/vgasrc/vga.c b/vgasrc/vga.c deleted file mode 100644 index 9e5884b..0000000 --- a/vgasrc/vga.c +++ /dev/null @@ -1,1596 +0,0 @@ -// VGA bios implementation -// -// Copyright (C) 2009 Kevin O'Connor kevin@koconnor.net -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - - -// TODO: -// * review correctness of converted asm by comparing with RBIL -// -// * convert vbe/clext code - -#include "bregs.h" // struct bregs -#include "biosvar.h" // GET_BDA -#include "util.h" // memset -#include "vgatables.h" // find_vga_entry -#include "optionroms.h" // struct pci_data -#include "config.h" // CONFIG_* -#include "vbe.h" // struct vbe_info -#include "geodelx.h" // geodelx_init -#include "bochsvga.h" // bochsvga_init - -// XXX -#define DEBUG_VGA_POST 1 -#define DEBUG_VGA_10 3 - - -/**************************************************************** - * PCI Data - ****************************************************************/ -#if CONFIG_VGA_PCI == 1 -struct pci_data rom_pci_data VAR16VISIBLE = { - .signature = PCI_ROM_SIGNATURE, - .vendor = CONFIG_VGA_VID, - .device = CONFIG_VGA_DID, - .dlen = 0x18, - .class_hi = 0x300, - .irevision = 1, - .type = PCIROM_CODETYPE_X86, - .indicator = 0x80, -}; -#endif - -/**************************************************************** - * Helper functions - ****************************************************************/ - -static inline void -call16_vgaint(u32 eax, u32 ebx) -{ - asm volatile( - "int $0x10\n" - "cli\n" - "cld" - : - : "a"(eax), "b"(ebx) - : "cc", "memory"); -} - -static void -perform_gray_scale_summing(u16 start, u16 count) -{ - vgahw_screen_disable(); - int i; - for (i = start; i < start+count; i++) { - u8 rgb[3]; - vgahw_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; - - vgahw_set_dac_regs(GET_SEG(SS), rgb, i, 1); - } - vgahw_screen_enable(); -} - -static void -set_cursor_shape(u8 start, u8 end) -{ - start &= 0x3f; - end &= 0x1f; - - u16 curs = (start << 8) + end; - SET_BDA(cursor_type, curs); - - u8 modeset_ctl = GET_BDA(modeset_ctl); - u16 cheight = GET_BDA(char_height); - if ((modeset_ctl & 0x01) && (cheight > 8) && (end < 8) && (start < 0x20)) { - if (end != (start + 1)) - start = ((start + 1) * cheight / 8) - 1; - else - start = ((end + 1) * cheight / 8) - 2; - end = ((end + 1) * cheight / 8) - 1; - } - vgahw_set_cursor_shape(start, end); -} - -static u16 -get_cursor_shape(u8 page) -{ - if (page > 7) - return 0; - // FIXME should handle VGA 14/16 lines - return GET_BDA(cursor_type); -} - -static void -set_cursor_pos(struct cursorpos cp) -{ - // Should not happen... - if (cp.page > 7) - return; - - // Bios cursor pos - SET_BDA(cursor_pos[cp.page], (cp.y << 8) | cp.x); - - // Set the hardware cursor - u8 current = GET_BDA(video_page); - if (cp.page != current) - return; - - // Get the dimensions - u16 nbcols = GET_BDA(video_cols); - u16 nbrows = GET_BDA(video_rows) + 1; - - // Calculate the address knowing nbcols nbrows and page num - u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page) - + cp.x + cp.y * nbcols); - - vgahw_set_cursor_pos(address); -} - -static struct cursorpos -get_cursor_pos(u8 page) -{ - if (page == 0xff) - // special case - use current page - page = GET_BDA(video_page); - if (page > 7) { - struct cursorpos cp = { 0, 0, 0xfe }; - return cp; - } - // FIXME should handle VGA 14/16 lines - u16 xy = GET_BDA(cursor_pos[page]); - struct cursorpos cp = {xy, xy>>8, page}; - return cp; -} - -static void -set_active_page(u8 page) -{ - if (page > 7) - return; - - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // Get pos curs pos for the right page - struct cursorpos cp = get_cursor_pos(page); - - u16 address; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { - // Get the dimensions - u16 nbcols = GET_BDA(video_cols); - u16 nbrows = GET_BDA(video_rows) + 1; - - // Calculate the address knowing nbcols nbrows and page num - address = SCREEN_MEM_START(nbcols, nbrows, page); - SET_BDA(video_pagestart, address); - - // Start address - address = SCREEN_IO_START(nbcols, nbrows, page); - } else { - address = page * GET_GLOBAL(vmode_g->slength); - } - - vgahw_set_active_page(address); - - // And change the BIOS page - SET_BDA(video_page, page); - - dprintf(1, "Set active page %02x address %04x\n", page, address); - - // Display the cursor, now the page is active - set_cursor_pos(cp); -} - -static void -set_scan_lines(u8 lines) -{ - vgahw_set_scan_lines(lines); - if (lines == 8) - set_cursor_shape(0x06, 0x07); - else - set_cursor_shape(lines - 4, lines - 3); - SET_BDA(char_height, lines); - u16 vde = vgahw_get_vde(); - u8 rows = vde / lines; - SET_BDA(video_rows, rows - 1); - u16 cols = GET_BDA(video_cols); - SET_BDA(video_pagesize, rows * cols * 2); -} - - -/**************************************************************** - * Character writing - ****************************************************************/ - -// Scroll the screen one line. This function is designed to be called -// tail-recursive to reduce stack usage. -static void noinline -scroll_one(u16 nbrows, u16 nbcols, u8 page) -{ - struct cursorpos ul = {0, 0, page}; - struct cursorpos lr = {nbcols-1, nbrows-1, page}; - vgafb_scroll(1, -1, ul, lr); -} - -// Write a character to the screen at a given position. Implement -// special characters and scroll the screen if necessary. -static void -write_teletype(struct cursorpos *pcp, struct carattr ca) -{ - struct cursorpos cp = *pcp; - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - switch (ca.car) { - case 7: - //FIXME should beep - break; - case 8: - if (cp.x > 0) - cp.x--; - break; - case '\r': - cp.x = 0; - break; - case '\n': - cp.y++; - break; - case '\t': - do { - struct carattr dummyca = {' ', ca.attr, ca.use_attr}; - vgafb_write_char(cp, dummyca); - cp.x++; - } while (cp.x < nbcols && cp.x % 8); - break; - default: - vgafb_write_char(cp, ca); - cp.x++; - } - - // Do we need to wrap ? - if (cp.x == nbcols) { - cp.x = 0; - cp.y++; - } - // Do we need to scroll ? - if (cp.y < nbrows) { - *pcp = cp; - return; - } - // Scroll screen - cp.y--; - *pcp = cp; - scroll_one(nbrows, nbcols, cp.page); -} - -// Write out a buffer of alternating characters and attributes. -static void -write_attr_string(struct cursorpos *pcp, u16 count, u16 seg, u8 *offset_far) -{ - while (count--) { - u8 car = GET_FARVAR(seg, *offset_far); - offset_far++; - u8 attr = GET_FARVAR(seg, *offset_far); - offset_far++; - - struct carattr ca = {car, attr, 1}; - write_teletype(pcp, ca); - } -} - -// Write out a buffer of characters. -static void -write_string(struct cursorpos *pcp, u8 attr, u16 count, u16 seg, u8 *offset_far) -{ - while (count--) { - u8 car = GET_FARVAR(seg, *offset_far); - offset_far++; - - struct carattr ca = {car, attr, 1}; - write_teletype(pcp, ca); - } -} - - -/**************************************************************** - * Save and restore bda state - ****************************************************************/ - -static void -save_bda_state(u16 seg, struct saveBDAstate *info) -{ - SET_FARVAR(seg, info->video_mode, GET_BDA(video_mode)); - SET_FARVAR(seg, info->video_cols, GET_BDA(video_cols)); - SET_FARVAR(seg, info->video_pagesize, GET_BDA(video_pagesize)); - SET_FARVAR(seg, info->crtc_address, GET_BDA(crtc_address)); - SET_FARVAR(seg, info->video_rows, GET_BDA(video_rows)); - SET_FARVAR(seg, info->char_height, GET_BDA(char_height)); - SET_FARVAR(seg, info->video_ctl, GET_BDA(video_ctl)); - SET_FARVAR(seg, info->video_switches, GET_BDA(video_switches)); - SET_FARVAR(seg, info->modeset_ctl, GET_BDA(modeset_ctl)); - SET_FARVAR(seg, info->cursor_type, GET_BDA(cursor_type)); - u16 i; - for (i=0; i<8; i++) - SET_FARVAR(seg, info->cursor_pos[i], GET_BDA(cursor_pos[i])); - SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart)); - SET_FARVAR(seg, info->video_page, GET_BDA(video_page)); - /* current font */ - SET_FARVAR(seg, info->font0, GET_IVT(0x1f)); - SET_FARVAR(seg, info->font1, GET_IVT(0x43)); -} - -static void -restore_bda_state(u16 seg, struct saveBDAstate *info) -{ - SET_BDA(video_mode, GET_FARVAR(seg, info->video_mode)); - SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols)); - SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize)); - SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address)); - SET_BDA(video_rows, GET_FARVAR(seg, info->video_rows)); - SET_BDA(char_height, GET_FARVAR(seg, info->char_height)); - SET_BDA(video_ctl, GET_FARVAR(seg, info->video_ctl)); - SET_BDA(video_switches, GET_FARVAR(seg, info->video_switches)); - SET_BDA(modeset_ctl, GET_FARVAR(seg, info->modeset_ctl)); - SET_BDA(cursor_type, GET_FARVAR(seg, info->cursor_type)); - u16 i; - for (i = 0; i < 8; i++) - SET_BDA(cursor_pos[i], GET_FARVAR(seg, info->cursor_pos[i])); - SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart)); - SET_BDA(video_page, GET_FARVAR(seg, info->video_page)); - /* current font */ - SET_IVT(0x1f, GET_FARVAR(seg, info->font0)); - SET_IVT(0x43, GET_FARVAR(seg, info->font1)); -} - - -/**************************************************************** - * VGA int 10 handler - ****************************************************************/ - -// set video mode -void -vga_set_mode(u8 mode, u8 noclearmem) -{ - // 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 - vgahw_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 - vgahw_set_dac_regs(get_global_seg(), palette_g, 0, palsize); - u16 i; - for (i = palsize; i < 0x0100; i++) { - static u8 rgb[3] VAR16; - vgahw_set_dac_regs(get_global_seg(), rgb, i, 1); - } - - if ((modeset_ctl & 0x02) == 0x02) - perform_gray_scale_summing(0x00, 0x100); - } - - vgahw_set_mode(vmode_g); - - if (noclearmem == 0x00) - clear_screen(vmode_g); - - // Set CRTC address VGA or MDA - u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; - if (GET_GLOBAL(vmode_g->memmodel) == MTEXT) - crtc_addr = VGAREG_MDA_CRTC_ADDRESS; - - // Set the BIOS mem - u16 cheight = GET_GLOBAL(vmode_g->cheight); - SET_BDA(video_mode, mode); - SET_BDA(video_cols, GET_GLOBAL(vmode_g->twidth)); - SET_BDA(video_pagesize, GET_GLOBAL(vmode_g->slength)); - SET_BDA(crtc_address, crtc_addr); - SET_BDA(video_rows, GET_GLOBAL(vmode_g->theight)-1); - SET_BDA(char_height, cheight); - SET_BDA(video_ctl, (0x60 | noclearmem)); - SET_BDA(video_switches, 0xF9); - SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); - - // FIXME We nearly have the good tables. to be reworked - SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now - SET_BDA(video_savetable - , SEGOFF(get_global_seg(), (u32)&video_save_pointer_table)); - - // FIXME - SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but... - SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but... - - // Set cursor shape - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - set_cursor_shape(0x06, 0x07); - // Set cursor pos for page 0..7 - int i; - for (i = 0; i < 8; i++) { - struct cursorpos cp = {0, 0, i}; - set_cursor_pos(cp); - } - - // Set active page 0 - set_active_page(0x00); - - // Write the fonts in memory - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { - call16_vgaint(0x1104, 0); - call16_vgaint(0x1103, 0); - } - // Set the ints 0x1F and 0x43 - SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8])); - - switch (cheight) { - case 8: - SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8)); - break; - case 14: - SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14)); - break; - case 16: - SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16)); - break; - } -} - -static void -handle_1000(struct bregs *regs) -{ - u8 noclearmem = regs->al & 0x80; - u8 mode = regs->al & 0x7f; - - // Set regs->al - if (mode > 7) - regs->al = 0x20; - else if (mode == 6) - regs->al = 0x3f; - else - regs->al = 0x30; - - if (CONFIG_VGA_CIRRUS) { - int ret = cirrus_set_video_mode(mode, noclearmem); - if (ret) - return; - } - - if (bochsvga_enabled()) - bochsvga_hires_enable(0); - - vga_set_mode(mode, noclearmem); -} - -static void -handle_1001(struct bregs *regs) -{ - set_cursor_shape(regs->ch, regs->cl); -} - -static void -handle_1002(struct bregs *regs) -{ - struct cursorpos cp = {regs->dl, regs->dh, regs->bh}; - set_cursor_pos(cp); -} - -static void -handle_1003(struct bregs *regs) -{ - regs->cx = get_cursor_shape(regs->bh); - struct cursorpos cp = get_cursor_pos(regs->bh); - regs->dl = cp.x; - regs->dh = cp.y; -} - -// Read light pen pos (unimplemented) -static void -handle_1004(struct bregs *regs) -{ - debug_stub(regs); - regs->ax = regs->bx = regs->cx = regs->dx = 0; -} - -static void -handle_1005(struct bregs *regs) -{ - set_active_page(regs->al); -} - -static void -verify_scroll(struct bregs *regs, int dir) -{ - u8 page = GET_BDA(video_page); - struct cursorpos ul = {regs->cl, regs->ch, page}; - struct cursorpos lr = {regs->dl, regs->dh, page}; - - u16 nbrows = GET_BDA(video_rows) + 1; - if (lr.y >= nbrows) - lr.y = nbrows - 1; - u16 nbcols = GET_BDA(video_cols); - if (lr.x >= nbcols) - lr.x = nbcols - 1; - - if (ul.x > lr.x || ul.y > lr.y) - return; - - u16 nblines = regs->al; - if (!nblines || nblines > lr.y - ul.y + 1) - nblines = lr.y - ul.y + 1; - - vgafb_scroll(dir * nblines, regs->bh, ul, lr); -} - -static void -handle_1006(struct bregs *regs) -{ - verify_scroll(regs, 1); -} - -static void -handle_1007(struct bregs *regs) -{ - verify_scroll(regs, -1); -} - -static void -handle_1008(struct bregs *regs) -{ - struct carattr ca = vgafb_read_char(get_cursor_pos(regs->bh)); - regs->al = ca.car; - regs->ah = ca.attr; -} - -static void noinline -write_chars(u8 page, struct carattr ca, u16 count) -{ - struct cursorpos cp = get_cursor_pos(page); - while (count--) { - vgafb_write_char(cp, ca); - cp.x++; - } -} - -static void -handle_1009(struct bregs *regs) -{ - struct carattr ca = {regs->al, regs->bl, 1}; - write_chars(regs->bh, ca, regs->cx); -} - -static void -handle_100a(struct bregs *regs) -{ - struct carattr ca = {regs->al, regs->bl, 0}; - write_chars(regs->bh, ca, regs->cx); -} - - -static void -handle_100b00(struct bregs *regs) -{ - vgahw_set_border_color(regs->bl); -} - -static void -handle_100b01(struct bregs *regs) -{ - vgahw_set_palette(regs->bl); -} - -static void -handle_100bXX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_100b(struct bregs *regs) -{ - switch (regs->bh) { - case 0x00: handle_100b00(regs); break; - case 0x01: handle_100b01(regs); break; - default: handle_100bXX(regs); break; - } -} - - -static void -handle_100c(struct bregs *regs) -{ - // XXX - page (regs->bh) is unused - vgafb_write_pixel(regs->al, regs->cx, regs->dx); -} - -static void -handle_100d(struct bregs *regs) -{ - // XXX - page (regs->bh) is unused - regs->al = vgafb_read_pixel(regs->cx, regs->dx); -} - -static void noinline -handle_100e(struct bregs *regs) -{ - // Ralf Brown Interrupt list is WRONG on bh(page) - // We do output only on the current page ! - struct carattr ca = {regs->al, regs->bl, 0}; - struct cursorpos cp = get_cursor_pos(0xff); - write_teletype(&cp, ca); - set_cursor_pos(cp); -} - -static void -handle_100f(struct bregs *regs) -{ - regs->bh = GET_BDA(video_page); - regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80); - regs->ah = GET_BDA(video_cols); -} - - -static void -handle_101000(struct bregs *regs) -{ - if (regs->bl > 0x14) - return; - vgahw_set_single_palette_reg(regs->bl, regs->bh); -} - -static void -handle_101001(struct bregs *regs) -{ - vgahw_set_overscan_border_color(regs->bh); -} - -static void -handle_101002(struct bregs *regs) -{ - vgahw_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); -} - -static void -handle_101003(struct bregs *regs) -{ - vgahw_toggle_intensity(regs->bl); -} - -static void -handle_101007(struct bregs *regs) -{ - if (regs->bl > 0x14) - return; - regs->bh = vgahw_get_single_palette_reg(regs->bl); -} - -static void -handle_101008(struct bregs *regs) -{ - regs->bh = vgahw_get_overscan_border_color(); -} - -static void -handle_101009(struct bregs *regs) -{ - vgahw_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); -} - -static void noinline -handle_101010(struct bregs *regs) -{ - u8 rgb[3] = {regs->dh, regs->ch, regs->cl}; - vgahw_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); -} - -static void -handle_101012(struct bregs *regs) -{ - vgahw_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); -} - -static void -handle_101013(struct bregs *regs) -{ - vgahw_select_video_dac_color_page(regs->bl, regs->bh); -} - -static void noinline -handle_101015(struct bregs *regs) -{ - u8 rgb[3]; - vgahw_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); - regs->dh = rgb[0]; - regs->ch = rgb[1]; - regs->cl = rgb[2]; -} - -static void -handle_101017(struct bregs *regs) -{ - vgahw_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); -} - -static void -handle_101018(struct bregs *regs) -{ - vgahw_set_pel_mask(regs->bl); -} - -static void -handle_101019(struct bregs *regs) -{ - regs->bl = vgahw_get_pel_mask(); -} - -static void -handle_10101a(struct bregs *regs) -{ - vgahw_read_video_dac_state(®s->bl, ®s->bh); -} - -static void -handle_10101b(struct bregs *regs) -{ - perform_gray_scale_summing(regs->bx, regs->cx); -} - -static void -handle_1010XX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_1010(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101000(regs); break; - case 0x01: handle_101001(regs); break; - case 0x02: handle_101002(regs); break; - case 0x03: handle_101003(regs); break; - case 0x07: handle_101007(regs); break; - case 0x08: handle_101008(regs); break; - case 0x09: handle_101009(regs); break; - case 0x10: handle_101010(regs); break; - case 0x12: handle_101012(regs); break; - case 0x13: handle_101013(regs); break; - case 0x15: handle_101015(regs); break; - case 0x17: handle_101017(regs); break; - case 0x18: handle_101018(regs); break; - case 0x19: handle_101019(regs); break; - case 0x1a: handle_10101a(regs); break; - case 0x1b: handle_10101b(regs); break; - default: handle_1010XX(regs); break; - } -} - - -static void -handle_101100(struct bregs *regs) -{ - vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx - , regs->dx, regs->bl, regs->bh); -} - -static void -handle_101101(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); -} - -static void -handle_101102(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); -} - -static void -handle_101103(struct bregs *regs) -{ - vgahw_set_text_block_specifier(regs->bl); -} - -static void -handle_101104(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); -} - -static void -handle_101110(struct bregs *regs) -{ - vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx - , regs->dx, regs->bl, regs->bh); - set_scan_lines(regs->bh); -} - -static void -handle_101111(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); - set_scan_lines(14); -} - -static void -handle_101112(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); - set_scan_lines(8); -} - -static void -handle_101114(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); - set_scan_lines(16); -} - -static void -handle_101130(struct bregs *regs) -{ - switch (regs->bh) { - case 0x00: { - struct segoff_s so = GET_IVT(0x1f); - regs->es = so.seg; - regs->bp = so.offset; - break; - } - case 0x01: { - struct segoff_s so = GET_IVT(0x43); - regs->es = so.seg; - regs->bp = so.offset; - break; - } - case 0x02: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont14; - break; - case 0x03: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont8; - break; - case 0x04: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont8 + 128 * 8; - break; - case 0x05: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont14alt; - break; - case 0x06: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont16; - break; - case 0x07: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont16alt; - break; - default: - dprintf(1, "Get font info BH(%02x) was discarded\n", regs->bh); - return; - } - // Set byte/char of on screen font - regs->cx = GET_BDA(char_height) & 0xff; - - // Set Highest char row - regs->dx = GET_BDA(video_rows); -} - -static void -handle_1011XX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_1011(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101100(regs); break; - case 0x01: handle_101101(regs); break; - case 0x02: handle_101102(regs); break; - case 0x03: handle_101103(regs); break; - case 0x04: handle_101104(regs); break; - case 0x10: handle_101110(regs); break; - case 0x11: handle_101111(regs); break; - case 0x12: handle_101112(regs); break; - case 0x14: handle_101114(regs); break; - case 0x30: handle_101130(regs); break; - default: handle_1011XX(regs); break; - } -} - - -static void -handle_101210(struct bregs *regs) -{ - u16 crtc_addr = GET_BDA(crtc_address); - if (crtc_addr == VGAREG_MDA_CRTC_ADDRESS) - regs->bx = 0x0103; - else - regs->bx = 0x0003; - regs->cx = GET_BDA(video_switches) & 0x0f; -} - -static void -handle_101230(struct bregs *regs) -{ - u8 mctl = GET_BDA(modeset_ctl); - u8 vswt = GET_BDA(video_switches); - switch (regs->al) { - case 0x00: - // 200 lines - mctl = (mctl & ~0x10) | 0x80; - vswt = (vswt & ~0x0f) | 0x08; - break; - case 0x01: - // 350 lines - mctl &= ~0x90; - vswt = (vswt & ~0x0f) | 0x09; - break; - case 0x02: - // 400 lines - mctl = (mctl & ~0x80) | 0x10; - vswt = (vswt & ~0x0f) | 0x09; - break; - default: - dprintf(1, "Select vert res (%02x) was discarded\n", regs->al); - break; - } - SET_BDA(modeset_ctl, mctl); - SET_BDA(video_switches, vswt); - regs->al = 0x12; -} - -static void -handle_101231(struct bregs *regs) -{ - u8 v = (regs->al & 0x01) << 3; - u8 mctl = GET_BDA(video_ctl) & ~0x08; - SET_BDA(video_ctl, mctl | v); - regs->al = 0x12; -} - -static void -handle_101232(struct bregs *regs) -{ - vgahw_enable_video_addressing(regs->al); - regs->al = 0x12; -} - -static void -handle_101233(struct bregs *regs) -{ - u8 v = ((regs->al << 1) & 0x02) ^ 0x02; - u8 v2 = GET_BDA(modeset_ctl) & ~0x02; - SET_BDA(modeset_ctl, v | v2); - regs->al = 0x12; -} - -static void -handle_101234(struct bregs *regs) -{ - u8 v = (regs->al & 0x01) ^ 0x01; - u8 v2 = GET_BDA(modeset_ctl) & ~0x01; - SET_BDA(modeset_ctl, v | v2); - regs->al = 0x12; -} - -static void -handle_101235(struct bregs *regs) -{ - debug_stub(regs); - regs->al = 0x12; -} - -static void -handle_101236(struct bregs *regs) -{ - debug_stub(regs); - regs->al = 0x12; -} - -static void -handle_1012XX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_1012(struct bregs *regs) -{ - switch (regs->bl) { - case 0x10: handle_101210(regs); break; - case 0x30: handle_101230(regs); break; - case 0x31: handle_101231(regs); break; - case 0x32: handle_101232(regs); break; - case 0x33: handle_101233(regs); break; - case 0x34: handle_101234(regs); break; - case 0x35: handle_101235(regs); break; - case 0x36: handle_101236(regs); break; - default: handle_1012XX(regs); break; - } - - // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae -} - - -// Write string -static void noinline -handle_1013(struct bregs *regs) -{ - struct cursorpos cp = {regs->dl, regs->dh, regs->bh}; - // if row=0xff special case : use current cursor position - if (cp.y == 0xff) - cp = get_cursor_pos(cp.page); - u8 flag = regs->al; - if (flag & 2) - write_attr_string(&cp, regs->cx, regs->es, (void*)(regs->bp + 0)); - else - write_string(&cp, regs->bl, regs->cx, regs->es, (void*)(regs->bp + 0)); - - if (flag & 1) - set_cursor_pos(cp); -} - - -static void -handle_101a00(struct bregs *regs) -{ - regs->bx = GET_BDA(dcc_index); - regs->al = 0x1a; -} - -static void -handle_101a01(struct bregs *regs) -{ - SET_BDA(dcc_index, regs->bl); - dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh); - regs->al = 0x1a; -} - -static void -handle_101aXX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_101a(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101a00(regs); break; - case 0x01: handle_101a01(regs); break; - default: handle_101aXX(regs); break; - } -} - - -struct funcInfo { - struct segoff_s static_functionality; - u8 bda_0x49[30]; - u8 bda_0x84[3]; - u8 dcc_index; - u8 dcc_alt; - u16 colors; - u8 pages; - u8 scan_lines; - u8 primary_char; - u8 secondar_char; - u8 misc; - u8 non_vga_mode; - u8 reserved_2f[2]; - u8 video_mem; - u8 save_flags; - u8 disp_info; - u8 reserved_34[12]; -}; - -static void -handle_101b(struct bregs *regs) -{ - u16 seg = regs->es; - struct funcInfo *info = (void*)(regs->di+0); - memset_far(seg, info, 0, sizeof(*info)); - // Address of static functionality table - SET_FARVAR(seg, info->static_functionality - , SEGOFF(get_global_seg(), (u32)static_functionality)); - - // Hard coded copy from BIOS area. Should it be cleaner ? - memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49 - , sizeof(info->bda_0x49)); - memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84 - , sizeof(info->bda_0x84)); - - SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index)); - SET_FARVAR(seg, info->colors, 16); - SET_FARVAR(seg, info->pages, 8); - SET_FARVAR(seg, info->scan_lines, 2); - SET_FARVAR(seg, info->video_mem, 3); - regs->al = 0x1B; -} - - -static void -handle_101c00(struct bregs *regs) -{ - u16 flags = regs->cx; - u16 size = 0; - if (flags & 1) - size += sizeof(struct saveVideoHardware); - if (flags & 2) - size += sizeof(struct saveBDAstate); - if (flags & 4) - size += sizeof(struct saveDACcolors); - regs->bx = size; - regs->al = 0x1c; -} - -static void -handle_101c01(struct bregs *regs) -{ - u16 flags = regs->cx; - u16 seg = regs->es; - void *data = (void*)(regs->bx+0); - if (flags & 1) { - vgahw_save_state(seg, data); - data += sizeof(struct saveVideoHardware); - } - if (flags & 2) { - save_bda_state(seg, data); - data += sizeof(struct saveBDAstate); - } - if (flags & 4) - vgahw_save_dac_state(seg, data); - regs->al = 0x1c; -} - -static void -handle_101c02(struct bregs *regs) -{ - u16 flags = regs->cx; - u16 seg = regs->es; - void *data = (void*)(regs->bx+0); - if (flags & 1) { - vgahw_restore_state(seg, data); - data += sizeof(struct saveVideoHardware); - } - if (flags & 2) { - restore_bda_state(seg, data); - data += sizeof(struct saveBDAstate); - } - if (flags & 4) - vgahw_restore_dac_state(seg, data); - regs->al = 0x1c; -} - -static void -handle_101cXX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_101c(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101c00(regs); break; - case 0x01: handle_101c01(regs); break; - case 0x02: handle_101c02(regs); break; - default: handle_101cXX(regs); break; - } -} - -static void -handle_104f00(struct bregs *regs) -{ - u16 seg = regs->es; - struct vbe_info *info = (void*)(regs->di+0); - - if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { - dprintf(4, "Get VBE Controller: VBE2 Signature found\n"); - } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) { - dprintf(4, "Get VBE Controller: VESA Signature found\n"); - } else { - dprintf(4, "Get VBE Controller: Invalid Signature\n"); - } - - memset_far(seg, info, 0, sizeof(*info)); - - SET_FARVAR(seg, info->signature, VESA_SIGNATURE); - - SET_FARVAR(seg, info->version, 0x0200); - - SET_FARVAR(seg, info->oem_string, - SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); - SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */ - - /* We generate our mode list in the reserved field of the info block */ - SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34)); - - /* Total memory (in 64 blocks) */ - SET_FARVAR(seg, info->total_memory, bochsvga_total_mem()); - - SET_FARVAR(seg, info->oem_vendor_string, - SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); - SET_FARVAR(seg, info->oem_product_string, - SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); - SET_FARVAR(seg, info->oem_revision_string, - SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); - - /* Fill list of modes */ - bochsvga_list_modes(seg, regs->di + 32); - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f01(struct bregs *regs) -{ - u16 seg = regs->es; - struct vbe_mode_info *info = (void*)(regs->di+0); - u16 mode = regs->cx; - struct vbe_modeinfo modeinfo; - int rc; - - dprintf(1, "VBE mode info request: %x\n", mode); - - rc = bochsvga_mode_info(mode, &modeinfo); - if (rc) { - dprintf(1, "VBE mode %x not found\n", mode); - regs->ax = 0x100; - return; - } - - u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | - VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | - VBE_MODE_ATTRIBUTE_COLOR_MODE | - VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; - if (modeinfo.depth == 4) - mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; - else - mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; - SET_FARVAR(seg, info->mode_attributes, mode_attr); - SET_FARVAR(seg, info->winA_attributes, - VBE_WINDOW_ATTRIBUTE_RELOCATABLE | - VBE_WINDOW_ATTRIBUTE_READABLE | - VBE_WINDOW_ATTRIBUTE_WRITEABLE); - SET_FARVAR(seg, info->winB_attributes, 0); - SET_FARVAR(seg, info->win_granularity, 64); /* Bank size 64K */ - SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ - SET_FARVAR(seg, info->winA_seg, 0xA000); - SET_FARVAR(seg, info->winB_seg, 0x0); - SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); - SET_FARVAR(seg, info->bytes_per_scanline, modeinfo.linesize); - SET_FARVAR(seg, info->xres, modeinfo.width); - SET_FARVAR(seg, info->yres, modeinfo.height); - SET_FARVAR(seg, info->xcharsize, 8); - SET_FARVAR(seg, info->ycharsize, 16); - if (modeinfo.depth == 4) - SET_FARVAR(seg, info->planes, 4); - else - SET_FARVAR(seg, info->planes, 1); - SET_FARVAR(seg, info->bits_per_pixel, modeinfo.depth); - SET_FARVAR(seg, info->banks, - (modeinfo.linesize * modeinfo.height + 65535) / 65536); - if (modeinfo.depth == 4) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); - else if (modeinfo.depth == 8) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); - else - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); - SET_FARVAR(seg, info->bank_size, 0); - u32 pages = modeinfo.vram_size / (modeinfo.height * modeinfo.linesize); - if (modeinfo.depth == 4) - SET_FARVAR(seg, info->pages, (pages / 4) - 1); - else - SET_FARVAR(seg, info->pages, pages - 1); - SET_FARVAR(seg, info->reserved0, 1); - - u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; - - switch (modeinfo.depth) { - case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; - b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; - case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; - b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break; - case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; - b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break; - case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; - b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break; - default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0; - b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break; - } - - SET_FARVAR(seg, info->red_size, r_size); - SET_FARVAR(seg, info->red_pos, r_pos); - SET_FARVAR(seg, info->green_size, g_size); - SET_FARVAR(seg, info->green_pos, g_pos); - SET_FARVAR(seg, info->blue_size, b_size); - SET_FARVAR(seg, info->blue_pos, b_pos); - SET_FARVAR(seg, info->alpha_size, a_size); - SET_FARVAR(seg, info->alpha_pos, a_pos); - - if (modeinfo.depth == 32) - SET_FARVAR(seg, info->directcolor_info, - VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE); - else - SET_FARVAR(seg, info->directcolor_info, 0); - - if (modeinfo.depth > 4) - SET_FARVAR(seg, info->phys_base, modeinfo.phys_base); - else - SET_FARVAR(seg, info->phys_base, 0); - - SET_FARVAR(seg, info->reserved1, 0); - SET_FARVAR(seg, info->reserved2, 0); - SET_FARVAR(seg, info->linear_bytes_per_scanline, modeinfo.linesize); - SET_FARVAR(seg, info->bank_pages, 0); - SET_FARVAR(seg, info->linear_pages, 0); - SET_FARVAR(seg, info->linear_red_size, r_size); - SET_FARVAR(seg, info->linear_red_pos, r_pos); - SET_FARVAR(seg, info->linear_green_size, g_size); - SET_FARVAR(seg, info->linear_green_pos, g_pos); - SET_FARVAR(seg, info->linear_blue_size, b_size); - SET_FARVAR(seg, info->linear_blue_pos, b_pos); - SET_FARVAR(seg, info->linear_alpha_size, a_size); - SET_FARVAR(seg, info->linear_alpha_pos, a_pos); - SET_FARVAR(seg, info->pixclock_max, 0); - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f02(struct bregs *regs) -{ - //u16 seg = regs->es; - //struct vbe_crtc_info *crtc_info = (void*)(regs->di+0); - u16 mode = regs->bx; - struct vbe_modeinfo modeinfo; - int rc; - - dprintf(1, "VBE mode set: %x\n", mode); - - if (mode < 0x100) { /* VGA */ - dprintf(1, "set VGA mode %x\n", mode); - - bochsvga_hires_enable(0); - vga_set_mode(mode, 0); - } else { /* VBE */ - rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); - if (rc) { - dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); - regs->ax = 0x100; - return; - } - bochsvga_hires_enable(1); - bochsvga_set_mode(mode & 0x1ff, &modeinfo); - - if (mode & 0x4000) { - /* Linear frame buffer */ - /* XXX: ??? */ - } - if (!(mode & 0x8000)) { - bochsvga_clear_scr(); - } - } - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f03(struct bregs *regs) -{ - if (!bochsvga_hires_enabled()) { - regs->bx = GET_BDA(video_mode); - } else { - regs->bx = bochsvga_curr_mode(); - } - - dprintf(1, "VBE current mode=%x\n", regs->bx); - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f04(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f05(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f06(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f07(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f08(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f0a(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104fXX(struct bregs *regs) -{ - debug_stub(regs); - regs->ax = 0x0100; -} - -static void -handle_104f(struct bregs *regs) -{ - if (!bochsvga_enabled()) { - handle_104fXX(regs); - return; - } - - switch (regs->al) { - case 0x00: handle_104f00(regs); break; - case 0x01: handle_104f01(regs); break; - case 0x02: handle_104f02(regs); break; - case 0x03: handle_104f03(regs); break; - case 0x04: handle_104f04(regs); break; - case 0x05: handle_104f05(regs); break; - case 0x06: handle_104f06(regs); break; - case 0x07: handle_104f07(regs); break; - case 0x08: handle_104f08(regs); break; - case 0x0a: handle_104f0a(regs); break; - default: handle_104fXX(regs); break; - } -} - - -static void -handle_10XX(struct bregs *regs) -{ - debug_stub(regs); -} - -// INT 10h Video Support Service Entry Point -void VISIBLE16 -handle_10(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - switch (regs->ah) { - case 0x00: handle_1000(regs); break; - case 0x01: handle_1001(regs); break; - case 0x02: handle_1002(regs); break; - case 0x03: handle_1003(regs); break; - case 0x04: handle_1004(regs); break; - case 0x05: handle_1005(regs); break; - case 0x06: handle_1006(regs); break; - case 0x07: handle_1007(regs); break; - case 0x08: handle_1008(regs); break; - case 0x09: handle_1009(regs); break; - case 0x0a: handle_100a(regs); break; - case 0x0b: handle_100b(regs); break; - case 0x0c: handle_100c(regs); break; - case 0x0d: handle_100d(regs); break; - case 0x0e: handle_100e(regs); break; - case 0x0f: handle_100f(regs); break; - case 0x10: handle_1010(regs); break; - case 0x11: handle_1011(regs); break; - case 0x12: handle_1012(regs); break; - case 0x13: handle_1013(regs); break; - case 0x1a: handle_101a(regs); break; - case 0x1b: handle_101b(regs); break; - case 0x1c: handle_101c(regs); break; - case 0x4f: handle_104f(regs); break; - default: handle_10XX(regs); break; - } -} - - -/**************************************************************** - * VGA post - ****************************************************************/ - -static void -init_bios_area(void) -{ - // init detected hardware BIOS Area - // set 80x25 color (not clear from RBIL but usual) - u16 eqf = GET_BDA(equipment_list_flags); - SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20); - - // Just for the first int10 find its children - - // the default char height - SET_BDA(char_height, 0x10); - - // Clear the screen - SET_BDA(video_ctl, 0x60); - - // Set the basic screen we have - SET_BDA(video_switches, 0xf9); - - // Set the basic modeset options - SET_BDA(modeset_ctl, 0x51); - - // Set the default MSR - SET_BDA(video_msr, 0x09); -} - -void VISIBLE16 -vga_post(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_POST); - - vgahw_init(); - - if (CONFIG_VGA_GEODELX) - geodelx_init(); - - init_bios_area(); - - bochsvga_init(regs->ah, regs->al); - - extern void entry_10(void); - SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10)); - - if (CONFIG_VGA_CIRRUS) - cirrus_init(); - - // XXX - clear screen and display info - - build_video_param(); - - // Fixup checksum - extern u8 _rom_header_size, _rom_header_checksum; - SET_VGA(_rom_header_checksum, 0); - u8 sum = -checksum_far(get_global_seg(), 0, _rom_header_size * 512); - SET_VGA(_rom_header_checksum, sum); -} diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c new file mode 100644 index 0000000..2ff677e --- /dev/null +++ b/vgasrc/vgabios.c @@ -0,0 +1,1596 @@ +// VGA bios implementation +// +// Copyright (C) 2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2001-2008 the LGPL VGABios developers Team +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + + +// TODO: +// * review correctness of converted asm by comparing with RBIL +// +// * convert vbe/clext code + +#include "bregs.h" // struct bregs +#include "biosvar.h" // GET_BDA +#include "util.h" // memset +#include "vgabios.h" // find_vga_entry +#include "optionroms.h" // struct pci_data +#include "config.h" // CONFIG_* +#include "vbe.h" // struct vbe_info +#include "geodelx.h" // geodelx_init +#include "bochsvga.h" // bochsvga_init + +// XXX +#define DEBUG_VGA_POST 1 +#define DEBUG_VGA_10 3 + + +/**************************************************************** + * PCI Data + ****************************************************************/ +#if CONFIG_VGA_PCI == 1 +struct pci_data rom_pci_data VAR16VISIBLE = { + .signature = PCI_ROM_SIGNATURE, + .vendor = CONFIG_VGA_VID, + .device = CONFIG_VGA_DID, + .dlen = 0x18, + .class_hi = 0x300, + .irevision = 1, + .type = PCIROM_CODETYPE_X86, + .indicator = 0x80, +}; +#endif + +/**************************************************************** + * Helper functions + ****************************************************************/ + +static inline void +call16_vgaint(u32 eax, u32 ebx) +{ + asm volatile( + "int $0x10\n" + "cli\n" + "cld" + : + : "a"(eax), "b"(ebx) + : "cc", "memory"); +} + +static void +perform_gray_scale_summing(u16 start, u16 count) +{ + vgahw_screen_disable(); + int i; + for (i = start; i < start+count; i++) { + u8 rgb[3]; + vgahw_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; + + vgahw_set_dac_regs(GET_SEG(SS), rgb, i, 1); + } + vgahw_screen_enable(); +} + +static void +set_cursor_shape(u8 start, u8 end) +{ + start &= 0x3f; + end &= 0x1f; + + u16 curs = (start << 8) + end; + SET_BDA(cursor_type, curs); + + u8 modeset_ctl = GET_BDA(modeset_ctl); + u16 cheight = GET_BDA(char_height); + if ((modeset_ctl & 0x01) && (cheight > 8) && (end < 8) && (start < 0x20)) { + if (end != (start + 1)) + start = ((start + 1) * cheight / 8) - 1; + else + start = ((end + 1) * cheight / 8) - 2; + end = ((end + 1) * cheight / 8) - 1; + } + vgahw_set_cursor_shape(start, end); +} + +static u16 +get_cursor_shape(u8 page) +{ + if (page > 7) + return 0; + // FIXME should handle VGA 14/16 lines + return GET_BDA(cursor_type); +} + +static void +set_cursor_pos(struct cursorpos cp) +{ + // Should not happen... + if (cp.page > 7) + return; + + // Bios cursor pos + SET_BDA(cursor_pos[cp.page], (cp.y << 8) | cp.x); + + // Set the hardware cursor + u8 current = GET_BDA(video_page); + if (cp.page != current) + return; + + // Get the dimensions + u16 nbcols = GET_BDA(video_cols); + u16 nbrows = GET_BDA(video_rows) + 1; + + // Calculate the address knowing nbcols nbrows and page num + u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page) + + cp.x + cp.y * nbcols); + + vgahw_set_cursor_pos(address); +} + +static struct cursorpos +get_cursor_pos(u8 page) +{ + if (page == 0xff) + // special case - use current page + page = GET_BDA(video_page); + if (page > 7) { + struct cursorpos cp = { 0, 0, 0xfe }; + return cp; + } + // FIXME should handle VGA 14/16 lines + u16 xy = GET_BDA(cursor_pos[page]); + struct cursorpos cp = {xy, xy>>8, page}; + return cp; +} + +static void +set_active_page(u8 page) +{ + if (page > 7) + return; + + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + + // Get pos curs pos for the right page + struct cursorpos cp = get_cursor_pos(page); + + u16 address; + if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { + // Get the dimensions + u16 nbcols = GET_BDA(video_cols); + u16 nbrows = GET_BDA(video_rows) + 1; + + // Calculate the address knowing nbcols nbrows and page num + address = SCREEN_MEM_START(nbcols, nbrows, page); + SET_BDA(video_pagestart, address); + + // Start address + address = SCREEN_IO_START(nbcols, nbrows, page); + } else { + address = page * GET_GLOBAL(vmode_g->slength); + } + + vgahw_set_active_page(address); + + // And change the BIOS page + SET_BDA(video_page, page); + + dprintf(1, "Set active page %02x address %04x\n", page, address); + + // Display the cursor, now the page is active + set_cursor_pos(cp); +} + +static void +set_scan_lines(u8 lines) +{ + vgahw_set_scan_lines(lines); + if (lines == 8) + set_cursor_shape(0x06, 0x07); + else + set_cursor_shape(lines - 4, lines - 3); + SET_BDA(char_height, lines); + u16 vde = vgahw_get_vde(); + u8 rows = vde / lines; + SET_BDA(video_rows, rows - 1); + u16 cols = GET_BDA(video_cols); + SET_BDA(video_pagesize, rows * cols * 2); +} + + +/**************************************************************** + * Character writing + ****************************************************************/ + +// Scroll the screen one line. This function is designed to be called +// tail-recursive to reduce stack usage. +static void noinline +scroll_one(u16 nbrows, u16 nbcols, u8 page) +{ + struct cursorpos ul = {0, 0, page}; + struct cursorpos lr = {nbcols-1, nbrows-1, page}; + vgafb_scroll(1, -1, ul, lr); +} + +// Write a character to the screen at a given position. Implement +// special characters and scroll the screen if necessary. +static void +write_teletype(struct cursorpos *pcp, struct carattr ca) +{ + struct cursorpos cp = *pcp; + + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + + switch (ca.car) { + case 7: + //FIXME should beep + break; + case 8: + if (cp.x > 0) + cp.x--; + break; + case '\r': + cp.x = 0; + break; + case '\n': + cp.y++; + break; + case '\t': + do { + struct carattr dummyca = {' ', ca.attr, ca.use_attr}; + vgafb_write_char(cp, dummyca); + cp.x++; + } while (cp.x < nbcols && cp.x % 8); + break; + default: + vgafb_write_char(cp, ca); + cp.x++; + } + + // Do we need to wrap ? + if (cp.x == nbcols) { + cp.x = 0; + cp.y++; + } + // Do we need to scroll ? + if (cp.y < nbrows) { + *pcp = cp; + return; + } + // Scroll screen + cp.y--; + *pcp = cp; + scroll_one(nbrows, nbcols, cp.page); +} + +// Write out a buffer of alternating characters and attributes. +static void +write_attr_string(struct cursorpos *pcp, u16 count, u16 seg, u8 *offset_far) +{ + while (count--) { + u8 car = GET_FARVAR(seg, *offset_far); + offset_far++; + u8 attr = GET_FARVAR(seg, *offset_far); + offset_far++; + + struct carattr ca = {car, attr, 1}; + write_teletype(pcp, ca); + } +} + +// Write out a buffer of characters. +static void +write_string(struct cursorpos *pcp, u8 attr, u16 count, u16 seg, u8 *offset_far) +{ + while (count--) { + u8 car = GET_FARVAR(seg, *offset_far); + offset_far++; + + struct carattr ca = {car, attr, 1}; + write_teletype(pcp, ca); + } +} + + +/**************************************************************** + * Save and restore bda state + ****************************************************************/ + +static void +save_bda_state(u16 seg, struct saveBDAstate *info) +{ + SET_FARVAR(seg, info->video_mode, GET_BDA(video_mode)); + SET_FARVAR(seg, info->video_cols, GET_BDA(video_cols)); + SET_FARVAR(seg, info->video_pagesize, GET_BDA(video_pagesize)); + SET_FARVAR(seg, info->crtc_address, GET_BDA(crtc_address)); + SET_FARVAR(seg, info->video_rows, GET_BDA(video_rows)); + SET_FARVAR(seg, info->char_height, GET_BDA(char_height)); + SET_FARVAR(seg, info->video_ctl, GET_BDA(video_ctl)); + SET_FARVAR(seg, info->video_switches, GET_BDA(video_switches)); + SET_FARVAR(seg, info->modeset_ctl, GET_BDA(modeset_ctl)); + SET_FARVAR(seg, info->cursor_type, GET_BDA(cursor_type)); + u16 i; + for (i=0; i<8; i++) + SET_FARVAR(seg, info->cursor_pos[i], GET_BDA(cursor_pos[i])); + SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart)); + SET_FARVAR(seg, info->video_page, GET_BDA(video_page)); + /* current font */ + SET_FARVAR(seg, info->font0, GET_IVT(0x1f)); + SET_FARVAR(seg, info->font1, GET_IVT(0x43)); +} + +static void +restore_bda_state(u16 seg, struct saveBDAstate *info) +{ + SET_BDA(video_mode, GET_FARVAR(seg, info->video_mode)); + SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols)); + SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize)); + SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address)); + SET_BDA(video_rows, GET_FARVAR(seg, info->video_rows)); + SET_BDA(char_height, GET_FARVAR(seg, info->char_height)); + SET_BDA(video_ctl, GET_FARVAR(seg, info->video_ctl)); + SET_BDA(video_switches, GET_FARVAR(seg, info->video_switches)); + SET_BDA(modeset_ctl, GET_FARVAR(seg, info->modeset_ctl)); + SET_BDA(cursor_type, GET_FARVAR(seg, info->cursor_type)); + u16 i; + for (i = 0; i < 8; i++) + SET_BDA(cursor_pos[i], GET_FARVAR(seg, info->cursor_pos[i])); + SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart)); + SET_BDA(video_page, GET_FARVAR(seg, info->video_page)); + /* current font */ + SET_IVT(0x1f, GET_FARVAR(seg, info->font0)); + SET_IVT(0x43, GET_FARVAR(seg, info->font1)); +} + + +/**************************************************************** + * VGA int 10 handler + ****************************************************************/ + +// set video mode +void +vga_set_mode(u8 mode, u8 noclearmem) +{ + // 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 + vgahw_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 + vgahw_set_dac_regs(get_global_seg(), palette_g, 0, palsize); + u16 i; + for (i = palsize; i < 0x0100; i++) { + static u8 rgb[3] VAR16; + vgahw_set_dac_regs(get_global_seg(), rgb, i, 1); + } + + if ((modeset_ctl & 0x02) == 0x02) + perform_gray_scale_summing(0x00, 0x100); + } + + vgahw_set_mode(vmode_g); + + if (noclearmem == 0x00) + clear_screen(vmode_g); + + // Set CRTC address VGA or MDA + u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; + if (GET_GLOBAL(vmode_g->memmodel) == MTEXT) + crtc_addr = VGAREG_MDA_CRTC_ADDRESS; + + // Set the BIOS mem + u16 cheight = GET_GLOBAL(vmode_g->cheight); + SET_BDA(video_mode, mode); + SET_BDA(video_cols, GET_GLOBAL(vmode_g->twidth)); + SET_BDA(video_pagesize, GET_GLOBAL(vmode_g->slength)); + SET_BDA(crtc_address, crtc_addr); + SET_BDA(video_rows, GET_GLOBAL(vmode_g->theight)-1); + SET_BDA(char_height, cheight); + SET_BDA(video_ctl, (0x60 | noclearmem)); + SET_BDA(video_switches, 0xF9); + SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); + + // FIXME We nearly have the good tables. to be reworked + SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now + SET_BDA(video_savetable + , SEGOFF(get_global_seg(), (u32)&video_save_pointer_table)); + + // FIXME + SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but... + SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but... + + // Set cursor shape + if (GET_GLOBAL(vmode_g->memmodel) & TEXT) + set_cursor_shape(0x06, 0x07); + // Set cursor pos for page 0..7 + int i; + for (i = 0; i < 8; i++) { + struct cursorpos cp = {0, 0, i}; + set_cursor_pos(cp); + } + + // Set active page 0 + set_active_page(0x00); + + // Write the fonts in memory + if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { + call16_vgaint(0x1104, 0); + call16_vgaint(0x1103, 0); + } + // Set the ints 0x1F and 0x43 + SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8])); + + switch (cheight) { + case 8: + SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8)); + break; + case 14: + SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14)); + break; + case 16: + SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16)); + break; + } +} + +static void +handle_1000(struct bregs *regs) +{ + u8 noclearmem = regs->al & 0x80; + u8 mode = regs->al & 0x7f; + + // Set regs->al + if (mode > 7) + regs->al = 0x20; + else if (mode == 6) + regs->al = 0x3f; + else + regs->al = 0x30; + + if (CONFIG_VGA_CIRRUS) { + int ret = cirrus_set_video_mode(mode, noclearmem); + if (ret) + return; + } + + if (bochsvga_enabled()) + bochsvga_hires_enable(0); + + vga_set_mode(mode, noclearmem); +} + +static void +handle_1001(struct bregs *regs) +{ + set_cursor_shape(regs->ch, regs->cl); +} + +static void +handle_1002(struct bregs *regs) +{ + struct cursorpos cp = {regs->dl, regs->dh, regs->bh}; + set_cursor_pos(cp); +} + +static void +handle_1003(struct bregs *regs) +{ + regs->cx = get_cursor_shape(regs->bh); + struct cursorpos cp = get_cursor_pos(regs->bh); + regs->dl = cp.x; + regs->dh = cp.y; +} + +// Read light pen pos (unimplemented) +static void +handle_1004(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = regs->bx = regs->cx = regs->dx = 0; +} + +static void +handle_1005(struct bregs *regs) +{ + set_active_page(regs->al); +} + +static void +verify_scroll(struct bregs *regs, int dir) +{ + u8 page = GET_BDA(video_page); + struct cursorpos ul = {regs->cl, regs->ch, page}; + struct cursorpos lr = {regs->dl, regs->dh, page}; + + u16 nbrows = GET_BDA(video_rows) + 1; + if (lr.y >= nbrows) + lr.y = nbrows - 1; + u16 nbcols = GET_BDA(video_cols); + if (lr.x >= nbcols) + lr.x = nbcols - 1; + + if (ul.x > lr.x || ul.y > lr.y) + return; + + u16 nblines = regs->al; + if (!nblines || nblines > lr.y - ul.y + 1) + nblines = lr.y - ul.y + 1; + + vgafb_scroll(dir * nblines, regs->bh, ul, lr); +} + +static void +handle_1006(struct bregs *regs) +{ + verify_scroll(regs, 1); +} + +static void +handle_1007(struct bregs *regs) +{ + verify_scroll(regs, -1); +} + +static void +handle_1008(struct bregs *regs) +{ + struct carattr ca = vgafb_read_char(get_cursor_pos(regs->bh)); + regs->al = ca.car; + regs->ah = ca.attr; +} + +static void noinline +write_chars(u8 page, struct carattr ca, u16 count) +{ + struct cursorpos cp = get_cursor_pos(page); + while (count--) { + vgafb_write_char(cp, ca); + cp.x++; + } +} + +static void +handle_1009(struct bregs *regs) +{ + struct carattr ca = {regs->al, regs->bl, 1}; + write_chars(regs->bh, ca, regs->cx); +} + +static void +handle_100a(struct bregs *regs) +{ + struct carattr ca = {regs->al, regs->bl, 0}; + write_chars(regs->bh, ca, regs->cx); +} + + +static void +handle_100b00(struct bregs *regs) +{ + vgahw_set_border_color(regs->bl); +} + +static void +handle_100b01(struct bregs *regs) +{ + vgahw_set_palette(regs->bl); +} + +static void +handle_100bXX(struct bregs *regs) +{ + debug_stub(regs); +} + +static void +handle_100b(struct bregs *regs) +{ + switch (regs->bh) { + case 0x00: handle_100b00(regs); break; + case 0x01: handle_100b01(regs); break; + default: handle_100bXX(regs); break; + } +} + + +static void +handle_100c(struct bregs *regs) +{ + // XXX - page (regs->bh) is unused + vgafb_write_pixel(regs->al, regs->cx, regs->dx); +} + +static void +handle_100d(struct bregs *regs) +{ + // XXX - page (regs->bh) is unused + regs->al = vgafb_read_pixel(regs->cx, regs->dx); +} + +static void noinline +handle_100e(struct bregs *regs) +{ + // Ralf Brown Interrupt list is WRONG on bh(page) + // We do output only on the current page ! + struct carattr ca = {regs->al, regs->bl, 0}; + struct cursorpos cp = get_cursor_pos(0xff); + write_teletype(&cp, ca); + set_cursor_pos(cp); +} + +static void +handle_100f(struct bregs *regs) +{ + regs->bh = GET_BDA(video_page); + regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80); + regs->ah = GET_BDA(video_cols); +} + + +static void +handle_101000(struct bregs *regs) +{ + if (regs->bl > 0x14) + return; + vgahw_set_single_palette_reg(regs->bl, regs->bh); +} + +static void +handle_101001(struct bregs *regs) +{ + vgahw_set_overscan_border_color(regs->bh); +} + +static void +handle_101002(struct bregs *regs) +{ + vgahw_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); +} + +static void +handle_101003(struct bregs *regs) +{ + vgahw_toggle_intensity(regs->bl); +} + +static void +handle_101007(struct bregs *regs) +{ + if (regs->bl > 0x14) + return; + regs->bh = vgahw_get_single_palette_reg(regs->bl); +} + +static void +handle_101008(struct bregs *regs) +{ + regs->bh = vgahw_get_overscan_border_color(); +} + +static void +handle_101009(struct bregs *regs) +{ + vgahw_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); +} + +static void noinline +handle_101010(struct bregs *regs) +{ + u8 rgb[3] = {regs->dh, regs->ch, regs->cl}; + vgahw_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); +} + +static void +handle_101012(struct bregs *regs) +{ + vgahw_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); +} + +static void +handle_101013(struct bregs *regs) +{ + vgahw_select_video_dac_color_page(regs->bl, regs->bh); +} + +static void noinline +handle_101015(struct bregs *regs) +{ + u8 rgb[3]; + vgahw_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); + regs->dh = rgb[0]; + regs->ch = rgb[1]; + regs->cl = rgb[2]; +} + +static void +handle_101017(struct bregs *regs) +{ + vgahw_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); +} + +static void +handle_101018(struct bregs *regs) +{ + vgahw_set_pel_mask(regs->bl); +} + +static void +handle_101019(struct bregs *regs) +{ + regs->bl = vgahw_get_pel_mask(); +} + +static void +handle_10101a(struct bregs *regs) +{ + vgahw_read_video_dac_state(®s->bl, ®s->bh); +} + +static void +handle_10101b(struct bregs *regs) +{ + perform_gray_scale_summing(regs->bx, regs->cx); +} + +static void +handle_1010XX(struct bregs *regs) +{ + debug_stub(regs); +} + +static void +handle_1010(struct bregs *regs) +{ + switch (regs->al) { + case 0x00: handle_101000(regs); break; + case 0x01: handle_101001(regs); break; + case 0x02: handle_101002(regs); break; + case 0x03: handle_101003(regs); break; + case 0x07: handle_101007(regs); break; + case 0x08: handle_101008(regs); break; + case 0x09: handle_101009(regs); break; + case 0x10: handle_101010(regs); break; + case 0x12: handle_101012(regs); break; + case 0x13: handle_101013(regs); break; + case 0x15: handle_101015(regs); break; + case 0x17: handle_101017(regs); break; + case 0x18: handle_101018(regs); break; + case 0x19: handle_101019(regs); break; + case 0x1a: handle_10101a(regs); break; + case 0x1b: handle_10101b(regs); break; + default: handle_1010XX(regs); break; + } +} + + +static void +handle_101100(struct bregs *regs) +{ + vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx + , regs->dx, regs->bl, regs->bh); +} + +static void +handle_101101(struct bregs *regs) +{ + vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); +} + +static void +handle_101102(struct bregs *regs) +{ + vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); +} + +static void +handle_101103(struct bregs *regs) +{ + vgahw_set_text_block_specifier(regs->bl); +} + +static void +handle_101104(struct bregs *regs) +{ + vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); +} + +static void +handle_101110(struct bregs *regs) +{ + vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx + , regs->dx, regs->bl, regs->bh); + set_scan_lines(regs->bh); +} + +static void +handle_101111(struct bregs *regs) +{ + vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); + set_scan_lines(14); +} + +static void +handle_101112(struct bregs *regs) +{ + vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); + set_scan_lines(8); +} + +static void +handle_101114(struct bregs *regs) +{ + vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); + set_scan_lines(16); +} + +static void +handle_101130(struct bregs *regs) +{ + switch (regs->bh) { + case 0x00: { + struct segoff_s so = GET_IVT(0x1f); + regs->es = so.seg; + regs->bp = so.offset; + break; + } + case 0x01: { + struct segoff_s so = GET_IVT(0x43); + regs->es = so.seg; + regs->bp = so.offset; + break; + } + case 0x02: + regs->es = get_global_seg(); + regs->bp = (u32)vgafont14; + break; + case 0x03: + regs->es = get_global_seg(); + regs->bp = (u32)vgafont8; + break; + case 0x04: + regs->es = get_global_seg(); + regs->bp = (u32)vgafont8 + 128 * 8; + break; + case 0x05: + regs->es = get_global_seg(); + regs->bp = (u32)vgafont14alt; + break; + case 0x06: + regs->es = get_global_seg(); + regs->bp = (u32)vgafont16; + break; + case 0x07: + regs->es = get_global_seg(); + regs->bp = (u32)vgafont16alt; + break; + default: + dprintf(1, "Get font info BH(%02x) was discarded\n", regs->bh); + return; + } + // Set byte/char of on screen font + regs->cx = GET_BDA(char_height) & 0xff; + + // Set Highest char row + regs->dx = GET_BDA(video_rows); +} + +static void +handle_1011XX(struct bregs *regs) +{ + debug_stub(regs); +} + +static void +handle_1011(struct bregs *regs) +{ + switch (regs->al) { + case 0x00: handle_101100(regs); break; + case 0x01: handle_101101(regs); break; + case 0x02: handle_101102(regs); break; + case 0x03: handle_101103(regs); break; + case 0x04: handle_101104(regs); break; + case 0x10: handle_101110(regs); break; + case 0x11: handle_101111(regs); break; + case 0x12: handle_101112(regs); break; + case 0x14: handle_101114(regs); break; + case 0x30: handle_101130(regs); break; + default: handle_1011XX(regs); break; + } +} + + +static void +handle_101210(struct bregs *regs) +{ + u16 crtc_addr = GET_BDA(crtc_address); + if (crtc_addr == VGAREG_MDA_CRTC_ADDRESS) + regs->bx = 0x0103; + else + regs->bx = 0x0003; + regs->cx = GET_BDA(video_switches) & 0x0f; +} + +static void +handle_101230(struct bregs *regs) +{ + u8 mctl = GET_BDA(modeset_ctl); + u8 vswt = GET_BDA(video_switches); + switch (regs->al) { + case 0x00: + // 200 lines + mctl = (mctl & ~0x10) | 0x80; + vswt = (vswt & ~0x0f) | 0x08; + break; + case 0x01: + // 350 lines + mctl &= ~0x90; + vswt = (vswt & ~0x0f) | 0x09; + break; + case 0x02: + // 400 lines + mctl = (mctl & ~0x80) | 0x10; + vswt = (vswt & ~0x0f) | 0x09; + break; + default: + dprintf(1, "Select vert res (%02x) was discarded\n", regs->al); + break; + } + SET_BDA(modeset_ctl, mctl); + SET_BDA(video_switches, vswt); + regs->al = 0x12; +} + +static void +handle_101231(struct bregs *regs) +{ + u8 v = (regs->al & 0x01) << 3; + u8 mctl = GET_BDA(video_ctl) & ~0x08; + SET_BDA(video_ctl, mctl | v); + regs->al = 0x12; +} + +static void +handle_101232(struct bregs *regs) +{ + vgahw_enable_video_addressing(regs->al); + regs->al = 0x12; +} + +static void +handle_101233(struct bregs *regs) +{ + u8 v = ((regs->al << 1) & 0x02) ^ 0x02; + u8 v2 = GET_BDA(modeset_ctl) & ~0x02; + SET_BDA(modeset_ctl, v | v2); + regs->al = 0x12; +} + +static void +handle_101234(struct bregs *regs) +{ + u8 v = (regs->al & 0x01) ^ 0x01; + u8 v2 = GET_BDA(modeset_ctl) & ~0x01; + SET_BDA(modeset_ctl, v | v2); + regs->al = 0x12; +} + +static void +handle_101235(struct bregs *regs) +{ + debug_stub(regs); + regs->al = 0x12; +} + +static void +handle_101236(struct bregs *regs) +{ + debug_stub(regs); + regs->al = 0x12; +} + +static void +handle_1012XX(struct bregs *regs) +{ + debug_stub(regs); +} + +static void +handle_1012(struct bregs *regs) +{ + switch (regs->bl) { + case 0x10: handle_101210(regs); break; + case 0x30: handle_101230(regs); break; + case 0x31: handle_101231(regs); break; + case 0x32: handle_101232(regs); break; + case 0x33: handle_101233(regs); break; + case 0x34: handle_101234(regs); break; + case 0x35: handle_101235(regs); break; + case 0x36: handle_101236(regs); break; + default: handle_1012XX(regs); break; + } + + // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae +} + + +// Write string +static void noinline +handle_1013(struct bregs *regs) +{ + struct cursorpos cp = {regs->dl, regs->dh, regs->bh}; + // if row=0xff special case : use current cursor position + if (cp.y == 0xff) + cp = get_cursor_pos(cp.page); + u8 flag = regs->al; + if (flag & 2) + write_attr_string(&cp, regs->cx, regs->es, (void*)(regs->bp + 0)); + else + write_string(&cp, regs->bl, regs->cx, regs->es, (void*)(regs->bp + 0)); + + if (flag & 1) + set_cursor_pos(cp); +} + + +static void +handle_101a00(struct bregs *regs) +{ + regs->bx = GET_BDA(dcc_index); + regs->al = 0x1a; +} + +static void +handle_101a01(struct bregs *regs) +{ + SET_BDA(dcc_index, regs->bl); + dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh); + regs->al = 0x1a; +} + +static void +handle_101aXX(struct bregs *regs) +{ + debug_stub(regs); +} + +static void +handle_101a(struct bregs *regs) +{ + switch (regs->al) { + case 0x00: handle_101a00(regs); break; + case 0x01: handle_101a01(regs); break; + default: handle_101aXX(regs); break; + } +} + + +struct funcInfo { + struct segoff_s static_functionality; + u8 bda_0x49[30]; + u8 bda_0x84[3]; + u8 dcc_index; + u8 dcc_alt; + u16 colors; + u8 pages; + u8 scan_lines; + u8 primary_char; + u8 secondar_char; + u8 misc; + u8 non_vga_mode; + u8 reserved_2f[2]; + u8 video_mem; + u8 save_flags; + u8 disp_info; + u8 reserved_34[12]; +}; + +static void +handle_101b(struct bregs *regs) +{ + u16 seg = regs->es; + struct funcInfo *info = (void*)(regs->di+0); + memset_far(seg, info, 0, sizeof(*info)); + // Address of static functionality table + SET_FARVAR(seg, info->static_functionality + , SEGOFF(get_global_seg(), (u32)static_functionality)); + + // Hard coded copy from BIOS area. Should it be cleaner ? + memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49 + , sizeof(info->bda_0x49)); + memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84 + , sizeof(info->bda_0x84)); + + SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index)); + SET_FARVAR(seg, info->colors, 16); + SET_FARVAR(seg, info->pages, 8); + SET_FARVAR(seg, info->scan_lines, 2); + SET_FARVAR(seg, info->video_mem, 3); + regs->al = 0x1B; +} + + +static void +handle_101c00(struct bregs *regs) +{ + u16 flags = regs->cx; + u16 size = 0; + if (flags & 1) + size += sizeof(struct saveVideoHardware); + if (flags & 2) + size += sizeof(struct saveBDAstate); + if (flags & 4) + size += sizeof(struct saveDACcolors); + regs->bx = size; + regs->al = 0x1c; +} + +static void +handle_101c01(struct bregs *regs) +{ + u16 flags = regs->cx; + u16 seg = regs->es; + void *data = (void*)(regs->bx+0); + if (flags & 1) { + vgahw_save_state(seg, data); + data += sizeof(struct saveVideoHardware); + } + if (flags & 2) { + save_bda_state(seg, data); + data += sizeof(struct saveBDAstate); + } + if (flags & 4) + vgahw_save_dac_state(seg, data); + regs->al = 0x1c; +} + +static void +handle_101c02(struct bregs *regs) +{ + u16 flags = regs->cx; + u16 seg = regs->es; + void *data = (void*)(regs->bx+0); + if (flags & 1) { + vgahw_restore_state(seg, data); + data += sizeof(struct saveVideoHardware); + } + if (flags & 2) { + restore_bda_state(seg, data); + data += sizeof(struct saveBDAstate); + } + if (flags & 4) + vgahw_restore_dac_state(seg, data); + regs->al = 0x1c; +} + +static void +handle_101cXX(struct bregs *regs) +{ + debug_stub(regs); +} + +static void +handle_101c(struct bregs *regs) +{ + switch (regs->al) { + case 0x00: handle_101c00(regs); break; + case 0x01: handle_101c01(regs); break; + case 0x02: handle_101c02(regs); break; + default: handle_101cXX(regs); break; + } +} + +static void +handle_104f00(struct bregs *regs) +{ + u16 seg = regs->es; + struct vbe_info *info = (void*)(regs->di+0); + + if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { + dprintf(4, "Get VBE Controller: VBE2 Signature found\n"); + } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) { + dprintf(4, "Get VBE Controller: VESA Signature found\n"); + } else { + dprintf(4, "Get VBE Controller: Invalid Signature\n"); + } + + memset_far(seg, info, 0, sizeof(*info)); + + SET_FARVAR(seg, info->signature, VESA_SIGNATURE); + + SET_FARVAR(seg, info->version, 0x0200); + + SET_FARVAR(seg, info->oem_string, + SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); + SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */ + + /* We generate our mode list in the reserved field of the info block */ + SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34)); + + /* Total memory (in 64 blocks) */ + SET_FARVAR(seg, info->total_memory, bochsvga_total_mem()); + + SET_FARVAR(seg, info->oem_vendor_string, + SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); + SET_FARVAR(seg, info->oem_product_string, + SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); + SET_FARVAR(seg, info->oem_revision_string, + SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); + + /* Fill list of modes */ + bochsvga_list_modes(seg, regs->di + 32); + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +handle_104f01(struct bregs *regs) +{ + u16 seg = regs->es; + struct vbe_mode_info *info = (void*)(regs->di+0); + u16 mode = regs->cx; + struct vbe_modeinfo modeinfo; + int rc; + + dprintf(1, "VBE mode info request: %x\n", mode); + + rc = bochsvga_mode_info(mode, &modeinfo); + if (rc) { + dprintf(1, "VBE mode %x not found\n", mode); + regs->ax = 0x100; + return; + } + + u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | + VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | + VBE_MODE_ATTRIBUTE_COLOR_MODE | + VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; + if (modeinfo.depth == 4) + mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; + else + mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; + SET_FARVAR(seg, info->mode_attributes, mode_attr); + SET_FARVAR(seg, info->winA_attributes, + VBE_WINDOW_ATTRIBUTE_RELOCATABLE | + VBE_WINDOW_ATTRIBUTE_READABLE | + VBE_WINDOW_ATTRIBUTE_WRITEABLE); + SET_FARVAR(seg, info->winB_attributes, 0); + SET_FARVAR(seg, info->win_granularity, 64); /* Bank size 64K */ + SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ + SET_FARVAR(seg, info->winA_seg, 0xA000); + SET_FARVAR(seg, info->winB_seg, 0x0); + SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); + SET_FARVAR(seg, info->bytes_per_scanline, modeinfo.linesize); + SET_FARVAR(seg, info->xres, modeinfo.width); + SET_FARVAR(seg, info->yres, modeinfo.height); + SET_FARVAR(seg, info->xcharsize, 8); + SET_FARVAR(seg, info->ycharsize, 16); + if (modeinfo.depth == 4) + SET_FARVAR(seg, info->planes, 4); + else + SET_FARVAR(seg, info->planes, 1); + SET_FARVAR(seg, info->bits_per_pixel, modeinfo.depth); + SET_FARVAR(seg, info->banks, + (modeinfo.linesize * modeinfo.height + 65535) / 65536); + if (modeinfo.depth == 4) + SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); + else if (modeinfo.depth == 8) + SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); + else + SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); + SET_FARVAR(seg, info->bank_size, 0); + u32 pages = modeinfo.vram_size / (modeinfo.height * modeinfo.linesize); + if (modeinfo.depth == 4) + SET_FARVAR(seg, info->pages, (pages / 4) - 1); + else + SET_FARVAR(seg, info->pages, pages - 1); + SET_FARVAR(seg, info->reserved0, 1); + + u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; + + switch (modeinfo.depth) { + case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; + b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; + case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; + b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break; + case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; + b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break; + case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; + b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break; + default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0; + b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break; + } + + SET_FARVAR(seg, info->red_size, r_size); + SET_FARVAR(seg, info->red_pos, r_pos); + SET_FARVAR(seg, info->green_size, g_size); + SET_FARVAR(seg, info->green_pos, g_pos); + SET_FARVAR(seg, info->blue_size, b_size); + SET_FARVAR(seg, info->blue_pos, b_pos); + SET_FARVAR(seg, info->alpha_size, a_size); + SET_FARVAR(seg, info->alpha_pos, a_pos); + + if (modeinfo.depth == 32) + SET_FARVAR(seg, info->directcolor_info, + VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE); + else + SET_FARVAR(seg, info->directcolor_info, 0); + + if (modeinfo.depth > 4) + SET_FARVAR(seg, info->phys_base, modeinfo.phys_base); + else + SET_FARVAR(seg, info->phys_base, 0); + + SET_FARVAR(seg, info->reserved1, 0); + SET_FARVAR(seg, info->reserved2, 0); + SET_FARVAR(seg, info->linear_bytes_per_scanline, modeinfo.linesize); + SET_FARVAR(seg, info->bank_pages, 0); + SET_FARVAR(seg, info->linear_pages, 0); + SET_FARVAR(seg, info->linear_red_size, r_size); + SET_FARVAR(seg, info->linear_red_pos, r_pos); + SET_FARVAR(seg, info->linear_green_size, g_size); + SET_FARVAR(seg, info->linear_green_pos, g_pos); + SET_FARVAR(seg, info->linear_blue_size, b_size); + SET_FARVAR(seg, info->linear_blue_pos, b_pos); + SET_FARVAR(seg, info->linear_alpha_size, a_size); + SET_FARVAR(seg, info->linear_alpha_pos, a_pos); + SET_FARVAR(seg, info->pixclock_max, 0); + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +handle_104f02(struct bregs *regs) +{ + //u16 seg = regs->es; + //struct vbe_crtc_info *crtc_info = (void*)(regs->di+0); + u16 mode = regs->bx; + struct vbe_modeinfo modeinfo; + int rc; + + dprintf(1, "VBE mode set: %x\n", mode); + + if (mode < 0x100) { /* VGA */ + dprintf(1, "set VGA mode %x\n", mode); + + bochsvga_hires_enable(0); + vga_set_mode(mode, 0); + } else { /* VBE */ + rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); + if (rc) { + dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); + regs->ax = 0x100; + return; + } + bochsvga_hires_enable(1); + bochsvga_set_mode(mode & 0x1ff, &modeinfo); + + if (mode & 0x4000) { + /* Linear frame buffer */ + /* XXX: ??? */ + } + if (!(mode & 0x8000)) { + bochsvga_clear_scr(); + } + } + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +handle_104f03(struct bregs *regs) +{ + if (!bochsvga_hires_enabled()) { + regs->bx = GET_BDA(video_mode); + } else { + regs->bx = bochsvga_curr_mode(); + } + + dprintf(1, "VBE current mode=%x\n", regs->bx); + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +handle_104f04(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + regs->ax = 0x0100; +} + +static void +handle_104f05(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + regs->ax = 0x0100; +} + +static void +handle_104f06(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + regs->ax = 0x0100; +} + +static void +handle_104f07(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + regs->ax = 0x0100; +} + +static void +handle_104f08(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + regs->ax = 0x0100; +} + +static void +handle_104f0a(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + regs->ax = 0x0100; +} + +static void +handle_104fXX(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +handle_104f(struct bregs *regs) +{ + if (!bochsvga_enabled()) { + handle_104fXX(regs); + return; + } + + switch (regs->al) { + case 0x00: handle_104f00(regs); break; + case 0x01: handle_104f01(regs); break; + case 0x02: handle_104f02(regs); break; + case 0x03: handle_104f03(regs); break; + case 0x04: handle_104f04(regs); break; + case 0x05: handle_104f05(regs); break; + case 0x06: handle_104f06(regs); break; + case 0x07: handle_104f07(regs); break; + case 0x08: handle_104f08(regs); break; + case 0x0a: handle_104f0a(regs); break; + default: handle_104fXX(regs); break; + } +} + + +static void +handle_10XX(struct bregs *regs) +{ + debug_stub(regs); +} + +// INT 10h Video Support Service Entry Point +void VISIBLE16 +handle_10(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_10); + switch (regs->ah) { + case 0x00: handle_1000(regs); break; + case 0x01: handle_1001(regs); break; + case 0x02: handle_1002(regs); break; + case 0x03: handle_1003(regs); break; + case 0x04: handle_1004(regs); break; + case 0x05: handle_1005(regs); break; + case 0x06: handle_1006(regs); break; + case 0x07: handle_1007(regs); break; + case 0x08: handle_1008(regs); break; + case 0x09: handle_1009(regs); break; + case 0x0a: handle_100a(regs); break; + case 0x0b: handle_100b(regs); break; + case 0x0c: handle_100c(regs); break; + case 0x0d: handle_100d(regs); break; + case 0x0e: handle_100e(regs); break; + case 0x0f: handle_100f(regs); break; + case 0x10: handle_1010(regs); break; + case 0x11: handle_1011(regs); break; + case 0x12: handle_1012(regs); break; + case 0x13: handle_1013(regs); break; + case 0x1a: handle_101a(regs); break; + case 0x1b: handle_101b(regs); break; + case 0x1c: handle_101c(regs); break; + case 0x4f: handle_104f(regs); break; + default: handle_10XX(regs); break; + } +} + + +/**************************************************************** + * VGA post + ****************************************************************/ + +static void +init_bios_area(void) +{ + // init detected hardware BIOS Area + // set 80x25 color (not clear from RBIL but usual) + u16 eqf = GET_BDA(equipment_list_flags); + SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20); + + // Just for the first int10 find its children + + // the default char height + SET_BDA(char_height, 0x10); + + // Clear the screen + SET_BDA(video_ctl, 0x60); + + // Set the basic screen we have + SET_BDA(video_switches, 0xf9); + + // Set the basic modeset options + SET_BDA(modeset_ctl, 0x51); + + // Set the default MSR + SET_BDA(video_msr, 0x09); +} + +void VISIBLE16 +vga_post(struct bregs *regs) +{ + debug_enter(regs, DEBUG_VGA_POST); + + vgahw_init(); + + if (CONFIG_VGA_GEODELX) + geodelx_init(); + + init_bios_area(); + + bochsvga_init(regs->ah, regs->al); + + extern void entry_10(void); + SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10)); + + if (CONFIG_VGA_CIRRUS) + cirrus_init(); + + // XXX - clear screen and display info + + build_video_param(); + + // Fixup checksum + extern u8 _rom_header_size, _rom_header_checksum; + SET_VGA(_rom_header_checksum, 0); + u8 sum = -checksum_far(get_global_seg(), 0, _rom_header_size * 512); + SET_VGA(_rom_header_checksum, sum); +} diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h new file mode 100644 index 0000000..913dd88 --- /dev/null +++ b/vgasrc/vgabios.h @@ -0,0 +1,225 @@ +#ifndef __VGABIOS_H +#define __VGABIOS_H + +#include "types.h" // u8 +#include "farptr.h" // struct segoff_s + +/* + * + * VGA registers + * + */ +#define VGAREG_ACTL_ADDRESS 0x3c0 +#define VGAREG_ACTL_WRITE_DATA 0x3c0 +#define VGAREG_ACTL_READ_DATA 0x3c1 + +#define VGAREG_INPUT_STATUS 0x3c2 +#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 +#define VGAREG_VIDEO_ENABLE 0x3c3 +#define VGAREG_SEQU_ADDRESS 0x3c4 +#define VGAREG_SEQU_DATA 0x3c5 + +#define VGAREG_PEL_MASK 0x3c6 +#define VGAREG_DAC_STATE 0x3c7 +#define VGAREG_DAC_READ_ADDRESS 0x3c7 +#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 +#define VGAREG_DAC_DATA 0x3c9 + +#define VGAREG_READ_FEATURE_CTL 0x3ca +#define VGAREG_READ_MISC_OUTPUT 0x3cc + +#define VGAREG_GRDC_ADDRESS 0x3ce +#define VGAREG_GRDC_DATA 0x3cf + +#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 +#define VGAREG_MDA_CRTC_DATA 0x3b5 +#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 +#define VGAREG_VGA_CRTC_DATA 0x3d5 + +#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba +#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da +#define VGAREG_ACTL_RESET 0x3da + +#define VGAREG_MDA_MODECTL 0x3b8 +#define VGAREG_CGA_MODECTL 0x3d8 +#define VGAREG_CGA_PALETTE 0x3d9 + +/* Video memory */ +#define SEG_GRAPH 0xA000 +#define SEG_CTEXT 0xB800 +#define SEG_MTEXT 0xB000 + +/* + * Tables of default values for each mode + */ +#define TEXT 0x80 + +#define CTEXT (0x00 | TEXT) +#define MTEXT (0x01 | TEXT) +#define CGA 0x02 +#define PLANAR1 0x03 +#define PLANAR4 0x04 +#define LINEAR8 0x05 + +// for SVGA +#define LINEAR15 0x10 +#define LINEAR16 0x11 +#define LINEAR24 0x12 +#define LINEAR32 0x13 + +#define SCREEN_IO_START(x,y,p) (((((x)*(y)) | 0x00ff) + 1) * (p)) +#define SCREEN_MEM_START(x,y,p) SCREEN_IO_START(((x)*2),(y),(p)) + +struct vgamode_s { + u8 svgamode; + u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ + u8 twidth; + u8 theight; + u8 cheight; + u8 pixbits; + u16 sstart; + u16 slength; + + u8 pelmask; + u8 *dac; + u16 dacsize; + u8 *sequ_regs; + u8 miscreg; + u8 *crtc_regs; + u8 *actl_regs; + u8 *grdc_regs; +}; + +struct saveVideoHardware { + u8 sequ_index; + u8 crtc_index; + u8 grdc_index; + u8 actl_index; + u8 feature; + u8 sequ_regs[4]; + u8 sequ0; + u8 crtc_regs[25]; + u8 actl_regs[20]; + u8 grdc_regs[9]; + u16 crtc_addr; + u8 plane_latch[4]; +}; + +struct saveBDAstate { + u8 video_mode; + u16 video_cols; + u16 video_pagesize; + u16 crtc_address; + u8 video_rows; + u16 char_height; + u8 video_ctl; + u8 video_switches; + u8 modeset_ctl; + u16 cursor_type; + u16 cursor_pos[8]; + u16 video_pagestart; + u8 video_page; + /* current font */ + struct segoff_s font0; + struct segoff_s font1; +}; + +struct saveDACcolors { + u8 rwmode; + u8 peladdr; + u8 pelmask; + u8 dac[768]; + u8 color_select; +}; + +// vgatables.c +struct vgamode_s *find_vga_entry(u8 mode); +void build_video_param(void); +extern struct VideoSavePointer_s video_save_pointer_table; +extern u8 static_functionality[]; + +// vgafonts.c +extern u8 vgafont8[]; +extern u8 vgafont14[]; +extern u8 vgafont16[]; +extern u8 vgafont14alt[]; +extern u8 vgafont16alt[]; + +// vgabios.c +#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val)) +struct carattr { + u8 car, attr, use_attr; +}; +struct cursorpos { + u8 x, y, page; +}; +void vga_set_mode(u8 mode, u8 noclearmem); + +// 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); +struct carattr vgafb_read_char(struct cursorpos cp); +void vgafb_write_pixel(u8 color, u16 x, u16 y); +u8 vgafb_read_pixel(u16 x, u16 y); +void vgafb_load_font(u16 seg, void *src_far, u16 count + , u16 start, u8 destflags, u8 fontsize); + +// vgaio.c +void vgahw_screen_disable(void); +void vgahw_screen_enable(void); +void vgahw_set_border_color(u8 color); +void vgahw_set_overscan_border_color(u8 color); +u8 vgahw_get_overscan_border_color(void); +void vgahw_set_palette(u8 palid); +void vgahw_set_single_palette_reg(u8 reg, u8 val); +u8 vgahw_get_single_palette_reg(u8 reg); +void vgahw_set_all_palette_reg(u16 seg, u8 *data_far); +void vgahw_get_all_palette_reg(u16 seg, u8 *data_far); +void vgahw_toggle_intensity(u8 flag); +void vgahw_select_video_dac_color_page(u8 flag, u8 data); +void vgahw_read_video_dac_state(u8 *pmode, u8 *curpage); +void vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); +void vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); +void vgahw_set_pel_mask(u8 val); +u8 vgahw_get_pel_mask(void); +void vgahw_save_dac_state(u16 seg, struct saveDACcolors *info); +void vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info); +void vgahw_sequ_write(u8 index, u8 value); +void vgahw_grdc_write(u8 index, u8 value); +void vgahw_set_text_block_specifier(u8 spec); +void get_font_access(void); +void release_font_access(void); +void vgahw_set_cursor_shape(u8 start, u8 end); +void vgahw_set_active_page(u16 address); +void vgahw_set_cursor_pos(u16 address); +void vgahw_set_scan_lines(u8 lines); +u16 vgahw_get_vde(void); +void vgahw_save_state(u16 seg, struct saveVideoHardware *info); +void vgahw_restore_state(u16 seg, struct saveVideoHardware *info); +void vgahw_set_mode(struct vgamode_s *vmode_g); +void vgahw_enable_video_addressing(u8 disable); +void vgahw_init(void); + +// clext.c +int cirrus_set_video_mode(u8 mode, u8 noclearmem); +void cirrus_init(void); + +// vbe.c +#define VBE_OEM_STRING "SeaBIOS VBE(C) 2011" +#define VBE_VENDOR_STRING "SeaBIOS Developers" +#define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter" +#define VBE_REVISION_STRING "Rev. 1" + +struct vbe_modeinfo +{ + u16 width; + u16 height; + u8 depth; + u16 linesize; + u32 phys_base; + u32 vram_size; +}; + +#endif // vgabios.h diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 1e1943d..f85cd28 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -7,7 +7,7 @@
#include "biosvar.h" // GET_BDA #include "util.h" // memset_far -#include "vgatables.h" // find_vga_entry +#include "vgabios.h" // find_vga_entry
/**************************************************************** diff --git a/vgasrc/vgafonts.c b/vgasrc/vgafonts.c index 8c1752c..47a6437 100644 --- a/vgasrc/vgafonts.c +++ b/vgasrc/vgafonts.c @@ -1,4 +1,4 @@ -#include "vgatables.h" // vgafont8 +#include "vgabios.h" // vgafont8
/* * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip diff --git a/vgasrc/vgaio.c b/vgasrc/vgaio.c index 6154076..bc4c968 100644 --- a/vgasrc/vgaio.c +++ b/vgasrc/vgaio.c @@ -8,7 +8,7 @@ #include "ioport.h" // outb #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_BDA -#include "vgatables.h" // VGAREG_* +#include "vgabios.h" // VGAREG_*
// TODO // * replace direct in/out calls with wrapper functions diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index 47395f2..90ffa89 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -5,7 +5,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "vgatables.h" // struct VideoParamTableEntry_s +#include "vgabios.h" // struct VideoParamTableEntry_s #include "biosvar.h" // GET_GLOBAL #include "util.h" // memcpy_far
diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h deleted file mode 100644 index e0d61c9..0000000 --- a/vgasrc/vgatables.h +++ /dev/null @@ -1,225 +0,0 @@ -#ifndef __VGATABLES_H -#define __VGATABLES_H - -#include "types.h" // u8 -#include "farptr.h" // struct segoff_s - -/* - * - * VGA registers - * - */ -#define VGAREG_ACTL_ADDRESS 0x3c0 -#define VGAREG_ACTL_WRITE_DATA 0x3c0 -#define VGAREG_ACTL_READ_DATA 0x3c1 - -#define VGAREG_INPUT_STATUS 0x3c2 -#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 -#define VGAREG_VIDEO_ENABLE 0x3c3 -#define VGAREG_SEQU_ADDRESS 0x3c4 -#define VGAREG_SEQU_DATA 0x3c5 - -#define VGAREG_PEL_MASK 0x3c6 -#define VGAREG_DAC_STATE 0x3c7 -#define VGAREG_DAC_READ_ADDRESS 0x3c7 -#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 -#define VGAREG_DAC_DATA 0x3c9 - -#define VGAREG_READ_FEATURE_CTL 0x3ca -#define VGAREG_READ_MISC_OUTPUT 0x3cc - -#define VGAREG_GRDC_ADDRESS 0x3ce -#define VGAREG_GRDC_DATA 0x3cf - -#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 -#define VGAREG_MDA_CRTC_DATA 0x3b5 -#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 -#define VGAREG_VGA_CRTC_DATA 0x3d5 - -#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba -#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da -#define VGAREG_ACTL_RESET 0x3da - -#define VGAREG_MDA_MODECTL 0x3b8 -#define VGAREG_CGA_MODECTL 0x3d8 -#define VGAREG_CGA_PALETTE 0x3d9 - -/* Video memory */ -#define SEG_GRAPH 0xA000 -#define SEG_CTEXT 0xB800 -#define SEG_MTEXT 0xB000 - -/* - * Tables of default values for each mode - */ -#define TEXT 0x80 - -#define CTEXT (0x00 | TEXT) -#define MTEXT (0x01 | TEXT) -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR4 0x04 -#define LINEAR8 0x05 - -// for SVGA -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - -#define SCREEN_IO_START(x,y,p) (((((x)*(y)) | 0x00ff) + 1) * (p)) -#define SCREEN_MEM_START(x,y,p) SCREEN_IO_START(((x)*2),(y),(p)) - -struct vgamode_s { - u8 svgamode; - u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - u8 twidth; - u8 theight; - u8 cheight; - u8 pixbits; - u16 sstart; - u16 slength; - - u8 pelmask; - u8 *dac; - u16 dacsize; - u8 *sequ_regs; - u8 miscreg; - u8 *crtc_regs; - u8 *actl_regs; - u8 *grdc_regs; -}; - -struct saveVideoHardware { - u8 sequ_index; - u8 crtc_index; - u8 grdc_index; - u8 actl_index; - u8 feature; - u8 sequ_regs[4]; - u8 sequ0; - u8 crtc_regs[25]; - u8 actl_regs[20]; - u8 grdc_regs[9]; - u16 crtc_addr; - u8 plane_latch[4]; -}; - -struct saveBDAstate { - u8 video_mode; - u16 video_cols; - u16 video_pagesize; - u16 crtc_address; - u8 video_rows; - u16 char_height; - u8 video_ctl; - u8 video_switches; - u8 modeset_ctl; - u16 cursor_type; - u16 cursor_pos[8]; - u16 video_pagestart; - u8 video_page; - /* current font */ - struct segoff_s font0; - struct segoff_s font1; -}; - -struct saveDACcolors { - u8 rwmode; - u8 peladdr; - u8 pelmask; - u8 dac[768]; - u8 color_select; -}; - -// vgatables.c -struct vgamode_s *find_vga_entry(u8 mode); -void build_video_param(void); -extern struct VideoSavePointer_s video_save_pointer_table; -extern u8 static_functionality[]; - -// vgafonts.c -extern u8 vgafont8[]; -extern u8 vgafont14[]; -extern u8 vgafont16[]; -extern u8 vgafont14alt[]; -extern u8 vgafont16alt[]; - -// vga.c -#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val)) -struct carattr { - u8 car, attr, use_attr; -}; -struct cursorpos { - u8 x, y, page; -}; -void vga_set_mode(u8 mode, u8 noclearmem); - -// 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); -struct carattr vgafb_read_char(struct cursorpos cp); -void vgafb_write_pixel(u8 color, u16 x, u16 y); -u8 vgafb_read_pixel(u16 x, u16 y); -void vgafb_load_font(u16 seg, void *src_far, u16 count - , u16 start, u8 destflags, u8 fontsize); - -// vgaio.c -void vgahw_screen_disable(void); -void vgahw_screen_enable(void); -void vgahw_set_border_color(u8 color); -void vgahw_set_overscan_border_color(u8 color); -u8 vgahw_get_overscan_border_color(void); -void vgahw_set_palette(u8 palid); -void vgahw_set_single_palette_reg(u8 reg, u8 val); -u8 vgahw_get_single_palette_reg(u8 reg); -void vgahw_set_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_get_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_toggle_intensity(u8 flag); -void vgahw_select_video_dac_color_page(u8 flag, u8 data); -void vgahw_read_video_dac_state(u8 *pmode, u8 *curpage); -void vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_set_pel_mask(u8 val); -u8 vgahw_get_pel_mask(void); -void vgahw_save_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_sequ_write(u8 index, u8 value); -void vgahw_grdc_write(u8 index, u8 value); -void vgahw_set_text_block_specifier(u8 spec); -void get_font_access(void); -void release_font_access(void); -void vgahw_set_cursor_shape(u8 start, u8 end); -void vgahw_set_active_page(u16 address); -void vgahw_set_cursor_pos(u16 address); -void vgahw_set_scan_lines(u8 lines); -u16 vgahw_get_vde(void); -void vgahw_save_state(u16 seg, struct saveVideoHardware *info); -void vgahw_restore_state(u16 seg, struct saveVideoHardware *info); -void vgahw_set_mode(struct vgamode_s *vmode_g); -void vgahw_enable_video_addressing(u8 disable); -void vgahw_init(void); - -// clext.c -int cirrus_set_video_mode(u8 mode, u8 noclearmem); -void cirrus_init(void); - -// vbe.c -#define VBE_OEM_STRING "SeaBIOS VBE(C) 2011" -#define VBE_VENDOR_STRING "SeaBIOS Developers" -#define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter" -#define VBE_REVISION_STRING "Rev. 1" - -struct vbe_modeinfo -{ - u16 width; - u16 height; - u8 depth; - u16 linesize; - u32 phys_base; - u32 vram_size; -}; - -#endif // vgatables.h
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- vgasrc/vbe.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/vgabios.c | 289 --------------------------------------------------- vgasrc/vgabios.h | 3 + 4 files changed, 305 insertions(+), 290 deletions(-) create mode 100644 vgasrc/vbe.c
diff --git a/Makefile b/Makefile index 2346ee3..08f8af2 100644 --- a/Makefile +++ b/Makefile @@ -170,7 +170,7 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py
# VGA src files SRCVGA=src/output.c src/util.c vgasrc/vgabios.c vgasrc/vgafb.c vgasrc/vgaio.c \ - vgasrc/vgatables.c vgasrc/vgafonts.c \ + vgasrc/vgatables.c vgasrc/vgafonts.c vgasrc/vbe.c \ vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodelx.c
CFLAGS16VGA = $(CFLAGS16INC) -g -Isrc diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c new file mode 100644 index 0000000..f598921 --- /dev/null +++ b/vgasrc/vbe.c @@ -0,0 +1,301 @@ +// Video Bios Extensions handlers +// +// Copyright (C) 2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2001-2008 the LGPL VGABios developers Team +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "vgabios.h" // handle_104f +#include "config.h" // CONFIG_* +#include "bregs.h" // struct bregs +#include "vbe.h" // struct vbe_info +#include "util.h" // dprintf +#include "biosvar.h" // get_global_set +#include "bochsvga.h" // bochsvga_set_mode + +static void +vbe_104f00(struct bregs *regs) +{ + u16 seg = regs->es; + struct vbe_info *info = (void*)(regs->di+0); + + if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { + dprintf(4, "Get VBE Controller: VBE2 Signature found\n"); + } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) { + dprintf(4, "Get VBE Controller: VESA Signature found\n"); + } else { + dprintf(4, "Get VBE Controller: Invalid Signature\n"); + } + + memset_far(seg, info, 0, sizeof(*info)); + + SET_FARVAR(seg, info->signature, VESA_SIGNATURE); + + SET_FARVAR(seg, info->version, 0x0200); + + SET_FARVAR(seg, info->oem_string, + SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); + SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */ + + /* We generate our mode list in the reserved field of the info block */ + SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34)); + + /* Total memory (in 64 blocks) */ + SET_FARVAR(seg, info->total_memory, bochsvga_total_mem()); + + SET_FARVAR(seg, info->oem_vendor_string, + SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); + SET_FARVAR(seg, info->oem_product_string, + SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); + SET_FARVAR(seg, info->oem_revision_string, + SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); + + /* Fill list of modes */ + bochsvga_list_modes(seg, regs->di + 32); + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +vbe_104f01(struct bregs *regs) +{ + u16 seg = regs->es; + struct vbe_mode_info *info = (void*)(regs->di+0); + u16 mode = regs->cx; + struct vbe_modeinfo modeinfo; + int rc; + + dprintf(1, "VBE mode info request: %x\n", mode); + + rc = bochsvga_mode_info(mode, &modeinfo); + if (rc) { + dprintf(1, "VBE mode %x not found\n", mode); + regs->ax = 0x100; + return; + } + + u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | + VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | + VBE_MODE_ATTRIBUTE_COLOR_MODE | + VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; + if (modeinfo.depth == 4) + mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; + else + mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; + SET_FARVAR(seg, info->mode_attributes, mode_attr); + SET_FARVAR(seg, info->winA_attributes, + VBE_WINDOW_ATTRIBUTE_RELOCATABLE | + VBE_WINDOW_ATTRIBUTE_READABLE | + VBE_WINDOW_ATTRIBUTE_WRITEABLE); + SET_FARVAR(seg, info->winB_attributes, 0); + SET_FARVAR(seg, info->win_granularity, 64); /* Bank size 64K */ + SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ + SET_FARVAR(seg, info->winA_seg, 0xA000); + SET_FARVAR(seg, info->winB_seg, 0x0); + SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); + SET_FARVAR(seg, info->bytes_per_scanline, modeinfo.linesize); + SET_FARVAR(seg, info->xres, modeinfo.width); + SET_FARVAR(seg, info->yres, modeinfo.height); + SET_FARVAR(seg, info->xcharsize, 8); + SET_FARVAR(seg, info->ycharsize, 16); + if (modeinfo.depth == 4) + SET_FARVAR(seg, info->planes, 4); + else + SET_FARVAR(seg, info->planes, 1); + SET_FARVAR(seg, info->bits_per_pixel, modeinfo.depth); + SET_FARVAR(seg, info->banks, + (modeinfo.linesize * modeinfo.height + 65535) / 65536); + if (modeinfo.depth == 4) + SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); + else if (modeinfo.depth == 8) + SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); + else + SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); + SET_FARVAR(seg, info->bank_size, 0); + u32 pages = modeinfo.vram_size / (modeinfo.height * modeinfo.linesize); + if (modeinfo.depth == 4) + SET_FARVAR(seg, info->pages, (pages / 4) - 1); + else + SET_FARVAR(seg, info->pages, pages - 1); + SET_FARVAR(seg, info->reserved0, 1); + + u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; + + switch (modeinfo.depth) { + case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; + b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; + case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; + b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break; + case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; + b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break; + case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; + b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break; + default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0; + b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break; + } + + SET_FARVAR(seg, info->red_size, r_size); + SET_FARVAR(seg, info->red_pos, r_pos); + SET_FARVAR(seg, info->green_size, g_size); + SET_FARVAR(seg, info->green_pos, g_pos); + SET_FARVAR(seg, info->blue_size, b_size); + SET_FARVAR(seg, info->blue_pos, b_pos); + SET_FARVAR(seg, info->alpha_size, a_size); + SET_FARVAR(seg, info->alpha_pos, a_pos); + + if (modeinfo.depth == 32) + SET_FARVAR(seg, info->directcolor_info, + VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE); + else + SET_FARVAR(seg, info->directcolor_info, 0); + + if (modeinfo.depth > 4) + SET_FARVAR(seg, info->phys_base, modeinfo.phys_base); + else + SET_FARVAR(seg, info->phys_base, 0); + + SET_FARVAR(seg, info->reserved1, 0); + SET_FARVAR(seg, info->reserved2, 0); + SET_FARVAR(seg, info->linear_bytes_per_scanline, modeinfo.linesize); + SET_FARVAR(seg, info->bank_pages, 0); + SET_FARVAR(seg, info->linear_pages, 0); + SET_FARVAR(seg, info->linear_red_size, r_size); + SET_FARVAR(seg, info->linear_red_pos, r_pos); + SET_FARVAR(seg, info->linear_green_size, g_size); + SET_FARVAR(seg, info->linear_green_pos, g_pos); + SET_FARVAR(seg, info->linear_blue_size, b_size); + SET_FARVAR(seg, info->linear_blue_pos, b_pos); + SET_FARVAR(seg, info->linear_alpha_size, a_size); + SET_FARVAR(seg, info->linear_alpha_pos, a_pos); + SET_FARVAR(seg, info->pixclock_max, 0); + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +vbe_104f02(struct bregs *regs) +{ + //u16 seg = regs->es; + //struct vbe_crtc_info *crtc_info = (void*)(regs->di+0); + u16 mode = regs->bx; + struct vbe_modeinfo modeinfo; + int rc; + + dprintf(1, "VBE mode set: %x\n", mode); + + if (mode < 0x100) { /* VGA */ + dprintf(1, "set VGA mode %x\n", mode); + + bochsvga_hires_enable(0); + vga_set_mode(mode, 0); + } else { /* VBE */ + rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); + if (rc) { + dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); + regs->ax = 0x100; + return; + } + bochsvga_hires_enable(1); + bochsvga_set_mode(mode & 0x1ff, &modeinfo); + + if (mode & 0x4000) { + /* Linear frame buffer */ + /* XXX: ??? */ + } + if (!(mode & 0x8000)) { + bochsvga_clear_scr(); + } + } + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +vbe_104f03(struct bregs *regs) +{ + if (!bochsvga_hires_enabled()) { + regs->bx = GET_BDA(video_mode); + } else { + regs->bx = bochsvga_curr_mode(); + } + + dprintf(1, "VBE current mode=%x\n", regs->bx); + + regs->al = regs->ah; /* 0x4F, Function supported */ + regs->ah = 0x0; /* 0x0, Function call successful */ +} + +static void +vbe_104f04(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +vbe_104f05(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +vbe_104f06(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +vbe_104f07(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +vbe_104f08(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +vbe_104f0a(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +static void +vbe_104fXX(struct bregs *regs) +{ + debug_stub(regs); + regs->ax = 0x0100; +} + +void +handle_104f(struct bregs *regs) +{ + if (!bochsvga_enabled()) { + vbe_104fXX(regs); + return; + } + + switch (regs->al) { + case 0x00: vbe_104f00(regs); break; + case 0x01: vbe_104f01(regs); break; + case 0x02: vbe_104f02(regs); break; + case 0x03: vbe_104f03(regs); break; + case 0x04: vbe_104f04(regs); break; + case 0x05: vbe_104f05(regs); break; + case 0x06: vbe_104f06(regs); break; + case 0x07: vbe_104f07(regs); break; + case 0x08: vbe_104f08(regs); break; + case 0x0a: vbe_104f0a(regs); break; + default: vbe_104fXX(regs); break; + } +} diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 2ff677e..f1b84f9 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -17,7 +17,6 @@ #include "vgabios.h" // find_vga_entry #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* -#include "vbe.h" // struct vbe_info #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init
@@ -1206,294 +1205,6 @@ handle_101c(struct bregs *regs) }
static void -handle_104f00(struct bregs *regs) -{ - u16 seg = regs->es; - struct vbe_info *info = (void*)(regs->di+0); - - if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { - dprintf(4, "Get VBE Controller: VBE2 Signature found\n"); - } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) { - dprintf(4, "Get VBE Controller: VESA Signature found\n"); - } else { - dprintf(4, "Get VBE Controller: Invalid Signature\n"); - } - - memset_far(seg, info, 0, sizeof(*info)); - - SET_FARVAR(seg, info->signature, VESA_SIGNATURE); - - SET_FARVAR(seg, info->version, 0x0200); - - SET_FARVAR(seg, info->oem_string, - SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); - SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */ - - /* We generate our mode list in the reserved field of the info block */ - SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34)); - - /* Total memory (in 64 blocks) */ - SET_FARVAR(seg, info->total_memory, bochsvga_total_mem()); - - SET_FARVAR(seg, info->oem_vendor_string, - SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); - SET_FARVAR(seg, info->oem_product_string, - SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); - SET_FARVAR(seg, info->oem_revision_string, - SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); - - /* Fill list of modes */ - bochsvga_list_modes(seg, regs->di + 32); - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f01(struct bregs *regs) -{ - u16 seg = regs->es; - struct vbe_mode_info *info = (void*)(regs->di+0); - u16 mode = regs->cx; - struct vbe_modeinfo modeinfo; - int rc; - - dprintf(1, "VBE mode info request: %x\n", mode); - - rc = bochsvga_mode_info(mode, &modeinfo); - if (rc) { - dprintf(1, "VBE mode %x not found\n", mode); - regs->ax = 0x100; - return; - } - - u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | - VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | - VBE_MODE_ATTRIBUTE_COLOR_MODE | - VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; - if (modeinfo.depth == 4) - mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; - else - mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; - SET_FARVAR(seg, info->mode_attributes, mode_attr); - SET_FARVAR(seg, info->winA_attributes, - VBE_WINDOW_ATTRIBUTE_RELOCATABLE | - VBE_WINDOW_ATTRIBUTE_READABLE | - VBE_WINDOW_ATTRIBUTE_WRITEABLE); - SET_FARVAR(seg, info->winB_attributes, 0); - SET_FARVAR(seg, info->win_granularity, 64); /* Bank size 64K */ - SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ - SET_FARVAR(seg, info->winA_seg, 0xA000); - SET_FARVAR(seg, info->winB_seg, 0x0); - SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); - SET_FARVAR(seg, info->bytes_per_scanline, modeinfo.linesize); - SET_FARVAR(seg, info->xres, modeinfo.width); - SET_FARVAR(seg, info->yres, modeinfo.height); - SET_FARVAR(seg, info->xcharsize, 8); - SET_FARVAR(seg, info->ycharsize, 16); - if (modeinfo.depth == 4) - SET_FARVAR(seg, info->planes, 4); - else - SET_FARVAR(seg, info->planes, 1); - SET_FARVAR(seg, info->bits_per_pixel, modeinfo.depth); - SET_FARVAR(seg, info->banks, - (modeinfo.linesize * modeinfo.height + 65535) / 65536); - if (modeinfo.depth == 4) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); - else if (modeinfo.depth == 8) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); - else - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); - SET_FARVAR(seg, info->bank_size, 0); - u32 pages = modeinfo.vram_size / (modeinfo.height * modeinfo.linesize); - if (modeinfo.depth == 4) - SET_FARVAR(seg, info->pages, (pages / 4) - 1); - else - SET_FARVAR(seg, info->pages, pages - 1); - SET_FARVAR(seg, info->reserved0, 1); - - u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; - - switch (modeinfo.depth) { - case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; - b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; - case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; - b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break; - case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; - b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break; - case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; - b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break; - default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0; - b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break; - } - - SET_FARVAR(seg, info->red_size, r_size); - SET_FARVAR(seg, info->red_pos, r_pos); - SET_FARVAR(seg, info->green_size, g_size); - SET_FARVAR(seg, info->green_pos, g_pos); - SET_FARVAR(seg, info->blue_size, b_size); - SET_FARVAR(seg, info->blue_pos, b_pos); - SET_FARVAR(seg, info->alpha_size, a_size); - SET_FARVAR(seg, info->alpha_pos, a_pos); - - if (modeinfo.depth == 32) - SET_FARVAR(seg, info->directcolor_info, - VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE); - else - SET_FARVAR(seg, info->directcolor_info, 0); - - if (modeinfo.depth > 4) - SET_FARVAR(seg, info->phys_base, modeinfo.phys_base); - else - SET_FARVAR(seg, info->phys_base, 0); - - SET_FARVAR(seg, info->reserved1, 0); - SET_FARVAR(seg, info->reserved2, 0); - SET_FARVAR(seg, info->linear_bytes_per_scanline, modeinfo.linesize); - SET_FARVAR(seg, info->bank_pages, 0); - SET_FARVAR(seg, info->linear_pages, 0); - SET_FARVAR(seg, info->linear_red_size, r_size); - SET_FARVAR(seg, info->linear_red_pos, r_pos); - SET_FARVAR(seg, info->linear_green_size, g_size); - SET_FARVAR(seg, info->linear_green_pos, g_pos); - SET_FARVAR(seg, info->linear_blue_size, b_size); - SET_FARVAR(seg, info->linear_blue_pos, b_pos); - SET_FARVAR(seg, info->linear_alpha_size, a_size); - SET_FARVAR(seg, info->linear_alpha_pos, a_pos); - SET_FARVAR(seg, info->pixclock_max, 0); - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f02(struct bregs *regs) -{ - //u16 seg = regs->es; - //struct vbe_crtc_info *crtc_info = (void*)(regs->di+0); - u16 mode = regs->bx; - struct vbe_modeinfo modeinfo; - int rc; - - dprintf(1, "VBE mode set: %x\n", mode); - - if (mode < 0x100) { /* VGA */ - dprintf(1, "set VGA mode %x\n", mode); - - bochsvga_hires_enable(0); - vga_set_mode(mode, 0); - } else { /* VBE */ - rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); - if (rc) { - dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); - regs->ax = 0x100; - return; - } - bochsvga_hires_enable(1); - bochsvga_set_mode(mode & 0x1ff, &modeinfo); - - if (mode & 0x4000) { - /* Linear frame buffer */ - /* XXX: ??? */ - } - if (!(mode & 0x8000)) { - bochsvga_clear_scr(); - } - } - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f03(struct bregs *regs) -{ - if (!bochsvga_hires_enabled()) { - regs->bx = GET_BDA(video_mode); - } else { - regs->bx = bochsvga_curr_mode(); - } - - dprintf(1, "VBE current mode=%x\n", regs->bx); - - regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ -} - -static void -handle_104f04(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f05(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f06(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f07(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f08(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104f0a(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - regs->ax = 0x0100; -} - -static void -handle_104fXX(struct bregs *regs) -{ - debug_stub(regs); - regs->ax = 0x0100; -} - -static void -handle_104f(struct bregs *regs) -{ - if (!bochsvga_enabled()) { - handle_104fXX(regs); - return; - } - - switch (regs->al) { - case 0x00: handle_104f00(regs); break; - case 0x01: handle_104f01(regs); break; - case 0x02: handle_104f02(regs); break; - case 0x03: handle_104f03(regs); break; - case 0x04: handle_104f04(regs); break; - case 0x05: handle_104f05(regs); break; - case 0x06: handle_104f06(regs); break; - case 0x07: handle_104f07(regs); break; - case 0x08: handle_104f08(regs); break; - case 0x0a: handle_104f0a(regs); break; - default: handle_104fXX(regs); break; - } -} - - -static void handle_10XX(struct bregs *regs) { debug_stub(regs); diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 913dd88..568e276 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -222,4 +222,7 @@ struct vbe_modeinfo u32 vram_size; };
+struct bregs; +void handle_104f(struct bregs *regs); + #endif // vgabios.h
Also, introduce stdvga.h.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 4 +- vgasrc/bochsvga.c | 1 + vgasrc/clext.c | 1 + vgasrc/geodelx.c | 1 + vgasrc/stdvga.c | 560 ++++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/stdvga.h | 143 +++++++++++++ vgasrc/vgabios.c | 1 + vgasrc/vgabios.h | 143 +------------- vgasrc/vgafb.c | 1 + vgasrc/vgaio.c | 559 --------------------------------------------------- vgasrc/vgatables.c | 1 + 11 files changed, 712 insertions(+), 703 deletions(-) create mode 100644 vgasrc/stdvga.c create mode 100644 vgasrc/stdvga.h delete mode 100644 vgasrc/vgaio.c
diff --git a/Makefile b/Makefile index 08f8af2..8395247 100644 --- a/Makefile +++ b/Makefile @@ -169,9 +169,9 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py ################ VGA build rules
# VGA src files -SRCVGA=src/output.c src/util.c vgasrc/vgabios.c vgasrc/vgafb.c vgasrc/vgaio.c \ +SRCVGA=src/output.c src/util.c vgasrc/vgabios.c vgasrc/vgafb.c \ vgasrc/vgatables.c vgasrc/vgafonts.c vgasrc/vbe.c \ - vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodelx.c + vgasrc/stdvga.c vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodelx.c
CFLAGS16VGA = $(CFLAGS16INC) -g -Isrc
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 9dd142b..3b5c711 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -4,6 +4,7 @@ #include "util.h" #include "config.h" // CONFIG_* #include "biosvar.h" // SET_BDA +#include "stdvga.h" // VGAREG_SEQU_ADDRESS
static struct mode { diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 40447ff..764d05b 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -10,6 +10,7 @@ #include "util.h" // dprintf #include "bregs.h" // struct bregs #include "vbe.h" // struct vbe_info +#include "stdvga.h" // VGAREG_SEQU_ADDRESS
/**************************************************************** diff --git a/vgasrc/geodelx.c b/vgasrc/geodelx.c index 1d58be0..4a5f873 100644 --- a/vgasrc/geodelx.c +++ b/vgasrc/geodelx.c @@ -15,6 +15,7 @@ #include "config.h" #include "types.h" #include "bregs.h" +#include "stdvga.h" // VGAREG_VGA_CRTC_ADDRESS
/**************************************************************** diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c new file mode 100644 index 0000000..1727fca --- /dev/null +++ b/vgasrc/stdvga.c @@ -0,0 +1,560 @@ +// VGA io port access +// +// Copyright (C) 2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2001-2008 the LGPL VGABios developers Team +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "stdvga.h" // vgahw_init +#include "ioport.h" // outb +#include "farptr.h" // SET_FARVAR +#include "biosvar.h" // GET_BDA +#include "vgabios.h" // VGAREG_* + +// TODO +// * replace direct in/out calls with wrapper functions + + +/**************************************************************** + * Attribute control + ****************************************************************/ + +void +vgahw_screen_disable(void) +{ + inb(VGAREG_ACTL_RESET); + outb(0x00, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_screen_enable(void) +{ + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_set_border_color(u8 color) +{ + inb(VGAREG_ACTL_RESET); + outb(0x00, VGAREG_ACTL_ADDRESS); + u8 v1 = color & 0x0f; + if (v1 & 0x08) + v1 += 0x08; + outb(v1, VGAREG_ACTL_WRITE_DATA); + + u8 v2 = color & 0x10; + int i; + for (i = 1; i < 4; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + + u8 cur = inb(VGAREG_ACTL_READ_DATA); + cur &= 0xef; + cur |= v2; + outb(cur, VGAREG_ACTL_WRITE_DATA); + } + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_set_overscan_border_color(u8 color) +{ + inb(VGAREG_ACTL_RESET); + outb(0x11, VGAREG_ACTL_ADDRESS); + outb(color, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +u8 +vgahw_get_overscan_border_color(void) +{ + inb(VGAREG_ACTL_RESET); + outb(0x11, VGAREG_ACTL_ADDRESS); + u8 v = inb(VGAREG_ACTL_READ_DATA); + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); + return v; +} + +void +vgahw_set_palette(u8 palid) +{ + inb(VGAREG_ACTL_RESET); + palid &= 0x01; + int i; + for (i = 1; i < 4; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + + u8 v = inb(VGAREG_ACTL_READ_DATA); + v &= 0xfe; + v |= palid; + outb(v, VGAREG_ACTL_WRITE_DATA); + } + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_set_single_palette_reg(u8 reg, u8 val) +{ + inb(VGAREG_ACTL_RESET); + outb(reg, VGAREG_ACTL_ADDRESS); + outb(val, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +u8 +vgahw_get_single_palette_reg(u8 reg) +{ + inb(VGAREG_ACTL_RESET); + outb(reg, VGAREG_ACTL_ADDRESS); + u8 v = inb(VGAREG_ACTL_READ_DATA); + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); + return v; +} + +void +vgahw_set_all_palette_reg(u16 seg, u8 *data_far) +{ + inb(VGAREG_ACTL_RESET); + int i; + for (i = 0; i < 0x10; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + u8 val = GET_FARVAR(seg, *data_far); + outb(val, VGAREG_ACTL_WRITE_DATA); + data_far++; + } + outb(0x11, VGAREG_ACTL_ADDRESS); + outb(GET_FARVAR(seg, *data_far), VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_get_all_palette_reg(u16 seg, u8 *data_far) +{ + int i; + for (i = 0; i < 0x10; i++) { + inb(VGAREG_ACTL_RESET); + outb(i, VGAREG_ACTL_ADDRESS); + SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA)); + data_far++; + } + inb(VGAREG_ACTL_RESET); + outb(0x11, VGAREG_ACTL_ADDRESS); + SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA)); + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_toggle_intensity(u8 flag) +{ + inb(VGAREG_ACTL_RESET); + outb(0x10, VGAREG_ACTL_ADDRESS); + u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0xf7) | ((flag & 0x01) << 3); + outb(val, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_select_video_dac_color_page(u8 flag, u8 data) +{ + inb(VGAREG_ACTL_RESET); + outb(0x10, VGAREG_ACTL_ADDRESS); + u8 val = inb(VGAREG_ACTL_READ_DATA); + if (!(flag & 0x01)) { + // select paging mode + val = (val & 0x7f) | (data << 7); + outb(val, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); + return; + } + // select page + inb(VGAREG_ACTL_RESET); + outb(0x14, VGAREG_ACTL_ADDRESS); + if (!(val & 0x80)) + data <<= 2; + data &= 0x0f; + outb(data, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +vgahw_read_video_dac_state(u8 *pmode, u8 *curpage) +{ + inb(VGAREG_ACTL_RESET); + outb(0x10, VGAREG_ACTL_ADDRESS); + u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7; + + inb(VGAREG_ACTL_RESET); + outb(0x14, VGAREG_ACTL_ADDRESS); + u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f; + if (!(val1 & 0x01)) + val2 >>= 2; + + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); + + *pmode = val1; + *curpage = val2; +} + + +/**************************************************************** + * DAC control + ****************************************************************/ + +void +vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count) +{ + outb(start, VGAREG_DAC_WRITE_ADDRESS); + while (count) { + outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); + data_far++; + outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); + data_far++; + outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); + data_far++; + count--; + } +} + +void +vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count) +{ + outb(start, VGAREG_DAC_READ_ADDRESS); + while (count) { + SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); + data_far++; + SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); + data_far++; + SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); + data_far++; + count--; + } +} + +void +vgahw_set_pel_mask(u8 val) +{ + outb(val, VGAREG_PEL_MASK); +} + +u8 +vgahw_get_pel_mask(void) +{ + return inb(VGAREG_PEL_MASK); +} + +void +vgahw_save_dac_state(u16 seg, struct saveDACcolors *info) +{ + /* XXX: check this */ + SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE)); + SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS)); + SET_FARVAR(seg, info->pelmask, inb(VGAREG_PEL_MASK)); + vgahw_get_dac_regs(seg, info->dac, 0, 256); + SET_FARVAR(seg, info->color_select, 0); +} + +void +vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info) +{ + outb(GET_FARVAR(seg, info->pelmask), VGAREG_PEL_MASK); + vgahw_set_dac_regs(seg, info->dac, 0, 256); + outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS); +} + + +/**************************************************************** + * Memory control + ****************************************************************/ + +void +vgahw_sequ_write(u8 index, u8 value) +{ + outw((value<<8) | index, VGAREG_SEQU_ADDRESS); +} + +void +vgahw_grdc_write(u8 index, u8 value) +{ + outw((value<<8) | index, VGAREG_GRDC_ADDRESS); +} + +void +vgahw_set_text_block_specifier(u8 spec) +{ + outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS); +} + +void +get_font_access(void) +{ + outw(0x0100, VGAREG_SEQU_ADDRESS); + outw(0x0402, VGAREG_SEQU_ADDRESS); + outw(0x0704, VGAREG_SEQU_ADDRESS); + outw(0x0300, VGAREG_SEQU_ADDRESS); + outw(0x0204, VGAREG_GRDC_ADDRESS); + outw(0x0005, VGAREG_GRDC_ADDRESS); + outw(0x0406, VGAREG_GRDC_ADDRESS); +} + +void +release_font_access(void) +{ + outw(0x0100, VGAREG_SEQU_ADDRESS); + outw(0x0302, VGAREG_SEQU_ADDRESS); + outw(0x0304, VGAREG_SEQU_ADDRESS); + outw(0x0300, VGAREG_SEQU_ADDRESS); + u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; + outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS); + outw(0x0004, VGAREG_GRDC_ADDRESS); + outw(0x1005, VGAREG_GRDC_ADDRESS); +} + + +/**************************************************************** + * CRTC registers + ****************************************************************/ + +static u16 +get_crtc(void) +{ + return GET_BDA(crtc_address); +} + +void +vgahw_set_cursor_shape(u8 start, u8 end) +{ + u16 crtc_addr = get_crtc(); + outb(0x0a, crtc_addr); + outb(start, crtc_addr + 1); + outb(0x0b, crtc_addr); + outb(end, crtc_addr + 1); +} + +void +vgahw_set_active_page(u16 address) +{ + u16 crtc_addr = get_crtc(); + outb(0x0c, crtc_addr); + outb((address & 0xff00) >> 8, crtc_addr + 1); + outb(0x0d, crtc_addr); + outb(address & 0x00ff, crtc_addr + 1); +} + +void +vgahw_set_cursor_pos(u16 address) +{ + u16 crtc_addr = get_crtc(); + outb(0x0e, crtc_addr); + outb((address & 0xff00) >> 8, crtc_addr + 1); + outb(0x0f, crtc_addr); + outb(address & 0x00ff, crtc_addr + 1); +} + +void +vgahw_set_scan_lines(u8 lines) +{ + u16 crtc_addr = get_crtc(); + outb(0x09, crtc_addr); + u8 crtc_r9 = inb(crtc_addr + 1); + crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); + outb(crtc_r9, crtc_addr + 1); +} + +// Get vertical display end +u16 +vgahw_get_vde(void) +{ + u16 crtc_addr = get_crtc(); + outb(0x12, crtc_addr); + u16 vde = inb(crtc_addr + 1); + outb(0x07, crtc_addr); + u8 ovl = inb(crtc_addr + 1); + vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); + return vde; +} + + +/**************************************************************** + * Save/Restore/Set state + ****************************************************************/ + +void +vgahw_save_state(u16 seg, struct saveVideoHardware *info) +{ + u16 crtc_addr = get_crtc(); + SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS)); + SET_FARVAR(seg, info->crtc_index, inb(crtc_addr)); + SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS)); + inb(VGAREG_ACTL_RESET); + u16 ar_index = inb(VGAREG_ACTL_ADDRESS); + SET_FARVAR(seg, info->actl_index, ar_index); + SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL)); + + u16 i; + for (i=0; i<4; i++) { + outb(i+1, VGAREG_SEQU_ADDRESS); + SET_FARVAR(seg, info->sequ_regs[i], inb(VGAREG_SEQU_DATA)); + } + outb(0, VGAREG_SEQU_ADDRESS); + SET_FARVAR(seg, info->sequ0, inb(VGAREG_SEQU_DATA)); + + for (i=0; i<25; i++) { + outb(i, crtc_addr); + SET_FARVAR(seg, info->crtc_regs[i], inb(crtc_addr + 1)); + } + + for (i=0; i<20; i++) { + inb(VGAREG_ACTL_RESET); + outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS); + SET_FARVAR(seg, info->actl_regs[i], inb(VGAREG_ACTL_READ_DATA)); + } + inb(VGAREG_ACTL_RESET); + + for (i=0; i<9; i++) { + outb(i, VGAREG_GRDC_ADDRESS); + SET_FARVAR(seg, info->grdc_regs[i], inb(VGAREG_GRDC_DATA)); + } + + SET_FARVAR(seg, info->crtc_addr, crtc_addr); + + /* XXX: read plane latches */ + for (i=0; i<4; i++) + SET_FARVAR(seg, info->plane_latch[i], 0); +} + +void +vgahw_restore_state(u16 seg, struct saveVideoHardware *info) +{ + // Reset Attribute Ctl flip-flop + inb(VGAREG_ACTL_RESET); + + u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr); + + u16 i; + for (i=0; i<4; i++) { + outb(i+1, VGAREG_SEQU_ADDRESS); + outb(GET_FARVAR(seg, info->sequ_regs[i]), VGAREG_SEQU_DATA); + } + outb(0, VGAREG_SEQU_ADDRESS); + outb(GET_FARVAR(seg, info->sequ0), VGAREG_SEQU_DATA); + + // Disable CRTC write protection + outw(0x0011, crtc_addr); + // Set CRTC regs + for (i=0; i<25; i++) + if (i != 0x11) { + outb(i, crtc_addr); + outb(GET_FARVAR(seg, info->crtc_regs[i]), crtc_addr + 1); + } + // select crtc base address + u16 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; + if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS) + v |= 0x01; + outb(v, VGAREG_WRITE_MISC_OUTPUT); + + // enable write protection if needed + outb(0x11, crtc_addr); + outb(GET_FARVAR(seg, info->crtc_regs[0x11]), crtc_addr + 1); + + // Set Attribute Ctl + u16 ar_index = GET_FARVAR(seg, info->actl_index); + inb(VGAREG_ACTL_RESET); + for (i=0; i<20; i++) { + outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS); + outb(GET_FARVAR(seg, info->actl_regs[i]), VGAREG_ACTL_WRITE_DATA); + } + outb(ar_index, VGAREG_ACTL_ADDRESS); + inb(VGAREG_ACTL_RESET); + + for (i=0; i<9; i++) { + outb(i, VGAREG_GRDC_ADDRESS); + outb(GET_FARVAR(seg, info->grdc_regs[i]), VGAREG_GRDC_DATA); + } + + outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS); + outb(GET_FARVAR(seg, info->crtc_index), crtc_addr); + outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS); + outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa); +} + +void +vgahw_set_mode(struct vgamode_s *vmode_g) +{ + // Reset Attribute Ctl flip-flop + inb(VGAREG_ACTL_RESET); + + // Set Attribute Ctl + u8 *regs = GET_GLOBAL(vmode_g->actl_regs); + u16 i; + for (i = 0; i <= 0x13; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + outb(GET_GLOBAL(regs[i]), VGAREG_ACTL_WRITE_DATA); + } + outb(0x14, VGAREG_ACTL_ADDRESS); + outb(0x00, VGAREG_ACTL_WRITE_DATA); + + // Set Sequencer Ctl + outb(0, VGAREG_SEQU_ADDRESS); + outb(0x03, VGAREG_SEQU_DATA); + regs = GET_GLOBAL(vmode_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); + 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); + u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; + if (!(miscreg & 1)) + crtc_addr = VGAREG_MDA_CRTC_ADDRESS; + + // Disable CRTC write protection + outw(0x0011, crtc_addr); + // Set CRTC regs + regs = GET_GLOBAL(vmode_g->crtc_regs); + for (i = 0; i <= 0x18; i++) { + outb(i, crtc_addr); + outb(GET_GLOBAL(regs[i]), crtc_addr + 1); + } + + // Set the misc register + outb(miscreg, VGAREG_WRITE_MISC_OUTPUT); + + // Enable video + outb(0x20, VGAREG_ACTL_ADDRESS); + inb(VGAREG_ACTL_RESET); +} + + +/**************************************************************** + * Misc + ****************************************************************/ + +void +vgahw_enable_video_addressing(u8 disable) +{ + u8 v = (disable & 1) ? 0x00 : 0x02; + u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02; + outb(v | v2, VGAREG_WRITE_MISC_OUTPUT); +} + +void +vgahw_init(void) +{ + // switch to color mode and enable CPU access 480 lines + outb(0xc3, VGAREG_WRITE_MISC_OUTPUT); + // more than 64k 3C4/04 + outb(0x04, VGAREG_SEQU_ADDRESS); + outb(0x02, VGAREG_SEQU_DATA); +} diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h new file mode 100644 index 0000000..53fe3cf --- /dev/null +++ b/vgasrc/stdvga.h @@ -0,0 +1,143 @@ +#ifndef __STDVGA_H +#define __STDVGA_H + +#include "types.h" // u8 + +// VGA registers +#define VGAREG_ACTL_ADDRESS 0x3c0 +#define VGAREG_ACTL_WRITE_DATA 0x3c0 +#define VGAREG_ACTL_READ_DATA 0x3c1 + +#define VGAREG_INPUT_STATUS 0x3c2 +#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 +#define VGAREG_VIDEO_ENABLE 0x3c3 +#define VGAREG_SEQU_ADDRESS 0x3c4 +#define VGAREG_SEQU_DATA 0x3c5 + +#define VGAREG_PEL_MASK 0x3c6 +#define VGAREG_DAC_STATE 0x3c7 +#define VGAREG_DAC_READ_ADDRESS 0x3c7 +#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 +#define VGAREG_DAC_DATA 0x3c9 + +#define VGAREG_READ_FEATURE_CTL 0x3ca +#define VGAREG_READ_MISC_OUTPUT 0x3cc + +#define VGAREG_GRDC_ADDRESS 0x3ce +#define VGAREG_GRDC_DATA 0x3cf + +#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 +#define VGAREG_MDA_CRTC_DATA 0x3b5 +#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 +#define VGAREG_VGA_CRTC_DATA 0x3d5 + +#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba +#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da +#define VGAREG_ACTL_RESET 0x3da + +#define VGAREG_MDA_MODECTL 0x3b8 +#define VGAREG_CGA_MODECTL 0x3d8 +#define VGAREG_CGA_PALETTE 0x3d9 + +/* Video memory */ +#define SEG_GRAPH 0xA000 +#define SEG_CTEXT 0xB800 +#define SEG_MTEXT 0xB000 + +/* + * Tables of default values for each mode + */ +#define TEXT 0x80 + +#define CTEXT (0x00 | TEXT) +#define MTEXT (0x01 | TEXT) +#define CGA 0x02 +#define PLANAR1 0x03 +#define PLANAR4 0x04 +#define LINEAR8 0x05 + +// for SVGA +#define LINEAR15 0x10 +#define LINEAR16 0x11 +#define LINEAR24 0x12 +#define LINEAR32 0x13 + +struct vgamode_s { + u8 svgamode; + u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ + u8 twidth; + u8 theight; + u8 cheight; + u8 pixbits; + u16 sstart; + u16 slength; + + u8 pelmask; + u8 *dac; + u16 dacsize; + u8 *sequ_regs; + u8 miscreg; + u8 *crtc_regs; + u8 *actl_regs; + u8 *grdc_regs; +}; + +struct saveVideoHardware { + u8 sequ_index; + u8 crtc_index; + u8 grdc_index; + u8 actl_index; + u8 feature; + u8 sequ_regs[4]; + u8 sequ0; + u8 crtc_regs[25]; + u8 actl_regs[20]; + u8 grdc_regs[9]; + u16 crtc_addr; + u8 plane_latch[4]; +}; + +struct saveDACcolors { + u8 rwmode; + u8 peladdr; + u8 pelmask; + u8 dac[768]; + u8 color_select; +}; + +void vgahw_screen_disable(void); +void vgahw_screen_enable(void); +void vgahw_set_border_color(u8 color); +void vgahw_set_overscan_border_color(u8 color); +u8 vgahw_get_overscan_border_color(void); +void vgahw_set_palette(u8 palid); +void vgahw_set_single_palette_reg(u8 reg, u8 val); +u8 vgahw_get_single_palette_reg(u8 reg); +void vgahw_set_all_palette_reg(u16 seg, u8 *data_far); +void vgahw_get_all_palette_reg(u16 seg, u8 *data_far); +void vgahw_toggle_intensity(u8 flag); +void vgahw_select_video_dac_color_page(u8 flag, u8 data); +void vgahw_read_video_dac_state(u8 *pmode, u8 *curpage); +void vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); +void vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); +void vgahw_set_pel_mask(u8 val); +u8 vgahw_get_pel_mask(void); +void vgahw_save_dac_state(u16 seg, struct saveDACcolors *info); +void vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info); +void vgahw_sequ_write(u8 index, u8 value); +void vgahw_grdc_write(u8 index, u8 value); +void vgahw_set_text_block_specifier(u8 spec); +void get_font_access(void); +void release_font_access(void); +void vgahw_set_cursor_shape(u8 start, u8 end); +void vgahw_set_active_page(u16 address); +void vgahw_set_cursor_pos(u16 address); +void vgahw_set_scan_lines(u8 lines); +u16 vgahw_get_vde(void); +void vgahw_save_state(u16 seg, struct saveVideoHardware *info); +void vgahw_restore_state(u16 seg, struct saveVideoHardware *info); +void vgahw_set_mode(struct vgamode_s *vmode_g); +void vgahw_enable_video_addressing(u8 disable); +void vgahw_init(void); + +#endif // stdvga.h diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index f1b84f9..3caff5f 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -17,6 +17,7 @@ #include "vgabios.h" // find_vga_entry #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* +#include "stdvga.h" // vgahw_screen_disable #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 568e276..5cf1f04 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -4,107 +4,9 @@ #include "types.h" // u8 #include "farptr.h" // struct segoff_s
-/* - * - * VGA registers - * - */ -#define VGAREG_ACTL_ADDRESS 0x3c0 -#define VGAREG_ACTL_WRITE_DATA 0x3c0 -#define VGAREG_ACTL_READ_DATA 0x3c1 - -#define VGAREG_INPUT_STATUS 0x3c2 -#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 -#define VGAREG_VIDEO_ENABLE 0x3c3 -#define VGAREG_SEQU_ADDRESS 0x3c4 -#define VGAREG_SEQU_DATA 0x3c5 - -#define VGAREG_PEL_MASK 0x3c6 -#define VGAREG_DAC_STATE 0x3c7 -#define VGAREG_DAC_READ_ADDRESS 0x3c7 -#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 -#define VGAREG_DAC_DATA 0x3c9 - -#define VGAREG_READ_FEATURE_CTL 0x3ca -#define VGAREG_READ_MISC_OUTPUT 0x3cc - -#define VGAREG_GRDC_ADDRESS 0x3ce -#define VGAREG_GRDC_DATA 0x3cf - -#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 -#define VGAREG_MDA_CRTC_DATA 0x3b5 -#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 -#define VGAREG_VGA_CRTC_DATA 0x3d5 - -#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba -#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da -#define VGAREG_ACTL_RESET 0x3da - -#define VGAREG_MDA_MODECTL 0x3b8 -#define VGAREG_CGA_MODECTL 0x3d8 -#define VGAREG_CGA_PALETTE 0x3d9 - -/* Video memory */ -#define SEG_GRAPH 0xA000 -#define SEG_CTEXT 0xB800 -#define SEG_MTEXT 0xB000 - -/* - * Tables of default values for each mode - */ -#define TEXT 0x80 - -#define CTEXT (0x00 | TEXT) -#define MTEXT (0x01 | TEXT) -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR4 0x04 -#define LINEAR8 0x05 - -// for SVGA -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - #define SCREEN_IO_START(x,y,p) (((((x)*(y)) | 0x00ff) + 1) * (p)) #define SCREEN_MEM_START(x,y,p) SCREEN_IO_START(((x)*2),(y),(p))
-struct vgamode_s { - u8 svgamode; - u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - u8 twidth; - u8 theight; - u8 cheight; - u8 pixbits; - u16 sstart; - u16 slength; - - u8 pelmask; - u8 *dac; - u16 dacsize; - u8 *sequ_regs; - u8 miscreg; - u8 *crtc_regs; - u8 *actl_regs; - u8 *grdc_regs; -}; - -struct saveVideoHardware { - u8 sequ_index; - u8 crtc_index; - u8 grdc_index; - u8 actl_index; - u8 feature; - u8 sequ_regs[4]; - u8 sequ0; - u8 crtc_regs[25]; - u8 actl_regs[20]; - u8 grdc_regs[9]; - u16 crtc_addr; - u8 plane_latch[4]; -}; - struct saveBDAstate { u8 video_mode; u16 video_cols; @@ -124,15 +26,8 @@ struct saveBDAstate { struct segoff_s font1; };
-struct saveDACcolors { - u8 rwmode; - u8 peladdr; - u8 pelmask; - u8 dac[768]; - u8 color_select; -}; - // vgatables.c +struct vgamode_s; struct vgamode_s *find_vga_entry(u8 mode); void build_video_param(void); extern struct VideoSavePointer_s video_save_pointer_table; @@ -166,42 +61,6 @@ u8 vgafb_read_pixel(u16 x, u16 y); void vgafb_load_font(u16 seg, void *src_far, u16 count , u16 start, u8 destflags, u8 fontsize);
-// vgaio.c -void vgahw_screen_disable(void); -void vgahw_screen_enable(void); -void vgahw_set_border_color(u8 color); -void vgahw_set_overscan_border_color(u8 color); -u8 vgahw_get_overscan_border_color(void); -void vgahw_set_palette(u8 palid); -void vgahw_set_single_palette_reg(u8 reg, u8 val); -u8 vgahw_get_single_palette_reg(u8 reg); -void vgahw_set_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_get_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_toggle_intensity(u8 flag); -void vgahw_select_video_dac_color_page(u8 flag, u8 data); -void vgahw_read_video_dac_state(u8 *pmode, u8 *curpage); -void vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_set_pel_mask(u8 val); -u8 vgahw_get_pel_mask(void); -void vgahw_save_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_sequ_write(u8 index, u8 value); -void vgahw_grdc_write(u8 index, u8 value); -void vgahw_set_text_block_specifier(u8 spec); -void get_font_access(void); -void release_font_access(void); -void vgahw_set_cursor_shape(u8 start, u8 end); -void vgahw_set_active_page(u16 address); -void vgahw_set_cursor_pos(u16 address); -void vgahw_set_scan_lines(u8 lines); -u16 vgahw_get_vde(void); -void vgahw_save_state(u16 seg, struct saveVideoHardware *info); -void vgahw_restore_state(u16 seg, struct saveVideoHardware *info); -void vgahw_set_mode(struct vgamode_s *vmode_g); -void vgahw_enable_video_addressing(u8 disable); -void vgahw_init(void); - // clext.c int cirrus_set_video_mode(u8 mode, u8 noclearmem); void cirrus_init(void); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index f85cd28..3838303 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -8,6 +8,7 @@ #include "biosvar.h" // GET_BDA #include "util.h" // memset_far #include "vgabios.h" // find_vga_entry +#include "stdvga.h" // vgahw_grdc_write
/**************************************************************** diff --git a/vgasrc/vgaio.c b/vgasrc/vgaio.c deleted file mode 100644 index bc4c968..0000000 --- a/vgasrc/vgaio.c +++ /dev/null @@ -1,559 +0,0 @@ -// VGA io port access -// -// Copyright (C) 2009 Kevin O'Connor kevin@koconnor.net -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "ioport.h" // outb -#include "farptr.h" // SET_FARVAR -#include "biosvar.h" // GET_BDA -#include "vgabios.h" // VGAREG_* - -// TODO -// * replace direct in/out calls with wrapper functions - - -/**************************************************************** - * Attribute control - ****************************************************************/ - -void -vgahw_screen_disable(void) -{ - inb(VGAREG_ACTL_RESET); - outb(0x00, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_screen_enable(void) -{ - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_set_border_color(u8 color) -{ - inb(VGAREG_ACTL_RESET); - outb(0x00, VGAREG_ACTL_ADDRESS); - u8 v1 = color & 0x0f; - if (v1 & 0x08) - v1 += 0x08; - outb(v1, VGAREG_ACTL_WRITE_DATA); - - u8 v2 = color & 0x10; - int i; - for (i = 1; i < 4; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - - u8 cur = inb(VGAREG_ACTL_READ_DATA); - cur &= 0xef; - cur |= v2; - outb(cur, VGAREG_ACTL_WRITE_DATA); - } - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_set_overscan_border_color(u8 color) -{ - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - outb(color, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -u8 -vgahw_get_overscan_border_color(void) -{ - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - u8 v = inb(VGAREG_ACTL_READ_DATA); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - return v; -} - -void -vgahw_set_palette(u8 palid) -{ - inb(VGAREG_ACTL_RESET); - palid &= 0x01; - int i; - for (i = 1; i < 4; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - - u8 v = inb(VGAREG_ACTL_READ_DATA); - v &= 0xfe; - v |= palid; - outb(v, VGAREG_ACTL_WRITE_DATA); - } - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_set_single_palette_reg(u8 reg, u8 val) -{ - inb(VGAREG_ACTL_RESET); - outb(reg, VGAREG_ACTL_ADDRESS); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -u8 -vgahw_get_single_palette_reg(u8 reg) -{ - inb(VGAREG_ACTL_RESET); - outb(reg, VGAREG_ACTL_ADDRESS); - u8 v = inb(VGAREG_ACTL_READ_DATA); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - return v; -} - -void -vgahw_set_all_palette_reg(u16 seg, u8 *data_far) -{ - inb(VGAREG_ACTL_RESET); - int i; - for (i = 0; i < 0x10; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - u8 val = GET_FARVAR(seg, *data_far); - outb(val, VGAREG_ACTL_WRITE_DATA); - data_far++; - } - outb(0x11, VGAREG_ACTL_ADDRESS); - outb(GET_FARVAR(seg, *data_far), VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_get_all_palette_reg(u16 seg, u8 *data_far) -{ - int i; - for (i = 0; i < 0x10; i++) { - inb(VGAREG_ACTL_RESET); - outb(i, VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA)); - data_far++; - } - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA)); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_toggle_intensity(u8 flag) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0xf7) | ((flag & 0x01) << 3); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_select_video_dac_color_page(u8 flag, u8 data) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val = inb(VGAREG_ACTL_READ_DATA); - if (!(flag & 0x01)) { - // select paging mode - val = (val & 0x7f) | (data << 7); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); - return; - } - // select page - inb(VGAREG_ACTL_RESET); - outb(0x14, VGAREG_ACTL_ADDRESS); - if (!(val & 0x80)) - data <<= 2; - data &= 0x0f; - outb(data, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_read_video_dac_state(u8 *pmode, u8 *curpage) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7; - - inb(VGAREG_ACTL_RESET); - outb(0x14, VGAREG_ACTL_ADDRESS); - u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f; - if (!(val1 & 0x01)) - val2 >>= 2; - - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - - *pmode = val1; - *curpage = val2; -} - - -/**************************************************************** - * DAC control - ****************************************************************/ - -void -vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count) -{ - outb(start, VGAREG_DAC_WRITE_ADDRESS); - while (count) { - outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); - data_far++; - outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); - data_far++; - outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); - data_far++; - count--; - } -} - -void -vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count) -{ - outb(start, VGAREG_DAC_READ_ADDRESS); - while (count) { - SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - count--; - } -} - -void -vgahw_set_pel_mask(u8 val) -{ - outb(val, VGAREG_PEL_MASK); -} - -u8 -vgahw_get_pel_mask(void) -{ - return inb(VGAREG_PEL_MASK); -} - -void -vgahw_save_dac_state(u16 seg, struct saveDACcolors *info) -{ - /* XXX: check this */ - SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE)); - SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS)); - SET_FARVAR(seg, info->pelmask, inb(VGAREG_PEL_MASK)); - vgahw_get_dac_regs(seg, info->dac, 0, 256); - SET_FARVAR(seg, info->color_select, 0); -} - -void -vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info) -{ - outb(GET_FARVAR(seg, info->pelmask), VGAREG_PEL_MASK); - vgahw_set_dac_regs(seg, info->dac, 0, 256); - outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS); -} - - -/**************************************************************** - * Memory control - ****************************************************************/ - -void -vgahw_sequ_write(u8 index, u8 value) -{ - outw((value<<8) | index, VGAREG_SEQU_ADDRESS); -} - -void -vgahw_grdc_write(u8 index, u8 value) -{ - outw((value<<8) | index, VGAREG_GRDC_ADDRESS); -} - -void -vgahw_set_text_block_specifier(u8 spec) -{ - outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS); -} - -void -get_font_access(void) -{ - outw(0x0100, VGAREG_SEQU_ADDRESS); - outw(0x0402, VGAREG_SEQU_ADDRESS); - outw(0x0704, VGAREG_SEQU_ADDRESS); - outw(0x0300, VGAREG_SEQU_ADDRESS); - outw(0x0204, VGAREG_GRDC_ADDRESS); - outw(0x0005, VGAREG_GRDC_ADDRESS); - outw(0x0406, VGAREG_GRDC_ADDRESS); -} - -void -release_font_access(void) -{ - outw(0x0100, VGAREG_SEQU_ADDRESS); - outw(0x0302, VGAREG_SEQU_ADDRESS); - outw(0x0304, VGAREG_SEQU_ADDRESS); - outw(0x0300, VGAREG_SEQU_ADDRESS); - u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; - outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS); - outw(0x0004, VGAREG_GRDC_ADDRESS); - outw(0x1005, VGAREG_GRDC_ADDRESS); -} - - -/**************************************************************** - * CRTC registers - ****************************************************************/ - -static u16 -get_crtc(void) -{ - return GET_BDA(crtc_address); -} - -void -vgahw_set_cursor_shape(u8 start, u8 end) -{ - u16 crtc_addr = get_crtc(); - outb(0x0a, crtc_addr); - outb(start, crtc_addr + 1); - outb(0x0b, crtc_addr); - outb(end, crtc_addr + 1); -} - -void -vgahw_set_active_page(u16 address) -{ - u16 crtc_addr = get_crtc(); - outb(0x0c, crtc_addr); - outb((address & 0xff00) >> 8, crtc_addr + 1); - outb(0x0d, crtc_addr); - outb(address & 0x00ff, crtc_addr + 1); -} - -void -vgahw_set_cursor_pos(u16 address) -{ - u16 crtc_addr = get_crtc(); - outb(0x0e, crtc_addr); - outb((address & 0xff00) >> 8, crtc_addr + 1); - outb(0x0f, crtc_addr); - outb(address & 0x00ff, crtc_addr + 1); -} - -void -vgahw_set_scan_lines(u8 lines) -{ - u16 crtc_addr = get_crtc(); - outb(0x09, crtc_addr); - u8 crtc_r9 = inb(crtc_addr + 1); - crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); - outb(crtc_r9, crtc_addr + 1); -} - -// Get vertical display end -u16 -vgahw_get_vde(void) -{ - u16 crtc_addr = get_crtc(); - outb(0x12, crtc_addr); - u16 vde = inb(crtc_addr + 1); - outb(0x07, crtc_addr); - u8 ovl = inb(crtc_addr + 1); - vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); - return vde; -} - - -/**************************************************************** - * Save/Restore/Set state - ****************************************************************/ - -void -vgahw_save_state(u16 seg, struct saveVideoHardware *info) -{ - u16 crtc_addr = get_crtc(); - SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS)); - SET_FARVAR(seg, info->crtc_index, inb(crtc_addr)); - SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS)); - inb(VGAREG_ACTL_RESET); - u16 ar_index = inb(VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, info->actl_index, ar_index); - SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL)); - - u16 i; - for (i=0; i<4; i++) { - outb(i+1, VGAREG_SEQU_ADDRESS); - SET_FARVAR(seg, info->sequ_regs[i], inb(VGAREG_SEQU_DATA)); - } - outb(0, VGAREG_SEQU_ADDRESS); - SET_FARVAR(seg, info->sequ0, inb(VGAREG_SEQU_DATA)); - - for (i=0; i<25; i++) { - outb(i, crtc_addr); - SET_FARVAR(seg, info->crtc_regs[i], inb(crtc_addr + 1)); - } - - for (i=0; i<20; i++) { - inb(VGAREG_ACTL_RESET); - outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, info->actl_regs[i], inb(VGAREG_ACTL_READ_DATA)); - } - inb(VGAREG_ACTL_RESET); - - for (i=0; i<9; i++) { - outb(i, VGAREG_GRDC_ADDRESS); - SET_FARVAR(seg, info->grdc_regs[i], inb(VGAREG_GRDC_DATA)); - } - - SET_FARVAR(seg, info->crtc_addr, crtc_addr); - - /* XXX: read plane latches */ - for (i=0; i<4; i++) - SET_FARVAR(seg, info->plane_latch[i], 0); -} - -void -vgahw_restore_state(u16 seg, struct saveVideoHardware *info) -{ - // Reset Attribute Ctl flip-flop - inb(VGAREG_ACTL_RESET); - - u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr); - - u16 i; - for (i=0; i<4; i++) { - outb(i+1, VGAREG_SEQU_ADDRESS); - outb(GET_FARVAR(seg, info->sequ_regs[i]), VGAREG_SEQU_DATA); - } - outb(0, VGAREG_SEQU_ADDRESS); - outb(GET_FARVAR(seg, info->sequ0), VGAREG_SEQU_DATA); - - // Disable CRTC write protection - outw(0x0011, crtc_addr); - // Set CRTC regs - for (i=0; i<25; i++) - if (i != 0x11) { - outb(i, crtc_addr); - outb(GET_FARVAR(seg, info->crtc_regs[i]), crtc_addr + 1); - } - // select crtc base address - u16 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; - if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS) - v |= 0x01; - outb(v, VGAREG_WRITE_MISC_OUTPUT); - - // enable write protection if needed - outb(0x11, crtc_addr); - outb(GET_FARVAR(seg, info->crtc_regs[0x11]), crtc_addr + 1); - - // Set Attribute Ctl - u16 ar_index = GET_FARVAR(seg, info->actl_index); - inb(VGAREG_ACTL_RESET); - for (i=0; i<20; i++) { - outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS); - outb(GET_FARVAR(seg, info->actl_regs[i]), VGAREG_ACTL_WRITE_DATA); - } - outb(ar_index, VGAREG_ACTL_ADDRESS); - inb(VGAREG_ACTL_RESET); - - for (i=0; i<9; i++) { - outb(i, VGAREG_GRDC_ADDRESS); - outb(GET_FARVAR(seg, info->grdc_regs[i]), VGAREG_GRDC_DATA); - } - - outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS); - outb(GET_FARVAR(seg, info->crtc_index), crtc_addr); - outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS); - outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa); -} - -void -vgahw_set_mode(struct vgamode_s *vmode_g) -{ - // Reset Attribute Ctl flip-flop - inb(VGAREG_ACTL_RESET); - - // Set Attribute Ctl - u8 *regs = GET_GLOBAL(vmode_g->actl_regs); - u16 i; - for (i = 0; i <= 0x13; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - outb(GET_GLOBAL(regs[i]), VGAREG_ACTL_WRITE_DATA); - } - outb(0x14, VGAREG_ACTL_ADDRESS); - outb(0x00, VGAREG_ACTL_WRITE_DATA); - - // Set Sequencer Ctl - outb(0, VGAREG_SEQU_ADDRESS); - outb(0x03, VGAREG_SEQU_DATA); - regs = GET_GLOBAL(vmode_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); - 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); - u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; - if (!(miscreg & 1)) - crtc_addr = VGAREG_MDA_CRTC_ADDRESS; - - // Disable CRTC write protection - outw(0x0011, crtc_addr); - // Set CRTC regs - regs = GET_GLOBAL(vmode_g->crtc_regs); - for (i = 0; i <= 0x18; i++) { - outb(i, crtc_addr); - outb(GET_GLOBAL(regs[i]), crtc_addr + 1); - } - - // Set the misc register - outb(miscreg, VGAREG_WRITE_MISC_OUTPUT); - - // Enable video - outb(0x20, VGAREG_ACTL_ADDRESS); - inb(VGAREG_ACTL_RESET); -} - - -/**************************************************************** - * Misc - ****************************************************************/ - -void -vgahw_enable_video_addressing(u8 disable) -{ - u8 v = (disable & 1) ? 0x00 : 0x02; - u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02; - outb(v | v2, VGAREG_WRITE_MISC_OUTPUT); -} - -void -vgahw_init(void) -{ - // switch to color mode and enable CPU access 480 lines - outb(0xc3, VGAREG_WRITE_MISC_OUTPUT); - // more than 64k 3C4/04 - outb(0x04, VGAREG_SEQU_ADDRESS); - outb(0x02, VGAREG_SEQU_DATA); -} diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index 90ffa89..0eda104 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -8,6 +8,7 @@ #include "vgabios.h" // struct VideoParamTableEntry_s #include "biosvar.h" // GET_GLOBAL #include "util.h" // memcpy_far +#include "stdvga.h" // struct vgamode_s
/****************************************************************
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 4 +- vgasrc/stdvga.c | 70 +++++++++++++++++++++++++------------------------- vgasrc/stdvga.h | 64 ++++++++++++++++++++++---------------------- vgasrc/vgabios.c | 76 +++++++++++++++++++++++++++--------------------------- vgasrc/vgafb.c | 38 +++++++++++++------------- 5 files changed, 126 insertions(+), 126 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 764d05b..7987d28 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -353,12 +353,12 @@ cirrus_switch_mode(struct cirrus_mode_s *table) outb(0xff, VGAREG_PEL_MASK);
u8 vesacolortype = GET_GLOBAL(table->vesacolortype); - u8 v = vgahw_get_single_palette_reg(0x10) & 0xfe; + u8 v = stdvga_get_single_palette_reg(0x10) & 0xfe; if (vesacolortype == 3) v |= 0x41; else if (vesacolortype) v |= 0x01; - vgahw_set_single_palette_reg(0x10, v); + stdvga_set_single_palette_reg(0x10, v); }
static u8 diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index 1727fca..fd8514e 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -5,7 +5,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "stdvga.h" // vgahw_init +#include "stdvga.h" // stdvga_init #include "ioport.h" // outb #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_BDA @@ -20,21 +20,21 @@ ****************************************************************/
void -vgahw_screen_disable(void) +stdvga_screen_disable(void) { inb(VGAREG_ACTL_RESET); outb(0x00, VGAREG_ACTL_ADDRESS); }
void -vgahw_screen_enable(void) +stdvga_screen_enable(void) { inb(VGAREG_ACTL_RESET); outb(0x20, VGAREG_ACTL_ADDRESS); }
void -vgahw_set_border_color(u8 color) +stdvga_set_border_color(u8 color) { inb(VGAREG_ACTL_RESET); outb(0x00, VGAREG_ACTL_ADDRESS); @@ -57,7 +57,7 @@ vgahw_set_border_color(u8 color) }
void -vgahw_set_overscan_border_color(u8 color) +stdvga_set_overscan_border_color(u8 color) { inb(VGAREG_ACTL_RESET); outb(0x11, VGAREG_ACTL_ADDRESS); @@ -66,7 +66,7 @@ vgahw_set_overscan_border_color(u8 color) }
u8 -vgahw_get_overscan_border_color(void) +stdvga_get_overscan_border_color(void) { inb(VGAREG_ACTL_RESET); outb(0x11, VGAREG_ACTL_ADDRESS); @@ -77,7 +77,7 @@ vgahw_get_overscan_border_color(void) }
void -vgahw_set_palette(u8 palid) +stdvga_set_palette(u8 palid) { inb(VGAREG_ACTL_RESET); palid &= 0x01; @@ -94,7 +94,7 @@ vgahw_set_palette(u8 palid) }
void -vgahw_set_single_palette_reg(u8 reg, u8 val) +stdvga_set_single_palette_reg(u8 reg, u8 val) { inb(VGAREG_ACTL_RESET); outb(reg, VGAREG_ACTL_ADDRESS); @@ -103,7 +103,7 @@ vgahw_set_single_palette_reg(u8 reg, u8 val) }
u8 -vgahw_get_single_palette_reg(u8 reg) +stdvga_get_single_palette_reg(u8 reg) { inb(VGAREG_ACTL_RESET); outb(reg, VGAREG_ACTL_ADDRESS); @@ -114,7 +114,7 @@ vgahw_get_single_palette_reg(u8 reg) }
void -vgahw_set_all_palette_reg(u16 seg, u8 *data_far) +stdvga_set_all_palette_reg(u16 seg, u8 *data_far) { inb(VGAREG_ACTL_RESET); int i; @@ -130,7 +130,7 @@ vgahw_set_all_palette_reg(u16 seg, u8 *data_far) }
void -vgahw_get_all_palette_reg(u16 seg, u8 *data_far) +stdvga_get_all_palette_reg(u16 seg, u8 *data_far) { int i; for (i = 0; i < 0x10; i++) { @@ -147,7 +147,7 @@ vgahw_get_all_palette_reg(u16 seg, u8 *data_far) }
void -vgahw_toggle_intensity(u8 flag) +stdvga_toggle_intensity(u8 flag) { inb(VGAREG_ACTL_RESET); outb(0x10, VGAREG_ACTL_ADDRESS); @@ -157,7 +157,7 @@ vgahw_toggle_intensity(u8 flag) }
void -vgahw_select_video_dac_color_page(u8 flag, u8 data) +stdvga_select_video_dac_color_page(u8 flag, u8 data) { inb(VGAREG_ACTL_RESET); outb(0x10, VGAREG_ACTL_ADDRESS); @@ -180,7 +180,7 @@ vgahw_select_video_dac_color_page(u8 flag, u8 data) }
void -vgahw_read_video_dac_state(u8 *pmode, u8 *curpage) +stdvga_read_video_dac_state(u8 *pmode, u8 *curpage) { inb(VGAREG_ACTL_RESET); outb(0x10, VGAREG_ACTL_ADDRESS); @@ -205,7 +205,7 @@ vgahw_read_video_dac_state(u8 *pmode, u8 *curpage) ****************************************************************/
void -vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count) +stdvga_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count) { outb(start, VGAREG_DAC_WRITE_ADDRESS); while (count) { @@ -220,7 +220,7 @@ vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count) }
void -vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count) +stdvga_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count) { outb(start, VGAREG_DAC_READ_ADDRESS); while (count) { @@ -235,33 +235,33 @@ vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count) }
void -vgahw_set_pel_mask(u8 val) +stdvga_set_pel_mask(u8 val) { outb(val, VGAREG_PEL_MASK); }
u8 -vgahw_get_pel_mask(void) +stdvga_get_pel_mask(void) { return inb(VGAREG_PEL_MASK); }
void -vgahw_save_dac_state(u16 seg, struct saveDACcolors *info) +stdvga_save_dac_state(u16 seg, struct saveDACcolors *info) { /* XXX: check this */ SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE)); SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS)); SET_FARVAR(seg, info->pelmask, inb(VGAREG_PEL_MASK)); - vgahw_get_dac_regs(seg, info->dac, 0, 256); + stdvga_get_dac_regs(seg, info->dac, 0, 256); SET_FARVAR(seg, info->color_select, 0); }
void -vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info) +stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info) { outb(GET_FARVAR(seg, info->pelmask), VGAREG_PEL_MASK); - vgahw_set_dac_regs(seg, info->dac, 0, 256); + stdvga_set_dac_regs(seg, info->dac, 0, 256); outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS); }
@@ -271,19 +271,19 @@ vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info) ****************************************************************/
void -vgahw_sequ_write(u8 index, u8 value) +stdvga_sequ_write(u8 index, u8 value) { outw((value<<8) | index, VGAREG_SEQU_ADDRESS); }
void -vgahw_grdc_write(u8 index, u8 value) +stdvga_grdc_write(u8 index, u8 value) { outw((value<<8) | index, VGAREG_GRDC_ADDRESS); }
void -vgahw_set_text_block_specifier(u8 spec) +stdvga_set_text_block_specifier(u8 spec) { outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS); } @@ -325,7 +325,7 @@ get_crtc(void) }
void -vgahw_set_cursor_shape(u8 start, u8 end) +stdvga_set_cursor_shape(u8 start, u8 end) { u16 crtc_addr = get_crtc(); outb(0x0a, crtc_addr); @@ -335,7 +335,7 @@ vgahw_set_cursor_shape(u8 start, u8 end) }
void -vgahw_set_active_page(u16 address) +stdvga_set_active_page(u16 address) { u16 crtc_addr = get_crtc(); outb(0x0c, crtc_addr); @@ -345,7 +345,7 @@ vgahw_set_active_page(u16 address) }
void -vgahw_set_cursor_pos(u16 address) +stdvga_set_cursor_pos(u16 address) { u16 crtc_addr = get_crtc(); outb(0x0e, crtc_addr); @@ -355,7 +355,7 @@ vgahw_set_cursor_pos(u16 address) }
void -vgahw_set_scan_lines(u8 lines) +stdvga_set_scan_lines(u8 lines) { u16 crtc_addr = get_crtc(); outb(0x09, crtc_addr); @@ -366,7 +366,7 @@ vgahw_set_scan_lines(u8 lines)
// Get vertical display end u16 -vgahw_get_vde(void) +stdvga_get_vde(void) { u16 crtc_addr = get_crtc(); outb(0x12, crtc_addr); @@ -383,7 +383,7 @@ vgahw_get_vde(void) ****************************************************************/
void -vgahw_save_state(u16 seg, struct saveVideoHardware *info) +stdvga_save_state(u16 seg, struct saveVideoHardware *info) { u16 crtc_addr = get_crtc(); SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS)); @@ -427,7 +427,7 @@ vgahw_save_state(u16 seg, struct saveVideoHardware *info) }
void -vgahw_restore_state(u16 seg, struct saveVideoHardware *info) +stdvga_restore_state(u16 seg, struct saveVideoHardware *info) { // Reset Attribute Ctl flip-flop inb(VGAREG_ACTL_RESET); @@ -482,7 +482,7 @@ vgahw_restore_state(u16 seg, struct saveVideoHardware *info) }
void -vgahw_set_mode(struct vgamode_s *vmode_g) +stdvga_set_mode(struct vgamode_s *vmode_g) { // Reset Attribute Ctl flip-flop inb(VGAREG_ACTL_RESET); @@ -542,7 +542,7 @@ vgahw_set_mode(struct vgamode_s *vmode_g) ****************************************************************/
void -vgahw_enable_video_addressing(u8 disable) +stdvga_enable_video_addressing(u8 disable) { u8 v = (disable & 1) ? 0x00 : 0x02; u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02; @@ -550,7 +550,7 @@ vgahw_enable_video_addressing(u8 disable) }
void -vgahw_init(void) +stdvga_init(void) { // switch to color mode and enable CPU access 480 lines outb(0xc3, VGAREG_WRITE_MISC_OUTPUT); diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 53fe3cf..7fa612e 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -105,39 +105,39 @@ struct saveDACcolors { u8 color_select; };
-void vgahw_screen_disable(void); -void vgahw_screen_enable(void); -void vgahw_set_border_color(u8 color); -void vgahw_set_overscan_border_color(u8 color); -u8 vgahw_get_overscan_border_color(void); -void vgahw_set_palette(u8 palid); -void vgahw_set_single_palette_reg(u8 reg, u8 val); -u8 vgahw_get_single_palette_reg(u8 reg); -void vgahw_set_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_get_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_toggle_intensity(u8 flag); -void vgahw_select_video_dac_color_page(u8 flag, u8 data); -void vgahw_read_video_dac_state(u8 *pmode, u8 *curpage); -void vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_set_pel_mask(u8 val); -u8 vgahw_get_pel_mask(void); -void vgahw_save_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_sequ_write(u8 index, u8 value); -void vgahw_grdc_write(u8 index, u8 value); -void vgahw_set_text_block_specifier(u8 spec); +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); +void stdvga_set_palette(u8 palid); +void stdvga_set_single_palette_reg(u8 reg, u8 val); +u8 stdvga_get_single_palette_reg(u8 reg); +void stdvga_set_all_palette_reg(u16 seg, u8 *data_far); +void stdvga_get_all_palette_reg(u16 seg, u8 *data_far); +void stdvga_toggle_intensity(u8 flag); +void stdvga_select_video_dac_color_page(u8 flag, u8 data); +void stdvga_read_video_dac_state(u8 *pmode, u8 *curpage); +void stdvga_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); +void stdvga_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); +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_sequ_write(u8 index, u8 value); +void stdvga_grdc_write(u8 index, u8 value); +void stdvga_set_text_block_specifier(u8 spec); void get_font_access(void); void release_font_access(void); -void vgahw_set_cursor_shape(u8 start, u8 end); -void vgahw_set_active_page(u16 address); -void vgahw_set_cursor_pos(u16 address); -void vgahw_set_scan_lines(u8 lines); -u16 vgahw_get_vde(void); -void vgahw_save_state(u16 seg, struct saveVideoHardware *info); -void vgahw_restore_state(u16 seg, struct saveVideoHardware *info); -void vgahw_set_mode(struct vgamode_s *vmode_g); -void vgahw_enable_video_addressing(u8 disable); -void vgahw_init(void); +void stdvga_set_cursor_shape(u8 start, u8 end); +void stdvga_set_active_page(u16 address); +void stdvga_set_cursor_pos(u16 address); +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_enable_video_addressing(u8 disable); +void stdvga_init(void);
#endif // stdvga.h diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 3caff5f..5f646cd 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" // vgahw_screen_disable +#include "stdvga.h" // stdvga_screen_disable #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init
@@ -61,20 +61,20 @@ call16_vgaint(u32 eax, u32 ebx) static void perform_gray_scale_summing(u16 start, u16 count) { - vgahw_screen_disable(); + stdvga_screen_disable(); int i; for (i = start; i < start+count; i++) { u8 rgb[3]; - vgahw_get_dac_regs(GET_SEG(SS), rgb, i, 1); + 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;
- vgahw_set_dac_regs(GET_SEG(SS), rgb, i, 1); + stdvga_set_dac_regs(GET_SEG(SS), rgb, i, 1); } - vgahw_screen_enable(); + stdvga_screen_enable(); }
static void @@ -95,7 +95,7 @@ set_cursor_shape(u8 start, u8 end) start = ((end + 1) * cheight / 8) - 2; end = ((end + 1) * cheight / 8) - 1; } - vgahw_set_cursor_shape(start, end); + stdvga_set_cursor_shape(start, end); }
static u16 @@ -130,7 +130,7 @@ set_cursor_pos(struct cursorpos cp) u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page) + cp.x + cp.y * nbcols);
- vgahw_set_cursor_pos(address); + stdvga_set_cursor_pos(address); }
static struct cursorpos @@ -179,7 +179,7 @@ set_active_page(u8 page) address = page * GET_GLOBAL(vmode_g->slength); }
- vgahw_set_active_page(address); + stdvga_set_active_page(address);
// And change the BIOS page SET_BDA(video_page, page); @@ -193,13 +193,13 @@ set_active_page(u8 page) static void set_scan_lines(u8 lines) { - vgahw_set_scan_lines(lines); + stdvga_set_scan_lines(lines); if (lines == 8) set_cursor_shape(0x06, 0x07); else set_cursor_shape(lines - 4, lines - 3); SET_BDA(char_height, lines); - u16 vde = vgahw_get_vde(); + u16 vde = stdvga_get_vde(); u8 rows = vde / lines; SET_BDA(video_rows, rows - 1); u16 cols = GET_BDA(video_cols); @@ -376,25 +376,25 @@ vga_set_mode(u8 mode, u8 noclearmem)
// if palette loading (bit 3 of modeset ctl = 0) if ((modeset_ctl & 0x08) == 0) { // Set the PEL mask - vgahw_set_pel_mask(GET_GLOBAL(vmode_g->pelmask)); + 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 - vgahw_set_dac_regs(get_global_seg(), palette_g, 0, palsize); + stdvga_set_dac_regs(get_global_seg(), palette_g, 0, palsize); u16 i; for (i = palsize; i < 0x0100; i++) { static u8 rgb[3] VAR16; - vgahw_set_dac_regs(get_global_seg(), rgb, i, 1); + stdvga_set_dac_regs(get_global_seg(), rgb, i, 1); }
if ((modeset_ctl & 0x02) == 0x02) perform_gray_scale_summing(0x00, 0x100); }
- vgahw_set_mode(vmode_g); + stdvga_set_mode(vmode_g);
if (noclearmem == 0x00) clear_screen(vmode_g); @@ -593,13 +593,13 @@ handle_100a(struct bregs *regs) static void handle_100b00(struct bregs *regs) { - vgahw_set_border_color(regs->bl); + stdvga_set_border_color(regs->bl); }
static void handle_100b01(struct bregs *regs) { - vgahw_set_palette(regs->bl); + stdvga_set_palette(regs->bl); }
static void @@ -658,25 +658,25 @@ handle_101000(struct bregs *regs) { if (regs->bl > 0x14) return; - vgahw_set_single_palette_reg(regs->bl, regs->bh); + stdvga_set_single_palette_reg(regs->bl, regs->bh); }
static void handle_101001(struct bregs *regs) { - vgahw_set_overscan_border_color(regs->bh); + stdvga_set_overscan_border_color(regs->bh); }
static void handle_101002(struct bregs *regs) { - vgahw_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); + stdvga_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); }
static void handle_101003(struct bregs *regs) { - vgahw_toggle_intensity(regs->bl); + stdvga_toggle_intensity(regs->bl); }
static void @@ -684,45 +684,45 @@ handle_101007(struct bregs *regs) { if (regs->bl > 0x14) return; - regs->bh = vgahw_get_single_palette_reg(regs->bl); + regs->bh = stdvga_get_single_palette_reg(regs->bl); }
static void handle_101008(struct bregs *regs) { - regs->bh = vgahw_get_overscan_border_color(); + regs->bh = stdvga_get_overscan_border_color(); }
static void handle_101009(struct bregs *regs) { - vgahw_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); + stdvga_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); }
static void noinline handle_101010(struct bregs *regs) { u8 rgb[3] = {regs->dh, regs->ch, regs->cl}; - vgahw_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); + stdvga_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); }
static void handle_101012(struct bregs *regs) { - vgahw_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); + stdvga_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); }
static void handle_101013(struct bregs *regs) { - vgahw_select_video_dac_color_page(regs->bl, regs->bh); + stdvga_select_video_dac_color_page(regs->bl, regs->bh); }
static void noinline handle_101015(struct bregs *regs) { u8 rgb[3]; - vgahw_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); + stdvga_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); regs->dh = rgb[0]; regs->ch = rgb[1]; regs->cl = rgb[2]; @@ -731,25 +731,25 @@ handle_101015(struct bregs *regs) static void handle_101017(struct bregs *regs) { - vgahw_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); + stdvga_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); }
static void handle_101018(struct bregs *regs) { - vgahw_set_pel_mask(regs->bl); + stdvga_set_pel_mask(regs->bl); }
static void handle_101019(struct bregs *regs) { - regs->bl = vgahw_get_pel_mask(); + regs->bl = stdvga_get_pel_mask(); }
static void handle_10101a(struct bregs *regs) { - vgahw_read_video_dac_state(®s->bl, ®s->bh); + stdvga_read_video_dac_state(®s->bl, ®s->bh); }
static void @@ -811,7 +811,7 @@ handle_101102(struct bregs *regs) static void handle_101103(struct bregs *regs) { - vgahw_set_text_block_specifier(regs->bl); + stdvga_set_text_block_specifier(regs->bl); }
static void @@ -978,7 +978,7 @@ handle_101231(struct bregs *regs) static void handle_101232(struct bregs *regs) { - vgahw_enable_video_addressing(regs->al); + stdvga_enable_video_addressing(regs->al); regs->al = 0x12; }
@@ -1157,7 +1157,7 @@ handle_101c01(struct bregs *regs) u16 seg = regs->es; void *data = (void*)(regs->bx+0); if (flags & 1) { - vgahw_save_state(seg, data); + stdvga_save_state(seg, data); data += sizeof(struct saveVideoHardware); } if (flags & 2) { @@ -1165,7 +1165,7 @@ handle_101c01(struct bregs *regs) data += sizeof(struct saveBDAstate); } if (flags & 4) - vgahw_save_dac_state(seg, data); + stdvga_save_dac_state(seg, data); regs->al = 0x1c; }
@@ -1176,7 +1176,7 @@ handle_101c02(struct bregs *regs) u16 seg = regs->es; void *data = (void*)(regs->bx+0); if (flags & 1) { - vgahw_restore_state(seg, data); + stdvga_restore_state(seg, data); data += sizeof(struct saveVideoHardware); } if (flags & 2) { @@ -1184,7 +1184,7 @@ handle_101c02(struct bregs *regs) data += sizeof(struct saveBDAstate); } if (flags & 4) - vgahw_restore_dac_state(seg, data); + stdvga_restore_dac_state(seg, data); regs->al = 0x1c; }
@@ -1281,7 +1281,7 @@ vga_post(struct bregs *regs) { debug_enter(regs, DEBUG_VGA_POST);
- vgahw_init(); + stdvga_init();
if (CONFIG_VGA_GEODELX) geodelx_init(); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 3838303..c9a257a 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -8,7 +8,7 @@ #include "biosvar.h" // GET_BDA #include "util.h" // memset_far #include "vgabios.h" // find_vga_entry -#include "stdvga.h" // vgahw_grdc_write +#include "stdvga.h" // stdvga_grdc_write
/**************************************************************** @@ -57,15 +57,15 @@ scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr int cols = lr.x - ul.x + 1; int rows = lr.y - ul.y + 1; if (nblines < rows) { - vgahw_grdc_write(0x05, 0x01); + stdvga_grdc_write(0x05, 0x01); dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols, stride , (rows - nblines) * cheight); } if (attr < 0) attr = 0; - vgahw_grdc_write(0x05, 0x02); + stdvga_grdc_write(0x05, 0x02); memset_stride(SEG_GRAPH, dest_far, attr, cols, stride, nblines * cheight); - vgahw_grdc_write(0x05, 0x00); + stdvga_grdc_write(0x05, 0x00); }
static void @@ -203,19 +203,19 @@ write_gfx_char_pl4(struct vgamode_s *vmode_g } u16 addr = cp.x + cp.y * cheight * nbcols; u16 src = ca.car * cheight; - vgahw_sequ_write(0x02, 0x0f); - vgahw_grdc_write(0x05, 0x02); + stdvga_sequ_write(0x02, 0x0f); + stdvga_grdc_write(0x05, 0x02); if (ca.attr & 0x80) - vgahw_grdc_write(0x03, 0x18); + stdvga_grdc_write(0x03, 0x18); else - vgahw_grdc_write(0x03, 0x00); + stdvga_grdc_write(0x03, 0x00); u8 i; for (i = 0; i < cheight; i++) { u8 *dest_far = (void*)(addr + i * nbcols); u8 j; for (j = 0; j < 8; j++) { u8 mask = 0x80 >> j; - vgahw_grdc_write(0x08, mask); + stdvga_grdc_write(0x08, mask); GET_FARVAR(SEG_GRAPH, *dest_far); if (GET_GLOBAL(fdata_g[src + i]) & mask) SET_FARVAR(SEG_GRAPH, *dest_far, ca.attr & 0x0f); @@ -223,9 +223,9 @@ write_gfx_char_pl4(struct vgamode_s *vmode_g SET_FARVAR(SEG_GRAPH, *dest_far, 0x00); } } - vgahw_grdc_write(0x08, 0xff); - vgahw_grdc_write(0x05, 0x00); - vgahw_grdc_write(0x03, 0x00); + stdvga_grdc_write(0x08, 0xff); + stdvga_grdc_write(0x05, 0x00); + stdvga_grdc_write(0x03, 0x00); }
static void @@ -408,15 +408,15 @@ vgafb_write_pixel(u8 color, u16 x, u16 y) case PLANAR1: addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); mask = 0x80 >> (x & 0x07); - vgahw_grdc_write(0x08, mask); - vgahw_grdc_write(0x05, 0x02); + stdvga_grdc_write(0x08, mask); + stdvga_grdc_write(0x05, 0x02); data = GET_FARVAR(SEG_GRAPH, *addr_far); if (color & 0x80) - vgahw_grdc_write(0x03, 0x18); + stdvga_grdc_write(0x03, 0x18); SET_FARVAR(SEG_GRAPH, *addr_far, color); - vgahw_grdc_write(0x08, 0xff); - vgahw_grdc_write(0x05, 0x00); - vgahw_grdc_write(0x03, 0x00); + stdvga_grdc_write(0x08, 0xff); + stdvga_grdc_write(0x05, 0x00); + stdvga_grdc_write(0x03, 0x00); break; case CGA: if (GET_GLOBAL(vmode_g->pixbits) == 2) @@ -466,7 +466,7 @@ vgafb_read_pixel(u16 x, u16 y) mask = 0x80 >> (x & 0x07); attr = 0x00; for (i = 0; i < 4; i++) { - vgahw_grdc_write(0x04, i); + stdvga_grdc_write(0x04, i); data = GET_FARVAR(SEG_GRAPH, *addr_far) & mask; if (data > 0) attr |= (0x01 << i);
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/stdvga.c | 24 ++++++++++++++++++++++-- vgasrc/stdvga.h | 4 ++-- vgasrc/vgabios.c | 20 ++++++++++---------- vgasrc/vgabios.h | 2 -- vgasrc/vgafb.c | 19 ------------------- 5 files changed, 34 insertions(+), 35 deletions(-)
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index fd8514e..9b91559 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -10,6 +10,7 @@ #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_BDA #include "vgabios.h" // VGAREG_* +#include "util.h" // memcpy_far
// TODO // * replace direct in/out calls with wrapper functions @@ -288,7 +289,12 @@ stdvga_set_text_block_specifier(u8 spec) outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS); }
-void + +/**************************************************************** + * Font loading + ****************************************************************/ + +static void get_font_access(void) { outw(0x0100, VGAREG_SEQU_ADDRESS); @@ -300,7 +306,7 @@ get_font_access(void) outw(0x0406, VGAREG_GRDC_ADDRESS); }
-void +static void release_font_access(void) { outw(0x0100, VGAREG_SEQU_ADDRESS); @@ -313,6 +319,20 @@ release_font_access(void) outw(0x1005, VGAREG_GRDC_ADDRESS); }
+void +stdvga_load_font(u16 seg, void *src_far, u16 count + , u16 start, u8 destflags, u8 fontsize) +{ + get_font_access(); + u16 blockaddr = ((destflags & 0x03) << 14) + ((destflags & 0x04) << 11); + void *dest_far = (void*)(blockaddr + start*32); + u16 i; + for (i = 0; i < count; i++) + memcpy_far(SEG_GRAPH, dest_far + i*32 + , seg, src_far + i*fontsize, fontsize); + release_font_access(); +} +
/**************************************************************** * CRTC registers diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 7fa612e..0d5f59b 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -127,8 +127,8 @@ void stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info); void stdvga_sequ_write(u8 index, u8 value); void stdvga_grdc_write(u8 index, u8 value); void stdvga_set_text_block_specifier(u8 spec); -void get_font_access(void); -void release_font_access(void); +void stdvga_load_font(u16 seg, void *src_far, u16 count + , u16 start, u8 destflags, u8 fontsize); void stdvga_set_cursor_shape(u8 start, u8 end); void stdvga_set_active_page(u16 address); void stdvga_set_cursor_pos(u16 address); diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 5f646cd..5083292 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -792,20 +792,20 @@ handle_1010(struct bregs *regs) static void handle_101100(struct bregs *regs) { - vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx - , regs->dx, regs->bl, regs->bh); + stdvga_load_font(regs->es, (void*)(regs->bp+0), regs->cx + , regs->dx, regs->bl, regs->bh); }
static void handle_101101(struct bregs *regs) { - vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); + stdvga_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); }
static void handle_101102(struct bregs *regs) { - vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); + stdvga_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); }
static void @@ -817,35 +817,35 @@ handle_101103(struct bregs *regs) static void handle_101104(struct bregs *regs) { - vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); + stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); }
static void handle_101110(struct bregs *regs) { - vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx - , regs->dx, regs->bl, regs->bh); + stdvga_load_font(regs->es, (void*)(regs->bp+0), regs->cx + , regs->dx, regs->bl, regs->bh); set_scan_lines(regs->bh); }
static void handle_101111(struct bregs *regs) { - vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); + stdvga_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); set_scan_lines(14); }
static void handle_101112(struct bregs *regs) { - vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); + stdvga_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); set_scan_lines(8); }
static void handle_101114(struct bregs *regs) { - vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); + stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); set_scan_lines(16); }
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 5cf1f04..d31161e 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -58,8 +58,6 @@ void vgafb_write_char(struct cursorpos cp, struct carattr ca); struct carattr vgafb_read_char(struct cursorpos cp); void vgafb_write_pixel(u8 color, u16 x, u16 y); u8 vgafb_read_pixel(u16 x, u16 y); -void vgafb_load_font(u16 seg, void *src_far, u16 count - , u16 start, u8 destflags, u8 fontsize);
// clext.c int cirrus_set_video_mode(u8 mode, u8 noclearmem); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index c9a257a..19ab1df 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -489,22 +489,3 @@ vgafb_read_pixel(u16 x, u16 y) } return attr; } - - -/**************************************************************** - * Font loading - ****************************************************************/ - -void -vgafb_load_font(u16 seg, void *src_far, u16 count - , u16 start, u8 destflags, u8 fontsize) -{ - get_font_access(); - u16 blockaddr = ((destflags & 0x03) << 14) + ((destflags & 0x04) << 11); - void *dest_far = (void*)(blockaddr + start*32); - u16 i; - for (i = 0; i < count; i++) - memcpy_far(SEG_GRAPH, dest_far + i*32 - , seg, src_far + i*fontsize, fontsize); - release_font_access(); -}
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/stdvga.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index 9b91559..8622d0c 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -313,7 +313,7 @@ release_font_access(void) outw(0x0302, VGAREG_SEQU_ADDRESS); outw(0x0304, VGAREG_SEQU_ADDRESS); outw(0x0300, VGAREG_SEQU_ADDRESS); - u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; + u16 v = (inb(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS); outw(0x0004, VGAREG_GRDC_ADDRESS); outw(0x1005, VGAREG_GRDC_ADDRESS);
The low level VGA code shouldn't depend on the crtc address stored in the BDA - it can find the address on its own.
The cirrus_get_crtc() function is the same - replace it with stdvga_get_crtc().
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 22 +++++++--------------- vgasrc/stdvga.c | 23 ++++++++++++----------- vgasrc/stdvga.h | 1 + 3 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 7987d28..7774ba3 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -327,14 +327,6 @@ cirrus_switch_mode_setregs(u16 *data, u16 port) } }
-static u16 -cirrus_get_crtc(void) -{ - if (inb(VGAREG_READ_MISC_OUTPUT) & 1) - return VGAREG_VGA_CRTC_ADDRESS; - return VGAREG_MDA_CRTC_ADDRESS; -} - static void cirrus_switch_mode(struct cirrus_mode_s *table) { @@ -342,7 +334,7 @@ cirrus_switch_mode(struct cirrus_mode_s *table) outw(0x1206, VGAREG_SEQU_ADDRESS); cirrus_switch_mode_setregs(GET_GLOBAL(table->seq), VGAREG_SEQU_ADDRESS); cirrus_switch_mode_setregs(GET_GLOBAL(table->graph), VGAREG_GRDC_ADDRESS); - cirrus_switch_mode_setregs(GET_GLOBAL(table->crtc), cirrus_get_crtc()); + cirrus_switch_mode_setregs(GET_GLOBAL(table->crtc), stdvga_get_crtc());
outb(0x00, VGAREG_PEL_MASK); inb(VGAREG_PEL_MASK); @@ -433,7 +425,7 @@ cirrus_check(void) static void cirrus_extbios_80h(struct bregs *regs) { - u16 crtc_addr = cirrus_get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x27, crtc_addr); u8 v = inb(crtc_addr + 1); if (v == 0xa0) @@ -458,7 +450,7 @@ cirrus_extbios_81h(struct bregs *regs) static void cirrus_extbios_82h(struct bregs *regs) { - u16 crtc_addr = cirrus_get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x27, crtc_addr); regs->al = inb(crtc_addr + 1) & 0x03; regs->ah = 0xAF; @@ -596,7 +588,7 @@ cirrus_get_bpp_bytes(void) static void cirrus_set_line_offset(u16 new_line_offset) { - u16 crtc_addr = cirrus_get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x13, crtc_addr); outb(new_line_offset / 8, crtc_addr + 1);
@@ -608,7 +600,7 @@ cirrus_set_line_offset(u16 new_line_offset) static u16 cirrus_get_line_offset(void) { - u16 crtc_addr = cirrus_get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x13, crtc_addr); u8 reg13 = inb(crtc_addr + 1); outb(0x1b, crtc_addr); @@ -648,7 +640,7 @@ cirrus_get_line_offset_entry(struct cirrus_mode_s *table_g) static void cirrus_set_start_addr(u32 addr) { - u16 crtc_addr = cirrus_get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x0d, crtc_addr); outb(addr, crtc_addr + 1);
@@ -668,7 +660,7 @@ cirrus_set_start_addr(u32 addr) static u32 cirrus_get_start_addr(void) { - u16 crtc_addr = cirrus_get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x0c, crtc_addr); u8 b2 = inb(crtc_addr + 1);
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index 8622d0c..f40c172 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -8,8 +8,7 @@ #include "stdvga.h" // stdvga_init #include "ioport.h" // outb #include "farptr.h" // SET_FARVAR -#include "biosvar.h" // GET_BDA -#include "vgabios.h" // VGAREG_* +#include "biosvar.h" // GET_GLOBAL #include "util.h" // memcpy_far
// TODO @@ -338,16 +337,18 @@ stdvga_load_font(u16 seg, void *src_far, u16 count * CRTC registers ****************************************************************/
-static u16 -get_crtc(void) +u16 +stdvga_get_crtc(void) { - return GET_BDA(crtc_address); + if (inb(VGAREG_READ_MISC_OUTPUT) & 1) + return VGAREG_VGA_CRTC_ADDRESS; + return VGAREG_MDA_CRTC_ADDRESS; }
void stdvga_set_cursor_shape(u8 start, u8 end) { - u16 crtc_addr = get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x0a, crtc_addr); outb(start, crtc_addr + 1); outb(0x0b, crtc_addr); @@ -357,7 +358,7 @@ stdvga_set_cursor_shape(u8 start, u8 end) void stdvga_set_active_page(u16 address) { - u16 crtc_addr = get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x0c, crtc_addr); outb((address & 0xff00) >> 8, crtc_addr + 1); outb(0x0d, crtc_addr); @@ -367,7 +368,7 @@ stdvga_set_active_page(u16 address) void stdvga_set_cursor_pos(u16 address) { - u16 crtc_addr = get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x0e, crtc_addr); outb((address & 0xff00) >> 8, crtc_addr + 1); outb(0x0f, crtc_addr); @@ -377,7 +378,7 @@ stdvga_set_cursor_pos(u16 address) void stdvga_set_scan_lines(u8 lines) { - u16 crtc_addr = get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x09, crtc_addr); u8 crtc_r9 = inb(crtc_addr + 1); crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); @@ -388,7 +389,7 @@ stdvga_set_scan_lines(u8 lines) u16 stdvga_get_vde(void) { - u16 crtc_addr = get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); outb(0x12, crtc_addr); u16 vde = inb(crtc_addr + 1); outb(0x07, crtc_addr); @@ -405,7 +406,7 @@ stdvga_get_vde(void) void stdvga_save_state(u16 seg, struct saveVideoHardware *info) { - u16 crtc_addr = get_crtc(); + u16 crtc_addr = stdvga_get_crtc(); SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS)); SET_FARVAR(seg, info->crtc_index, inb(crtc_addr)); SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS)); diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 0d5f59b..fb98304 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -129,6 +129,7 @@ void stdvga_grdc_write(u8 index, u8 value); void stdvga_set_text_block_specifier(u8 spec); void stdvga_load_font(u16 seg, void *src_far, u16 count , u16 start, u8 destflags, u8 fontsize); +u16 stdvga_get_crtc(void); void stdvga_set_cursor_shape(u8 start, u8 end); void stdvga_set_active_page(u16 address); void stdvga_set_cursor_pos(u16 address);
Don't call int10 to load the fonts - instead call the font loading functions directly.
Theoretically, this could change behavior if an external program has captured int10 and redirects the font loading calls. However, there does not seem to be any indication that an external app could expect that to work.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgabios.c | 16 ++-------------- 1 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 5083292..4724c4b 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -46,18 +46,6 @@ struct pci_data rom_pci_data VAR16VISIBLE = { * Helper functions ****************************************************************/
-static inline void -call16_vgaint(u32 eax, u32 ebx) -{ - asm volatile( - "int $0x10\n" - "cli\n" - "cld" - : - : "a"(eax), "b"(ebx) - : "cc", "memory"); -} - static void perform_gray_scale_summing(u16 start, u16 count) { @@ -440,8 +428,8 @@ vga_set_mode(u8 mode, u8 noclearmem)
// Write the fonts in memory if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { - call16_vgaint(0x1104, 0); - call16_vgaint(0x1103, 0); + stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16); + stdvga_set_text_block_specifier(0); } // Set the ints 0x1F and 0x43 SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
The calls to set_cursor_shape, set_cursor_pos, and set_active_page have no impact other than to set the BDA variables, because the standard vga mode switch already programed the registers these functions set. So, just setup the BDA directly.
The stdvga_set_text_block_specifier call is unnecessary - it sets a register which is already programmed that way.
Call stdvga_get_crtc() to obtain the crtc address instead of inferring it from the memory model.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgabios.c | 34 +++++++++++----------------------- 1 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 4724c4b..cb8793e 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -387,22 +387,28 @@ vga_set_mode(u8 mode, u8 noclearmem) if (noclearmem == 0x00) clear_screen(vmode_g);
- // Set CRTC address VGA or MDA - u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; - if (GET_GLOBAL(vmode_g->memmodel) == MTEXT) - crtc_addr = VGAREG_MDA_CRTC_ADDRESS; + // 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); SET_BDA(video_cols, GET_GLOBAL(vmode_g->twidth)); SET_BDA(video_pagesize, GET_GLOBAL(vmode_g->slength)); - SET_BDA(crtc_address, crtc_addr); + 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_switches, 0xF9); SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); + SET_BDA(cursor_type, memmodel & TEXT ? 0x0607 : 0x0000); + int i; + for (i=0; i<8; i++) + SET_BDA(cursor_pos[i], 0x0000); + SET_BDA(video_pagestart, 0x0000); + SET_BDA(video_page, 0x00);
// FIXME We nearly have the good tables. to be reworked SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now @@ -413,24 +419,6 @@ vga_set_mode(u8 mode, u8 noclearmem) SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but... SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
- // Set cursor shape - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - set_cursor_shape(0x06, 0x07); - // Set cursor pos for page 0..7 - int i; - for (i = 0; i < 8; i++) { - struct cursorpos cp = {0, 0, i}; - set_cursor_pos(cp); - } - - // Set active page 0 - set_active_page(0x00); - - // Write the fonts in memory - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { - stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16); - stdvga_set_text_block_specifier(0); - } // Set the ints 0x1F and 0x43 SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
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 kevin@koconnor.net --- 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
@@ -47,25 +47,6 @@ struct pci_data rom_pci_data VAR16VISIBLE = { ****************************************************************/
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) { start &= 0x3f; @@ -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
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 7 ++++--- vgasrc/clext.h | 9 +++++++++ vgasrc/vgabios.c | 5 +++-- vgasrc/vgabios.h | 4 ---- 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 vgasrc/clext.h
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 7774ba3..7071749 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -5,7 +5,8 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "vgabios.h" // cirrus_init +#include "clext.h" // clext_init +#include "vgabios.h" // VBE_VENDOR_STRING #include "biosvar.h" // GET_GLOBAL #include "util.h" // dprintf #include "bregs.h" // struct bregs @@ -392,7 +393,7 @@ cirrus_clear_vram(u16 param) }
int -cirrus_set_video_mode(u8 mode, u8 noclearmem) +clext_set_video_mode(u8 mode, u8 noclearmem) { dprintf(1, "cirrus mode %d\n", mode); SET_BDA(vbe_mode, 0); @@ -932,7 +933,7 @@ cirrus_vesa(struct bregs *regs) ****************************************************************/
void -cirrus_init(void) +clext_init(void) { dprintf(1, "cirrus init\n"); if (! cirrus_check()) diff --git a/vgasrc/clext.h b/vgasrc/clext.h new file mode 100644 index 0000000..7d486a3 --- /dev/null +++ b/vgasrc/clext.h @@ -0,0 +1,9 @@ +#ifndef __CLEXT_H +#define __CLEXT_H + +#include "types.h" // u8 + +int clext_set_video_mode(u8 mode, u8 noclearmem); +void clext_init(void); + +#endif // clext.h diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index d7c559a..203a394 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -20,6 +20,7 @@ #include "stdvga.h" // stdvga_set_mode #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init +#include "clext.h" // clext_init
// XXX #define DEBUG_VGA_POST 1 @@ -389,7 +390,7 @@ handle_1000(struct bregs *regs) regs->al = 0x30;
if (CONFIG_VGA_CIRRUS) { - int ret = cirrus_set_video_mode(mode, noclearmem); + int ret = clext_set_video_mode(mode, noclearmem); if (ret) return; } @@ -1213,7 +1214,7 @@ vga_post(struct bregs *regs) SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
if (CONFIG_VGA_CIRRUS) - cirrus_init(); + clext_init();
// XXX - clear screen and display info
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 0371f8c..c973d5f 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -65,10 +65,6 @@ struct carattr vgafb_read_char(struct cursorpos cp); void vgafb_write_pixel(u8 color, u16 x, u16 y); u8 vgafb_read_pixel(u16 x, u16 y);
-// clext.c -int cirrus_set_video_mode(u8 mode, u8 noclearmem); -void cirrus_init(void); - // vbe.c #define VBE_OEM_STRING "SeaBIOS VBE(C) 2011" #define VBE_VENDOR_STRING "SeaBIOS Developers"
Use the same function signature for cirrus, bochsvga, and stdvga set_mode code.
Make both the int1000 interface and the VBE 104f02 interface use the same set_mode function.
Where clext and bochsvga need to fallback to the standard vga mode switching, have them call vgastd_mode_switch directly.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 35 ++++++++++++++++++++++++++++++----- vgasrc/bochsvga.h | 2 +- vgasrc/clext.c | 8 ++++---- vgasrc/clext.h | 2 +- vgasrc/stdvga.c | 7 +++++-- vgasrc/stdvga.h | 2 +- vgasrc/vbe.c | 42 ++++++++---------------------------------- vgasrc/vgabios.c | 17 ++++------------- vgasrc/vgahw.h | 19 +++++++++++++++++++ 9 files changed, 73 insertions(+), 61 deletions(-) create mode 100644 vgasrc/vgahw.h
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 4ba6611..c64919f 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -1,7 +1,7 @@ #include "vgabios.h" // struct vbe_modeinfo -#include "vbe.h" -#include "bochsvga.h" -#include "util.h" +#include "vbe.h" // VBE_MODE_VESA_DEFINED +#include "bochsvga.h" // bochsvga_set_mode +#include "util.h" // dprintf #include "config.h" // CONFIG_* #include "biosvar.h" // SET_BDA #include "stdvga.h" // VGAREG_SEQU_ADDRESS @@ -259,9 +259,24 @@ bochsvga_hires_enable(int enable) dispi_write(VBE_DISPI_INDEX_ENABLE, flags); }
-void -bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info) +int +bochsvga_set_mode(int mode, int flags) { + if (!(mode & VBE_MODE_VESA_DEFINED)) { + dprintf(1, "set VGA mode %x\n", mode); + + bochsvga_hires_enable(0); + return stdvga_set_mode(mode, flags); + } + + struct vbe_modeinfo modeinfo, *info = &modeinfo; + int ret = bochsvga_mode_info(mode, &modeinfo); + if (ret) { + dprintf(1, "VBE mode %x not found\n", mode); + return VBE_RETURN_STATUS_FAILED; + } + bochsvga_hires_enable(1); + if (info->depth == 4) stdvga_set_mode(0x6a, 0); if (info->depth == 8) @@ -315,6 +330,16 @@ bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info) }
SET_BDA(vbe_mode, mode); + + if (flags & MF_LINEARFB) { + /* Linear frame buffer */ + /* XXX: ??? */ + } + if (!(mode & MF_NOCLEARMEM)) { + bochsvga_clear_scr(); + } + + return 0; }
void diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index f0263d7..af60503 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -59,7 +59,7 @@ int bochsvga_list_modes(u16 seg, u16 ptr); struct vbe_modeinfo; int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info); void bochsvga_hires_enable(int enable); -void bochsvga_set_mode(u16 mode, struct vbe_modeinfo *info); +int bochsvga_set_mode(int mode, int flags); void bochsvga_clear_scr(void); int bochsvga_hires_enabled(void); u16 bochsvga_curr_mode(void); diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 7071749..f468002 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -393,22 +393,22 @@ cirrus_clear_vram(u16 param) }
int -clext_set_video_mode(u8 mode, u8 noclearmem) +clext_set_mode(int mode, int flags) { dprintf(1, "cirrus mode %d\n", mode); SET_BDA(vbe_mode, 0); struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); if (table_g) { cirrus_switch_mode(table_g); - if (!noclearmem) + if (!(flags & MF_NOCLEARMEM)) cirrus_clear_vram(0xffff); SET_BDA(video_mode, mode); - return 1; + return 0; } table_g = cirrus_get_modeentry(0xfe); cirrus_switch_mode(table_g); dprintf(1, "cirrus mode switch regular\n"); - return 0; + return stdvga_set_mode(mode, flags); }
static int diff --git a/vgasrc/clext.h b/vgasrc/clext.h index 7d486a3..537cbea 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -3,7 +3,7 @@
#include "types.h" // u8
-int clext_set_video_mode(u8 mode, u8 noclearmem); +int clext_set_mode(int mode, int flags); void clext_init(void);
#endif // clext.h diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index b756f59..e55f8fa 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 #include "vgabios.h" // find_vga_entry
// TODO @@ -540,14 +541,14 @@ clear_screen(struct vgamode_s *vmode_g) } }
-void +int 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; + return VBE_RETURN_STATUS_FAILED;
// if palette loading (bit 3 of modeset ctl = 0) if (!(flags & MF_NOPALETTE)) { // Set the PEL mask @@ -631,6 +632,8 @@ stdvga_set_mode(int mode, int flags)
// Setup BDA variables modeswitch_set_bda(mode, flags, vmode_g); + + return 0; }
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index ac5dea4..c260ae0 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -136,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(int mode, int flags); +int 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 df95148..8256cae 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -11,8 +11,8 @@ #include "vbe.h" // struct vbe_info #include "util.h" // dprintf #include "biosvar.h" // get_global_set -#include "bochsvga.h" // bochsvga_set_mode -#include "stdvga.h" // stdvga_set_mode +#include "bochsvga.h" // bochsvga_hires_enabled +#include "vgahw.h" // vgahw_set_mode
static void vbe_104f00(struct bregs *regs) @@ -178,40 +178,14 @@ vbe_104f01(struct bregs *regs) static void vbe_104f02(struct bregs *regs) { - //u16 seg = regs->es; - //struct vbe_crtc_info *crtc_info = (void*)(regs->di+0); - u16 mode = regs->bx; - struct vbe_modeinfo modeinfo; - int rc; + dprintf(1, "VBE mode set: %x\n", regs->bx);
- dprintf(1, "VBE mode set: %x\n", mode); - - if (mode < 0x100) { /* VGA */ - dprintf(1, "set VGA mode %x\n", mode); - - bochsvga_hires_enable(0); - stdvga_set_mode(mode, 0); - } else { /* VBE */ - rc = bochsvga_mode_info(mode & 0x1ff, &modeinfo); - if (rc) { - dprintf(1, "VBE mode %x not found\n", mode & 0x1ff); - regs->ax = 0x100; - return; - } - bochsvga_hires_enable(1); - bochsvga_set_mode(mode & 0x1ff, &modeinfo); - - if (mode & 0x4000) { - /* Linear frame buffer */ - /* XXX: ??? */ - } - if (!(mode & 0x8000)) { - bochsvga_clear_scr(); - } - } + int mode = regs->bx & 0x1ff; + int flags = regs->bx & (MF_CUSTOMCRTC|MF_LINEARFB|MF_NOCLEARMEM); + int ret = vgahw_set_mode(mode, flags);
- regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ + regs->ah = ret; + regs->al = 0x4f; }
static void diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 203a394..9e8863a 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -21,6 +21,7 @@ #include "geodelx.h" // geodelx_init #include "bochsvga.h" // bochsvga_init #include "clext.h" // clext_init +#include "vgahw.h" // vgahw_set_mode
// XXX #define DEBUG_VGA_POST 1 @@ -378,8 +379,7 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) static void handle_1000(struct bregs *regs) { - u8 noclearmem = regs->al & 0x80; - u8 mode = regs->al & 0x7f; + int mode = regs->al & 0x7f;
// Set regs->al if (mode > 7) @@ -389,20 +389,11 @@ handle_1000(struct bregs *regs) else regs->al = 0x30;
- if (CONFIG_VGA_CIRRUS) { - int ret = clext_set_video_mode(mode, noclearmem); - if (ret) - return; - } - - if (bochsvga_enabled()) - bochsvga_hires_enable(0); - int flags = GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM); - if (noclearmem) + if (regs->al & 0x80) flags |= MF_NOCLEARMEM;
- stdvga_set_mode(mode, flags); + vgahw_set_mode(mode, flags); }
static void diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h new file mode 100644 index 0000000..57e41c3 --- /dev/null +++ b/vgasrc/vgahw.h @@ -0,0 +1,19 @@ +#ifndef __VGAHW_H +#define __VGAHW_H + +#include "types.h" // u8 +#include "config.h" // CONFIG_* + +#include "clext.h" // clext_set_mode +#include "bochsvga.h" // bochsvga_set_mode +#include "stdvga.h" // stdvga_set_mode + +static inline int vgahw_set_mode(int mode, int flags) { + if (CONFIG_VGA_CIRRUS) + return clext_set_mode(mode, flags); + if (CONFIG_VGA_BOCHS) + return bochsvga_set_mode(mode, flags); + return stdvga_set_mode(mode, flags); +} + +#endif // vgahw.h
Use the same function signature for cirrus, bochsvga, geodelx, and stdvga init code.
Have each hardware type explicitly call stdvga_init when needed.
To unify bochsvga_init() signature, store the device BDF passed into the optionrom init code in a global variable (VgaBDF).
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 15 +++++++-------- vgasrc/bochsvga.h | 2 +- vgasrc/clext.c | 10 ++++++++-- vgasrc/clext.h | 2 +- vgasrc/geodelx.c | 9 ++++----- vgasrc/stdvga.c | 4 +++- vgasrc/stdvga.h | 2 +- vgasrc/vgabios.c | 18 +++++++++--------- vgasrc/vgabios.h | 1 + vgasrc/vgahw.h | 11 +++++++++++ 10 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index c64919f..70ac449 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -83,11 +83,10 @@ static struct mode
u32 pci_lfb_addr VAR16;
-static inline u32 pci_config_readl(u8 bus, u8 devfn, u16 addr) +static inline u32 pci_config_readl(u16 bdf, u16 addr) { int status; u32 val; - u16 bdf = (bus << 16) | devfn;
addr &= ~3;
@@ -136,12 +135,11 @@ static u16 dispi_get_max_bpp(void)
/* Called only during POST */ int -bochsvga_init(u8 bus, u8 devfn) +bochsvga_init(void) { - u32 lfb_addr; - - if (!CONFIG_VGA_BOCHS) - return -1; + int ret = stdvga_init(); + if (ret) + return ret;
/* Sanity checks */ dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID0); @@ -153,8 +151,9 @@ bochsvga_init(u8 bus, u8 devfn) SET_BDA(vbe_flag, 0x1); dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5);
+ u32 lfb_addr; if (CONFIG_VGA_PCI) - lfb_addr = pci_config_readl(bus, devfn, 0x10) & ~0xf; + lfb_addr = pci_config_readl(GET_GLOBAL(VgaBDF), 0x10) & ~0xf; else lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index af60503..32554d5 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -52,7 +52,7 @@ static inline void dispi_write(u16 reg, u16 val) outw(val, VBE_DISPI_IOPORT_DATA); }
-int bochsvga_init(u8 bus, u8 devfn); +int bochsvga_init(void); int bochsvga_enabled(void); u16 bochsvga_total_mem(void); int bochsvga_list_modes(u16 seg, u16 ptr); diff --git a/vgasrc/clext.c b/vgasrc/clext.c index f468002..afab582 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -932,12 +932,16 @@ cirrus_vesa(struct bregs *regs) * init ****************************************************************/
-void +int clext_init(void) { + int ret = stdvga_init(); + if (ret) + return ret; + dprintf(1, "cirrus init\n"); if (! cirrus_check()) - return; + return -1; dprintf(1, "cirrus init 2\n");
// memory setup @@ -949,4 +953,6 @@ clext_init(void) // reset bitblt outw(0x0431, VGAREG_GRDC_ADDRESS); outw(0x0031, VGAREG_GRDC_ADDRESS); + + return 0; } diff --git a/vgasrc/clext.h b/vgasrc/clext.h index 537cbea..6fd0a58 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -4,6 +4,6 @@ #include "types.h" // u8
int clext_set_mode(int mode, int flags); -void clext_init(void); +int clext_init(void);
#endif // clext.h diff --git a/vgasrc/geodelx.c b/vgasrc/geodelx.c index 4a5f873..8b03444 100644 --- a/vgasrc/geodelx.c +++ b/vgasrc/geodelx.c @@ -6,15 +6,12 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "geodelx.h" +#include "geodelx.h" // geodelx_init #include "ioport.h" // outb #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_BDA #include "vgabios.h" // VGAREG_* #include "util.h" // memset -#include "config.h" -#include "types.h" -#include "bregs.h" #include "stdvga.h" // VGAREG_VGA_CRTC_ADDRESS
@@ -342,7 +339,9 @@ static u8 lx_crtc_13[] VAR16 = {
int geodelx_init(void) { - int ret; + int ret = stdvga_init(); + if (ret) + return ret;
dprintf(1,"GEODELX_INIT\n");
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index e55f8fa..c7331e4 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -649,7 +649,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 @@ -657,4 +657,6 @@ stdvga_init(void) // more than 64k 3C4/04 outb(0x04, VGAREG_SEQU_ADDRESS); outb(0x02, VGAREG_SEQU_DATA); + + return 0; } diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index c260ae0..0685584 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -138,6 +138,6 @@ void stdvga_save_state(u16 seg, struct saveVideoHardware *info); void stdvga_restore_state(u16 seg, struct saveVideoHardware *info); int stdvga_set_mode(int mode, int flags); void stdvga_enable_video_addressing(u8 disable); -void stdvga_init(void); +int stdvga_init(void);
#endif // stdvga.h diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 9e8863a..7d558c1 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -1187,30 +1187,30 @@ init_bios_area(void) SET_BDA(video_msr, 0x09); }
+u16 VgaBDF VAR16; + void VISIBLE16 vga_post(struct bregs *regs) { debug_enter(regs, DEBUG_VGA_POST);
- stdvga_init(); + SET_VGA(VgaBDF, regs->ax);
- if (CONFIG_VGA_GEODELX) - geodelx_init(); + int ret = vgahw_init(); + if (ret) { + dprintf(1, "Failed to initialize VGA hardware. Exiting.\n"); + return; + }
init_bios_area();
- bochsvga_init(regs->ah, regs->al); + build_video_param();
extern void entry_10(void); SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
- if (CONFIG_VGA_CIRRUS) - clext_init(); - // XXX - clear screen and display info
- build_video_param(); - // Fixup checksum extern u8 _rom_header_size, _rom_header_checksum; SET_VGA(_rom_header_checksum, 0); diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index c973d5f..176f71c 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -48,6 +48,7 @@ extern u8 vgafont14alt[]; extern u8 vgafont16alt[];
// vgabios.c +extern u16 VgaBDF; #define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val)) struct carattr { u8 car, attr, use_attr; diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 57e41c3..d34b0e7 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -7,6 +7,7 @@ #include "clext.h" // clext_set_mode #include "bochsvga.h" // bochsvga_set_mode #include "stdvga.h" // stdvga_set_mode +#include "geodelx.h" // geodelx_init
static inline int vgahw_set_mode(int mode, int flags) { if (CONFIG_VGA_CIRRUS) @@ -16,4 +17,14 @@ static inline int vgahw_set_mode(int mode, int flags) { return stdvga_set_mode(mode, flags); }
+static inline int vgahw_init(void) { + if (CONFIG_VGA_CIRRUS) + return clext_init(); + if (CONFIG_VGA_BOCHS) + return bochsvga_init(); + if (CONFIG_VGA_GEODELX) + return geodelx_init(); + return stdvga_init(); +} + #endif // vgahw.h
Fix missing divide by 2 in CGA mode scroll. Consistently use cheight/2 for all uses.
Planar graphics character write has a read to video memory with a side effect - mark that as volatile so the compiler doesn't optimize it away.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgafb.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 38ed070..e2110cc 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -72,7 +72,7 @@ static void scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { - u8 cheight = GET_GLOBAL(vmode_g->cheight); + u8 cheight = GET_GLOBAL(vmode_g->cheight) / 2; u8 bpp = GET_GLOBAL(vmode_g->pixbits); int stride = GET_BDA(video_cols) * bpp; void *src_far, *dest_far; @@ -90,16 +90,16 @@ scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr int rows = lr.y - ul.y + 1; if (nblines < rows) { memcpy_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000, cols - , stride, (rows - nblines) * cheight / 2); + , stride, (rows - nblines) * cheight); dest_far = memcpy_stride(SEG_CTEXT, dest_far, src_far, cols - , stride, (rows - nblines) * cheight / 2); + , stride, (rows - nblines) * cheight); } if (attr < 0) attr = 0; memset_stride(SEG_CTEXT, dest_far + 0x2000, attr, cols - , stride, nblines * cheight / 2); + , stride, nblines * cheight); memset_stride(SEG_CTEXT, dest_far, attr, cols - , stride, nblines * cheight / 2); + , stride, nblines * cheight); }
static void @@ -198,7 +198,7 @@ write_gfx_char_pl4(struct vgamode_s *vmode_g for (j = 0; j < 8; j++) { u8 mask = 0x80 >> j; stdvga_grdc_write(0x08, mask); - GET_FARVAR(SEG_GRAPH, *dest_far); + GET_FARVAR(SEG_GRAPH, *(volatile u8*)dest_far); if (GET_GLOBAL(fdata_g[src + i]) & mask) SET_FARVAR(SEG_GRAPH, *dest_far, ca.attr & 0x0f); else @@ -392,7 +392,7 @@ vgafb_write_pixel(u8 color, u16 x, u16 y) mask = 0x80 >> (x & 0x07); stdvga_grdc_write(0x08, mask); stdvga_grdc_write(0x05, 0x02); - data = GET_FARVAR(SEG_GRAPH, *addr_far); + GET_FARVAR(SEG_GRAPH, *(volatile u8*)addr_far); if (color & 0x80) stdvga_grdc_write(0x03, 0x18); SET_FARVAR(SEG_GRAPH, *addr_far, color);
All three scroll function variants have the same format, but those that have an implicit character width or height of 1 have those multiplications omitted. Add those multiplications back in (the compiler will optimize them away) so all the variants look similar.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgafb.c | 57 ++++++++++++++++++++++++++++++------------------------- 1 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index e2110cc..2104b44 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -41,16 +41,17 @@ static void scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { - u8 cheight = GET_GLOBAL(vmode_g->cheight); - int stride = GET_BDA(video_cols); + int cheight = GET_GLOBAL(vmode_g->cheight); + int cwidth = 1; + int stride = GET_BDA(video_cols) * cwidth; void *src_far, *dest_far; if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x); + dest_far = (void*)(ul.y * cheight * stride + ul.x * cwidth); src_far = dest_far + nblines * cheight * stride; } else { // Scroll down nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x); + dest_far = (void*)(lr.y * cheight * stride + ul.x * cwidth); src_far = dest_far - nblines * cheight * stride; stride = -stride; } @@ -58,13 +59,14 @@ scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr int rows = lr.y - ul.y + 1; if (nblines < rows) { stdvga_grdc_write(0x05, 0x01); - dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols, stride - , (rows - nblines) * cheight); + dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols * cwidth + , stride, (rows - nblines) * cheight); } if (attr < 0) attr = 0; stdvga_grdc_write(0x05, 0x02); - memset_stride(SEG_GRAPH, dest_far, attr, cols, stride, nblines * cheight); + memset_stride(SEG_GRAPH, dest_far, attr, cols * cwidth + , stride, nblines * cheight); stdvga_grdc_write(0x05, 0x00); }
@@ -72,33 +74,33 @@ static void scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { - u8 cheight = GET_GLOBAL(vmode_g->cheight) / 2; - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - int stride = GET_BDA(video_cols) * bpp; + int cheight = GET_GLOBAL(vmode_g->cheight) / 2; + int cwidth = GET_GLOBAL(vmode_g->pixbits); + int stride = GET_BDA(video_cols) * cwidth; void *src_far, *dest_far; if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x * bpp); + dest_far = (void*)(ul.y * cheight * stride + ul.x * cwidth); src_far = dest_far + nblines * cheight * stride; } else { // Scroll down nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x * bpp); + dest_far = (void*)(lr.y * cheight * stride + ul.x * cwidth); src_far = dest_far - nblines * cheight * stride; stride = -stride; } - int cols = (lr.x - ul.x + 1) * bpp; + int cols = lr.x - ul.x + 1; int rows = lr.y - ul.y + 1; if (nblines < rows) { - memcpy_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000, cols + memcpy_stride(SEG_CTEXT, dest_far+0x2000, src_far+0x2000, cols * cwidth , stride, (rows - nblines) * cheight); - dest_far = memcpy_stride(SEG_CTEXT, dest_far, src_far, cols + dest_far = memcpy_stride(SEG_CTEXT, dest_far, src_far, cols * cwidth , stride, (rows - nblines) * cheight); } if (attr < 0) attr = 0; - memset_stride(SEG_CTEXT, dest_far + 0x2000, attr, cols + memset_stride(SEG_CTEXT, dest_far + 0x2000, attr, cols * cwidth , stride, nblines * cheight); - memset_stride(SEG_CTEXT, dest_far, attr, cols + memset_stride(SEG_CTEXT, dest_far, attr, cols * cwidth , stride, nblines * cheight); }
@@ -106,30 +108,33 @@ static void scroll_text(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { + int cheight = 1; + int cwidth = 2; u16 nbrows = GET_BDA(video_rows) + 1; u16 nbcols = GET_BDA(video_cols); + int stride = nbcols * cwidth; void *src_far, *dest_far = (void*)SCREEN_MEM_START(nbcols, nbrows, ul.page); - int stride = nbcols * 2; if (nblines >= 0) { - dest_far += ul.y * stride + ul.x * 2; - src_far = dest_far + nblines * stride; + dest_far += ul.y * cheight * stride + ul.x * cwidth; + src_far = dest_far + nblines * cheight * stride; } else { // Scroll down nblines = -nblines; - dest_far += lr.y * stride + ul.x * 2; - src_far = dest_far - nblines * stride; + dest_far += lr.y * cheight * stride + ul.x * cwidth; + src_far = dest_far - nblines * cheight * stride; stride = -stride; } - int cols = (lr.x - ul.x + 1) * 2; + int cols = lr.x - ul.x + 1; int rows = lr.y - ul.y + 1; u16 seg = GET_GLOBAL(vmode_g->sstart); if (nblines < rows) - dest_far = memcpy_stride(seg, dest_far, src_far, cols, stride - , (rows - nblines)); + dest_far = memcpy_stride(seg, dest_far, src_far, cols * cwidth + , stride, (rows - nblines) * cheight); if (attr < 0) attr = 0x07; attr = (attr << 8) | ' '; - memset16_stride(seg, dest_far, attr, cols, stride, nblines); + memset16_stride(seg, dest_far, attr, cols * cwidth + , stride, nblines * cheight); }
void
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgafb.c | 34 ++++++++++++++++++++++++++++++++-- 1 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 2104b44..85e4ab3 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -105,6 +105,35 @@ scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr }
static void +scroll_lin(struct vgamode_s *vmode_g, int nblines, int attr + , struct cursorpos ul, struct cursorpos lr) +{ + int cheight = 8; + int cwidth = 8; + int stride = GET_BDA(video_cols) * cwidth; + void *src_far, *dest_far; + if (nblines >= 0) { + dest_far = (void*)(ul.y * cheight * stride + ul.x * cwidth); + src_far = dest_far + nblines * cheight * stride; + } else { + // Scroll down + nblines = -nblines; + dest_far = (void*)(lr.y * cheight * stride + ul.x * cwidth); + src_far = dest_far - nblines * cheight * stride; + stride = -stride; + } + int cols = lr.x - ul.x + 1; + int rows = lr.y - ul.y + 1; + if (nblines < rows) + dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols * cwidth + , stride, (rows - nblines) * cheight); + if (attr < 0) + attr = 0; + memset_stride(SEG_GRAPH, dest_far, attr, cols * cwidth + , stride, nblines * cheight); +} + +static void scroll_text(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { @@ -158,8 +187,9 @@ vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr) case CGA: scroll_cga(vmode_g, nblines, attr, ul, lr); break; - default: - dprintf(1, "Scroll in graphics mode\n"); + case LINEAR8: + scroll_lin(vmode_g, nblines, attr, ul, lr); + break; } }