macroify and share VGA registers

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-05-17 02:25:37 +02:00
parent 368e544ba6
commit 967828eb5a
5 changed files with 254 additions and 343 deletions

161
include/grub/vga.h Normal file
View file

@ -0,0 +1,161 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_VGA_HEADER
#define GRUB_VGA_HEADER 1
enum
{
GRUB_VGA_IO_SR_INDEX = 0x3c4,
GRUB_VGA_IO_SR_DATA = 0x3c5,
GRUB_VGA_IO_PIXEL_MASK = 0x3c6,
GRUB_VGA_IO_PALLETTE_READ_INDEX = 0x3c7,
GRUB_VGA_IO_PALLETTE_WRITE_INDEX = 0x3c8,
GRUB_VGA_IO_PALLETTE_DATA = 0x3c9,
GRUB_VGA_IO_GR_INDEX = 0x3ce,
GRUB_VGA_IO_GR_DATA = 0x3cf,
GRUB_VGA_IO_CR_INDEX = 0x3d4,
GRUB_VGA_IO_CR_DATA = 0x3d5,
GRUB_VGA_IO_INPUT_STATUS1_REGISTER = 0x3da
};
#define GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT 0x08
enum
{
GRUB_VGA_CR_WIDTH = 0x01,
GRUB_VGA_CR_OVERFLOW = 0x07,
GRUB_VGA_CR_CELL_HEIGHT = 0x09,
GRUB_VGA_CR_CURSOR = 0x0a,
GRUB_VGA_CR_START_ADDR_HIGH_REGISTER = 0x0c,
GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d,
GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e,
GRUB_VGA_CR_CURSOR_ADDR_LOW = 0x0f,
GRUB_VGA_CR_VSYNC_END = 0x11,
GRUB_VGA_CR_HEIGHT = 0x12,
GRUB_VGA_CR_PITCH = 0x13,
GRUB_VGA_CR_MODE = 0x17,
GRUB_VGA_CR_LINE_COMPARE = 0x18,
};
#define GRUB_VGA_CR_WIDTH_DIVISOR 8
#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7
#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02
#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3
#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK 0xc0
#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT 4
#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK 0x10
#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40
#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3
#define GRUB_VGA_CR_CURSOR_DISABLE (1 << 5)
#define GRUB_VGA_CR_PITCH_DIVISOR 8
#define GRUB_VGA_CR_MODE_TIMING_ENABLE 0x80
#define GRUB_VGA_CR_MODE_BYTE_MODE 0x40
#define GRUB_VGA_CR_MODE_NO_HERCULES 0x02
#define GRUB_VGA_CR_MODE_NO_CGA 0x01
enum
{
GRUB_VGA_SR_MAP_MASK_REGISTER = 0x02,
GRUB_VGA_SR_MEMORY_MODE = 0x04,
};
#define GRUB_VGA_SR_MEMORY_MODE_CHAIN4 8
#define GRUB_VGA_SR_MEMORY_MODE_NORMAL 0
enum
{
GRUB_VGA_GR_READ_MAP_REGISTER = 0x04,
GRUB_VGA_GR_MODE = 5,
GRUB_VGA_GR_GR6 = 6,
GRUB_VGA_GR_MAX
};
#define GRUB_VGA_GR_GR6_GRAPHICS_MODE 1
#define GRUB_VGA_GR_MODE_256_COLOR 0x40
#define GRUB_VGA_GR_MODE_READ_MODE1 0x08
static inline void
grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_GR_INDEX);
grub_outb (val, GRUB_VGA_IO_GR_DATA);
}
static inline grub_uint8_t
grub_vga_gr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_GR_INDEX);
return grub_inb (GRUB_VGA_IO_GR_DATA);
}
static inline void
grub_vga_cr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_CR_INDEX);
grub_outb (val, GRUB_VGA_IO_CR_DATA);
}
static inline grub_uint8_t
grub_vga_cr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_CR_INDEX);
return grub_inb (GRUB_VGA_IO_CR_DATA);
}
static inline void
grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_SR_INDEX);
grub_outb (val, GRUB_VGA_IO_SR_DATA);
}
static inline grub_uint8_t
grub_vga_sr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_SR_INDEX);
return grub_inb (GRUB_VGA_IO_SR_DATA);
}
static inline void
grub_vga_palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g,
grub_uint8_t *b)
{
grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX);
*r = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
*g = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
*b = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
}
static inline void
grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g,
grub_uint8_t b)
{
grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX);
grub_outb (r, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (g, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (b, GRUB_VGA_IO_PALLETTE_DATA);
}
#endif

View file

@ -20,6 +20,7 @@
#include <grub/i386/vga_common.h>
#include <grub/i386/io.h>
#include <grub/types.h>
#include <grub/vga.h>
#define COLS 80
#define ROWS 25
@ -28,15 +29,6 @@ static int grub_curr_x, grub_curr_y;
#define VGA_TEXT_SCREEN 0xb8000
#define CRTC_ADDR_PORT 0x3D4
#define CRTC_DATA_PORT 0x3D5
#define CRTC_CURSOR 0x0a
#define CRTC_CURSOR_ADDR_HIGH 0x0e
#define CRTC_CURSOR_ADDR_LOW 0x0f
#define CRTC_CURSOR_DISABLE (1 << 5)
static void
screen_write_char (int x, int y, short c)
{
@ -53,10 +45,8 @@ static void
update_cursor (void)
{
unsigned int pos = grub_curr_y * COLS + grub_curr_x;
grub_outb (CRTC_CURSOR_ADDR_HIGH, CRTC_ADDR_PORT);
grub_outb (pos >> 8, CRTC_DATA_PORT);
grub_outb (CRTC_CURSOR_ADDR_LOW, CRTC_ADDR_PORT);
grub_outb (pos & 0xFF, CRTC_DATA_PORT);
grub_vga_cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH);
grub_vga_cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW);
}
static void
@ -134,12 +124,11 @@ static void
grub_vga_text_setcursor (int on)
{
grub_uint8_t old;
grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT);
old = grub_inb (CRTC_DATA_PORT);
old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR);
if (on)
grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
grub_vga_cr_write (old & ~GRUB_VGA_CR_CURSOR_DISABLE, GRUB_VGA_CR_CURSOR);
else
grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
grub_vga_cr_write (old | GRUB_VGA_CR_CURSOR_DISABLE, GRUB_VGA_CR_CURSOR);
}
static grub_err_t

