//
// This file may be distributed under the terms of the GNU LGPLv3 license.
+#include "vgabios.h" // struct vgamode_s
#include "stdvga.h" // stdvga_init
#include "ioport.h" // outb
#include "farptr.h" // SET_FARVAR
return VGAREG_MDA_CRTC_ADDRESS;
}
-void
-stdvga_set_cursor_shape(u8 start, u8 end)
+// Return the multiplication factor needed for the vga offset register.
+int
+stdvga_bpp_factor(struct vgamode_s *vmode_g)
{
- u16 crtc_addr = stdvga_get_crtc();
- stdvga_crtc_write(crtc_addr, 0x0a, start);
- stdvga_crtc_write(crtc_addr, 0x0b, end);
+ switch (GET_GLOBAL(vmode_g->memmodel)) {
+ case MM_TEXT:
+ return 2;
+ case MM_CGA:
+ return GET_GLOBAL(vmode_g->depth);
+ case MM_PLANAR:
+ return 1;
+ default:
+ return 4;
+ }
}
void
-stdvga_set_active_page(u16 address)
+stdvga_set_cursor_shape(u8 start, u8 end)
{
u16 crtc_addr = stdvga_get_crtc();
- stdvga_crtc_write(crtc_addr, 0x0c, address >> 8);
- stdvga_crtc_write(crtc_addr, 0x0d, address);
+ stdvga_crtc_write(crtc_addr, 0x0a, start);
+ stdvga_crtc_write(crtc_addr, 0x0b, end);
}
void
-stdvga_set_cursor_pos(u16 address)
+stdvga_set_cursor_pos(int address)
{
u16 crtc_addr = stdvga_get_crtc();
+ address /= 2; // Assume we're in text mode.
stdvga_crtc_write(crtc_addr, 0x0e, address >> 8);
stdvga_crtc_write(crtc_addr, 0x0f, address);
}
return -1;
}
+int
+stdvga_get_linelength(struct vgamode_s *vmode_g)
+{
+ u8 val = stdvga_crtc_read(stdvga_get_crtc(), 0x13);
+ return val * stdvga_bpp_factor(vmode_g) * 2;
+}
+
+int
+stdvga_set_linelength(struct vgamode_s *vmode_g, int val)
+{
+ int factor = stdvga_bpp_factor(vmode_g) * 2;
+ stdvga_crtc_write(stdvga_get_crtc(), 0x13, DIV_ROUND_UP(val, factor));
+ return 0;
+}
+
+int
+stdvga_get_displaystart(struct vgamode_s *vmode_g)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ int addr = (stdvga_crtc_read(crtc_addr, 0x0c) << 8
+ | stdvga_crtc_read(crtc_addr, 0x0d));
+ return addr * stdvga_bpp_factor(vmode_g);
+}
+
+int
+stdvga_set_displaystart(struct vgamode_s *vmode_g, int val)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ val /= stdvga_bpp_factor(vmode_g);
+ stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
+ stdvga_crtc_write(crtc_addr, 0x0d, val);
+ return 0;
+}
+
/****************************************************************
- * Save/Restore/Set state
+ * Save/Restore state
****************************************************************/
void
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 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(struct vgamode_s *vmode_g, int flags)
-{
- if (! stdvga_is_mode(vmode_g)) {
- warn_internalerror();
- return -1;
- }
- 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_pelmask_write(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_dac_write(get_global_seg(), palette_g, 0, palsize);
- int i;
- for (i = palsize; i < 0x0100; i++) {
- static u8 rgb[3] VAR16;
- stdvga_dac_write(get_global_seg(), rgb, i, 1);
- }
-
- if (flags & MF_GRAYSUM)
- stdvga_perform_gray_scale_summing(0x00, 0x100);
- }
-
- // Set Attribute Ctl
- u8 *regs = GET_GLOBAL(stdmode_g->actl_regs);
- int i;
- for (i = 0; i <= 0x13; i++)
- stdvga_attr_write(i, GET_GLOBAL(regs[i]));
- stdvga_attr_write(0x14, 0x00);
-
- // Set Sequencer Ctl
- stdvga_sequ_write(0x00, 0x03);
- regs = GET_GLOBAL(stdmode_g->sequ_regs);
- for (i = 1; i <= 4; i++)
- stdvga_sequ_write(i, GET_GLOBAL(regs[i - 1]));
-
- // Set Grafx Ctl
- regs = GET_GLOBAL(stdmode_g->grdc_regs);
- for (i = 0; i <= 8; i++)
- stdvga_grdc_write(i, GET_GLOBAL(regs[i]));
-
- // Set CRTC address VGA or MDA
- 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
- stdvga_crtc_write(crtc_addr, 0x11, 0x00);
- // Set CRTC regs
- regs = GET_GLOBAL(stdmode_g->crtc_regs);
- for (i = 0; i <= 0x18; i++)
- stdvga_crtc_write(crtc_addr, i, GET_GLOBAL(regs[i]));
-
- // Set the misc register
- stdvga_misc_write(miscreg);
-
- // Enable video
- stdvga_attrindex_write(0x20);
-
- // 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);
-
- 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)
{