#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
+#include "vbe.h" // VBE_RETURN_STATUS_FAILED
// TODO
// * replace direct in/out calls with wrapper functions
* 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);
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
* 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);
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);
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);
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);
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);
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));
outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa);
}
-void
-stdvga_set_mode(struct vgamode_s *vmode_g)
+static void
+clear_screen(struct vgamode_s *vmode_g)
+{
+ switch (GET_GLOBAL(vmode_g->memmodel)) {
+ case MM_TEXT:
+ memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024);
+ break;
+ case MM_CGA:
+ memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024);
+ break;
+ default:
+ // XXX - old code gets/sets/restores sequ register 2 to 0xf -
+ // but it should always be 0xf anyway.
+ memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024);
+ }
+}
+
+int
+stdvga_set_mode(int mode, int flags)
{
+ // find the entry in the video modes
+ struct vgamode_s *vmode_g = stdvga_find_mode(mode);
+ dprintf(1, "mode search %02x found %p\n", mode, vmode_g);
+ if (!vmode_g)
+ return VBE_RETURN_STATUS_FAILED;
+ struct stdvga_mode_s *stdmode_g = container_of(
+ vmode_g, struct stdvga_mode_s, info);
+
+ // if palette loading (bit 3 of modeset ctl = 0)
+ if (!(flags & MF_NOPALETTE)) { // Set the PEL mask
+ stdvga_set_pel_mask(GET_GLOBAL(stdmode_g->pelmask));
+
+ // From which palette
+ u8 *palette_g = GET_GLOBAL(stdmode_g->dac);
+ u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3;
+
+ // Always 256*3 values
+ stdvga_set_dac_regs(get_global_seg(), palette_g, 0, palsize);
+ u16 i;
+ for (i = palsize; i < 0x0100; i++) {
+ static u8 rgb[3] VAR16;
+ stdvga_set_dac_regs(get_global_seg(), rgb, i, 1);
+ }
+
+ if (flags & MF_GRAYSUM)
+ stdvga_perform_gray_scale_summing(0x00, 0x100);
+ }
+
// Reset Attribute Ctl flip-flop
inb(VGAREG_ACTL_RESET);
// Set Attribute Ctl
- u8 *regs = GET_GLOBAL(vmode_g->actl_regs);
+ u8 *regs = GET_GLOBAL(stdmode_g->actl_regs);
u16 i;
for (i = 0; i <= 0x13; i++) {
outb(i, VGAREG_ACTL_ADDRESS);
// Set Sequencer Ctl
outb(0, VGAREG_SEQU_ADDRESS);
outb(0x03, VGAREG_SEQU_DATA);
- regs = GET_GLOBAL(vmode_g->sequ_regs);
+ regs = GET_GLOBAL(stdmode_g->sequ_regs);
for (i = 1; i <= 4; i++) {
outb(i, VGAREG_SEQU_ADDRESS);
outb(GET_GLOBAL(regs[i - 1]), VGAREG_SEQU_DATA);
}
// Set Grafx Ctl
- regs = GET_GLOBAL(vmode_g->grdc_regs);
+ regs = GET_GLOBAL(stdmode_g->grdc_regs);
for (i = 0; i <= 8; i++) {
outb(i, VGAREG_GRDC_ADDRESS);
outb(GET_GLOBAL(regs[i]), VGAREG_GRDC_DATA);
}
// Set CRTC address VGA or MDA
- u8 miscreg = GET_GLOBAL(vmode_g->miscreg);
+ u8 miscreg = GET_GLOBAL(stdmode_g->miscreg);
u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
if (!(miscreg & 1))
crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
// Disable CRTC write protection
outw(0x0011, crtc_addr);
// Set CRTC regs
- regs = GET_GLOBAL(vmode_g->crtc_regs);
+ regs = GET_GLOBAL(stdmode_g->crtc_regs);
for (i = 0; i <= 0x18; i++) {
outb(i, crtc_addr);
outb(GET_GLOBAL(regs[i]), crtc_addr + 1);
// Enable video
outb(0x20, VGAREG_ACTL_ADDRESS);
inb(VGAREG_ACTL_RESET);
+
+ // Clear screen
+ if (!(flags & MF_NOCLEARMEM))
+ clear_screen(vmode_g);
+
+ // Write the fonts in memory
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ if (memmodel == MM_TEXT)
+ stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
+
+ // Setup BDA variables
+ modeswitch_set_bda(mode, flags, vmode_g);
+
+ return 0;
}
* Misc
****************************************************************/
+void
+stdvga_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+ SET_FARVAR(seg, *dest, 0xffff);
+}
+
void
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
// more than 64k 3C4/04
outb(0x04, VGAREG_SEQU_ADDRESS);
outb(0x02, VGAREG_SEQU_DATA);
+
+ return 0;
}