Support index color in video_cirrus
This commit is contained in:
parent
63c1b71cbb
commit
31e0ce4d10
1 changed files with 97 additions and 40 deletions
137
video/cirrus.c
137
video/cirrus.c
|
@ -40,12 +40,19 @@ static struct
|
||||||
|
|
||||||
#define CIRRUS_APERTURE_SIZE 0x200000
|
#define CIRRUS_APERTURE_SIZE 0x200000
|
||||||
|
|
||||||
#define GR_INDEX 0x3ce
|
enum
|
||||||
#define GR_DATA 0x3cf
|
{
|
||||||
#define CR_INDEX 0x3d4
|
SR_INDEX = 0x3c4,
|
||||||
#define CR_DATA 0x3d5
|
SR_DATA = 0x3c5,
|
||||||
#define SR_INDEX 0x3c4
|
CIRRUS_PIXEL_MASK = 0x3c6,
|
||||||
#define SR_DATA 0x3c5
|
CIRRUS_PALLETTE_READ_INDEX = 0x3c7,
|
||||||
|
CIRRUS_PALLETTE_WRITE_INDEX = 0x3c8,
|
||||||
|
CIRRUS_PALLETTE_DATA = 0x3c9,
|
||||||
|
GR_INDEX = 0x3ce,
|
||||||
|
GR_DATA = 0x3cf,
|
||||||
|
CR_INDEX = 0x3d4,
|
||||||
|
CR_DATA = 0x3d5,
|
||||||
|
};
|
||||||
|
|
||||||
#define CIRRUS_MAX_WIDTH 0x800
|
#define CIRRUS_MAX_WIDTH 0x800
|
||||||
#define CIRRUS_WIDTH_DIVISOR 8
|
#define CIRRUS_WIDTH_DIVISOR 8
|
||||||
|
@ -117,12 +124,14 @@ enum
|
||||||
#define CIRRUS_SR_MEMORY_MODE_NORMAL 0
|
#define CIRRUS_SR_MEMORY_MODE_NORMAL 0
|
||||||
#define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0
|
#define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0
|
||||||
#define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01
|
#define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01
|
||||||
#define CIRRUS_SR_EXTENDED_MODE_24BPP 0x04
|
#define CIRRUS_SR_EXTENDED_MODE_8BPP 0x00
|
||||||
#define CIRRUS_SR_EXTENDED_MODE_16BPP 0x06
|
#define CIRRUS_SR_EXTENDED_MODE_16BPP 0x06
|
||||||
|
#define CIRRUS_SR_EXTENDED_MODE_24BPP 0x04
|
||||||
#define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08
|
#define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08
|
||||||
|
|
||||||
#define CIRRUS_HIDDEN_DAC_ENABLE_EXT 0x80
|
#define CIRRUS_HIDDEN_DAC_ENABLE_EXT 0x80
|
||||||
#define CIRRUS_HIDDEN_DAC_ENABLE_ALL 0x40
|
#define CIRRUS_HIDDEN_DAC_ENABLE_ALL 0x40
|
||||||
|
#define CIRRUS_HIDDEN_DAC_8BPP 0
|
||||||
#define CIRRUS_HIDDEN_DAC_15BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \
|
#define CIRRUS_HIDDEN_DAC_15BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \
|
||||||
| CIRRUS_HIDDEN_DAC_ENABLE_ALL | 0)
|
| CIRRUS_HIDDEN_DAC_ENABLE_ALL | 0)
|
||||||
#define CIRRUS_HIDDEN_DAC_16BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \
|
#define CIRRUS_HIDDEN_DAC_16BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \
|
||||||
|
@ -175,23 +184,43 @@ sr_read (grub_uint8_t addr)
|
||||||
static void
|
static void
|
||||||
write_hidden_dac (grub_uint8_t data)
|
write_hidden_dac (grub_uint8_t data)
|
||||||
{
|
{
|
||||||
grub_inb (0x3c8);
|
grub_inb (CIRRUS_PALLETTE_WRITE_INDEX);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_outb (data, 0x3c6);
|
grub_outb (data, CIRRUS_PIXEL_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_uint8_t
|
static grub_uint8_t
|
||||||
read_hidden_dac (void)
|
read_hidden_dac (void)
|
||||||
{
|
{
|
||||||
grub_inb (0x3c8);
|
grub_inb (CIRRUS_PALLETTE_WRITE_INDEX);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
grub_inb (0x3c6);
|
grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
return grub_inb (0x3c6);
|
return grub_inb (CIRRUS_PIXEL_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g,
|
||||||
|
grub_uint8_t *b)
|
||||||
|
{
|
||||||
|
grub_outb (addr, CIRRUS_PALLETTE_READ_INDEX);
|
||||||
|
*r = grub_inb (CIRRUS_PALLETTE_DATA);
|
||||||
|
*g = grub_inb (CIRRUS_PALLETTE_DATA);
|
||||||
|
*b = grub_inb (CIRRUS_PALLETTE_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g,
|
||||||
|
grub_uint8_t b)
|
||||||
|
{
|
||||||
|
grub_outb (addr, CIRRUS_PALLETTE_READ_INDEX);
|
||||||
|
grub_outb (r, CIRRUS_PALLETTE_DATA);
|
||||||
|
grub_outb (g, CIRRUS_PALLETTE_DATA);
|
||||||
|
grub_outb (b, CIRRUS_PALLETTE_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct saved_state
|
struct saved_state
|
||||||
|
@ -202,6 +231,9 @@ struct saved_state
|
||||||
grub_uint8_t hidden_dac;
|
grub_uint8_t hidden_dac;
|
||||||
/* We need to preserve VGA font and VGA text. */
|
/* We need to preserve VGA font and VGA text. */
|
||||||
grub_uint8_t vram[32 * 4 * 256];
|
grub_uint8_t vram[32 * 4 * 256];
|
||||||
|
grub_uint8_t r[256];
|
||||||
|
grub_uint8_t g[256];
|
||||||
|
grub_uint8_t b[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct saved_state initial_state;
|
static struct saved_state initial_state;
|
||||||
|
@ -217,6 +249,9 @@ save_state (struct saved_state *st)
|
||||||
st->sr[i] = sr_read (i);
|
st->sr[i] = sr_read (i);
|
||||||
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
|
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
|
||||||
st->gr[i] = gr_read (i);
|
st->gr[i] = gr_read (i);
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
palette_read (i, st->r + i, st->g + i, st->b + i);
|
||||||
|
|
||||||
st->hidden_dac = read_hidden_dac ();
|
st->hidden_dac = read_hidden_dac ();
|
||||||
sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE);
|
sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE);
|
||||||
grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram));
|
grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram));
|
||||||
|
@ -234,6 +269,9 @@ restore_state (struct saved_state *st)
|
||||||
sr_write (st->sr[i], i);
|
sr_write (st->sr[i], i);
|
||||||
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
|
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
|
||||||
gr_write (st->gr[i], i);
|
gr_write (st->gr[i], i);
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
palette_write (i, st->r[i], st->g[i], st->b[i]);
|
||||||
|
|
||||||
write_hidden_dac (st->hidden_dac);
|
write_hidden_dac (st->hidden_dac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,9 +327,30 @@ doublebuf_pageflipping_set_page (int page)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_video_cirrus_set_palette (unsigned int start, unsigned int count,
|
||||||
|
struct grub_video_palette_data *palette_data)
|
||||||
|
{
|
||||||
|
if (framebuffer.mode_info.mode_type == GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
if (start >= 0x100)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
if (start + count >= 0x100)
|
||||||
|
count = 0x100 - start;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
palette_write (start + i, palette_data[i].r, palette_data[i].g,
|
||||||
|
palette_data[i].b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then set color to emulated palette. */
|
||||||
|
return grub_video_fb_set_palette (start, count, palette_data);
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_video_cirrus_setup (unsigned int width, unsigned int height,
|
grub_video_cirrus_setup (unsigned int width, unsigned int height,
|
||||||
unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
|
unsigned int mode_type, unsigned int mode_mask)
|
||||||
{
|
{
|
||||||
int depth;
|
int depth;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
@ -342,12 +401,17 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
|
||||||
return grub_error (GRUB_ERR_IO,
|
return grub_error (GRUB_ERR_IO,
|
||||||
"screen height must be at most %d", CIRRUS_MAX_HEIGHT);
|
"screen height must be at most %d", CIRRUS_MAX_HEIGHT);
|
||||||
|
|
||||||
if (depth == 0)
|
if (depth == 0
|
||||||
|
&& !grub_video_check_mode_flag (mode_type, mode_mask,
|
||||||
|
GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0))
|
||||||
depth = 24;
|
depth = 24;
|
||||||
|
|
||||||
if (depth != 32 && depth != 24 && depth != 16 && depth != 15)
|
if (depth == 0)
|
||||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
depth = 8;
|
||||||
"only 32, 24, 16 and 15-bit bpp are supported");
|
|
||||||
|
if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8)
|
||||||
|
return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bit bpp are"
|
||||||
|
" supported by cirrus video");
|
||||||
|
|
||||||
bytes_per_pixel = (depth + 7) / 8;
|
bytes_per_pixel = (depth + 7) / 8;
|
||||||
pitch = width * bytes_per_pixel;
|
pitch = width * bytes_per_pixel;
|
||||||
|
@ -448,6 +512,10 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
|
||||||
hidden_dac = CIRRUS_HIDDEN_DAC_15BPP;
|
hidden_dac = CIRRUS_HIDDEN_DAC_15BPP;
|
||||||
sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP;
|
sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP;
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
hidden_dac = CIRRUS_HIDDEN_DAC_8BPP;
|
||||||
|
sr_ext |= CIRRUS_SR_EXTENDED_MODE_8BPP;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE);
|
sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE);
|
||||||
write_hidden_dac (hidden_dac);
|
write_hidden_dac (hidden_dac);
|
||||||
|
@ -466,6 +534,9 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
|
||||||
|
|
||||||
switch (depth)
|
switch (depth)
|
||||||
{
|
{
|
||||||
|
case 8:
|
||||||
|
framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
|
||||||
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
framebuffer.mode_info.red_mask_size = 5;
|
framebuffer.mode_info.red_mask_size = 5;
|
||||||
framebuffer.mode_info.red_field_pos = 11;
|
framebuffer.mode_info.red_field_pos = 11;
|
||||||
|
@ -513,25 +584,11 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
|
||||||
|
|
||||||
|
|
||||||
/* Copy default palette to initialize emulated palette. */
|
/* Copy default palette to initialize emulated palette. */
|
||||||
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
|
err = grub_video_cirrus_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
|
||||||
grub_video_fbstd_colors);
|
grub_video_fbstd_colors);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_video_cirrus_set_palette (unsigned int start, unsigned int count,
|
|
||||||
struct grub_video_palette_data *palette_data)
|
|
||||||
{
|
|
||||||
/* if (framebuffer.index_color_mode) */
|
|
||||||
{
|
|
||||||
/* TODO: Implement setting indexed color mode palette to hardware. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then set color to emulated palette. */
|
|
||||||
return grub_video_fb_set_palette (start, count, palette_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct grub_video_adapter grub_video_cirrus_adapter =
|
static struct grub_video_adapter grub_video_cirrus_adapter =
|
||||||
{
|
{
|
||||||
.name = "Cirrus CLGD 5446 PCI Video Driver",
|
.name = "Cirrus CLGD 5446 PCI Video Driver",
|
||||||
|
|
Loading…
Reference in a new issue