View file

@ -26,6 +26,7 @@
#include <grub/video.h>
#include <grub/video_fb.h>
#include <grub/pci.h>
#include <grub/vga.h>
static struct
{
@ -42,27 +43,10 @@ static struct
#define BOCHS_MAX_HEIGHT 1200
#define BOCHS_WIDTH_ALIGN 8
enum
{
CIRRUS_SR_MEMORY_MODE = 4,
CIRRUS_SR_EXTENDED_MODE = 7,
CIRRUS_SR_MAX
};
#define CIRRUS_SR_MEMORY_MODE_CHAIN4 8
enum
{
BOCHS_VBE_INDEX = 0x1ce,
BOCHS_VBE_DATA = 0x1cf,
SR_INDEX = 0x3c4,
SR_DATA = 0x3c5,
BOCHS_PALLETTE_READ_INDEX = 0x3c7,
BOCHS_PALLETTE_WRITE_INDEX = 0x3c8,
BOCHS_PALLETTE_DATA = 0x3c9,
GR_INDEX = 0x3ce,
GR_DATA = 0x3cf,
CR_INDEX = 0x3d4,
CR_DATA = 0x3d5,
};
enum
@ -89,68 +73,6 @@ vbe_read (grub_uint16_t addr)
return grub_inw (BOCHS_VBE_DATA);
}
static void
gr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GR_INDEX);
grub_outb (val, GR_DATA);
}
static grub_uint8_t
gr_read (grub_uint8_t addr)
{
grub_outb (addr, GR_INDEX);
return grub_inb (GR_DATA);
}
static void
cr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, CR_INDEX);
grub_outb (val, CR_DATA);
}
static grub_uint8_t
cr_read (grub_uint8_t addr)
{
grub_outb (addr, CR_INDEX);
return grub_inb (CR_DATA);
}
static void
palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g,
grub_uint8_t *b)
{
grub_outb (addr, BOCHS_PALLETTE_READ_INDEX);
*r = grub_inb (BOCHS_PALLETTE_DATA);
*g = grub_inb (BOCHS_PALLETTE_DATA);
*b = grub_inb (BOCHS_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, BOCHS_PALLETTE_READ_INDEX);
grub_outb (r, BOCHS_PALLETTE_DATA);
grub_outb (g, BOCHS_PALLETTE_DATA);
grub_outb (b, BOCHS_PALLETTE_DATA);
}
static void
sr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, SR_INDEX);
grub_outb (val, SR_DATA);
}
static grub_uint8_t
sr_read (grub_uint8_t addr)
{
grub_outb (addr, SR_INDEX);
return grub_inb (SR_DATA);
}
struct saved_state
{
grub_uint8_t cr[256];
@ -174,24 +96,23 @@ save_state (struct saved_state *st)
unsigned i;
for (i = 0; i < ARRAY_SIZE (st->cr); i++)
st->cr[i] = cr_read (i);
st->cr[i] = grub_vga_cr_read (i);
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
st->gr[i] = gr_read (i);
st->gr[i] = grub_vga_gr_read (i);
for (i = 0; i < ARRAY_SIZE (st->sr); i++)
st->sr[i] = sr_read (i);
grub_printf ("%d\n", st->cr[1]);
st->sr[i] = grub_vga_sr_read (i);
for (i = 0; i < 256; i++)
palette_read (i, st->r + i, st->g + i, st->b + i);
grub_vga_palette_read (i, st->r + i, st->g + i, st->b + i);
st->vbe_enable = vbe_read (BOCHS_VBE_ENABLE) & 1;
if (st->vbe_enable)
for (i = 0; i < ARRAY_SIZE (st->vbe); i++)
st->vbe[i] = vbe_read (i);
sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE);
grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram));
sr_write (st->sr[CIRRUS_SR_MEMORY_MODE], CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (st->sr[GRUB_VGA_SR_MEMORY_MODE], GRUB_VGA_SR_MEMORY_MODE);
}
static void
@ -205,20 +126,20 @@ restore_state (struct saved_state *st)
else
vbe_write (0, BOCHS_VBE_ENABLE);
cr_write (0, 0x11);
grub_vga_cr_write (0, 0x11);
for (i = 0; i < ARRAY_SIZE (st->cr); i++)
cr_write (st->cr[i], i);
grub_vga_cr_write (st->cr[i], i);
for (i = 0; i < ARRAY_SIZE (st->sr); i++)
sr_write (st->sr[i], i);
grub_vga_sr_write (st->sr[i], i);
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
gr_write (st->gr[i], i);
grub_vga_gr_write (st->gr[i], i);
for (i = 0; i < 256; i++)
palette_write (i, st->r[i], st->g[i], st->b[i]);
grub_vga_palette_write (i, st->r[i], st->g[i], st->b[i]);
sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE);
grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram));
sr_write (st->sr[CIRRUS_SR_MEMORY_MODE], CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (st->sr[GRUB_VGA_SR_MEMORY_MODE], GRUB_VGA_SR_MEMORY_MODE);
}
static grub_err_t
@ -268,8 +189,8 @@ grub_video_bochs_set_palette (unsigned int start, unsigned int count,
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);
grub_vga_palette_write (start + i, palette_data[i].r, palette_data[i].g,
palette_data[i].b);
}
/* Then set color to emulated palette. */

View file

@ -26,6 +26,7 @@
#include <grub/video.h>
#include <grub/video_fb.h>
#include <grub/pci.h>
#include <grub/vga.h>
static struct
{
@ -40,69 +41,17 @@ static struct
#define CIRRUS_APERTURE_SIZE 0x1000000
enum
{
SR_INDEX = 0x3c4,
SR_DATA = 0x3c5,
CIRRUS_PIXEL_MASK = 0x3c6,
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_WIDTH_DIVISOR 8
#define CIRRUS_MAX_HEIGHT 0x800
#define CIRRUS_MAX_PITCH (0x1ff * CIRRUS_WIDTH_DIVISOR)
#define CIRRUS_MAX_PITCH (0x1ff * GRUB_VGA_CR_PITCH_DIVISOR)
enum
{
CIRRUS_GR_MODE = 5,
CIRRUS_GR_GR6 = 6,
CIRRUS_GR_MAX
};
#define CIRRUS_GR_GR6_GRAPHICS_MODE 1
#define CIRRUS_GR_MODE_256_COLOR 0x40
#define CIRRUS_GR_MODE_READ_MODE1 0x08
enum
{
CIRRUS_CR_WIDTH = 0x01,
CIRRUS_CR_OVERFLOW = 0x07,
CIRRUS_CR_CELL_HEIGHT = 0x09,
CIRRUS_CR_SCREEN_START_HIGH = 0xc,
CIRRUS_CR_SCREEN_START_LOW = 0xd,
CIRRUS_CR_VSYNC_END = 0x11,
CIRRUS_CR_HEIGHT = 0x12,
CIRRUS_CR_PITCH = 0x13,
CIRRUS_CR_MODE = 0x17,
CIRRUS_CR_LINE_COMPARE = 0x18,
CIRRUS_CR_EXTENDED_DISPLAY = 0x1b,
CIRRUS_CR_EXTENDED_OVERLAY = 0x1d,
CIRRUS_CR_MAX
};
#define CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40
#define CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3
#define CIRRUS_CR_OVERFLOW_HEIGHT1_SHIFT 7
#define CIRRUS_CR_OVERFLOW_HEIGHT1_MASK 0x02
#define CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT 3
#define CIRRUS_CR_OVERFLOW_HEIGHT2_MASK 0xc0
#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT 4
#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK 0x10
#define CIRRUS_CR_MODE_TIMING_ENABLE 0x80
#define CIRRUS_CR_MODE_BYTE_MODE 0x40
#define CIRRUS_CR_MODE_NO_HERCULES 0x02
#define CIRRUS_CR_MODE_NO_CGA 0x01
#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10
#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4
#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 0x1
@ -113,15 +62,12 @@ enum
#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK 0x80
#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT 12
enum
{
CIRRUS_SR_MEMORY_MODE = 4,
CIRRUS_SR_EXTENDED_MODE = 7,
CIRRUS_SR_MAX
};
#define CIRRUS_SR_MEMORY_MODE_CHAIN4 8
#define CIRRUS_SR_MEMORY_MODE_NORMAL 0
#define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0
#define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01
#define CIRRUS_SR_EXTENDED_MODE_8BPP 0x00
@ -139,94 +85,32 @@ enum
#define CIRRUS_HIDDEN_DAC_888COLOR (CIRRUS_HIDDEN_DAC_ENABLE_EXT \
| CIRRUS_HIDDEN_DAC_ENABLE_ALL | 5)
static void
gr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GR_INDEX);
grub_outb (val, GR_DATA);
}
static grub_uint8_t
gr_read (grub_uint8_t addr)
{
grub_outb (addr, GR_INDEX);
return grub_inb (GR_DATA);
}
static void
cr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, CR_INDEX);
grub_outb (val, CR_DATA);
}
static grub_uint8_t
cr_read (grub_uint8_t addr)
{
grub_outb (addr, CR_INDEX);
return grub_inb (CR_DATA);
}
static void
sr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, SR_INDEX);
grub_outb (val, SR_DATA);
}
static grub_uint8_t
sr_read (grub_uint8_t addr)
{
grub_outb (addr, SR_INDEX);
return grub_inb (SR_DATA);
}
static void
write_hidden_dac (grub_uint8_t data)
{
grub_inb (CIRRUS_PALLETTE_WRITE_INDEX);
grub_inb (CIRRUS_PIXEL_MASK);
grub_inb (CIRRUS_PIXEL_MASK);
grub_inb (CIRRUS_PIXEL_MASK);
grub_inb (CIRRUS_PIXEL_MASK);
grub_outb (data, CIRRUS_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PALLETTE_WRITE_INDEX);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_outb (data, GRUB_VGA_IO_PIXEL_MASK);
}
static grub_uint8_t
read_hidden_dac (void)
{
grub_inb (CIRRUS_PALLETTE_WRITE_INDEX);
grub_inb (CIRRUS_PIXEL_MASK);
grub_inb (CIRRUS_PIXEL_MASK);
grub_inb (CIRRUS_PIXEL_MASK);
grub_inb (CIRRUS_PIXEL_MASK);
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);
grub_inb (GRUB_VGA_IO_PALLETTE_WRITE_INDEX);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
grub_inb (GRUB_VGA_IO_PIXEL_MASK);
return grub_inb (GRUB_VGA_IO_PIXEL_MASK);
}
struct saved_state
{
grub_uint8_t cr[CIRRUS_CR_MAX];
grub_uint8_t gr[CIRRUS_GR_MAX];
grub_uint8_t gr[GRUB_VGA_GR_MAX];
grub_uint8_t sr[CIRRUS_SR_MAX];
grub_uint8_t hidden_dac;
/* We need to preserve VGA font and VGA text. */
@ -244,16 +128,16 @@ save_state (struct saved_state *st)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE (st->cr); i++)
st->cr[i] = cr_read (i);
st->cr[i] = grub_vga_cr_read (i);
for (i = 0; i < ARRAY_SIZE (st->sr); i++)
st->sr[i] = sr_read (i);
st->sr[i] = grub_vga_sr_read (i);
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
st->gr[i] = gr_read (i);
st->gr[i] = grub_vga_gr_read (i);
for (i = 0; i < 256; i++)
palette_read (i, st->r + i, st->g + i, st->b + i);
grub_vga_palette_read (i, st->r + i, st->g + i, st->b + i);
st->hidden_dac = read_hidden_dac ();
sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE);
grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram));
}
@ -261,16 +145,16 @@ static void
restore_state (struct saved_state *st)
{
unsigned i;
sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE);
grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram));
for (i = 0; i < ARRAY_SIZE (st->cr); i++)
cr_write (st->cr[i], i);
grub_vga_cr_write (st->cr[i], i);
for (i = 0; i < ARRAY_SIZE (st->sr); i++)
sr_write (st->sr[i], i);
grub_vga_sr_write (st->sr[i], i);
for (i = 0; i < ARRAY_SIZE (st->gr); i++)
gr_write (st->gr[i], i);
grub_vga_gr_write (st->gr[i], i);
for (i = 0; i < 256; i++)
palette_write (i, st->r[i], st->g[i], st->b[i]);
grub_vga_palette_write (i, st->r[i], st->g[i], st->b[i]);
write_hidden_dac (st->hidden_dac);
}
@ -306,23 +190,24 @@ doublebuf_pageflipping_set_page (int page)
int start = framebuffer.page_size * page / 4;
grub_uint8_t cr_ext, cr_overlay;
cr_write (start & 0xff, CIRRUS_CR_SCREEN_START_LOW);
cr_write ((start & 0xff00) >> 8, CIRRUS_CR_SCREEN_START_HIGH);
grub_vga_cr_write (start & 0xff, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
grub_vga_cr_write ((start & 0xff00) >> 8,
GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
cr_ext = cr_read (CIRRUS_CR_EXTENDED_DISPLAY);
cr_ext = grub_vga_cr_read (CIRRUS_CR_EXTENDED_DISPLAY);
cr_ext &= ~(CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1
| CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2);
cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1)
& CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1);
cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2)
& CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2);
cr_write (cr_ext, CIRRUS_CR_EXTENDED_DISPLAY);
grub_vga_cr_write (cr_ext, CIRRUS_CR_EXTENDED_DISPLAY);
cr_overlay = cr_read (CIRRUS_CR_EXTENDED_OVERLAY);
cr_overlay = grub_vga_cr_read (CIRRUS_CR_EXTENDED_OVERLAY);
cr_overlay &= ~(CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK);
cr_overlay |= ((start >> CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT)
& CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK);
cr_write (cr_overlay, CIRRUS_CR_EXTENDED_OVERLAY);
grub_vga_cr_write (cr_overlay, CIRRUS_CR_EXTENDED_OVERLAY);
return GRUB_ERR_NONE;
}
@ -340,8 +225,8 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count,
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);
grub_vga_palette_write (start + i, palette_data[i].r, palette_data[i].g,
palette_data[i].b);
}
/* Then set color to emulated palette. */
@ -388,10 +273,10 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
height = 600;
}
if (width & (CIRRUS_WIDTH_DIVISOR - 1))
if (width & (GRUB_VGA_CR_WIDTH_DIVISOR - 1))
return grub_error (GRUB_ERR_IO,
"screen width must be a multiple of %d",
CIRRUS_WIDTH_DIVISOR);
GRUB_VGA_CR_WIDTH_DIVISOR);
if (width > CIRRUS_MAX_WIDTH)
return grub_error (GRUB_ERR_IO,
@ -452,42 +337,44 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
int pitch_reg, overflow_reg = 0, line_compare = 0x3ff;
grub_uint8_t sr_ext = 0, hidden_dac = 0;
pitch_reg = pitch / CIRRUS_WIDTH_DIVISOR;
pitch_reg = pitch / GRUB_VGA_CR_PITCH_DIVISOR;
gr_write (CIRRUS_GR_MODE_256_COLOR | CIRRUS_GR_MODE_READ_MODE1,
CIRRUS_GR_MODE);
gr_write (CIRRUS_GR_GR6_GRAPHICS_MODE, CIRRUS_GR_GR6);
grub_vga_gr_write (GRUB_VGA_GR_MODE_256_COLOR | GRUB_VGA_GR_MODE_READ_MODE1,
GRUB_VGA_GR_MODE);
grub_vga_gr_write (GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6);
sr_write (CIRRUS_SR_MEMORY_MODE_NORMAL, CIRRUS_SR_MEMORY_MODE);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE);
/* Disable CR0-7 write protection. */
cr_write (0, CIRRUS_CR_VSYNC_END);
grub_vga_cr_write (0, GRUB_VGA_CR_VSYNC_END);
cr_write (width / CIRRUS_WIDTH_DIVISOR - 1, CIRRUS_CR_WIDTH);
cr_write ((height - 1) & 0xff, CIRRUS_CR_HEIGHT);
overflow_reg |= (((height - 1) >> CIRRUS_CR_OVERFLOW_HEIGHT1_SHIFT) &
CIRRUS_CR_OVERFLOW_HEIGHT1_MASK)
| (((height - 1) >> CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT) &
CIRRUS_CR_OVERFLOW_HEIGHT2_MASK);
grub_vga_cr_write (width / GRUB_VGA_CR_WIDTH_DIVISOR - 1,
GRUB_VGA_CR_WIDTH);
grub_vga_cr_write ((height - 1) & 0xff, GRUB_VGA_CR_HEIGHT);
overflow_reg |= (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) &
GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK)
| (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) &
GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK);
cr_write (pitch_reg & 0xff, CIRRUS_CR_PITCH);
grub_vga_cr_write (pitch_reg & 0xff, GRUB_VGA_CR_PITCH);
cr_write (line_compare & 0xff, CIRRUS_CR_LINE_COMPARE);
overflow_reg |= (line_compare >> CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT)
& CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK;
grub_vga_cr_write (line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE);
overflow_reg |= (line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT)
& GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK;
cr_write (overflow_reg, CIRRUS_CR_OVERFLOW);
grub_vga_cr_write (overflow_reg, GRUB_VGA_CR_OVERFLOW);
cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT)
grub_vga_cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT)
& CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK,
CIRRUS_CR_EXTENDED_DISPLAY);
cr_write ((line_compare >> CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT)
& CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_MASK, CIRRUS_CR_CELL_HEIGHT);
grub_vga_cr_write ((line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT)
& GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK, GRUB_VGA_CR_CELL_HEIGHT);
cr_write (CIRRUS_CR_MODE_TIMING_ENABLE | CIRRUS_CR_MODE_BYTE_MODE
| CIRRUS_CR_MODE_NO_HERCULES | CIRRUS_CR_MODE_NO_CGA,
CIRRUS_CR_MODE);
grub_vga_cr_write (GRUB_VGA_CR_MODE_TIMING_ENABLE
| GRUB_VGA_CR_MODE_BYTE_MODE
| GRUB_VGA_CR_MODE_NO_HERCULES | GRUB_VGA_CR_MODE_NO_CGA,
GRUB_VGA_CR_MODE);
doublebuf_pageflipping_set_page (0);
@ -517,7 +404,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
sr_ext |= CIRRUS_SR_EXTENDED_MODE_8BPP;
break;
}
sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE);
grub_vga_sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE);
write_hidden_dac (hidden_dac);
}

View file

@ -27,6 +27,7 @@
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/vga.h>
#define VGA_WIDTH 640
#define VGA_HEIGHT 350
@ -45,58 +46,26 @@ static struct
int back_page;
} framebuffer;
#define SEQUENCER_ADDR_PORT 0x3C4
#define SEQUENCER_DATA_PORT 0x3C5
#define MAP_MASK_REGISTER 0x02
#define CRTC_ADDR_PORT 0x3D4
#define CRTC_DATA_PORT 0x3D5
#define START_ADDR_HIGH_REGISTER 0x0C
#define START_ADDR_LOW_REGISTER 0x0D
#define GRAPHICS_ADDR_PORT 0x3CE
#define GRAPHICS_DATA_PORT 0x3CF
#define READ_MAP_REGISTER 0x04
#define INPUT_STATUS1_REGISTER 0x3DA
#define INPUT_STATUS1_VERTR_BIT 0x08
static inline void
wait_vretrace (void)
{
/* Wait until there is a vertical retrace. */
while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT));
while (! (grub_inb (GRUB_VGA_IO_INPUT_STATUS1_REGISTER)
& GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT));
}
/* Get Map Mask Register. */
static unsigned char
get_map_mask (void)
{
unsigned char old_addr;
unsigned char old_data;
old_addr = grub_inb (SEQUENCER_ADDR_PORT);
grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
old_data = grub_inb (SEQUENCER_DATA_PORT);
grub_outb (old_addr, SEQUENCER_ADDR_PORT);
return old_data;
return grub_vga_sr_read (GRUB_VGA_SR_MAP_MASK_REGISTER);
}
/* Set Map Mask Register. */
static void
set_map_mask (unsigned char mask)
{
unsigned char old_addr;
old_addr = grub_inb (SEQUENCER_ADDR_PORT);
grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
grub_outb (mask, SEQUENCER_DATA_PORT);
grub_outb (old_addr, SEQUENCER_ADDR_PORT);
grub_vga_sr_write (mask, GRUB_VGA_SR_MAP_MASK_REGISTER);
}
#if 0
@ -104,14 +73,7 @@ set_map_mask (unsigned char mask)
static void
set_read_map (unsigned char map)
{
unsigned char old_addr;
old_addr = grub_inb (GRAPHICS_ADDR_PORT);
grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT);
grub_outb (map, GRAPHICS_DATA_PORT);
grub_outb (old_addr, GRAPHICS_ADDR_PORT);
grub_vga_gr_write (map, GRUB_VGA_GR_READ_MAP_REGISTER);
}
#endif
@ -119,17 +81,8 @@ set_read_map (unsigned char map)
static void
set_start_address (unsigned int start)
{
unsigned char old_addr;
old_addr = grub_inb (CRTC_ADDR_PORT);
grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT);
grub_outb (start & 0xFF, CRTC_DATA_PORT);
grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT);
grub_outb (start >> 8, CRTC_DATA_PORT);
grub_outb (old_addr, CRTC_ADDR_PORT);
grub_vga_cr_write (start & 0xFF, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
grub_vga_cr_write (start >> 8, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
}
static int setup = 0;