Mirroring from commit 106549a4362f6b499da522f8f8f5ed9f98388f87 from Coreboot upstream
This commit is contained in:
+222
@@ -0,0 +1,222 @@
|
||||
# Kconfig SeaBIOS VGA BIOS configuration
|
||||
|
||||
menu "VGA ROM"
|
||||
choice
|
||||
prompt "VGA Hardware Type"
|
||||
default NO_VGABIOS
|
||||
|
||||
config NO_VGABIOS
|
||||
bool "None"
|
||||
help
|
||||
Do not build a VGA BIOS.
|
||||
|
||||
config VGA_STANDARD_VGA
|
||||
depends on QEMU
|
||||
bool "QEMU/Bochs Original IBM 256K VGA"
|
||||
select VGA_STDVGA_PORTS
|
||||
help
|
||||
Build basic VGA BIOS support (pre Super-VGA) for use
|
||||
on emulators.
|
||||
|
||||
config VGA_CIRRUS
|
||||
depends on QEMU
|
||||
bool "QEMU/Bochs Cirrus SVGA"
|
||||
select VGA_STDVGA_PORTS
|
||||
help
|
||||
Build support for Cirrus VGA emulation found on QEMU
|
||||
and Bochs emulators. This is for emulators; it is not
|
||||
intended for use on real Cirrus hardware.
|
||||
|
||||
config VGA_ATI
|
||||
depends on QEMU
|
||||
bool "QEMU ATI SVGA"
|
||||
select VGA_STDVGA_PORTS
|
||||
help
|
||||
Build support for ATI VGA emulation found on QEMU
|
||||
and emulators. This is for emulators; it is not
|
||||
intended for use on real ATI hardware.
|
||||
|
||||
config VGA_BOCHS
|
||||
depends on QEMU
|
||||
bool "QEMU/Bochs VBE SVGA"
|
||||
select VGA_STDVGA_PORTS
|
||||
help
|
||||
Build support for Bochs DISPI interface (a custom VBE
|
||||
protocol) found on QEMU and Bochs emulators.
|
||||
|
||||
config VGA_GEODEGX2
|
||||
bool "GeodeGX2"
|
||||
select VGA_STDVGA_PORTS
|
||||
help
|
||||
Build support for Geode GX2 vga.
|
||||
|
||||
config VGA_GEODELX
|
||||
bool "GeodeLX"
|
||||
select VGA_STDVGA_PORTS
|
||||
help
|
||||
Build support for Geode LX vga.
|
||||
|
||||
config VGA_COREBOOT
|
||||
depends on COREBOOT
|
||||
bool "coreboot linear framebuffer"
|
||||
select VGA_EMULATE_TEXT
|
||||
help
|
||||
Build support for a vgabios wrapper around video
|
||||
devices initialized using coreboot native vga init.
|
||||
|
||||
config DISPLAY_BOCHS
|
||||
depends on QEMU
|
||||
bool "qemu bochs-display support"
|
||||
select VGA_EMULATE_TEXT
|
||||
help
|
||||
Build support for the qemu bochs-display device, which
|
||||
is basically qemu stdvga without the legacy vga
|
||||
emulation, supporting only 16+32 bpp VESA video modes
|
||||
in a linear framebuffer. So this uses cbvga text mode
|
||||
emulation.
|
||||
|
||||
The bochs-display device is available in qemu
|
||||
v3.0+. The vgabios works with the qemu stdvga too (use
|
||||
"qemu -device VGA,romfile=/path/to/vgabios.bin")".
|
||||
|
||||
config VGA_RAMFB
|
||||
depends on QEMU
|
||||
bool "qemu ramfb"
|
||||
select VGA_EMULATE_TEXT
|
||||
help
|
||||
qemu ram framebuffer support (-device ramfb).
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
depends on VGA_BOCHS
|
||||
prompt "bochs vga variant"
|
||||
default VGA_BOCHS_STDVGA
|
||||
|
||||
config VGA_BOCHS_STDVGA
|
||||
bool "qemu stdvga / bochs svga"
|
||||
|
||||
config VGA_BOCHS_VMWARE
|
||||
bool "qemu vmware svga"
|
||||
|
||||
config VGA_BOCHS_QXL
|
||||
bool "qemu qxl vga"
|
||||
|
||||
config VGA_BOCHS_VIRTIO
|
||||
bool "qemu virtio vga"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
depends on VGA_GEODEGX2 || VGA_GEODELX
|
||||
prompt "Output Mode"
|
||||
default VGA_OUTPUT_CRT
|
||||
|
||||
config VGA_OUTPUT_CRT
|
||||
bool "CRT"
|
||||
help
|
||||
Use CRT for output.
|
||||
|
||||
config VGA_OUTPUT_PANEL
|
||||
bool "Flat Panel"
|
||||
help
|
||||
Use flat panel for output.
|
||||
|
||||
config VGA_OUTPUT_CRT_PANEL
|
||||
bool "CRT and Flat Panel"
|
||||
help
|
||||
Use CRT and flat panel for output.
|
||||
endchoice
|
||||
|
||||
config BUILD_VGABIOS
|
||||
bool
|
||||
default !NO_VGABIOS
|
||||
|
||||
config VGA_STDVGA_PORTS
|
||||
bool
|
||||
config VGA_EMULATE_TEXT
|
||||
bool
|
||||
help
|
||||
Support emulating text mode features when only a
|
||||
framebuffer is available.
|
||||
|
||||
config VGA_FIXUP_ASM
|
||||
depends on BUILD_VGABIOS
|
||||
bool "Fixup assembler to work with broken emulators"
|
||||
default y
|
||||
help
|
||||
This option will cause the build to attempt to avoid
|
||||
certain x86 machine instructions that are known to confuse
|
||||
some emulators. In particular, it works around
|
||||
deficiencies in the Windows vgabios emulator and the
|
||||
x86emu vgabios emulator (frequently used in Xorg).
|
||||
|
||||
config VGA_ALLOCATE_EXTRA_STACK
|
||||
depends on BUILD_VGABIOS
|
||||
bool "Allocate an internal stack for 16bit interrupt entry point"
|
||||
default y
|
||||
help
|
||||
Attempt to allocate (via BIOS PMM call) an internal stack
|
||||
for the legacy 16bit 0x10 interrupt entry point. This
|
||||
reduces the amount of space on the caller's stack that
|
||||
SeaVGABIOS uses.
|
||||
|
||||
config VGA_EXTRA_STACK_SIZE
|
||||
int
|
||||
default 512
|
||||
|
||||
config VGA_VBE
|
||||
depends on BUILD_VGABIOS
|
||||
bool "Video BIOS Extensions (VBE)"
|
||||
default y
|
||||
help
|
||||
Support VBE.
|
||||
|
||||
config VGA_PCI
|
||||
depends on BUILD_VGABIOS && !VGA_COREBOOT
|
||||
bool "PCI ROM Headers"
|
||||
default y
|
||||
help
|
||||
Build PCI ROM headers so the vga rom can be extracted from
|
||||
a PCI device.
|
||||
|
||||
config OVERRIDE_PCI_ID
|
||||
depends on VGA_PCI
|
||||
bool "Override PCI Vendor and Device IDs"
|
||||
help
|
||||
Specify specific values for the PCI Vendor and Device IDs.
|
||||
|
||||
config VGA_VID
|
||||
depends on VGA_PCI
|
||||
hex
|
||||
prompt "PCI Vendor ID" if OVERRIDE_PCI_ID
|
||||
default 0x1013 if VGA_CIRRUS
|
||||
default 0x1002 if VGA_ATI
|
||||
default 0x1234 if VGA_BOCHS_STDVGA
|
||||
default 0x15ad if VGA_BOCHS_VMWARE
|
||||
default 0x1b36 if VGA_BOCHS_QXL
|
||||
default 0x1af4 if VGA_BOCHS_VIRTIO
|
||||
default 0x100b if VGA_GEODEGX2
|
||||
default 0x1022 if VGA_GEODELX
|
||||
default 0x1234 if DISPLAY_BOCHS
|
||||
default 0x0000
|
||||
help
|
||||
Vendor ID for the PCI ROM
|
||||
|
||||
config VGA_DID
|
||||
depends on VGA_PCI
|
||||
hex
|
||||
prompt "PCI Vendor ID" if OVERRIDE_PCI_ID
|
||||
default 0x00b8 if VGA_CIRRUS
|
||||
default 0x5159 if VGA_ATI
|
||||
default 0x1111 if VGA_BOCHS_STDVGA
|
||||
default 0x0405 if VGA_BOCHS_VMWARE
|
||||
default 0x0100 if VGA_BOCHS_QXL
|
||||
default 0x1050 if VGA_BOCHS_VIRTIO
|
||||
default 0x0030 if VGA_GEODEGX2
|
||||
default 0x2081 if VGA_GEODELX
|
||||
default 0x1111 if DISPLAY_BOCHS
|
||||
default 0x0000
|
||||
help
|
||||
Device ID for the PCI ROM
|
||||
endmenu
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Fake ati bios tables.
|
||||
//
|
||||
// aty128fb and radeonfb try to gather informations from these tables,
|
||||
// so add some stuff here to make the drivers happy. Specifically
|
||||
// radeonfb needs the pll information, otherwise it'll crash with a
|
||||
// division by zero ...
|
||||
//
|
||||
.org 0x48
|
||||
.word _ati_main
|
||||
|
||||
// main info
|
||||
.org 0x50
|
||||
_ati_main:
|
||||
.org 0x50 + 0x30
|
||||
.word _ati_pll
|
||||
.org 0x50 + 0x50
|
||||
.word _ati_connector
|
||||
|
||||
// pll info
|
||||
.org 0x100
|
||||
_ati_pll:
|
||||
.word 0 // ??? (not used by radeonfb)
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 23000 // sclk
|
||||
.word 23000 // mclk
|
||||
.word 0
|
||||
.word 2700 // ref_clk
|
||||
.word 4 // ref_div
|
||||
.long 12000 // ppll_min
|
||||
.long 35000 // ppll_max
|
||||
|
||||
// connector info
|
||||
.org 0x140
|
||||
_ati_connector:
|
||||
.byte 0x10 // one chip
|
||||
.byte 0x01 // one connector
|
||||
.word 0x3000 // type DVI-I
|
||||
.word 0 // end of list
|
||||
|
||||
.org 0x200
|
||||
+413
@@ -0,0 +1,413 @@
|
||||
// QEMU ATI VGABIOS Extension.
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_GLOBAL
|
||||
#include "bregs.h" // struct bregs
|
||||
#include "hw/pci.h" // pci_config_readl
|
||||
#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
|
||||
#include "output.h" // dprintf
|
||||
#include "stdvga.h" // VGAREG_SEQU_ADDRESS
|
||||
#include "string.h" // memset16_far
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
#include "vgafb.h" // memset_high
|
||||
|
||||
#include "svgamodes.h"
|
||||
|
||||
#define MM_INDEX 0x0000
|
||||
#define MM_DATA 0x0004
|
||||
#define CRTC_GEN_CNTL 0x0050
|
||||
#define CRTC_EXT_CNTL 0x0054
|
||||
#define GPIO_VGA_DDC 0x0060
|
||||
#define GPIO_DVI_DDC 0x0064
|
||||
#define GPIO_MONID 0x0068
|
||||
#define CRTC_H_TOTAL_DISP 0x0200
|
||||
#define CRTC_V_TOTAL_DISP 0x0208
|
||||
#define CRTC_OFFSET 0x0224
|
||||
#define CRTC_PITCH 0x022c
|
||||
|
||||
/* CRTC control values (CRTC_GEN_CNTL) */
|
||||
#define CRTC2_EXT_DISP_EN 0x01000000
|
||||
#define CRTC2_EN 0x02000000
|
||||
|
||||
#define CRTC_PIX_WIDTH_MASK 0x00000700
|
||||
#define CRTC_PIX_WIDTH_4BPP 0x00000100
|
||||
#define CRTC_PIX_WIDTH_8BPP 0x00000200
|
||||
#define CRTC_PIX_WIDTH_15BPP 0x00000300
|
||||
#define CRTC_PIX_WIDTH_16BPP 0x00000400
|
||||
#define CRTC_PIX_WIDTH_24BPP 0x00000500
|
||||
#define CRTC_PIX_WIDTH_32BPP 0x00000600
|
||||
|
||||
/* CRTC_EXT_CNTL */
|
||||
#define CRT_CRTC_DISPLAY_DIS 0x00000400
|
||||
#define CRT_CRTC_ON 0x00008000
|
||||
|
||||
static u32 ati_io_addr VAR16 = 0;
|
||||
static u32 ati_i2c_reg VAR16;
|
||||
static u32 ati_i2c_bit_scl_out VAR16;
|
||||
static u32 ati_i2c_bit_sda_out VAR16;
|
||||
static u32 ati_i2c_bit_sda_in VAR16;
|
||||
static u32 ati_i2c_bit_enable VAR16 = -1;
|
||||
|
||||
|
||||
int
|
||||
is_ati_mode(struct vgamode_s *vmode_g)
|
||||
{
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
|
||||
return (vmode_g >= &svga_modes[0].info &&
|
||||
vmode_g <= &svga_modes[mcount-1].info);
|
||||
}
|
||||
|
||||
struct vgamode_s *
|
||||
ati_find_mode(int mode)
|
||||
{
|
||||
u32 io_addr = GET_GLOBAL(ati_io_addr);
|
||||
struct generic_svga_mode *table_g = svga_modes;
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
|
||||
if (io_addr) {
|
||||
while (table_g < &svga_modes[mcount]) {
|
||||
if (GET_GLOBAL(table_g->mode) == mode)
|
||||
return &table_g->info;
|
||||
table_g++;
|
||||
}
|
||||
}
|
||||
|
||||
return stdvga_find_mode(mode);
|
||||
}
|
||||
|
||||
void
|
||||
ati_list_modes(u16 seg, u16 *dest, u16 *last)
|
||||
{
|
||||
u32 io_addr = GET_GLOBAL(ati_io_addr);
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
|
||||
dprintf(1, "%s: ati ext %s\n", __func__, io_addr ? "yes" : "no");
|
||||
if (io_addr) {
|
||||
int i;
|
||||
for (i=0; i<mcount && dest<last; i++) {
|
||||
u16 mode = GET_GLOBAL(svga_modes[i].mode);
|
||||
if (mode == 0xffff)
|
||||
continue;
|
||||
SET_FARVAR(seg, *dest, mode);
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
|
||||
stdvga_list_modes(seg, dest, last);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Mode setting
|
||||
****************************************************************/
|
||||
|
||||
static inline void ati_write(u32 reg, u32 val)
|
||||
{
|
||||
u32 io_addr = GET_GLOBAL(ati_io_addr);
|
||||
|
||||
if (reg < 0x100) {
|
||||
outl(val, io_addr + reg);
|
||||
} else {
|
||||
outl(reg, io_addr + MM_INDEX);
|
||||
outl(val, io_addr + MM_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 ati_read(u32 reg)
|
||||
{
|
||||
u32 io_addr = GET_GLOBAL(ati_io_addr);
|
||||
u32 val;
|
||||
|
||||
if (reg < 0x100) {
|
||||
val = inl(io_addr + reg);
|
||||
} else {
|
||||
outl(reg, io_addr + MM_INDEX);
|
||||
val = inl(io_addr + MM_DATA);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void ati_clear(u32 offset, u32 size)
|
||||
{
|
||||
u8 data[64];
|
||||
void *datap = MAKE_FLATPTR(GET_SEG(SS), data);
|
||||
void *fb = (void*)(GET_GLOBAL(VBE_framebuffer) + offset);
|
||||
u32 i, pos;
|
||||
|
||||
for (i = 0; i < sizeof(data); i++)
|
||||
data[i] = 0;
|
||||
for (pos = 0; pos < size; pos += sizeof(data)) {
|
||||
memcpy_high(fb, datap, sizeof(data));
|
||||
fb += sizeof(data);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ati_ext_mode(struct generic_svga_mode *table, int flags)
|
||||
{
|
||||
u32 width = GET_GLOBAL(table->info.width);
|
||||
u32 height = GET_GLOBAL(table->info.height);
|
||||
u32 depth = GET_GLOBAL(table->info.depth);
|
||||
u32 stride = width;
|
||||
u32 offset = 0;
|
||||
u32 pxmask = 0;
|
||||
u32 bytes = 0;
|
||||
|
||||
dprintf(1, "%s: 0x%x, %dx%d-%d\n", __func__,
|
||||
GET_GLOBAL(table->mode),
|
||||
width, height, depth);
|
||||
|
||||
switch (depth) {
|
||||
case 8: pxmask = CRTC_PIX_WIDTH_8BPP; bytes = 1; break;
|
||||
case 15: pxmask = CRTC_PIX_WIDTH_15BPP; bytes = 2; break;
|
||||
case 16: pxmask = CRTC_PIX_WIDTH_16BPP; bytes = 2; break;
|
||||
case 24: pxmask = CRTC_PIX_WIDTH_24BPP; bytes = 3; break;
|
||||
case 32: pxmask = CRTC_PIX_WIDTH_32BPP; bytes = 4; break;
|
||||
}
|
||||
|
||||
/* disable display */
|
||||
ati_write(CRTC_EXT_CNTL, CRT_CRTC_DISPLAY_DIS);
|
||||
|
||||
/* modeset */
|
||||
ati_write(CRTC_GEN_CNTL, CRTC2_EXT_DISP_EN | CRTC2_EN | pxmask);
|
||||
ati_write(CRTC_H_TOTAL_DISP, ((width / 8) - 1) << 16);
|
||||
ati_write(CRTC_V_TOTAL_DISP, (height - 1) << 16);
|
||||
ati_write(CRTC_OFFSET, offset);
|
||||
ati_write(CRTC_PITCH, stride / 8);
|
||||
|
||||
/* clear screen */
|
||||
if (!(flags & MF_NOCLEARMEM)) {
|
||||
u32 size = width * height * bytes;
|
||||
ati_clear(offset, size);
|
||||
}
|
||||
|
||||
/* enable display */
|
||||
ati_write(CRTC_EXT_CNTL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ati_set_mode(struct vgamode_s *vmode_g, int flags)
|
||||
{
|
||||
struct generic_svga_mode *table_g =
|
||||
container_of(vmode_g, struct generic_svga_mode, info);
|
||||
|
||||
if (is_ati_mode(vmode_g)) {
|
||||
return ati_ext_mode(table_g, flags);
|
||||
}
|
||||
|
||||
ati_write(CRTC_GEN_CNTL, 0);
|
||||
return stdvga_set_mode(vmode_g, flags);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* edid
|
||||
****************************************************************/
|
||||
|
||||
static void
|
||||
ati_i2c_set_scl_sda(int scl, int sda)
|
||||
{
|
||||
u32 enable = GET_GLOBAL(ati_i2c_bit_enable);
|
||||
u32 data = 0;
|
||||
|
||||
if (enable != -1)
|
||||
data |= (1 << enable);
|
||||
if (!scl)
|
||||
data |= (1 << GET_GLOBAL(ati_i2c_bit_scl_out));
|
||||
if (!sda)
|
||||
data |= (1 << GET_GLOBAL(ati_i2c_bit_sda_out));
|
||||
ati_write(GET_GLOBAL(ati_i2c_reg), data);
|
||||
}
|
||||
|
||||
static int
|
||||
ati_i2c_get_sda(void)
|
||||
{
|
||||
u32 data = ati_read(GET_GLOBAL(ati_i2c_reg));
|
||||
|
||||
return data & (1 << GET_GLOBAL(ati_i2c_bit_sda_in)) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void ati_i2c_start(void)
|
||||
{
|
||||
ati_i2c_set_scl_sda(1, 1);
|
||||
ati_i2c_set_scl_sda(1, 0);
|
||||
ati_i2c_set_scl_sda(0, 0);
|
||||
}
|
||||
|
||||
static void ati_i2c_ack(void)
|
||||
{
|
||||
ati_i2c_set_scl_sda(0, 0);
|
||||
ati_i2c_set_scl_sda(1, 0);
|
||||
ati_i2c_set_scl_sda(0, 0);
|
||||
}
|
||||
|
||||
static void ati_i2c_stop(void)
|
||||
{
|
||||
ati_i2c_set_scl_sda(0, 0);
|
||||
ati_i2c_set_scl_sda(1, 0);
|
||||
ati_i2c_set_scl_sda(1, 1);
|
||||
}
|
||||
|
||||
static void ati_i2c_send_byte(u8 byte)
|
||||
{
|
||||
int i, bit;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
bit = (1 << (7-i)) & byte ? 1 : 0;
|
||||
ati_i2c_set_scl_sda(0, bit);
|
||||
ati_i2c_set_scl_sda(1, bit);
|
||||
ati_i2c_set_scl_sda(0, bit);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 ati_i2c_recv_byte(void)
|
||||
{
|
||||
u8 byte = 0;
|
||||
int i, bit;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
ati_i2c_set_scl_sda(0, 1);
|
||||
ati_i2c_set_scl_sda(1, 1);
|
||||
bit = ati_i2c_get_sda();
|
||||
ati_i2c_set_scl_sda(0, 1);
|
||||
if (bit)
|
||||
byte |= (1 << (7-i));
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
static void ati_i2c_edid(void)
|
||||
{
|
||||
u8 byte;
|
||||
int i;
|
||||
|
||||
ati_i2c_start();
|
||||
ati_i2c_send_byte(0x50 << 1 | 1);
|
||||
ati_i2c_ack();
|
||||
for (i = 0; i < 128; i++) {
|
||||
byte = ati_i2c_recv_byte();
|
||||
ati_i2c_ack();
|
||||
SET_VGA(VBE_edid[i], byte);
|
||||
}
|
||||
ati_i2c_stop();
|
||||
}
|
||||
|
||||
static void ati_i2c_edid_radeon(void)
|
||||
{
|
||||
int valid;
|
||||
|
||||
SET_VGA(ati_i2c_bit_scl_out, 17);
|
||||
SET_VGA(ati_i2c_bit_sda_out, 16);
|
||||
SET_VGA(ati_i2c_bit_sda_in, 8);
|
||||
|
||||
dprintf(1, "ati: reading edid blob (radeon vga) ... \n");
|
||||
SET_VGA(ati_i2c_reg, GPIO_VGA_DDC);
|
||||
ati_i2c_edid();
|
||||
valid = (GET_GLOBAL(VBE_edid[0]) == 0x00 &&
|
||||
GET_GLOBAL(VBE_edid[1]) == 0xff);
|
||||
dprintf(1, "ati: ... %s\n", valid ? "good" : "invalid");
|
||||
if (valid)
|
||||
return;
|
||||
|
||||
dprintf(1, "ati: reading edid blob (radeon dvi) ... \n");
|
||||
SET_VGA(ati_i2c_reg, GPIO_DVI_DDC);
|
||||
ati_i2c_edid();
|
||||
valid = (GET_GLOBAL(VBE_edid[0]) == 0x00 &&
|
||||
GET_GLOBAL(VBE_edid[1]) == 0xff);
|
||||
dprintf(1, "ati: ... %s\n", valid ? "good" : "invalid");
|
||||
}
|
||||
|
||||
static void ati_i2c_edid_rage128(void)
|
||||
{
|
||||
int valid;
|
||||
|
||||
SET_VGA(ati_i2c_bit_enable, 25);
|
||||
SET_VGA(ati_i2c_bit_scl_out, 18);
|
||||
SET_VGA(ati_i2c_bit_sda_out, 17);
|
||||
SET_VGA(ati_i2c_bit_sda_in, 9);
|
||||
SET_VGA(ati_i2c_reg, GPIO_MONID);
|
||||
|
||||
dprintf(1, "ati: reading edid blob (rage128) ... \n");
|
||||
ati_i2c_edid();
|
||||
valid = (GET_GLOBAL(VBE_edid[0]) == 0x00 &&
|
||||
GET_GLOBAL(VBE_edid[1]) == 0xff);
|
||||
dprintf(1, "ati: ... %s\n", valid ? "good" : "invalid");
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* init
|
||||
****************************************************************/
|
||||
|
||||
int
|
||||
ati_setup(void)
|
||||
{
|
||||
int ret = stdvga_setup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dprintf(1, "%s:%d\n", __func__, __LINE__);
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return 0;
|
||||
|
||||
int bdf = GET_GLOBAL(VgaBDF);
|
||||
if (!CONFIG_VGA_PCI || bdf == 0)
|
||||
return 0;
|
||||
|
||||
u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_0);
|
||||
u32 lfb_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
|
||||
pci_config_writel(bdf, PCI_BASE_ADDRESS_0, ~0);
|
||||
u32 barmask = pci_config_readl(bdf, PCI_BASE_ADDRESS_0);
|
||||
u32 totalmem = ~(barmask & PCI_BASE_ADDRESS_MEM_MASK) + 1;
|
||||
pci_config_writel(bdf, PCI_BASE_ADDRESS_0, bar);
|
||||
|
||||
bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_1);
|
||||
u32 io_addr = bar & PCI_BASE_ADDRESS_IO_MASK;
|
||||
|
||||
bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_2);
|
||||
u32 mmio_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
|
||||
|
||||
dprintf(1, "ati: bdf %02x:%02x.%x, lfb 0x%x, %d MB, io 0x%x, mmio 0x%x\n",
|
||||
pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
|
||||
lfb_addr, totalmem / (1024 * 1024), io_addr, mmio_addr);
|
||||
|
||||
SET_VGA(VBE_framebuffer, lfb_addr);
|
||||
SET_VGA(VBE_total_memory, totalmem);
|
||||
SET_VGA(ati_io_addr, io_addr);
|
||||
|
||||
// Validate modes
|
||||
struct generic_svga_mode *m = svga_modes;
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
for (; m < &svga_modes[mcount]; m++) {
|
||||
u8 memmodel = GET_GLOBAL(m->info.memmodel);
|
||||
u16 width = GET_GLOBAL(m->info.width);
|
||||
u16 height = GET_GLOBAL(m->info.height);
|
||||
u32 mem = (height * DIV_ROUND_UP(width * vga_bpp(&m->info), 8)
|
||||
* stdvga_vram_ratio(&m->info));
|
||||
|
||||
if (width % 8 != 0 ||
|
||||
width > 0x7ff * 8 ||
|
||||
height > 0xfff ||
|
||||
mem > totalmem ||
|
||||
memmodel != MM_DIRECT) {
|
||||
dprintf(3, "ati: removing mode 0x%x\n", GET_GLOBAL(m->mode));
|
||||
SET_VGA(m->mode, 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
u16 device = pci_config_readw(bdf, PCI_DEVICE_ID);
|
||||
switch (device) {
|
||||
case 0x5046:
|
||||
ati_i2c_edid_rage128();
|
||||
break;
|
||||
case 0x5159:
|
||||
ati_i2c_edid_radeon();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Simple framebuffer vgabios for use with qemu bochs-display device
|
||||
//
|
||||
// Copyright (C) 2019 Gerd Hoffmann <kraxel@redhat.com>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_BDA
|
||||
#include "output.h" // dprintf
|
||||
#include "string.h" // memset16_far
|
||||
#include "bochsvga.h" // VBE_BOCHS_*
|
||||
#include "hw/pci.h" // pci_config_readl
|
||||
#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
|
||||
#define FRAMEBUFFER_WIDTH 1024
|
||||
#define FRAMEBUFFER_HEIGHT 768
|
||||
#define FRAMEBUFFER_BPP 4
|
||||
|
||||
int
|
||||
bochs_display_setup(void)
|
||||
{
|
||||
dprintf(1, "bochs-display: setup called\n");
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return 0;
|
||||
|
||||
int bdf = GET_GLOBAL(VgaBDF);
|
||||
if (bdf == 0)
|
||||
return 0;
|
||||
|
||||
u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_0);
|
||||
u32 lfb_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
|
||||
bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_2);
|
||||
u32 io_addr = bar & PCI_BASE_ADDRESS_IO_MASK;
|
||||
dprintf(1, "bochs-display: bdf %02x:%02x.%x, bar 0 at 0x%x, bar 1 at 0x%x\n"
|
||||
, pci_bdf_to_bus(bdf) , pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
|
||||
lfb_addr, io_addr);
|
||||
|
||||
u16 *dispi = (void*)(io_addr + 0x500);
|
||||
u8 *vga = (void*)(io_addr + 0x400);
|
||||
u16 id = readw(dispi + VBE_DISPI_INDEX_ID);
|
||||
dprintf(1, "bochs-display: id is 0x%x, %s\n", id
|
||||
, id == VBE_DISPI_ID5 ? "good" : "FAIL");
|
||||
if (id != VBE_DISPI_ID5)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
u8 *edid = (void*)(io_addr);
|
||||
for (i = 0; i < sizeof(VBE_edid); i++)
|
||||
SET_VGA(VBE_edid[i], readb(edid + i));
|
||||
|
||||
int fb_width = FRAMEBUFFER_WIDTH;
|
||||
int fb_height = FRAMEBUFFER_HEIGHT;
|
||||
if (GET_GLOBAL(VBE_edid[0]) == 0x00 &&
|
||||
GET_GLOBAL(VBE_edid[1]) == 0xff) {
|
||||
fb_width = GET_GLOBAL(VBE_edid[54 + 2]);
|
||||
fb_width |= (GET_GLOBAL(VBE_edid[54 + 4]) & 0xf0) << 4;
|
||||
fb_height = GET_GLOBAL(VBE_edid[54 + 5]);
|
||||
fb_height |= (GET_GLOBAL(VBE_edid[54 + 7]) & 0xf0) << 4;
|
||||
}
|
||||
int fb_stride = FRAMEBUFFER_BPP * fb_width;
|
||||
|
||||
dprintf(1, "bochs-display: using %dx%d, %d bpp (%d stride)\n"
|
||||
, fb_width, fb_height
|
||||
, FRAMEBUFFER_BPP * 8, fb_stride);
|
||||
|
||||
cbvga_setup_modes(lfb_addr, FRAMEBUFFER_BPP * 8,
|
||||
fb_width, fb_height, fb_stride);
|
||||
|
||||
writew(dispi + VBE_DISPI_INDEX_XRES, fb_width);
|
||||
writew(dispi + VBE_DISPI_INDEX_YRES, fb_height);
|
||||
writew(dispi + VBE_DISPI_INDEX_BPP, FRAMEBUFFER_BPP * 8);
|
||||
writew(dispi + VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
|
||||
|
||||
writeb(vga, 0x20); /* unblank (for qemu -device VGA) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
// Bochs VGA interface to extended "VBE" modes
|
||||
//
|
||||
// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2011 Julian Pidancet <julian.pidancet@citrix.com>
|
||||
// Copyright (C) 2002 Jeroen Janssen
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_GLOBAL
|
||||
#include "bochsvga.h" // bochsvga_set_mode
|
||||
#include "config.h" // CONFIG_*
|
||||
#include "hw/pci.h" // pci_config_readl
|
||||
#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
|
||||
#include "output.h" // dprintf
|
||||
#include "std/vbe.h" // VBE_CAPABILITY_8BIT_DAC
|
||||
#include "stdvga.h" // stdvga_get_linelength
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
#include "x86.h" // outw
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Mode tables
|
||||
****************************************************************/
|
||||
|
||||
#include "svgamodes.h"
|
||||
|
||||
static int dispi_found VAR16 = 0;
|
||||
|
||||
static int is_bochsvga_mode(struct vgamode_s *vmode_g)
|
||||
{
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
|
||||
return (vmode_g >= &svga_modes[0].info
|
||||
&& vmode_g <= &svga_modes[mcount-1].info);
|
||||
}
|
||||
|
||||
struct vgamode_s *bochsvga_find_mode(int mode)
|
||||
{
|
||||
struct generic_svga_mode *m = svga_modes;
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
|
||||
if (GET_GLOBAL(dispi_found))
|
||||
for (; m < &svga_modes[mcount]; m++)
|
||||
if (GET_GLOBAL(m->mode) == mode)
|
||||
return &m->info;
|
||||
return stdvga_find_mode(mode);
|
||||
}
|
||||
|
||||
void
|
||||
bochsvga_list_modes(u16 seg, u16 *dest, u16 *last)
|
||||
{
|
||||
struct generic_svga_mode *m = svga_modes;
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
|
||||
if (GET_GLOBAL(dispi_found)) {
|
||||
for (; m < &svga_modes[mcount] && dest<last; m++) {
|
||||
u16 mode = GET_GLOBAL(m->mode);
|
||||
if (mode == 0xffff)
|
||||
continue;
|
||||
SET_FARVAR(seg, *dest, mode);
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
stdvga_list_modes(seg, dest, last);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Helper functions
|
||||
****************************************************************/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static u8
|
||||
bochsvga_dispi_enabled(void)
|
||||
{
|
||||
if (!GET_GLOBAL(dispi_found))
|
||||
return 0;
|
||||
u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
|
||||
if (!(en & VBE_DISPI_ENABLED))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_get_window(struct vgamode_s *curmode_g, int window)
|
||||
{
|
||||
if (!bochsvga_dispi_enabled())
|
||||
return stdvga_get_window(curmode_g, window);
|
||||
if (window != 0)
|
||||
return -1;
|
||||
return dispi_read(VBE_DISPI_INDEX_BANK);
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_set_window(struct vgamode_s *curmode_g, int window, int val)
|
||||
{
|
||||
if (!bochsvga_dispi_enabled())
|
||||
return stdvga_set_window(curmode_g, window, val);
|
||||
if (window != 0)
|
||||
return -1;
|
||||
dispi_write(VBE_DISPI_INDEX_BANK, val);
|
||||
if (dispi_read(VBE_DISPI_INDEX_BANK) != val)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_get_linelength(struct vgamode_s *curmode_g)
|
||||
{
|
||||
if (!bochsvga_dispi_enabled())
|
||||
return stdvga_get_linelength(curmode_g);
|
||||
return dispi_read(VBE_DISPI_INDEX_VIRT_WIDTH) * vga_bpp(curmode_g) / 8;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_set_linelength(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
stdvga_set_linelength(curmode_g, val);
|
||||
if (bochsvga_dispi_enabled()) {
|
||||
int pixels = (val * 8) / vga_bpp(curmode_g);
|
||||
dispi_write(VBE_DISPI_INDEX_VIRT_WIDTH, pixels);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_get_displaystart(struct vgamode_s *curmode_g)
|
||||
{
|
||||
if (!bochsvga_dispi_enabled())
|
||||
return stdvga_get_displaystart(curmode_g);
|
||||
int bpp = vga_bpp(curmode_g);
|
||||
int linelength = dispi_read(VBE_DISPI_INDEX_VIRT_WIDTH) * bpp / 8;
|
||||
int x = dispi_read(VBE_DISPI_INDEX_X_OFFSET);
|
||||
int y = dispi_read(VBE_DISPI_INDEX_Y_OFFSET);
|
||||
return x * bpp / 8 + linelength * y;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_set_displaystart(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
stdvga_set_displaystart(curmode_g, val);
|
||||
if (bochsvga_dispi_enabled()) {
|
||||
int bpp = vga_bpp(curmode_g);
|
||||
int linelength = dispi_read(VBE_DISPI_INDEX_VIRT_WIDTH) * bpp / 8;
|
||||
if (!linelength)
|
||||
return 0;
|
||||
dispi_write(VBE_DISPI_INDEX_X_OFFSET, (val % linelength) * 8 / bpp);
|
||||
dispi_write(VBE_DISPI_INDEX_Y_OFFSET, val / linelength);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_get_dacformat(struct vgamode_s *curmode_g)
|
||||
{
|
||||
if (!bochsvga_dispi_enabled())
|
||||
return stdvga_get_dacformat(curmode_g);
|
||||
u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
|
||||
return (en & VBE_DISPI_8BIT_DAC) ? 8 : 6;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_set_dacformat(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
if (!bochsvga_dispi_enabled())
|
||||
return stdvga_set_dacformat(curmode_g, val);
|
||||
u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
|
||||
if (val == 6)
|
||||
en &= ~VBE_DISPI_8BIT_DAC;
|
||||
else if (val == 8)
|
||||
en |= VBE_DISPI_8BIT_DAC;
|
||||
else
|
||||
return -1;
|
||||
dispi_write(VBE_DISPI_INDEX_ENABLE, en);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bochsvga_save_state(u16 seg, u16 *info)
|
||||
{
|
||||
u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
|
||||
SET_FARVAR(seg, *info, en);
|
||||
info++;
|
||||
if (!(en & VBE_DISPI_ENABLED))
|
||||
return 0;
|
||||
int i;
|
||||
for (i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++)
|
||||
if (i != VBE_DISPI_INDEX_ENABLE) {
|
||||
u16 v = dispi_read(i);
|
||||
SET_FARVAR(seg, *info, v);
|
||||
info++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bochsvga_restore_state(u16 seg, u16 *info)
|
||||
{
|
||||
u16 en = GET_FARVAR(seg, *info);
|
||||
info++;
|
||||
if (!(en & VBE_DISPI_ENABLED)) {
|
||||
dispi_write(VBE_DISPI_INDEX_ENABLE, en);
|
||||
return 0;
|
||||
}
|
||||
int i;
|
||||
for (i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++)
|
||||
if (i == VBE_DISPI_INDEX_ENABLE) {
|
||||
dispi_write(i, en);
|
||||
} else {
|
||||
dispi_write(i, GET_FARVAR(seg, *info));
|
||||
info++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bochsvga_save_restore(int cmd, u16 seg, void *data)
|
||||
{
|
||||
int ret = stdvga_save_restore(cmd, seg, data);
|
||||
if (ret < 0 || !(cmd & SR_REGISTERS) || !GET_GLOBAL(dispi_found))
|
||||
return ret;
|
||||
|
||||
u16 *info = (data + ret);
|
||||
if (cmd & SR_SAVE)
|
||||
bochsvga_save_state(seg, info);
|
||||
if (cmd & SR_RESTORE)
|
||||
bochsvga_restore_state(seg, info);
|
||||
return ret + (VBE_DISPI_INDEX_Y_OFFSET-VBE_DISPI_INDEX_XRES+1)*sizeof(u16);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Mode setting
|
||||
****************************************************************/
|
||||
|
||||
int
|
||||
bochsvga_set_mode(struct vgamode_s *vmode_g, int flags)
|
||||
{
|
||||
if (GET_GLOBAL(dispi_found))
|
||||
dispi_write(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
if (! is_bochsvga_mode(vmode_g))
|
||||
return stdvga_set_mode(vmode_g, flags);
|
||||
if (!GET_GLOBAL(dispi_found))
|
||||
return -1;
|
||||
|
||||
u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
|
||||
if (memmodel == MM_PLANAR)
|
||||
stdvga_set_mode(stdvga_find_mode(0x6a), 0);
|
||||
if (memmodel == MM_PACKED && !(flags & MF_NOPALETTE))
|
||||
stdvga_set_packed_palette();
|
||||
|
||||
dispi_write(VBE_DISPI_INDEX_BPP, GET_GLOBAL(vmode_g->depth));
|
||||
u16 width = GET_GLOBAL(vmode_g->width);
|
||||
u16 height = GET_GLOBAL(vmode_g->height);
|
||||
dispi_write(VBE_DISPI_INDEX_XRES, width);
|
||||
dispi_write(VBE_DISPI_INDEX_YRES, height);
|
||||
dispi_write(VBE_DISPI_INDEX_BANK, 0);
|
||||
u16 bf = ((flags & MF_NOCLEARMEM ? VBE_DISPI_NOCLEARMEM : 0)
|
||||
| (flags & MF_LINEARFB ? VBE_DISPI_LFB_ENABLED : 0));
|
||||
dispi_write(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | bf);
|
||||
|
||||
/* VGA compat setup */
|
||||
u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
|
||||
stdvga_crtc_write(crtc_addr, 0x11, 0x00);
|
||||
stdvga_crtc_write(crtc_addr, 0x01, width / 8 - 1);
|
||||
stdvga_set_linelength(vmode_g, width);
|
||||
stdvga_set_vertical_size(height);
|
||||
|
||||
stdvga_crtc_write(crtc_addr, 0x09, 0x00);
|
||||
stdvga_crtc_mask(crtc_addr, 0x17, 0x00, 0x03);
|
||||
stdvga_attr_mask(0x10, 0x00, 0x01);
|
||||
stdvga_grdc_write(0x06, 0x05);
|
||||
stdvga_sequ_write(0x02, 0x0f);
|
||||
if (memmodel != MM_PLANAR) {
|
||||
stdvga_crtc_mask(crtc_addr, 0x14, 0x00, 0x40);
|
||||
stdvga_attr_mask(0x10, 0x00, 0x40);
|
||||
stdvga_sequ_mask(0x04, 0x00, 0x08);
|
||||
stdvga_grdc_mask(0x05, 0x20, 0x40);
|
||||
}
|
||||
stdvga_attrindex_write(0x20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Init
|
||||
****************************************************************/
|
||||
|
||||
int
|
||||
bochsvga_setup(void)
|
||||
{
|
||||
int ret = stdvga_setup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 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, falling back to stdvga\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5);
|
||||
SET_VGA(dispi_found, 1);
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return 0;
|
||||
|
||||
u32 lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
|
||||
u32 io_addr = 0;
|
||||
int bdf = GET_GLOBAL(VgaBDF);
|
||||
if (CONFIG_VGA_PCI && bdf >= 0) {
|
||||
u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
|
||||
int barid, bar;
|
||||
switch (vendor) {
|
||||
case 0x15ad: /* qemu vmware vga */
|
||||
barid = 1;
|
||||
break;
|
||||
case 0x1234: /* stdvga */
|
||||
bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_2);
|
||||
io_addr = bar & PCI_BASE_ADDRESS_IO_MASK;
|
||||
barid = 0;
|
||||
break;
|
||||
default: /* qxl, virtio */
|
||||
barid = 0;
|
||||
break;
|
||||
}
|
||||
bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_0 + barid * 4);
|
||||
lfb_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
|
||||
dprintf(1, "VBE DISPI: bdf %02x:%02x.%x, bar %d\n", pci_bdf_to_bus(bdf)
|
||||
, pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf), barid);
|
||||
}
|
||||
|
||||
SET_VGA(VBE_framebuffer, lfb_addr);
|
||||
u32 totalmem = dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K) * 64 * 1024;
|
||||
SET_VGA(VBE_total_memory, totalmem);
|
||||
SET_VGA(VBE_win_granularity, 64);
|
||||
SET_VGA(VBE_capabilities, VBE_CAPABILITY_8BIT_DAC);
|
||||
|
||||
dprintf(1, "VBE DISPI: lfb_addr=%x, size %d MB\n",
|
||||
lfb_addr, totalmem >> 20);
|
||||
|
||||
// Validate modes
|
||||
u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
|
||||
dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS);
|
||||
u16 max_xres = dispi_read(VBE_DISPI_INDEX_XRES);
|
||||
u16 max_bpp = dispi_read(VBE_DISPI_INDEX_BPP);
|
||||
dispi_write(VBE_DISPI_INDEX_ENABLE, en);
|
||||
struct generic_svga_mode *m = svga_modes;
|
||||
unsigned int mcount = GET_GLOBAL(svga_mcount);
|
||||
for (; m < &svga_modes[mcount]; m++) {
|
||||
u16 width = GET_GLOBAL(m->info.width);
|
||||
u16 height = GET_GLOBAL(m->info.height);
|
||||
u8 depth = GET_GLOBAL(m->info.depth);
|
||||
u32 mem = (height * DIV_ROUND_UP(width * vga_bpp(&m->info), 8)
|
||||
* stdvga_vram_ratio(&m->info));
|
||||
|
||||
if (width > max_xres || depth > max_bpp || mem > totalmem) {
|
||||
dprintf(1, "Removing mode %x\n", GET_GLOBAL(m->mode));
|
||||
SET_VGA(m->mode, 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
if (io_addr) {
|
||||
int i;
|
||||
u8 *edid = (void*)(io_addr);
|
||||
for (i = 0; i < sizeof(VBE_edid); i++)
|
||||
SET_VGA(VBE_edid[i], readb(edid + i));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef __BOCHSVGA_H
|
||||
#define __BOCHSVGA_H
|
||||
|
||||
#include "types.h" // u8
|
||||
|
||||
#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
|
||||
|
||||
struct vgamode_s *bochsvga_find_mode(int mode);
|
||||
void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last);
|
||||
int bochsvga_get_window(struct vgamode_s *curmode_g, int window);
|
||||
int bochsvga_set_window(struct vgamode_s *curmode_g, int window, int val);
|
||||
int bochsvga_get_linelength(struct vgamode_s *curmode_g);
|
||||
int bochsvga_set_linelength(struct vgamode_s *curmode_g, int val);
|
||||
int bochsvga_get_displaystart(struct vgamode_s *curmode_g);
|
||||
int bochsvga_set_displaystart(struct vgamode_s *curmode_g, int val);
|
||||
int bochsvga_get_dacformat(struct vgamode_s *curmode_g);
|
||||
int bochsvga_set_dacformat(struct vgamode_s *curmode_g, int val);
|
||||
int bochsvga_save_restore(int cmd, u16 seg, void *data);
|
||||
int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags);
|
||||
int bochsvga_setup(void);
|
||||
|
||||
#endif // bochsvga.h
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
// Simple framebuffer vgabios for use with coreboot native vga init.
|
||||
//
|
||||
// Copyright (C) 2014 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_BDA
|
||||
#include "output.h" // dprintf
|
||||
#include "stdvga.h" // SEG_CTEXT
|
||||
#include "string.h" // memset16_far
|
||||
#include "util.h" // find_cb_table
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgafb.h" // handle_gfx_op
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
#include "svgamodes.h" // svga_modes
|
||||
|
||||
static int CBmode VAR16;
|
||||
static struct vgamode_s CBmodeinfo VAR16;
|
||||
static struct vgamode_s CBemulinfo VAR16;
|
||||
static u32 CBlinelength VAR16;
|
||||
|
||||
struct vgamode_s *cbvga_find_mode(int mode)
|
||||
{
|
||||
if (mode == GET_GLOBAL(CBmode))
|
||||
return &CBmodeinfo;
|
||||
if (mode == 0x03)
|
||||
return &CBemulinfo;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < GET_GLOBAL(svga_mcount); i++) {
|
||||
struct generic_svga_mode *cbmode_g = &svga_modes[i];
|
||||
if (GET_GLOBAL(cbmode_g->mode) == 0xffff)
|
||||
continue;
|
||||
if (GET_GLOBAL(cbmode_g->mode) == mode)
|
||||
return &cbmode_g->info;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
cbvga_list_modes(u16 seg, u16 *dest, u16 *last)
|
||||
{
|
||||
int seen = 0;
|
||||
|
||||
if (GET_GLOBAL(CBmode) != 0x3) {
|
||||
/* Advertise additional SVGA modes for Microsoft NTLDR graphical mode.
|
||||
* Microsoft NTLDR:
|
||||
* + Graphical mode uses a maximum resolution of 1600x1200.
|
||||
* + Expects to find VESA mode with 800x600 or 1024x768.
|
||||
* + 24 Bpp and 32 Bpp are supported
|
||||
*/
|
||||
int i;
|
||||
for (i = 0; i < GET_GLOBAL(svga_mcount) && dest < last; i++) {
|
||||
struct generic_svga_mode *cbmode_g = &svga_modes[i];
|
||||
u16 mode = GET_GLOBAL(cbmode_g->mode);
|
||||
if (mode == 0xffff)
|
||||
continue;
|
||||
SET_FARVAR(seg, *dest, mode);
|
||||
dest++;
|
||||
if (GET_GLOBAL(CBmode) == mode)
|
||||
seen = 1;
|
||||
}
|
||||
}
|
||||
if (dest < last && !seen) {
|
||||
SET_FARVAR(seg, *dest, GET_GLOBAL(CBmode));
|
||||
dest++;
|
||||
}
|
||||
SET_FARVAR(seg, *dest, 0xffff);
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_get_window(struct vgamode_s *curmode_g, int window)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_set_window(struct vgamode_s *curmode_g, int window, int val)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_minimum_linelength(struct vgamode_s *vmode_g)
|
||||
{
|
||||
/* Can't change mode, always report active pitch. */
|
||||
return GET_GLOBAL(CBlinelength);
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_get_linelength(struct vgamode_s *curmode_g)
|
||||
{
|
||||
return GET_GLOBAL(CBlinelength);
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_set_linelength(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_get_displaystart(struct vgamode_s *curmode_g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_set_displaystart(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_get_dacformat(struct vgamode_s *curmode_g)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_set_dacformat(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_save_restore(int cmd, u16 seg, void *data)
|
||||
{
|
||||
if (cmd & (SR_HARDWARE|SR_DAC|SR_REGISTERS))
|
||||
return -1;
|
||||
return bda_save_restore(cmd, seg, data);
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_set_mode(struct vgamode_s *vmode_g, int flags)
|
||||
{
|
||||
u8 emul = vmode_g == &CBemulinfo || GET_GLOBAL(CBmode) == 0x03;
|
||||
/*
|
||||
* The extra_stack flag is false when running in windows x86
|
||||
* emulator, to avoid stack switching triggering bugs. Using the
|
||||
* same flag here to skip screen clearing, because the windows
|
||||
* emulator seems to have problems to handle the int 1587 call
|
||||
* too, and GO_MEMSET uses that.
|
||||
*/
|
||||
u8 extra_stack = GET_BDA_EXT(flags) & BF_EXTRA_STACK;
|
||||
MASK_BDA_EXT(flags, BF_EMULATE_TEXT, emul ? BF_EMULATE_TEXT : 0);
|
||||
if (!(flags & MF_NOCLEARMEM)) {
|
||||
if (GET_GLOBAL(CBmodeinfo.memmodel) == MM_TEXT) {
|
||||
memset16_far(SEG_CTEXT, (void*)0, 0x0720, 80*25*2);
|
||||
return 0;
|
||||
}
|
||||
if (extra_stack || flags & MF_LEGACY) {
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, &CBmodeinfo);
|
||||
op.x = op.y = 0;
|
||||
op.xlen = GET_GLOBAL(CBmodeinfo.width);
|
||||
op.ylen = GET_GLOBAL(CBmodeinfo.height);
|
||||
op.op = GO_MEMSET;
|
||||
handle_gfx_op(&op);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CB_TAG_FRAMEBUFFER 0x0012
|
||||
struct cb_framebuffer {
|
||||
u32 tag;
|
||||
u32 size;
|
||||
|
||||
u64 physical_address;
|
||||
u32 x_resolution;
|
||||
u32 y_resolution;
|
||||
u32 bytes_per_line;
|
||||
u8 bits_per_pixel;
|
||||
u8 red_mask_pos;
|
||||
u8 red_mask_size;
|
||||
u8 green_mask_pos;
|
||||
u8 green_mask_size;
|
||||
u8 blue_mask_pos;
|
||||
u8 blue_mask_size;
|
||||
u8 reserved_mask_pos;
|
||||
u8 reserved_mask_size;
|
||||
};
|
||||
|
||||
void
|
||||
cbvga_setup_modes(u64 addr, u8 bpp, u32 xlines, u32 ylines, u32 linelength)
|
||||
{
|
||||
int i;
|
||||
|
||||
SET_VGA(CBmode, 0x140);
|
||||
SET_VGA(VBE_framebuffer, addr);
|
||||
SET_VGA(VBE_total_memory, linelength * ylines);
|
||||
SET_VGA(CBlinelength, linelength);
|
||||
SET_VGA(CBmodeinfo.memmodel, MM_DIRECT);
|
||||
SET_VGA(CBmodeinfo.width, xlines);
|
||||
SET_VGA(CBmodeinfo.height, ylines);
|
||||
SET_VGA(CBmodeinfo.depth, bpp);
|
||||
SET_VGA(CBmodeinfo.cwidth, 8);
|
||||
SET_VGA(CBmodeinfo.cheight, 16);
|
||||
memcpy_far(get_global_seg(), &CBemulinfo
|
||||
, get_global_seg(), &CBmodeinfo, sizeof(CBemulinfo));
|
||||
|
||||
// Validate modes
|
||||
for (i = 0; i < GET_GLOBAL(svga_mcount); i++) {
|
||||
struct generic_svga_mode *cbmode_g = &svga_modes[i];
|
||||
/* Skip VBE modes that doesn't fit into coreboot's framebuffer */
|
||||
if ((GET_GLOBAL(cbmode_g->info.memmodel) != MM_DIRECT)
|
||||
|| (GET_GLOBAL(cbmode_g->info.height) > ylines)
|
||||
|| (GET_GLOBAL(cbmode_g->info.width) > xlines)
|
||||
|| (GET_GLOBAL(cbmode_g->info.depth) != bpp)) {
|
||||
dprintf(3, "Removing mode %x\n", GET_GLOBAL(cbmode_g->mode));
|
||||
SET_VGA(cbmode_g->mode, 0xffff);
|
||||
}
|
||||
if ((GET_GLOBAL(cbmode_g->info.height) == ylines)
|
||||
&& (GET_GLOBAL(cbmode_g->info.width) == xlines)
|
||||
&& (GET_GLOBAL(cbmode_g->info.depth) == bpp)) {
|
||||
SET_VGA(CBmode, GET_GLOBAL(cbmode_g->mode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cbvga_setup(void)
|
||||
{
|
||||
dprintf(1, "coreboot vga init\n");
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return 0;
|
||||
|
||||
struct cb_header *cbh = find_cb_table();
|
||||
if (!cbh) {
|
||||
dprintf(1, "Unable to find coreboot table\n");
|
||||
return -1;
|
||||
}
|
||||
struct cb_framebuffer *cbfb = find_cb_subtable(cbh, CB_TAG_FRAMEBUFFER);
|
||||
if (!cbfb) {
|
||||
// Assume there is an EGA text framebuffer.
|
||||
dprintf(1, "Did not find coreboot framebuffer - assuming EGA text\n");
|
||||
SET_VGA(CBmode, 0x03);
|
||||
SET_VGA(CBlinelength, 80*2);
|
||||
SET_VGA(CBmodeinfo.memmodel, MM_TEXT);
|
||||
SET_VGA(CBmodeinfo.width, 80);
|
||||
SET_VGA(CBmodeinfo.height, 25);
|
||||
SET_VGA(CBmodeinfo.depth, 4);
|
||||
SET_VGA(CBmodeinfo.cwidth, 9);
|
||||
SET_VGA(CBmodeinfo.cheight, 16);
|
||||
SET_VGA(CBmodeinfo.sstart, SEG_CTEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 addr = GET_FARVAR(0, cbfb->physical_address);
|
||||
u8 bpp = GET_FARVAR(0, cbfb->blue_mask_size)
|
||||
+ GET_FARVAR(0, cbfb->green_mask_size)
|
||||
+ GET_FARVAR(0, cbfb->red_mask_size)
|
||||
+ GET_FARVAR(0, cbfb->reserved_mask_size);
|
||||
u32 xlines = GET_FARVAR(0, cbfb->x_resolution);
|
||||
u32 ylines = GET_FARVAR(0, cbfb->y_resolution);
|
||||
u32 linelength = GET_FARVAR(0, cbfb->bytes_per_line);
|
||||
//fall back to coreboot reported bpp if calculated value invalid
|
||||
if (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32)
|
||||
bpp = GET_FARVAR(0, cbfb->bits_per_pixel);
|
||||
|
||||
dprintf(1, "Found FB @ %llx %dx%d with %d bpp (%d stride)\n"
|
||||
, addr, xlines, ylines, bpp, linelength);
|
||||
|
||||
if (!addr || addr > 0xffffffff
|
||||
|| (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32)) {
|
||||
dprintf(1, "Unable to use FB\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cbvga_setup_modes(addr, bpp, xlines, ylines, linelength);
|
||||
return 0;
|
||||
}
|
||||
+627
@@ -0,0 +1,627 @@
|
||||
// QEMU Cirrus CLGD 54xx VGABIOS Extension.
|
||||
//
|
||||
// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (c) 2004 Makoto Suzuki (suzu)
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_GLOBAL
|
||||
#include "bregs.h" // struct bregs
|
||||
#include "hw/pci.h" // pci_config_readl
|
||||
#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
|
||||
#include "output.h" // dprintf
|
||||
#include "stdvga.h" // VGAREG_SEQU_ADDRESS
|
||||
#include "string.h" // memset16_far
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Cirrus mode tables
|
||||
****************************************************************/
|
||||
|
||||
/* VGA */
|
||||
static u16 cseq_vga[] VAR16 = {0x0007,0xffff};
|
||||
static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff};
|
||||
static u16 ccrtc_vga[] VAR16 = {0x001a,0x001b,0x001d,0xffff};
|
||||
|
||||
/* extensions */
|
||||
static u16 cgraph_svgacolor[] VAR16 = {
|
||||
0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,
|
||||
0x0009,0x000a,0x000b,
|
||||
0xffff
|
||||
};
|
||||
/* 640x480x8 */
|
||||
static u16 cseq_640x480x8[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
|
||||
0x580b,0x580c,0x580d,0x580e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x331b,0x331c,0x331d,0x331e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_640x480x8[] VAR16 = {
|
||||
0x2c11,
|
||||
0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
|
||||
0x4009,0x000c,0x000d,
|
||||
0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 640x480x16 */
|
||||
static u16 cseq_640x480x16[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
|
||||
0x580b,0x580c,0x580d,0x580e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x331b,0x331c,0x331d,0x331e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_640x480x16[] VAR16 = {
|
||||
0x2c11,
|
||||
0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
|
||||
0x4009,0x000c,0x000d,
|
||||
0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 640x480x24 */
|
||||
static u16 cseq_640x480x24[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
|
||||
0x580b,0x580c,0x580d,0x580e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x331b,0x331c,0x331d,0x331e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_640x480x24[] VAR16 = {
|
||||
0x2c11,
|
||||
0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
|
||||
0x4009,0x000c,0x000d,
|
||||
0xea10,0xdf12,0xf013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 800x600x8 */
|
||||
static u16 cseq_800x600x8[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
|
||||
0x230b,0x230c,0x230d,0x230e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x141b,0x141c,0x141d,0x141e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_800x600x8[] VAR16 = {
|
||||
0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 800x600x16 */
|
||||
static u16 cseq_800x600x16[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
|
||||
0x230b,0x230c,0x230d,0x230e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x141b,0x141c,0x141d,0x141e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_800x600x16[] VAR16 = {
|
||||
0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 800x600x24 */
|
||||
static u16 cseq_800x600x24[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
|
||||
0x230b,0x230c,0x230d,0x230e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x141b,0x141c,0x141d,0x141e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_800x600x24[] VAR16 = {
|
||||
0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,
|
||||
0x001a,0x321b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 1024x768x8 */
|
||||
static u16 cseq_1024x768x8[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
|
||||
0x760b,0x760c,0x760d,0x760e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x341b,0x341c,0x341d,0x341e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_1024x768x8[] VAR16 = {
|
||||
0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 1024x768x16 */
|
||||
static u16 cseq_1024x768x16[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
|
||||
0x760b,0x760c,0x760d,0x760e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x341b,0x341c,0x341d,0x341e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_1024x768x16[] VAR16 = {
|
||||
0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,
|
||||
0x001a,0x321b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 1024x768x24 */
|
||||
static u16 cseq_1024x768x24[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
|
||||
0x760b,0x760c,0x760d,0x760e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x341b,0x341c,0x341d,0x341e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_1024x768x24[] VAR16 = {
|
||||
0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
|
||||
0x001a,0x321b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 1280x1024x8 */
|
||||
static u16 cseq_1280x1024x8[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
|
||||
0x760b,0x760c,0x760d,0x760e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x341b,0x341c,0x341d,0x341e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_1280x1024x8[] VAR16 = {
|
||||
0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
/* 1280x1024x16 */
|
||||
static u16 cseq_1280x1024x16[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
|
||||
0x760b,0x760c,0x760d,0x760e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x341b,0x341c,0x341d,0x341e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_1280x1024x16[] VAR16 = {
|
||||
0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,
|
||||
0x001a,0x321b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
|
||||
/* 1600x1200x8 */
|
||||
static u16 cseq_1600x1200x8[] VAR16 = {
|
||||
0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
|
||||
0x760b,0x760c,0x760d,0x760e,
|
||||
0x0412,0x0013,0x2017,
|
||||
0x341b,0x341c,0x341d,0x341e,
|
||||
0xffff
|
||||
};
|
||||
static u16 ccrtc_1600x1200x8[] VAR16 = {
|
||||
0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
|
||||
0x6009,0x000c,0x000d,
|
||||
0x0310,0xff12,0xc813,0x4014,0xff15,0x2416,0xc317,0xff18,
|
||||
0x001a,0x221b,0x001d,
|
||||
0xffff
|
||||
};
|
||||
|
||||
struct cirrus_mode_s {
|
||||
u16 mode, vesamode;
|
||||
struct vgamode_s info;
|
||||
|
||||
u16 hidden_dac; /* 0x3c6 */
|
||||
u16 *seq; /* 0x3c4 */
|
||||
u16 *graph; /* 0x3ce */
|
||||
u16 *crtc; /* 0x3d4 */
|
||||
};
|
||||
|
||||
static struct cirrus_mode_s cirrus_modes[] VAR16 = {
|
||||
{0x5f,0x101,{MM_PACKED,640,480,8,8,16,SEG_GRAPH},0x00,
|
||||
cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8},
|
||||
{0x64,0x111,{MM_DIRECT,640,480,16,8,16,SEG_GRAPH},0xe1,
|
||||
cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16},
|
||||
{0x66,0x110,{MM_DIRECT,640,480,15,8,16,SEG_GRAPH},0xf0,
|
||||
cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16},
|
||||
{0x71,0x112,{MM_DIRECT,640,480,24,8,16,SEG_GRAPH},0xe5,
|
||||
cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24},
|
||||
|
||||
{0x5c,0x103,{MM_PACKED,800,600,8,8,16,SEG_GRAPH},0x00,
|
||||
cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8},
|
||||
{0x65,0x114,{MM_DIRECT,800,600,16,8,16,SEG_GRAPH},0xe1,
|
||||
cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16},
|
||||
{0x67,0x113,{MM_DIRECT,800,600,15,8,16,SEG_GRAPH},0xf0,
|
||||
cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16},
|
||||
|
||||
{0x60,0x105,{MM_PACKED,1024,768,8,8,16,SEG_GRAPH},0x00,
|
||||
cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8},
|
||||
{0x74,0x117,{MM_DIRECT,1024,768,16,8,16,SEG_GRAPH},0xe1,
|
||||
cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16},
|
||||
{0x68,0x116,{MM_DIRECT,1024,768,15,8,16,SEG_GRAPH},0xf0,
|
||||
cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16},
|
||||
|
||||
{0x78,0x115,{MM_DIRECT,800,600,24,8,16,SEG_GRAPH},0xe5,
|
||||
cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24},
|
||||
{0x79,0x118,{MM_DIRECT,1024,768,24,8,16,SEG_GRAPH},0xe5,
|
||||
cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24},
|
||||
|
||||
{0x6d,0x107,{MM_PACKED,1280,1024,8,8,16,SEG_GRAPH},0x00,
|
||||
cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8},
|
||||
{0x69,0x119,{MM_DIRECT,1280,1024,15,8,16,SEG_GRAPH},0xf0,
|
||||
cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16},
|
||||
{0x75,0x11a,{MM_DIRECT,1280,1024,16,8,16,SEG_GRAPH},0xe1,
|
||||
cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16},
|
||||
|
||||
{0x7b,0xffff,{MM_PACKED,1600,1200,8,8,16,SEG_GRAPH},0x00,
|
||||
cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8},
|
||||
};
|
||||
|
||||
static struct cirrus_mode_s mode_switchback VAR16 =
|
||||
{0xfe,0xffff,{0xff},0,cseq_vga,cgraph_vga,ccrtc_vga};
|
||||
|
||||
int
|
||||
is_cirrus_mode(struct vgamode_s *vmode_g)
|
||||
{
|
||||
return (vmode_g >= &cirrus_modes[0].info
|
||||
&& vmode_g <= &cirrus_modes[ARRAY_SIZE(cirrus_modes)-1].info);
|
||||
}
|
||||
|
||||
struct vgamode_s *
|
||||
clext_find_mode(int mode)
|
||||
{
|
||||
struct cirrus_mode_s *table_g = cirrus_modes;
|
||||
while (table_g < &cirrus_modes[ARRAY_SIZE(cirrus_modes)]) {
|
||||
if (GET_GLOBAL(table_g->mode) == mode
|
||||
|| GET_GLOBAL(table_g->vesamode) == mode)
|
||||
return &table_g->info;
|
||||
table_g++;
|
||||
}
|
||||
return stdvga_find_mode(mode);
|
||||
}
|
||||
|
||||
void
|
||||
clext_list_modes(u16 seg, u16 *dest, u16 *last)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<ARRAY_SIZE(cirrus_modes) && dest<last; i++) {
|
||||
u16 mode = GET_GLOBAL(cirrus_modes[i].vesamode);
|
||||
if (mode == 0xffff)
|
||||
continue;
|
||||
SET_FARVAR(seg, *dest, mode);
|
||||
dest++;
|
||||
}
|
||||
stdvga_list_modes(seg, dest, last);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* helper functions
|
||||
****************************************************************/
|
||||
|
||||
int
|
||||
clext_get_window(struct vgamode_s *curmode_g, int window)
|
||||
{
|
||||
return stdvga_grdc_read(window + 9);
|
||||
}
|
||||
|
||||
int
|
||||
clext_set_window(struct vgamode_s *curmode_g, int window, int val)
|
||||
{
|
||||
if (val >= 0x100)
|
||||
return -1;
|
||||
stdvga_grdc_write(window + 9, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
clext_get_linelength(struct vgamode_s *curmode_g)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
u8 reg13 = stdvga_crtc_read(crtc_addr, 0x13);
|
||||
u8 reg1b = stdvga_crtc_read(crtc_addr, 0x1b);
|
||||
return (((reg1b & 0x10) << 4) + reg13) * 8 / stdvga_vram_ratio(curmode_g);
|
||||
}
|
||||
|
||||
int
|
||||
clext_set_linelength(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
val = DIV_ROUND_UP(val * stdvga_vram_ratio(curmode_g), 8);
|
||||
stdvga_crtc_write(crtc_addr, 0x13, val);
|
||||
stdvga_crtc_mask(crtc_addr, 0x1b, 0x10, (val & 0x100) >> 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
clext_get_displaystart(struct vgamode_s *curmode_g)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
u8 b2 = stdvga_crtc_read(crtc_addr, 0x0c);
|
||||
u8 b1 = stdvga_crtc_read(crtc_addr, 0x0d);
|
||||
u8 b3 = stdvga_crtc_read(crtc_addr, 0x1b);
|
||||
u8 b4 = stdvga_crtc_read(crtc_addr, 0x1d);
|
||||
int val = (b1 | (b2<<8) | ((b3 & 0x01) << 16) | ((b3 & 0x0c) << 15)
|
||||
| ((b4 & 0x80) << 12));
|
||||
return val * 4 / stdvga_vram_ratio(curmode_g);
|
||||
}
|
||||
|
||||
int
|
||||
clext_set_displaystart(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
val = val * stdvga_vram_ratio(curmode_g) / 4;
|
||||
stdvga_crtc_write(crtc_addr, 0x0d, val);
|
||||
stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
|
||||
stdvga_crtc_mask(crtc_addr, 0x1d, 0x80, (val & 0x0800) >> 4);
|
||||
stdvga_crtc_mask(crtc_addr, 0x1b, 0x0d
|
||||
, ((val & 0x0100) >> 8) | ((val & 0x0600) >> 7));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
clext_save_restore(int cmd, u16 seg, void *data)
|
||||
{
|
||||
if (cmd & SR_REGISTERS)
|
||||
return -1;
|
||||
return stdvga_save_restore(cmd, seg, data);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Mode setting
|
||||
****************************************************************/
|
||||
|
||||
static void
|
||||
cirrus_switch_mode_setregs(u16 *data, u16 port)
|
||||
{
|
||||
for (;;) {
|
||||
u16 val = GET_GLOBAL(*data);
|
||||
if (val == 0xffff)
|
||||
return;
|
||||
outw(val, port);
|
||||
data++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cirrus_switch_mode(struct cirrus_mode_s *table)
|
||||
{
|
||||
// Unlock cirrus special
|
||||
stdvga_sequ_write(0x06, 0x12);
|
||||
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), stdvga_get_crtc());
|
||||
|
||||
stdvga_pelmask_write(0x00);
|
||||
stdvga_pelmask_read();
|
||||
stdvga_pelmask_read();
|
||||
stdvga_pelmask_read();
|
||||
stdvga_pelmask_read();
|
||||
stdvga_pelmask_write(GET_GLOBAL(table->hidden_dac));
|
||||
stdvga_pelmask_write(0xff);
|
||||
|
||||
u8 memmodel = GET_GLOBAL(table->info.memmodel);
|
||||
u8 on = 0;
|
||||
if (memmodel == MM_PLANAR)
|
||||
on = 0x41;
|
||||
else if (memmodel != MM_TEXT)
|
||||
on = 0x01;
|
||||
stdvga_attr_mask(0x10, 0x01, on);
|
||||
stdvga_attrindex_write(0x20);
|
||||
}
|
||||
|
||||
static void
|
||||
cirrus_enable_16k_granularity(void)
|
||||
{
|
||||
stdvga_grdc_mask(0x0b, 0x00, 0x20);
|
||||
}
|
||||
|
||||
static void
|
||||
cirrus_clear_vram(u16 fill)
|
||||
{
|
||||
cirrus_enable_16k_granularity();
|
||||
int count = GET_GLOBAL(VBE_total_memory) / (16 * 1024);
|
||||
int i;
|
||||
for (i=0; i<count; i++) {
|
||||
stdvga_grdc_write(0x09, i);
|
||||
memset16_far(SEG_GRAPH, 0, fill, 16 * 1024);
|
||||
}
|
||||
stdvga_grdc_write(0x09, 0x00);
|
||||
}
|
||||
|
||||
int
|
||||
clext_set_mode(struct vgamode_s *vmode_g, int flags)
|
||||
{
|
||||
if (!is_cirrus_mode(vmode_g)) {
|
||||
cirrus_switch_mode(&mode_switchback);
|
||||
dprintf(1, "cirrus mode switch regular\n");
|
||||
return stdvga_set_mode(vmode_g, flags);
|
||||
}
|
||||
struct cirrus_mode_s *table_g = container_of(
|
||||
vmode_g, struct cirrus_mode_s, info);
|
||||
cirrus_switch_mode(table_g);
|
||||
if (GET_GLOBAL(vmode_g->memmodel) == MM_PACKED && !(flags & MF_NOPALETTE))
|
||||
stdvga_set_packed_palette();
|
||||
if (!(flags & MF_LINEARFB))
|
||||
cirrus_enable_16k_granularity();
|
||||
if (!(flags & MF_NOCLEARMEM))
|
||||
// fill with 0xff to keep win 2K happy
|
||||
cirrus_clear_vram(flags & MF_LEGACY ? 0xffff : 0x0000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* extbios
|
||||
****************************************************************/
|
||||
|
||||
static void
|
||||
clext_101280(struct bregs *regs)
|
||||
{
|
||||
u8 v = stdvga_crtc_read(stdvga_get_crtc(), 0x27);
|
||||
if (v == 0xa0)
|
||||
// 5430
|
||||
regs->ax = 0x0032;
|
||||
else if (v == 0xb8)
|
||||
// 5446
|
||||
regs->ax = 0x0039;
|
||||
else
|
||||
regs->ax = 0x00ff;
|
||||
regs->bx = 0x00;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
clext_101281(struct bregs *regs)
|
||||
{
|
||||
// XXX
|
||||
regs->ax = 0x0100;
|
||||
}
|
||||
|
||||
static void
|
||||
clext_101282(struct bregs *regs)
|
||||
{
|
||||
regs->al = stdvga_crtc_read(stdvga_get_crtc(), 0x27) & 0x03;
|
||||
regs->ah = 0xAF;
|
||||
}
|
||||
|
||||
static void
|
||||
clext_101285(struct bregs *regs)
|
||||
{
|
||||
regs->al = GET_GLOBAL(VBE_total_memory) / (64*1024);
|
||||
}
|
||||
|
||||
static void
|
||||
clext_10129a(struct bregs *regs)
|
||||
{
|
||||
regs->ax = 0x4060;
|
||||
regs->cx = 0x1132;
|
||||
}
|
||||
|
||||
extern void a0h_callback(void);
|
||||
ASM16(
|
||||
// fatal: not implemented yet
|
||||
"a0h_callback:"
|
||||
"cli\n"
|
||||
"hlt\n"
|
||||
"lretw");
|
||||
|
||||
static void
|
||||
clext_1012a0(struct bregs *regs)
|
||||
{
|
||||
struct vgamode_s *table_g = clext_find_mode(regs->al & 0x7f);
|
||||
regs->ah = (table_g ? 1 : 0);
|
||||
regs->bx = (u32)a0h_callback;
|
||||
regs->ds = regs->si = regs->es = regs->di = 0xffff;
|
||||
}
|
||||
|
||||
static void
|
||||
clext_1012a1(struct bregs *regs)
|
||||
{
|
||||
regs->bx = 0x0e00; // IBM 8512/8513, color
|
||||
}
|
||||
|
||||
static void
|
||||
clext_1012a2(struct bregs *regs)
|
||||
{
|
||||
regs->al = 0x07; // HSync 31.5 - 64.0 kHz
|
||||
}
|
||||
|
||||
static void
|
||||
clext_1012ae(struct bregs *regs)
|
||||
{
|
||||
regs->al = 0x01; // High Refresh 75Hz
|
||||
}
|
||||
|
||||
static void
|
||||
clext_1012XX(struct bregs *regs)
|
||||
{
|
||||
debug_stub(regs);
|
||||
}
|
||||
|
||||
void
|
||||
clext_1012(struct bregs *regs)
|
||||
{
|
||||
switch (regs->bl) {
|
||||
case 0x80: clext_101280(regs); break;
|
||||
case 0x81: clext_101281(regs); break;
|
||||
case 0x82: clext_101282(regs); break;
|
||||
case 0x85: clext_101285(regs); break;
|
||||
case 0x9a: clext_10129a(regs); break;
|
||||
case 0xa0: clext_1012a0(regs); break;
|
||||
case 0xa1: clext_1012a1(regs); break;
|
||||
case 0xa2: clext_1012a2(regs); break;
|
||||
case 0xae: clext_1012ae(regs); break;
|
||||
default: clext_1012XX(regs); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* init
|
||||
****************************************************************/
|
||||
|
||||
static int
|
||||
cirrus_check(void)
|
||||
{
|
||||
stdvga_sequ_write(0x06, 0x92);
|
||||
return stdvga_sequ_read(0x06) == 0x12;
|
||||
}
|
||||
|
||||
static u8
|
||||
cirrus_get_memsize(void)
|
||||
{
|
||||
// get DRAM band width
|
||||
u8 v = stdvga_sequ_read(0x0f);
|
||||
u8 x = (v >> 3) & 0x03;
|
||||
if (x == 0x03 && v & 0x80)
|
||||
// 4MB
|
||||
return 0x40;
|
||||
return 0x04 << x;
|
||||
}
|
||||
|
||||
int
|
||||
clext_setup(void)
|
||||
{
|
||||
int ret = stdvga_setup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dprintf(1, "cirrus init\n");
|
||||
if (! cirrus_check())
|
||||
return -1;
|
||||
dprintf(1, "cirrus init 2\n");
|
||||
|
||||
// memory setup
|
||||
stdvga_sequ_write(0x0a, stdvga_sequ_read(0x0f) & 0x18);
|
||||
// set vga mode
|
||||
stdvga_sequ_write(0x07, 0x00);
|
||||
// reset bitblt
|
||||
stdvga_grdc_write(0x31, 0x04);
|
||||
stdvga_grdc_write(0x31, 0x00);
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return 0;
|
||||
|
||||
u32 lfb_addr = 0;
|
||||
int bdf = GET_GLOBAL(VgaBDF);
|
||||
if (CONFIG_VGA_PCI && bdf >= 0)
|
||||
lfb_addr = (pci_config_readl(bdf, PCI_BASE_ADDRESS_0)
|
||||
& PCI_BASE_ADDRESS_MEM_MASK);
|
||||
SET_VGA(VBE_framebuffer, lfb_addr);
|
||||
u16 totalmem = cirrus_get_memsize();
|
||||
SET_VGA(VBE_total_memory, totalmem * 64 * 1024);
|
||||
SET_VGA(VBE_win_granularity, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
// Geode GX2/LX VGA functions
|
||||
//
|
||||
// Copyright (C) 2009 Chris Kindt
|
||||
//
|
||||
// Written for Google Summer of Code 2009 for the coreboot project
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_BDA
|
||||
#include "farptr.h" // SET_FARVAR
|
||||
#include "geodevga.h" // geodevga_setup
|
||||
#include "hw/pci.h" // pci_config_readl
|
||||
#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
|
||||
#include "output.h" // dprintf
|
||||
#include "stdvga.h" // stdvga_crtc_write
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* MSR and High Mem access through VSA Virtual Register
|
||||
****************************************************************/
|
||||
|
||||
static u64 geode_msr_read(u32 msrAddr)
|
||||
{
|
||||
union u64_u32_u val;
|
||||
asm __volatile__ (
|
||||
"movw $0x0AC1C, %%dx \n"
|
||||
"movl $0xFC530007, %%eax \n"
|
||||
"outl %%eax, %%dx \n"
|
||||
"addb $2, %%dl \n"
|
||||
"inw %%dx, %%ax \n"
|
||||
: "=a" (val.lo), "=d"(val.hi)
|
||||
: "c"(msrAddr)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
dprintf(4, "%s(0x%08x) = 0x%08x-0x%08x\n"
|
||||
, __func__, msrAddr, val.hi, val.lo);
|
||||
return val.val;
|
||||
}
|
||||
|
||||
static void geode_msr_mask(u32 msrAddr, u64 off, u64 on)
|
||||
{
|
||||
union u64_u32_u uand, uor;
|
||||
uand.val = ~off;
|
||||
uor.val = on;
|
||||
|
||||
dprintf(4, "%s(0x%08x, 0x%016llx, 0x%016llx)\n"
|
||||
, __func__, msrAddr, off, on);
|
||||
|
||||
asm __volatile__ (
|
||||
"push %%eax \n"
|
||||
"movw $0x0AC1C, %%dx \n"
|
||||
"movl $0xFC530007, %%eax \n"
|
||||
"outl %%eax, %%dx \n"
|
||||
"addb $2, %%dl \n"
|
||||
"pop %%eax \n"
|
||||
"outw %%ax, %%dx \n"
|
||||
:
|
||||
: "c"(msrAddr), "S" (uand.hi), "D" (uand.lo), "b" (uor.hi), "a" (uor.lo)
|
||||
: "%edx","cc"
|
||||
);
|
||||
}
|
||||
|
||||
static u32 geode_mem_read(u32 addr)
|
||||
{
|
||||
u32 val;
|
||||
asm __volatile__ (
|
||||
"movw $0x0AC1C, %%dx \n"
|
||||
"movl $0xFC530001, %%eax \n"
|
||||
"outl %%eax, %%dx \n"
|
||||
"addb $2, %%dl \n"
|
||||
"inw %%dx, %%ax \n"
|
||||
: "=a" (val)
|
||||
: "b"(addr)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void geode_mem_mask(u32 addr, u32 off, u32 or)
|
||||
{
|
||||
asm __volatile__ (
|
||||
"movw $0x0AC1C, %%dx \n"
|
||||
"movl $0xFC530001, %%eax \n"
|
||||
"outl %%eax, %%dx \n"
|
||||
"addb $2, %%dl \n"
|
||||
"outw %%ax, %%dx \n"
|
||||
:
|
||||
: "b"(addr), "S" (~off), "D" (or)
|
||||
: "%eax","cc"
|
||||
);
|
||||
}
|
||||
|
||||
#define VP_FP_START 0x400
|
||||
|
||||
static u32 GeodeFB VAR16;
|
||||
static u32 GeodeDC VAR16;
|
||||
static u32 GeodeVP VAR16;
|
||||
|
||||
static u32 geode_dc_read(int reg)
|
||||
{
|
||||
u32 val = geode_mem_read(GET_GLOBAL(GeodeDC) + reg);
|
||||
dprintf(4, "%s(0x%08x) = 0x%08x\n"
|
||||
, __func__, GET_GLOBAL(GeodeDC) + reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void geode_dc_write(int reg, u32 val)
|
||||
{
|
||||
dprintf(4, "%s(0x%08x, 0x%08x)\n"
|
||||
, __func__, GET_GLOBAL(GeodeDC) + reg, val);
|
||||
geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, ~0, val);
|
||||
}
|
||||
|
||||
static void geode_dc_mask(int reg, u32 off, u32 on)
|
||||
{
|
||||
dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n"
|
||||
, __func__, GET_GLOBAL(GeodeDC) + reg, off, on);
|
||||
geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, off, on);
|
||||
}
|
||||
|
||||
static u32 geode_vp_read(int reg)
|
||||
{
|
||||
u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + reg);
|
||||
dprintf(4, "%s(0x%08x) = 0x%08x\n"
|
||||
, __func__, GET_GLOBAL(GeodeVP) + reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void geode_vp_write(int reg, u32 val)
|
||||
{
|
||||
dprintf(4, "%s(0x%08x, 0x%08x)\n"
|
||||
, __func__, GET_GLOBAL(GeodeVP) + reg, val);
|
||||
geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, ~0, val);
|
||||
}
|
||||
|
||||
static void geode_vp_mask(int reg, u32 off, u32 on)
|
||||
{
|
||||
dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n"
|
||||
, __func__, GET_GLOBAL(GeodeVP) + reg, off, on);
|
||||
geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, off, on);
|
||||
}
|
||||
|
||||
static u32 geode_fp_read(int reg)
|
||||
{
|
||||
u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + VP_FP_START + reg);
|
||||
dprintf(4, "%s(0x%08x) = 0x%08x\n"
|
||||
, __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void geode_fp_write(int reg, u32 val)
|
||||
{
|
||||
dprintf(4, "%s(0x%08x, 0x%08x)\n"
|
||||
, __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val);
|
||||
geode_mem_mask(GET_GLOBAL(GeodeVP) + VP_FP_START + reg, ~0, val);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Helper functions
|
||||
****************************************************************/
|
||||
|
||||
static int legacyio_check(void)
|
||||
{
|
||||
int ret=0;
|
||||
u64 val;
|
||||
|
||||
if (CONFIG_VGA_GEODEGX2)
|
||||
val = geode_msr_read(GLIU0_P2D_BM_4);
|
||||
else
|
||||
val = geode_msr_read(MSR_GLIU0_BASE4);
|
||||
if ((val & 0xffffffff) != 0x0A0fffe0)
|
||||
ret|=1;
|
||||
|
||||
val = geode_msr_read(GLIU0_IOD_BM_0);
|
||||
if ((val & 0xffffffff) != 0x3c0ffff0)
|
||||
ret|=2;
|
||||
|
||||
val = geode_msr_read(GLIU0_IOD_BM_1);
|
||||
if ((val & 0xffffffff) != 0x3d0ffff0)
|
||||
ret|=4;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 framebuffer_size(void)
|
||||
{
|
||||
/* We use the P2D_R0 msr to read out the number of pages.
|
||||
* One page has a size of 4k
|
||||
*
|
||||
* Bit Name Description
|
||||
* 39:20 PMAX Physical Memory Address Max
|
||||
* 19:0 PMIX Physical Memory Address Min
|
||||
*
|
||||
*/
|
||||
u64 msr = geode_msr_read(GLIU0_P2D_RO);
|
||||
|
||||
u32 pmax = (msr >> 20) & 0x000fffff;
|
||||
u32 pmin = msr & 0x000fffff;
|
||||
|
||||
u32 val = pmax - pmin;
|
||||
val += 1;
|
||||
|
||||
/* The page size is 4k */
|
||||
return (val << 12);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Init Functions
|
||||
****************************************************************/
|
||||
|
||||
static void geodevga_set_output_mode(void)
|
||||
{
|
||||
u64 msr_addr;
|
||||
u64 msr;
|
||||
|
||||
/* set output to crt and RGB/YUV */
|
||||
if (CONFIG_VGA_GEODEGX2)
|
||||
msr_addr = VP_MSR_CONFIG_GX2;
|
||||
else
|
||||
msr_addr = VP_MSR_CONFIG_LX;
|
||||
|
||||
/* set output mode (RGB/YUV) */
|
||||
msr = geode_msr_read(msr_addr);
|
||||
msr &= ~VP_MSR_CONFIG_FMT; // mask out FMT (bits 5:3)
|
||||
|
||||
if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) {
|
||||
msr |= VP_MSR_CONFIG_FMT_FP; // flat panel
|
||||
|
||||
if (CONFIG_VGA_OUTPUT_CRT_PANEL) {
|
||||
msr |= VP_MSR_CONFIG_FPC; // simultaneous Flat Panel and CRT
|
||||
dprintf(1, "output: simultaneous Flat Panel and CRT\n");
|
||||
} else {
|
||||
msr &= ~VP_MSR_CONFIG_FPC; // no simultaneous Flat Panel and CRT
|
||||
dprintf(1, "ouput: flat panel\n");
|
||||
}
|
||||
} else {
|
||||
msr |= VP_MSR_CONFIG_FMT_CRT; // CRT only
|
||||
dprintf(1, "output: CRT\n");
|
||||
}
|
||||
geode_msr_mask(msr_addr, ~msr, msr);
|
||||
}
|
||||
|
||||
/* Set up the dc (display controller) portion of the geodelx
|
||||
* The dc provides hardware support for VGA graphics.
|
||||
*/
|
||||
static void dc_setup(void)
|
||||
{
|
||||
dprintf(2, "DC_SETUP\n");
|
||||
|
||||
geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK);
|
||||
|
||||
/* zero memory config */
|
||||
geode_dc_write(DC_FB_ST_OFFSET, 0x0);
|
||||
geode_dc_write(DC_CB_ST_OFFSET, 0x0);
|
||||
geode_dc_write(DC_CURS_ST_OFFSET, 0x0);
|
||||
|
||||
geode_dc_mask(DC_DISPLAY_CFG, ~DC_CFG_MSK, DC_DISPLAY_CFG_GDEN|DC_DISPLAY_CFG_TRUP);
|
||||
geode_dc_write(DC_GENERAL_CFG, DC_GENERAL_CFG_VGAE);
|
||||
|
||||
geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK);
|
||||
}
|
||||
|
||||
/* Setup the vp (video processor) portion of the geodelx
|
||||
* Under VGA modes the vp was handled by softvg from inside VSA2.
|
||||
* Without a softvg module, access is only available through a pci bar.
|
||||
* The High Mem Access virtual register is used to configure the
|
||||
* pci mmio bar from 16bit friendly io space.
|
||||
*/
|
||||
static void vp_setup(void)
|
||||
{
|
||||
dprintf(2,"VP_SETUP\n");
|
||||
|
||||
geodevga_set_output_mode();
|
||||
|
||||
/* Set mmio registers
|
||||
* there may be some timing issues here, the reads seem
|
||||
* to slow things down enough work reliably
|
||||
*/
|
||||
|
||||
u32 reg = geode_vp_read(VP_MISC);
|
||||
dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
|
||||
geode_vp_write(VP_MISC, VP_DCFG_BYP_BOTH);
|
||||
reg = geode_vp_read(VP_MISC);
|
||||
dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
|
||||
|
||||
reg = geode_vp_read(VP_DCFG);
|
||||
dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
|
||||
geode_vp_mask(VP_DCFG, 0, VP_DCFG_CRT_EN|VP_DCFG_HSYNC_EN|VP_DCFG_VSYNC_EN|VP_DCFG_DAC_BL_EN|VP_DCFG_CRT_SKEW);
|
||||
reg = geode_vp_read(VP_DCFG);
|
||||
dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
|
||||
|
||||
/* setup flat panel */
|
||||
if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) {
|
||||
u64 msr;
|
||||
|
||||
dprintf(1, "Setting up flat panel\n");
|
||||
/* write timing register */
|
||||
geode_fp_write(FP_PT1, 0x0);
|
||||
geode_fp_write(FP_PT2, FP_PT2_SCRC);
|
||||
|
||||
/* set pad select for TFT/LVDS */
|
||||
msr = VP_MSR_PADSEL_TFT_SEL_HIGH;
|
||||
msr = msr << 32;
|
||||
msr |= VP_MSR_PADSEL_TFT_SEL_LOW;
|
||||
geode_msr_mask(VP_MSR_PADSEL, ~msr, msr);
|
||||
|
||||
/* turn the panel on (if it isn't already) */
|
||||
reg = geode_fp_read(FP_PM);
|
||||
reg |= FP_PM_P;
|
||||
geode_fp_write(FP_PM, reg);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 geode_crtc_01[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
|
||||
0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x14, 0x1f, 0x97, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 geode_crtc_03[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
|
||||
0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x28, 0x1f, 0x97, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 geode_crtc_04[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
|
||||
0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
|
||||
0xff };
|
||||
static u8 geode_crtc_05[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
|
||||
0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8e, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
|
||||
0xff };
|
||||
static u8 geode_crtc_06[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
|
||||
0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xc2,
|
||||
0xff };
|
||||
static u8 geode_crtc_07[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
|
||||
0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x28, 0x0f, 0x97, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 geode_crtc_0d[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xe3,
|
||||
0xff };
|
||||
static u8 geode_crtc_0e[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xe3,
|
||||
0xff };
|
||||
static u8 geode_crtc_0f[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x83, 0x85, 0x5d, 0x28, 0x0f, 0x65, 0xb9, 0xe3,
|
||||
0xff };
|
||||
static u8 geode_crtc_11[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0x0b, 0x3e,
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
|
||||
0xff };
|
||||
static u8 geode_crtc_13[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
|
||||
0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3,
|
||||
0xff };
|
||||
|
||||
int geodevga_setup(void)
|
||||
{
|
||||
int ret = stdvga_setup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dprintf(1,"GEODEVGA_SETUP\n");
|
||||
|
||||
if ((ret=legacyio_check())) {
|
||||
dprintf(1,"GEODEVGA_SETUP legacyio_check=0x%x\n",ret);
|
||||
}
|
||||
|
||||
// Updated timings from geode datasheets, table 6-53 in particular
|
||||
static u8 *new_crtc[] VAR16 = {
|
||||
geode_crtc_01, geode_crtc_01, geode_crtc_03, geode_crtc_03,
|
||||
geode_crtc_04, geode_crtc_05, geode_crtc_06, geode_crtc_07,
|
||||
0, 0, 0, 0, 0,
|
||||
geode_crtc_0d, geode_crtc_0e, geode_crtc_0f, geode_crtc_0f,
|
||||
geode_crtc_11, geode_crtc_11, geode_crtc_13 };
|
||||
int i;
|
||||
for (i=0; i<ARRAY_SIZE(new_crtc); i++) {
|
||||
u8 *crtc = GET_GLOBAL(new_crtc[i]);
|
||||
if (crtc)
|
||||
stdvga_override_crtc(i, crtc);
|
||||
}
|
||||
|
||||
if (GET_GLOBAL(VgaBDF) < 0)
|
||||
// Device should be at 00:01.1
|
||||
SET_VGA(VgaBDF, pci_to_bdf(0, 1, 1));
|
||||
|
||||
// setup geode struct which is used for register access
|
||||
SET_VGA(GeodeFB, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0));
|
||||
SET_VGA(GeodeDC, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2));
|
||||
SET_VGA(GeodeVP, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3));
|
||||
|
||||
dprintf(1, "fb addr: 0x%08x\n", GET_GLOBAL(GeodeFB));
|
||||
dprintf(1, "dc addr: 0x%08x\n", GET_GLOBAL(GeodeDC));
|
||||
dprintf(1, "vp addr: 0x%08x\n", GET_GLOBAL(GeodeVP));
|
||||
|
||||
/* setup framebuffer */
|
||||
geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK);
|
||||
|
||||
/* read fb-bar from pci, then point dc to the fb base */
|
||||
u32 fb = GET_GLOBAL(GeodeFB);
|
||||
if (geode_dc_read(DC_GLIU0_MEM_OFFSET) != fb)
|
||||
geode_dc_write(DC_GLIU0_MEM_OFFSET, fb);
|
||||
|
||||
geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK);
|
||||
|
||||
u32 fb_size = framebuffer_size(); // in byte
|
||||
dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb);
|
||||
|
||||
/* update VBE variables */
|
||||
SET_VGA(VBE_framebuffer, fb);
|
||||
SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks
|
||||
|
||||
vp_setup();
|
||||
dc_setup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// Geode GX2/LX VGA functions
|
||||
//
|
||||
// Copyright (C) 2009 Chris Kindt
|
||||
//
|
||||
// Written for Google Summer of Code 2009 for the coreboot project
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#ifndef GEODEVGA_H
|
||||
#define GEODEVGA_H
|
||||
|
||||
#define VRC_INDEX 0xAC1C // Index register
|
||||
#define VRC_DATA 0xAC1E // Data register
|
||||
#define VR_UNLOCK 0xFC53 // Virtual register unlock code
|
||||
|
||||
// Graphics-specific registers:
|
||||
#define OEM_BAR0 0x50
|
||||
#define OEM_BAR1 0x54
|
||||
#define OEM_BAR2 0x58
|
||||
#define OEM_BAR3 0x5C
|
||||
|
||||
#define DC_LOCK_LOCK 0x00000000
|
||||
#define DC_LOCK_UNLOCK 0x00004758
|
||||
|
||||
/* LX MSRs */
|
||||
#define MSR_GLIU0 (1 << 28)
|
||||
#define MSR_GLIU0_BASE4 (MSR_GLIU0 + 0x23) /* LX */
|
||||
#define GLIU0_P2D_BM_4 (MSR_GLIU0 + 0x24) /* GX2 */
|
||||
#define GLIU0_P2D_RO (MSR_GLIU0 + 0x29)
|
||||
#define GLIU0_IOD_BM_0 (MSR_GLIU0 + 0xE0)
|
||||
#define GLIU0_IOD_BM_1 (MSR_GLIU0 + 0xE1)
|
||||
#define DC_SPARE 0x80000011
|
||||
#define VP_MSR_CONFIG_GX2 0xc0002001 /* GX2 */
|
||||
#define VP_MSR_CONFIG_LX 0x48002001 /* LX */
|
||||
#define VP_MSR_PADSEL 0x48002011
|
||||
|
||||
#define VP_MSR_PADSEL_TFT_SEL_LOW 0xDFFFFFFF
|
||||
#define VP_MSR_PADSEL_TFT_SEL_HIGH 0x0000003F
|
||||
|
||||
/* VP_MSR_CONFIG bits */
|
||||
#define VP_MSR_CONFIG_FMT_CRT (0)
|
||||
#define VP_MSR_CONFIG_FMT_FP (1 << 3)
|
||||
#define VP_MSR_CONFIG_FPC (1 << 15)
|
||||
#define VP_MSR_CONFIG_FMT ((1 << 3) | (1 << 4) | (1 << 5))
|
||||
|
||||
|
||||
/* DC REG OFFSET */
|
||||
#define DC_UNLOCK 0x0
|
||||
#define DC_GENERAL_CFG 0x4
|
||||
#define DC_DISPLAY_CFG 0x8
|
||||
#define DC_FB_ST_OFFSET 0x10
|
||||
#define DC_CB_ST_OFFSET 0x14
|
||||
#define DC_CURS_ST_OFFSET 0x18
|
||||
#define DC_GLIU0_MEM_OFFSET 0x84
|
||||
|
||||
/* VP REG OFFSET */
|
||||
#define VP_VCFG 0x0
|
||||
#define VP_DCFG 0x8
|
||||
#define VP_MISC 0x50
|
||||
|
||||
/* FP REG OFFSET */
|
||||
#define FP_PT1 0x00
|
||||
#define FP_PT2 0x08
|
||||
#define FP_PM 0x10
|
||||
|
||||
|
||||
/* DC bits */
|
||||
#define DC_GENERAL_CFG_VGAE (1 << 7)
|
||||
#define DC_DISPLAY_CFG_GDEN (1 << 3)
|
||||
#define DC_DISPLAY_CFG_TRUP (1 << 6)
|
||||
|
||||
/* VP bits */
|
||||
#define VP_DCFG_CRT_EN (1 << 0)
|
||||
#define VP_DCFG_HSYNC_EN (1 << 1)
|
||||
#define VP_DCFG_VSYNC_EN (1 << 2)
|
||||
#define VP_DCFG_DAC_BL_EN (1 << 3)
|
||||
#define VP_DCFG_CRT_SKEW (1 << 16)
|
||||
#define VP_DCFG_BYP_BOTH (1 << 0)
|
||||
|
||||
/* FP bits */
|
||||
#define FP_PM_P (1 << 24) /* panel power ctl */
|
||||
#define FP_PT2_SCRC (1 << 27) /* panel shift clock retrace activity ctl */
|
||||
|
||||
/* Mask */
|
||||
#define DC_CFG_MSK 0xf000a6
|
||||
|
||||
int geodevga_setup();
|
||||
|
||||
#endif
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
// Simple framebuffer vgabios for use with qemu ramfb device
|
||||
//
|
||||
// Copyright (C) 2019 Gerd Hoffmann <kraxel@redhat.com>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_BDA
|
||||
#include "output.h" // dprintf
|
||||
#include "string.h" // memset16_far
|
||||
#include "vgautil.h" // VBE_total_memory
|
||||
#include "std/pmm.h" // struct pmmheader
|
||||
#include "byteorder.h"
|
||||
#include "fw/paravirt.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* minimal qemu fc_cfg support bits, requires dma support */
|
||||
|
||||
#define QEMU_CFG_FILE_DIR 0x19
|
||||
|
||||
struct QemuCfgFile {
|
||||
u32 size; /* file size */
|
||||
u16 select; /* write this to 0x510 to read it */
|
||||
u16 reserved;
|
||||
char name[56];
|
||||
};
|
||||
|
||||
static void
|
||||
qemu_cfg_dma_transfer(void *address, u32 length, u32 control)
|
||||
{
|
||||
QemuCfgDmaAccess access;
|
||||
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
access.address = cpu_to_be64((u64)(u32)address);
|
||||
access.length = cpu_to_be32(length);
|
||||
access.control = cpu_to_be32(control);
|
||||
|
||||
barrier();
|
||||
|
||||
outl(cpu_to_be32((u32)&access), PORT_QEMU_CFG_DMA_ADDR_LOW);
|
||||
|
||||
while(be32_to_cpu(access.control) & ~QEMU_CFG_DMA_CTL_ERROR)
|
||||
/* wait */;
|
||||
}
|
||||
|
||||
static void
|
||||
qemu_cfg_read(void *buf, int len)
|
||||
{
|
||||
qemu_cfg_dma_transfer(buf, len, QEMU_CFG_DMA_CTL_READ);
|
||||
}
|
||||
|
||||
static void
|
||||
qemu_cfg_read_entry(void *buf, int e, int len)
|
||||
{
|
||||
u32 control = (e << 16) | QEMU_CFG_DMA_CTL_SELECT
|
||||
| QEMU_CFG_DMA_CTL_READ;
|
||||
qemu_cfg_dma_transfer(buf, len, control);
|
||||
}
|
||||
|
||||
static void
|
||||
qemu_cfg_write_entry(void *buf, int e, int len)
|
||||
{
|
||||
u32 control = (e << 16) | QEMU_CFG_DMA_CTL_SELECT
|
||||
| QEMU_CFG_DMA_CTL_WRITE;
|
||||
qemu_cfg_dma_transfer(buf, len, control);
|
||||
}
|
||||
|
||||
static int
|
||||
qemu_cfg_find_file(const char *filename)
|
||||
{
|
||||
u32 count, e, select;
|
||||
|
||||
qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
|
||||
count = be32_to_cpu(count);
|
||||
for (select = 0, e = 0; e < count; e++) {
|
||||
struct QemuCfgFile qfile;
|
||||
qemu_cfg_read(&qfile, sizeof(qfile));
|
||||
if (memcmp_far(GET_SEG(SS), qfile.name,
|
||||
GET_SEG(CS), filename, 10) == 0)
|
||||
select = be16_to_cpu(qfile.select);
|
||||
}
|
||||
return select;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define FRAMEBUFFER_WIDTH 1024
|
||||
#define FRAMEBUFFER_HEIGHT 768
|
||||
#define FRAMEBUFFER_BPP 4
|
||||
#define FRAMEBUFFER_STRIDE (FRAMEBUFFER_BPP * FRAMEBUFFER_WIDTH)
|
||||
#define FRAMEBUFFER_SIZE (FRAMEBUFFER_STRIDE * FRAMEBUFFER_HEIGHT)
|
||||
|
||||
struct QemuRAMFBCfg {
|
||||
u64 addr;
|
||||
u32 fourcc;
|
||||
u32 flags;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 stride;
|
||||
};
|
||||
|
||||
#define fourcc_code(a, b, c, d) ((u32)(a) | ((u32)(b) << 8) | \
|
||||
((u32)(c) << 16) | ((u32)(d) << 24))
|
||||
|
||||
#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */
|
||||
#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */
|
||||
#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */
|
||||
|
||||
static u32
|
||||
allocate_framebuffer(void)
|
||||
{
|
||||
u32 res = allocate_pmm(FRAMEBUFFER_SIZE, 1, 1);
|
||||
if (!res)
|
||||
return 0;
|
||||
dprintf(1, "ramfb: framebuffer allocated at %x\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
ramfb_setup(void)
|
||||
{
|
||||
dprintf(1, "ramfb: init\n");
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return 0;
|
||||
|
||||
u32 select = qemu_cfg_find_file("etc/ramfb");
|
||||
if (select == 0) {
|
||||
dprintf(1, "ramfb: fw_cfg (etc/ramfb) file not found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dprintf(1, "ramfb: fw_cfg (etc/ramfb) file at slot 0x%x\n", select);
|
||||
u32 fb = allocate_framebuffer();
|
||||
if (!fb) {
|
||||
dprintf(1, "ramfb: allocating framebuffer failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
u64 addr = fb;
|
||||
u8 bpp = FRAMEBUFFER_BPP * 8;
|
||||
u32 xlines = FRAMEBUFFER_WIDTH;
|
||||
u32 ylines = FRAMEBUFFER_HEIGHT;
|
||||
u32 linelength = FRAMEBUFFER_STRIDE;
|
||||
dprintf(1, "Found FB @ %llx %dx%d with %d bpp (%d stride)\n"
|
||||
, addr, xlines, ylines, bpp, linelength);
|
||||
|
||||
if (!addr || addr > 0xffffffff
|
||||
|| (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32)) {
|
||||
dprintf(1, "Unable to use FB\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cbvga_setup_modes(addr, bpp, xlines, ylines, linelength);
|
||||
|
||||
struct QemuRAMFBCfg cfg = {
|
||||
.addr = cpu_to_be64(fb),
|
||||
.fourcc = cpu_to_be32(DRM_FORMAT_XRGB8888),
|
||||
.flags = cpu_to_be32(0),
|
||||
.width = cpu_to_be32(FRAMEBUFFER_WIDTH),
|
||||
.height = cpu_to_be32(FRAMEBUFFER_HEIGHT),
|
||||
.stride = cpu_to_be32(FRAMEBUFFER_STRIDE),
|
||||
};
|
||||
qemu_cfg_write_entry(&cfg, select, sizeof(cfg));
|
||||
|
||||
return 0;
|
||||
}
|
||||
+567
@@ -0,0 +1,567 @@
|
||||
// Standard VGA driver code
|
||||
//
|
||||
// Copyright (C) 2009-2024 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 "biosvar.h" // GET_GLOBAL
|
||||
#include "farptr.h" // SET_FARVAR
|
||||
#include "stdvga.h" // stdvga_setup
|
||||
#include "string.h" // memset_far
|
||||
#include "vgabios.h" // struct vgamode_s
|
||||
#include "x86.h" // outb
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Attribute control
|
||||
****************************************************************/
|
||||
|
||||
// Emulate CGA background setting via VGA palette index registers
|
||||
void
|
||||
stdvga_set_cga_background_color(u8 color)
|
||||
{
|
||||
// Set the background color (via palette index 0)
|
||||
u8 v1 = color & 0x0f;
|
||||
if (v1 & 0x08)
|
||||
v1 += 0x08;
|
||||
stdvga_attr_write(0x00, v1);
|
||||
|
||||
// Dim/brighten foreground (see pal_cga[] in stdvgamodes.c)
|
||||
int i;
|
||||
for (i = 1; i < 4; i++)
|
||||
stdvga_attr_mask(i, 0x10, color & 0x10);
|
||||
}
|
||||
|
||||
// Emulate CGA palette setting by altering VGA palette index registers
|
||||
void
|
||||
stdvga_set_cga_palette(u8 palid)
|
||||
{
|
||||
// Switch foreground colors (see pal_cga[] in stdvgamodes.c)
|
||||
int i;
|
||||
for (i = 1; i < 4; i++)
|
||||
stdvga_attr_mask(i, 0x01, palid & 0x01);
|
||||
}
|
||||
|
||||
// Set the VGA palette index register for the "overscan" area
|
||||
void
|
||||
stdvga_set_overscan_border_color(u8 color)
|
||||
{
|
||||
stdvga_attr_write(0x11, color);
|
||||
}
|
||||
|
||||
// Get the VGA palette index register for the "overscan" area
|
||||
u8
|
||||
stdvga_get_overscan_border_color(void)
|
||||
{
|
||||
return stdvga_attr_read(0x11);
|
||||
}
|
||||
|
||||
// Set the VGA palette index registers
|
||||
void
|
||||
stdvga_set_all_palette_reg(u16 seg, u8 *data_far)
|
||||
{
|
||||
// Set palette indexes (offset into DAC colors)
|
||||
int i;
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
stdvga_attr_write(i, GET_FARVAR(seg, *data_far));
|
||||
data_far++;
|
||||
}
|
||||
// Set "overscan" palette index (offset into DAC colors)
|
||||
stdvga_attr_write(0x11, GET_FARVAR(seg, *data_far));
|
||||
}
|
||||
|
||||
// Get the VGA palette index registers
|
||||
void
|
||||
stdvga_get_all_palette_reg(u16 seg, u8 *data_far)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
SET_FARVAR(seg, *data_far, stdvga_attr_read(i));
|
||||
data_far++;
|
||||
}
|
||||
SET_FARVAR(seg, *data_far, stdvga_attr_read(0x11));
|
||||
}
|
||||
|
||||
// Set blinking mode (when enabled, palette index bit 0x08 indicates blinking)
|
||||
void
|
||||
stdvga_set_palette_blinking(u8 enable_blink)
|
||||
{
|
||||
stdvga_attr_mask(0x10, 0x08, (enable_blink & 0x01) << 3);
|
||||
}
|
||||
|
||||
// Select 4-bit or 6-bit palette indexes (for "page" switching of colors)
|
||||
void
|
||||
stdvga_set_palette_pagesize(u8 pal_pagesize)
|
||||
{
|
||||
stdvga_attr_mask(0x10, 0x80, pal_pagesize << 7);
|
||||
}
|
||||
|
||||
// Set palette index offset (enables color switching via "pages")
|
||||
void
|
||||
stdvga_set_palette_page(u8 pal_page)
|
||||
{
|
||||
// Check if using 4-bit or 6-bit "palette index pages"
|
||||
u8 val = stdvga_attr_read(0x10);
|
||||
if (!(val & 0x80))
|
||||
pal_page <<= 2;
|
||||
// select page
|
||||
pal_page &= 0x0f;
|
||||
stdvga_attr_write(0x14, pal_page);
|
||||
}
|
||||
|
||||
// Report current palette index pagesize and current page
|
||||
void
|
||||
stdvga_get_palette_page(u8 *pal_pagesize, u8 *pal_page)
|
||||
{
|
||||
u8 val1 = stdvga_attr_read(0x10) >> 7;
|
||||
u8 val2 = stdvga_attr_read(0x14) & 0x0f;
|
||||
if (!(val1 & 0x01))
|
||||
val2 >>= 2;
|
||||
*pal_pagesize = val1;
|
||||
*pal_page = val2;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* DAC control
|
||||
****************************************************************/
|
||||
|
||||
// Store dac colors into memory in 3-byte rgb format
|
||||
void
|
||||
stdvga_dac_read_many(u16 seg, u8 *data_far, u8 start, int count)
|
||||
{
|
||||
while (count) {
|
||||
struct vbe_palette_entry rgb = stdvga_dac_read(start);
|
||||
SET_FARVAR(seg, *data_far, rgb.red);
|
||||
data_far++;
|
||||
SET_FARVAR(seg, *data_far, rgb.green);
|
||||
data_far++;
|
||||
SET_FARVAR(seg, *data_far, rgb.blue);
|
||||
data_far++;
|
||||
start++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
// Load dac colors from memory in 3-byte rgb format
|
||||
void
|
||||
stdvga_dac_write_many(u16 seg, u8 *data_far, u8 start, int count)
|
||||
{
|
||||
while (count) {
|
||||
u8 r = GET_FARVAR(seg, *data_far);
|
||||
data_far++;
|
||||
u8 g = GET_FARVAR(seg, *data_far);
|
||||
data_far++;
|
||||
u8 b = GET_FARVAR(seg, *data_far);
|
||||
data_far++;
|
||||
struct vbe_palette_entry rgb = { .red=r, .green=g, .blue=b };
|
||||
stdvga_dac_write(start, rgb);
|
||||
start++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert all loaded colors to shades of gray
|
||||
void
|
||||
stdvga_perform_gray_scale_summing(u16 start, u16 count)
|
||||
{
|
||||
stdvga_attrindex_write(0x00);
|
||||
int i;
|
||||
for (i = start; i < start+count; i++) {
|
||||
struct vbe_palette_entry rgb = stdvga_dac_read(i);
|
||||
|
||||
// intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
|
||||
u16 intensity = ((77 * rgb.red + 151 * rgb.green
|
||||
+ 28 * rgb.blue) + 0x80) >> 8;
|
||||
if (intensity > 0x3f)
|
||||
intensity = 0x3f;
|
||||
rgb.red = rgb.green = rgb.blue = intensity;
|
||||
|
||||
stdvga_dac_write(i, rgb);
|
||||
}
|
||||
stdvga_attrindex_write(0x20);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Memory control
|
||||
****************************************************************/
|
||||
|
||||
// Enable reads and writes to the given "plane" when in planar4 mode.
|
||||
void
|
||||
stdvga_planar4_plane(int plane)
|
||||
{
|
||||
if (plane < 0) {
|
||||
// Return to default mode (read plane0, write all planes)
|
||||
stdvga_sequ_write(0x02, 0x0f);
|
||||
stdvga_grdc_write(0x04, 0);
|
||||
} else {
|
||||
stdvga_sequ_write(0x02, 1<<plane);
|
||||
stdvga_grdc_write(0x04, plane);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Font loading
|
||||
****************************************************************/
|
||||
|
||||
// Set the video memory location of the start of character fonts
|
||||
void
|
||||
stdvga_set_font_location(u8 spec)
|
||||
{
|
||||
stdvga_sequ_write(0x03, spec);
|
||||
}
|
||||
|
||||
static void
|
||||
get_font_access(void)
|
||||
{
|
||||
stdvga_sequ_write(0x00, 0x01);
|
||||
stdvga_sequ_write(0x02, 0x04);
|
||||
stdvga_sequ_write(0x04, 0x07);
|
||||
stdvga_sequ_write(0x00, 0x03);
|
||||
stdvga_grdc_write(0x04, 0x02);
|
||||
stdvga_grdc_write(0x05, 0x00);
|
||||
stdvga_grdc_write(0x06, 0x04);
|
||||
}
|
||||
|
||||
static void
|
||||
release_font_access(void)
|
||||
{
|
||||
stdvga_sequ_write(0x00, 0x01);
|
||||
stdvga_sequ_write(0x02, 0x03);
|
||||
stdvga_sequ_write(0x04, 0x03);
|
||||
stdvga_sequ_write(0x00, 0x03);
|
||||
u16 v = (stdvga_misc_read() & 0x01) ? 0x0e : 0x0a;
|
||||
stdvga_grdc_write(0x06, v);
|
||||
stdvga_grdc_write(0x04, 0x00);
|
||||
stdvga_grdc_write(0x05, 0x10);
|
||||
}
|
||||
|
||||
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
|
||||
****************************************************************/
|
||||
|
||||
// Return the IO port used to access the CRTC register
|
||||
u16
|
||||
stdvga_get_crtc(void)
|
||||
{
|
||||
if (stdvga_misc_read() & 1)
|
||||
return VGAREG_VGA_CRTC_ADDRESS;
|
||||
return VGAREG_MDA_CRTC_ADDRESS;
|
||||
}
|
||||
|
||||
// Ratio between system visible framebuffer ram and the actual videoram used.
|
||||
int
|
||||
stdvga_vram_ratio(struct vgamode_s *vmode_g)
|
||||
{
|
||||
switch (GET_GLOBAL(vmode_g->memmodel)) {
|
||||
case MM_TEXT:
|
||||
return 2;
|
||||
case MM_CGA:
|
||||
return 4 / GET_GLOBAL(vmode_g->depth);
|
||||
case MM_PLANAR:
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Set cursor shape (when in text mode)
|
||||
void
|
||||
stdvga_set_cursor_shape(u16 cursor_type)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
stdvga_crtc_write(crtc_addr, 0x0a, cursor_type >> 8);
|
||||
stdvga_crtc_write(crtc_addr, 0x0b, cursor_type);
|
||||
}
|
||||
|
||||
// Set the position of the text cursor (as offset into system framebuffer)
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
// Set the character height (when in text mode)
|
||||
void
|
||||
stdvga_set_character_height(u8 lines)
|
||||
{
|
||||
stdvga_crtc_mask(stdvga_get_crtc(), 0x09, 0x1f, lines - 1);
|
||||
}
|
||||
|
||||
// Get vertical screen size (number of horizontal lines in the display)
|
||||
u16
|
||||
stdvga_get_vertical_size(void)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
u16 vde = stdvga_crtc_read(crtc_addr, 0x12);
|
||||
u8 ovl = stdvga_crtc_read(crtc_addr, 0x07);
|
||||
vde += ((ovl & 0x02) << 7) + ((ovl & 0x40) << 3);
|
||||
return vde + 1;
|
||||
}
|
||||
|
||||
// Set vertical screen size (number of horizontal lines in the display)
|
||||
void
|
||||
stdvga_set_vertical_size(int lines)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
u16 vde = lines - 1;
|
||||
stdvga_crtc_write(crtc_addr, 0x12, vde);
|
||||
u8 ovl = ((vde >> 7) & 0x02) + ((vde >> 3) & 0x40);
|
||||
stdvga_crtc_mask(crtc_addr, 0x07, 0x42, ovl);
|
||||
}
|
||||
|
||||
// Get offset into framebuffer accessible from real-mode 64K segment
|
||||
int
|
||||
stdvga_get_window(struct vgamode_s *curmode_g, int window)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set offset into framebuffer that is accessible from real-mode 64K
|
||||
// segment (in units of VBE_win_granularity windows)
|
||||
int
|
||||
stdvga_set_window(struct vgamode_s *curmode_g, int window, int val)
|
||||
{
|
||||
// Stdvga does not support changing window offset
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Minimum framebuffer bytes between each vertical line for given mode
|
||||
int
|
||||
stdvga_minimum_linelength(struct vgamode_s *vmode_g)
|
||||
{
|
||||
return DIV_ROUND_UP(GET_GLOBAL(vmode_g->width) * vga_bpp(vmode_g), 8);
|
||||
}
|
||||
|
||||
// Return number of framebuffer bytes between start of each vertical line
|
||||
int
|
||||
stdvga_get_linelength(struct vgamode_s *curmode_g)
|
||||
{
|
||||
u8 val = stdvga_crtc_read(stdvga_get_crtc(), 0x13);
|
||||
return val * 8 / stdvga_vram_ratio(curmode_g);
|
||||
}
|
||||
|
||||
// Set number of framebuffer bytes between start of each vertical line
|
||||
int
|
||||
stdvga_set_linelength(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
val = DIV_ROUND_UP(val * stdvga_vram_ratio(curmode_g), 8);
|
||||
stdvga_crtc_write(stdvga_get_crtc(), 0x13, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return framebuffer offset of first byte of displayed content
|
||||
int
|
||||
stdvga_get_displaystart(struct vgamode_s *curmode_g)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
int addr = (stdvga_crtc_read(crtc_addr, 0x0c) << 8
|
||||
| stdvga_crtc_read(crtc_addr, 0x0d));
|
||||
return addr * 4 / stdvga_vram_ratio(curmode_g);
|
||||
}
|
||||
|
||||
// Set framebuffer offset of first byte of displayed content
|
||||
int
|
||||
stdvga_set_displaystart(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
u16 crtc_addr = stdvga_get_crtc();
|
||||
val = val * stdvga_vram_ratio(curmode_g) / 4;
|
||||
stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
|
||||
stdvga_crtc_write(crtc_addr, 0x0d, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Report if using 8bit per rgb (24bit total) or 6bit per rgb (18bit total)
|
||||
int
|
||||
stdvga_get_dacformat(struct vgamode_s *curmode_g)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set 8bit per rgb (24bit total) or 6bit per rgb (18bit total)
|
||||
int
|
||||
stdvga_set_dacformat(struct vgamode_s *curmode_g, int val)
|
||||
{
|
||||
// Stdvga only supports 6bits for each color channel
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Save/Restore state
|
||||
****************************************************************/
|
||||
|
||||
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];
|
||||
} PACKED;
|
||||
|
||||
static void
|
||||
stdvga_save_hw_state(u16 seg, struct saveVideoHardware *info)
|
||||
{
|
||||
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));
|
||||
SET_FARVAR(seg, info->actl_index, stdvga_attrindex_read());
|
||||
SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL));
|
||||
|
||||
int i;
|
||||
for (i=0; i<4; i++)
|
||||
SET_FARVAR(seg, info->sequ_regs[i], stdvga_sequ_read(i+1));
|
||||
SET_FARVAR(seg, info->sequ0, stdvga_sequ_read(0));
|
||||
|
||||
for (i=0; i<25; i++)
|
||||
SET_FARVAR(seg, info->crtc_regs[i], stdvga_crtc_read(crtc_addr, i));
|
||||
|
||||
for (i=0; i<20; i++)
|
||||
SET_FARVAR(seg, info->actl_regs[i], stdvga_attr_read(i));
|
||||
|
||||
for (i=0; i<9; i++)
|
||||
SET_FARVAR(seg, info->grdc_regs[i], stdvga_grdc_read(i));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
stdvga_restore_hw_state(u16 seg, struct saveVideoHardware *info)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<4; i++)
|
||||
stdvga_sequ_write(i+1, GET_FARVAR(seg, info->sequ_regs[i]));
|
||||
stdvga_sequ_write(0x00, GET_FARVAR(seg, info->sequ0));
|
||||
|
||||
// Disable CRTC write protection
|
||||
u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr);
|
||||
stdvga_crtc_write(crtc_addr, 0x11, 0x00);
|
||||
// Set CRTC regs
|
||||
for (i=0; i<25; i++)
|
||||
if (i != 0x11)
|
||||
stdvga_crtc_write(crtc_addr, i, GET_FARVAR(seg, info->crtc_regs[i]));
|
||||
// select crtc base address
|
||||
stdvga_misc_mask(0x01, crtc_addr == VGAREG_VGA_CRTC_ADDRESS ? 0x01 : 0x00);
|
||||
|
||||
// enable write protection if needed
|
||||
stdvga_crtc_write(crtc_addr, 0x11, GET_FARVAR(seg, info->crtc_regs[0x11]));
|
||||
|
||||
// Set Attribute Ctl
|
||||
for (i=0; i<20; i++)
|
||||
stdvga_attr_write(i, GET_FARVAR(seg, info->actl_regs[i]));
|
||||
stdvga_attrindex_write(GET_FARVAR(seg, info->actl_index));
|
||||
|
||||
for (i=0; i<9; i++)
|
||||
stdvga_grdc_write(i, GET_FARVAR(seg, info->grdc_regs[i]));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct saveDACcolors {
|
||||
u8 rwmode;
|
||||
u8 peladdr;
|
||||
u8 pelmask;
|
||||
u8 dac[768];
|
||||
u8 color_select;
|
||||
} PACKED;
|
||||
|
||||
static void
|
||||
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, stdvga_pelmask_read());
|
||||
stdvga_dac_read_many(seg, info->dac, 0, 256);
|
||||
SET_FARVAR(seg, info->color_select, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info)
|
||||
{
|
||||
stdvga_pelmask_write(GET_FARVAR(seg, info->pelmask));
|
||||
stdvga_dac_write_many(seg, info->dac, 0, 256);
|
||||
outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS);
|
||||
}
|
||||
|
||||
int
|
||||
stdvga_save_restore(int cmd, u16 seg, void *data)
|
||||
{
|
||||
void *pos = data;
|
||||
if (cmd & SR_HARDWARE) {
|
||||
if (cmd & SR_SAVE)
|
||||
stdvga_save_hw_state(seg, pos);
|
||||
if (cmd & SR_RESTORE)
|
||||
stdvga_restore_hw_state(seg, pos);
|
||||
pos += sizeof(struct saveVideoHardware);
|
||||
}
|
||||
pos += bda_save_restore(cmd, seg, pos);
|
||||
if (cmd & SR_DAC) {
|
||||
if (cmd & SR_SAVE)
|
||||
stdvga_save_dac_state(seg, pos);
|
||||
if (cmd & SR_RESTORE)
|
||||
stdvga_restore_dac_state(seg, pos);
|
||||
pos += sizeof(struct saveDACcolors);
|
||||
}
|
||||
return pos - data;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Misc
|
||||
****************************************************************/
|
||||
|
||||
// Enable/disable system access to the video memory
|
||||
void
|
||||
stdvga_enable_video_addressing(u8 disable)
|
||||
{
|
||||
u8 v = (disable & 1) ? 0x00 : 0x02;
|
||||
stdvga_misc_mask(0x02, v);
|
||||
}
|
||||
|
||||
int
|
||||
stdvga_setup(void)
|
||||
{
|
||||
// switch to color mode and enable CPU access 480 lines
|
||||
stdvga_misc_write(0xc3);
|
||||
// more than 64k 3C4/04
|
||||
stdvga_sequ_write(0x04, 0x02);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
#ifndef __STDVGA_H
|
||||
#define __STDVGA_H
|
||||
|
||||
#include "types.h" // u8
|
||||
#include "std/vbe.h" // struct vbe_palette_entry
|
||||
|
||||
// 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
|
||||
|
||||
// stdvga.c
|
||||
void stdvga_set_cga_background_color(u8 color);
|
||||
void stdvga_set_cga_palette(u8 palid);
|
||||
void stdvga_set_overscan_border_color(u8 color);
|
||||
u8 stdvga_get_overscan_border_color(void);
|
||||
void stdvga_set_all_palette_reg(u16 seg, u8 *data_far);
|
||||
void stdvga_get_all_palette_reg(u16 seg, u8 *data_far);
|
||||
void stdvga_set_palette_blinking(u8 enable_blink);
|
||||
void stdvga_set_palette_pagesize(u8 pal_pagesize);
|
||||
void stdvga_set_palette_page(u8 pal_page);
|
||||
void stdvga_get_palette_page(u8 *pal_pagesize, u8 *pal_page);
|
||||
void stdvga_dac_read_many(u16 seg, u8 *data_far, u8 start, int count);
|
||||
void stdvga_dac_write_many(u16 seg, u8 *data_far, u8 start, int count);
|
||||
void stdvga_perform_gray_scale_summing(u16 start, u16 count);
|
||||
void stdvga_planar4_plane(int plane);
|
||||
void stdvga_set_font_location(u8 spec);
|
||||
void stdvga_load_font(u16 seg, void *src_far, u16 count
|
||||
, u16 start, u8 destflags, u8 fontsize);
|
||||
u16 stdvga_get_crtc(void);
|
||||
struct vgamode_s;
|
||||
int stdvga_vram_ratio(struct vgamode_s *vmode_g);
|
||||
void stdvga_set_cursor_shape(u16 cursor_type);
|
||||
void stdvga_set_cursor_pos(int address);
|
||||
void stdvga_set_character_height(u8 lines);
|
||||
u16 stdvga_get_vertical_size(void);
|
||||
void stdvga_set_vertical_size(int lines);
|
||||
int stdvga_get_window(struct vgamode_s *curmode_g, int window);
|
||||
int stdvga_set_window(struct vgamode_s *curmode_g, int window, int val);
|
||||
int stdvga_minimum_linelength(struct vgamode_s *vmode_g);
|
||||
int stdvga_get_linelength(struct vgamode_s *curmode_g);
|
||||
int stdvga_set_linelength(struct vgamode_s *curmode_g, int val);
|
||||
int stdvga_get_displaystart(struct vgamode_s *curmode_g);
|
||||
int stdvga_set_displaystart(struct vgamode_s *curmode_g, int val);
|
||||
int stdvga_get_dacformat(struct vgamode_s *curmode_g);
|
||||
int stdvga_set_dacformat(struct vgamode_s *curmode_g, int val);
|
||||
int stdvga_save_restore(int cmd, u16 seg, void *data);
|
||||
void stdvga_enable_video_addressing(u8 disable);
|
||||
int stdvga_setup(void);
|
||||
|
||||
// stdvgaio.c
|
||||
u8 stdvga_pelmask_read(void);
|
||||
void stdvga_pelmask_write(u8 val);
|
||||
u8 stdvga_misc_read(void);
|
||||
void stdvga_misc_write(u8 value);
|
||||
void stdvga_misc_mask(u8 off, u8 on);
|
||||
u8 stdvga_sequ_read(u8 index);
|
||||
void stdvga_sequ_write(u8 index, u8 value);
|
||||
void stdvga_sequ_mask(u8 index, u8 off, u8 on);
|
||||
u8 stdvga_grdc_read(u8 index);
|
||||
void stdvga_grdc_write(u8 index, u8 value);
|
||||
void stdvga_grdc_mask(u8 index, u8 off, u8 on);
|
||||
u8 stdvga_crtc_read(u16 crtc_addr, u8 index);
|
||||
void stdvga_crtc_write(u16 crtc_addr, u8 index, u8 value);
|
||||
void stdvga_crtc_mask(u16 crtc_addr, u8 index, u8 off, u8 on);
|
||||
u8 stdvga_attr_read(u8 index);
|
||||
void stdvga_attr_write(u8 index, u8 value);
|
||||
void stdvga_attr_mask(u8 index, u8 off, u8 on);
|
||||
u8 stdvga_attrindex_read(void);
|
||||
void stdvga_attrindex_write(u8 value);
|
||||
struct vbe_palette_entry stdvga_dac_read(u8 color);
|
||||
void stdvga_dac_write(u8 color, struct vbe_palette_entry rgb);
|
||||
|
||||
#endif // stdvga.h
|
||||
@@ -0,0 +1,174 @@
|
||||
// Standard VGA IO port access
|
||||
//
|
||||
// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "farptr.h" // GET_FARVAR
|
||||
#include "stdvga.h" // VGAREG_PEL_MASK
|
||||
#include "x86.h" // inb
|
||||
|
||||
u8
|
||||
stdvga_pelmask_read(void)
|
||||
{
|
||||
return inb(VGAREG_PEL_MASK);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_pelmask_write(u8 value)
|
||||
{
|
||||
outb(value, VGAREG_PEL_MASK);
|
||||
}
|
||||
|
||||
|
||||
u8
|
||||
stdvga_misc_read(void)
|
||||
{
|
||||
return inb(VGAREG_READ_MISC_OUTPUT);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_misc_write(u8 value)
|
||||
{
|
||||
outb(value, VGAREG_WRITE_MISC_OUTPUT);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_misc_mask(u8 off, u8 on)
|
||||
{
|
||||
stdvga_misc_write((stdvga_misc_read() & ~off) | on);
|
||||
}
|
||||
|
||||
|
||||
u8
|
||||
stdvga_sequ_read(u8 index)
|
||||
{
|
||||
outb(index, VGAREG_SEQU_ADDRESS);
|
||||
return inb(VGAREG_SEQU_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_sequ_write(u8 index, u8 value)
|
||||
{
|
||||
outw((value<<8) | index, VGAREG_SEQU_ADDRESS);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_sequ_mask(u8 index, u8 off, u8 on)
|
||||
{
|
||||
outb(index, VGAREG_SEQU_ADDRESS);
|
||||
u8 v = inb(VGAREG_SEQU_DATA);
|
||||
outb((v & ~off) | on, VGAREG_SEQU_DATA);
|
||||
}
|
||||
|
||||
|
||||
u8
|
||||
stdvga_grdc_read(u8 index)
|
||||
{
|
||||
outb(index, VGAREG_GRDC_ADDRESS);
|
||||
return inb(VGAREG_GRDC_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_grdc_write(u8 index, u8 value)
|
||||
{
|
||||
outw((value<<8) | index, VGAREG_GRDC_ADDRESS);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_grdc_mask(u8 index, u8 off, u8 on)
|
||||
{
|
||||
outb(index, VGAREG_GRDC_ADDRESS);
|
||||
u8 v = inb(VGAREG_GRDC_DATA);
|
||||
outb((v & ~off) | on, VGAREG_GRDC_DATA);
|
||||
}
|
||||
|
||||
|
||||
u8
|
||||
stdvga_crtc_read(u16 crtc_addr, u8 index)
|
||||
{
|
||||
outb(index, crtc_addr);
|
||||
return inb(crtc_addr + 1);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_crtc_write(u16 crtc_addr, u8 index, u8 value)
|
||||
{
|
||||
outw((value<<8) | index, crtc_addr);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_crtc_mask(u16 crtc_addr, u8 index, u8 off, u8 on)
|
||||
{
|
||||
outb(index, crtc_addr);
|
||||
u8 v = inb(crtc_addr + 1);
|
||||
outb((v & ~off) | on, crtc_addr + 1);
|
||||
}
|
||||
|
||||
|
||||
u8
|
||||
stdvga_attr_read(u8 index)
|
||||
{
|
||||
inb(VGAREG_ACTL_RESET);
|
||||
u8 orig = inb(VGAREG_ACTL_ADDRESS);
|
||||
outb(index, VGAREG_ACTL_ADDRESS);
|
||||
u8 v = inb(VGAREG_ACTL_READ_DATA);
|
||||
inb(VGAREG_ACTL_RESET);
|
||||
outb(orig, VGAREG_ACTL_ADDRESS);
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_attr_write(u8 index, u8 value)
|
||||
{
|
||||
inb(VGAREG_ACTL_RESET);
|
||||
u8 orig = inb(VGAREG_ACTL_ADDRESS);
|
||||
outb(index, VGAREG_ACTL_ADDRESS);
|
||||
outb(value, VGAREG_ACTL_WRITE_DATA);
|
||||
outb(orig, VGAREG_ACTL_ADDRESS);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_attr_mask(u8 index, u8 off, u8 on)
|
||||
{
|
||||
inb(VGAREG_ACTL_RESET);
|
||||
u8 orig = inb(VGAREG_ACTL_ADDRESS);
|
||||
outb(index, VGAREG_ACTL_ADDRESS);
|
||||
u8 v = inb(VGAREG_ACTL_READ_DATA);
|
||||
outb((v & ~off) | on, VGAREG_ACTL_WRITE_DATA);
|
||||
outb(orig, VGAREG_ACTL_ADDRESS);
|
||||
}
|
||||
|
||||
u8
|
||||
stdvga_attrindex_read(void)
|
||||
{
|
||||
inb(VGAREG_ACTL_RESET);
|
||||
return inb(VGAREG_ACTL_ADDRESS);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_attrindex_write(u8 value)
|
||||
{
|
||||
inb(VGAREG_ACTL_RESET);
|
||||
outb(value, VGAREG_ACTL_ADDRESS);
|
||||
}
|
||||
|
||||
|
||||
struct vbe_palette_entry
|
||||
stdvga_dac_read(u8 color)
|
||||
{
|
||||
outb(color, VGAREG_DAC_READ_ADDRESS);
|
||||
u8 r = inb(VGAREG_DAC_DATA);
|
||||
u8 g = inb(VGAREG_DAC_DATA);
|
||||
u8 b = inb(VGAREG_DAC_DATA);
|
||||
return (struct vbe_palette_entry){ .red=r, .green=g, .blue=b };
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_dac_write(u8 color, struct vbe_palette_entry rgb)
|
||||
{
|
||||
outb(color, VGAREG_DAC_WRITE_ADDRESS);
|
||||
outb(rgb.red, VGAREG_DAC_DATA);
|
||||
outb(rgb.green, VGAREG_DAC_DATA);
|
||||
outb(rgb.blue, VGAREG_DAC_DATA);
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
// Standard VGA mode information.
|
||||
//
|
||||
// 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 "biosvar.h" // GET_GLOBAL
|
||||
#include "output.h" // warn_internalerror
|
||||
#include "std/vga.h" // struct video_param_s
|
||||
#include "stdvga.h" // stdvga_find_mode
|
||||
#include "string.h" // memcpy_far
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgautil.h" // vgafont16
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Default color palettes (stored in DAC registers)
|
||||
****************************************************************/
|
||||
|
||||
// 4 grey palette used for MDA card compatibility
|
||||
static u8 pal_mda[] VAR16 = {
|
||||
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
|
||||
0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
|
||||
0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
|
||||
0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f
|
||||
};
|
||||
|
||||
// 16 colors used for CGA mode compatibility
|
||||
static u8 pal_cga[] VAR16 = {
|
||||
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
|
||||
0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
|
||||
0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
|
||||
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
|
||||
0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
|
||||
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
|
||||
0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
|
||||
0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
|
||||
0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
|
||||
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
|
||||
0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
|
||||
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
|
||||
0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
|
||||
};
|
||||
|
||||
// 64 colors used for EGA mode compatibility
|
||||
static u8 pal_ega[] VAR16 = {
|
||||
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
|
||||
0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
|
||||
0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f,
|
||||
0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
|
||||
0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a,
|
||||
0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
|
||||
0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f,
|
||||
0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
|
||||
0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a,
|
||||
0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
|
||||
0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f,
|
||||
0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
|
||||
0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a,
|
||||
0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
|
||||
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
|
||||
0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
|
||||
};
|
||||
|
||||
// Default 256 colors used in VGA "packed" mode
|
||||
static u8 pal_vga[] VAR16 = {
|
||||
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
|
||||
0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
|
||||
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
|
||||
0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
|
||||
0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b,
|
||||
0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
|
||||
0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28,
|
||||
0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
|
||||
0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f,
|
||||
0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
|
||||
0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00,
|
||||
0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
|
||||
0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f,
|
||||
0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
|
||||
0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f,
|
||||
0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
|
||||
|
||||
0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f,
|
||||
0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
|
||||
0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37,
|
||||
0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
|
||||
0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f,
|
||||
0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
|
||||
0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d,
|
||||
0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
|
||||
0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a,
|
||||
0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
|
||||
0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c,
|
||||
0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
|
||||
0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00,
|
||||
0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
|
||||
0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15,
|
||||
0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
|
||||
|
||||
0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c,
|
||||
0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
|
||||
0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e,
|
||||
0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
|
||||
0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18,
|
||||
0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
|
||||
0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c,
|
||||
0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
|
||||
0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14,
|
||||
0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
|
||||
0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a,
|
||||
0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
|
||||
0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10,
|
||||
0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
|
||||
0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00,
|
||||
0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
|
||||
|
||||
0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c,
|
||||
0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
|
||||
0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10,
|
||||
0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
|
||||
0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08,
|
||||
0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
|
||||
0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e,
|
||||
0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
|
||||
0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10,
|
||||
0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
|
||||
0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b,
|
||||
0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
|
||||
0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f,
|
||||
0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
|
||||
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Video mode register definitions
|
||||
****************************************************************/
|
||||
|
||||
static u8 sequ_01[] VAR16 = { 0x08, 0x03, 0x00, 0x02 };
|
||||
static u8 crtc_01[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
|
||||
0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 actl_01[] VAR16 = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x0c, 0x00, 0x0f, 0x08 };
|
||||
static u8 grdc_01[] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
|
||||
static u8 sequ_03[] VAR16 = { 0x00, 0x03, 0x00, 0x02 };
|
||||
static u8 crtc_03[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
|
||||
0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 sequ_04[] VAR16 = { 0x09, 0x03, 0x00, 0x02 };
|
||||
static u8 crtc_04[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
|
||||
0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
|
||||
0xff };
|
||||
static u8 actl_04[] VAR16 = {
|
||||
0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x01, 0x00, 0x03, 0x00 };
|
||||
static u8 grdc_04[] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff };
|
||||
static u8 sequ_06[] VAR16 = { 0x01, 0x01, 0x00, 0x06 };
|
||||
static u8 crtc_06[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
|
||||
0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
|
||||
0xff };
|
||||
static u8 actl_06[] VAR16 = {
|
||||
0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
|
||||
0x01, 0x00, 0x01, 0x00 };
|
||||
static u8 grdc_06[] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff };
|
||||
static u8 crtc_07[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
|
||||
0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 actl_07[] VAR16 = {
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x0e, 0x00, 0x0f, 0x08 };
|
||||
static u8 grdc_07[] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff };
|
||||
static u8 sequ_0d[] VAR16 = { 0x09, 0x0f, 0x00, 0x06 };
|
||||
static u8 crtc_0d[] VAR16 = {
|
||||
0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
|
||||
0xff };
|
||||
static u8 actl_0d[] VAR16 = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x01, 0x00, 0x0f, 0x00 };
|
||||
static u8 grdc_0d[] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff };
|
||||
static u8 sequ_0e[] VAR16 = { 0x01, 0x0f, 0x00, 0x06 };
|
||||
static u8 crtc_0e[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
|
||||
0xff };
|
||||
static u8 crtc_0f[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
|
||||
0xff };
|
||||
static u8 actl_0f[] VAR16 = {
|
||||
0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
|
||||
0x01, 0x00, 0x01, 0x00 };
|
||||
static u8 actl_10[] VAR16 = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x01, 0x00, 0x0f, 0x00 };
|
||||
static u8 crtc_11[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
|
||||
0xff };
|
||||
static u8 actl_11[] VAR16 = {
|
||||
0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
|
||||
0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
|
||||
0x01, 0x00, 0x0f, 0x00 };
|
||||
static u8 sequ_13[] VAR16 = { 0x01, 0x0f, 0x00, 0x0e };
|
||||
static u8 crtc_13[] VAR16 = {
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
|
||||
0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
|
||||
0xff };
|
||||
static u8 actl_13[] VAR16 = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x41, 0x00, 0x0f, 0x00 };
|
||||
static u8 grdc_13[] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff };
|
||||
static u8 crtc_6A[] VAR16 = {
|
||||
0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
|
||||
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
|
||||
0xff };
|
||||
|
||||
#define PAL(x) x, sizeof(x)
|
||||
|
||||
struct stdvga_mode_s {
|
||||
u16 mode;
|
||||
struct vgamode_s info;
|
||||
u8 *dac;
|
||||
u16 dacsize;
|
||||
|
||||
u8 *sequ_regs;
|
||||
u8 miscreg;
|
||||
u8 *crtc_regs;
|
||||
u8 *actl_regs;
|
||||
u8 *grdc_regs;
|
||||
};
|
||||
|
||||
static struct stdvga_mode_s vga_modes[] VAR16 = {
|
||||
//mode { model tx ty bpp cw ch sstart } dac
|
||||
// sequ misc crtc actl grdc
|
||||
{0x00, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }, PAL(pal_ega)
|
||||
, sequ_01, 0x67, crtc_01, actl_01, grdc_01},
|
||||
{0x01, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }, PAL(pal_ega)
|
||||
, sequ_01, 0x67, crtc_01, actl_01, grdc_01},
|
||||
{0x02, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }, PAL(pal_ega)
|
||||
, sequ_03, 0x67, crtc_03, actl_01, grdc_01},
|
||||
{0x03, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }, PAL(pal_ega)
|
||||
, sequ_03, 0x67, crtc_03, actl_01, grdc_01},
|
||||
{0x04, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }, PAL(pal_cga)
|
||||
, sequ_04, 0x63, crtc_04, actl_04, grdc_04},
|
||||
{0x05, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }, PAL(pal_cga)
|
||||
, sequ_04, 0x63, crtc_04, actl_04, grdc_04},
|
||||
{0x06, { MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT }, PAL(pal_cga)
|
||||
, sequ_06, 0x63, crtc_06, actl_06, grdc_06},
|
||||
{0x07, { MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT }, PAL(pal_mda)
|
||||
, sequ_03, 0x66, crtc_07, actl_07, grdc_07},
|
||||
{0x0D, { MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH }, PAL(pal_cga)
|
||||
, sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d},
|
||||
{0x0E, { MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH }, PAL(pal_cga)
|
||||
, sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d},
|
||||
{0x0F, { MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH }, PAL(pal_mda)
|
||||
, sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d},
|
||||
{0x10, { MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH }, PAL(pal_ega)
|
||||
, sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d},
|
||||
{0x11, { MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH }, PAL(pal_ega)
|
||||
, sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d},
|
||||
{0x12, { MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH }, PAL(pal_ega)
|
||||
, sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d},
|
||||
{0x13, { MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH }, PAL(pal_vga)
|
||||
, sequ_13, 0x63, crtc_13, actl_13, grdc_13},
|
||||
{0x6A, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH }, PAL(pal_ega)
|
||||
, sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d},
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Mode functions
|
||||
****************************************************************/
|
||||
|
||||
static int
|
||||
is_stdvga_mode(struct vgamode_s *vmode_g)
|
||||
{
|
||||
return (vmode_g >= &vga_modes[0].info
|
||||
&& vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
|
||||
}
|
||||
|
||||
struct vgamode_s *
|
||||
stdvga_find_mode(int mode)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
|
||||
struct stdvga_mode_s *stdmode_g = &vga_modes[i];
|
||||
if (GET_GLOBAL(stdmode_g->mode) == mode)
|
||||
return &stdmode_g->info;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_list_modes(u16 seg, u16 *dest, u16 *last)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(vga_modes) && dest < last; i++) {
|
||||
struct stdvga_mode_s *stdmode_g = &vga_modes[i];
|
||||
u16 mode = GET_GLOBAL(stdmode_g->mode);
|
||||
if (mode == 0xffff)
|
||||
continue;
|
||||
SET_FARVAR(seg, *dest, mode);
|
||||
dest++;
|
||||
}
|
||||
|
||||
SET_FARVAR(seg, *dest, 0xffff);
|
||||
}
|
||||
|
||||
static struct video_save_pointer_s video_save_pointer_table VAR16;
|
||||
|
||||
static struct video_param_s video_param_table[29] VAR16;
|
||||
|
||||
void
|
||||
stdvga_build_video_param(void)
|
||||
{
|
||||
SET_BDA(video_savetable
|
||||
, SEGOFF(get_global_seg(), (u32)&video_save_pointer_table));
|
||||
SET_VGA(video_save_pointer_table.videoparam
|
||||
, SEGOFF(get_global_seg(), (u32)video_param_table));
|
||||
|
||||
static u8 parammodes[] VAR16 = {
|
||||
0, 0, 0, 0, 0x04, 0x05, 0x06, 0x07,
|
||||
0, 0, 0, 0, 0, 0x0d, 0x0e, 0,
|
||||
0, 0x0f, 0x10, 0, 0, 0, 0, 0x01,
|
||||
0x03, 0x07, 0x11, 0x12, 0x13
|
||||
};
|
||||
|
||||
int i;
|
||||
for (i=0; i<ARRAY_SIZE(parammodes); i++) {
|
||||
int mode = GET_GLOBAL(parammodes[i]);
|
||||
if (! mode)
|
||||
continue;
|
||||
struct video_param_s *vparam_g = &video_param_table[i];
|
||||
struct vgamode_s *vmode_g = stdvga_find_mode(mode);
|
||||
if (!vmode_g)
|
||||
continue;
|
||||
int width = GET_GLOBAL(vmode_g->width);
|
||||
int height = GET_GLOBAL(vmode_g->height);
|
||||
u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
|
||||
int cheight = GET_GLOBAL(vmode_g->cheight);
|
||||
if (memmodel == MM_TEXT) {
|
||||
SET_VGA(vparam_g->twidth, width);
|
||||
SET_VGA(vparam_g->theightm1, height-1);
|
||||
} else {
|
||||
int cwidth = GET_GLOBAL(vmode_g->cwidth);
|
||||
SET_VGA(vparam_g->twidth, width / cwidth);
|
||||
SET_VGA(vparam_g->theightm1, (height / cheight) - 1);
|
||||
}
|
||||
SET_VGA(vparam_g->cheight, cheight);
|
||||
SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height));
|
||||
struct stdvga_mode_s *stdmode_g = container_of(
|
||||
vmode_g, struct stdvga_mode_s, info);
|
||||
memcpy_far(get_global_seg(), vparam_g->sequ_regs
|
||||
, get_global_seg(), GET_GLOBAL(stdmode_g->sequ_regs)
|
||||
, ARRAY_SIZE(vparam_g->sequ_regs));
|
||||
SET_VGA(vparam_g->miscreg, GET_GLOBAL(stdmode_g->miscreg));
|
||||
memcpy_far(get_global_seg(), vparam_g->crtc_regs
|
||||
, get_global_seg(), GET_GLOBAL(stdmode_g->crtc_regs)
|
||||
, ARRAY_SIZE(vparam_g->crtc_regs));
|
||||
memcpy_far(get_global_seg(), vparam_g->actl_regs
|
||||
, get_global_seg(), GET_GLOBAL(stdmode_g->actl_regs)
|
||||
, ARRAY_SIZE(vparam_g->actl_regs));
|
||||
memcpy_far(get_global_seg(), vparam_g->grdc_regs
|
||||
, get_global_seg(), GET_GLOBAL(stdmode_g->grdc_regs)
|
||||
, ARRAY_SIZE(vparam_g->grdc_regs));
|
||||
}
|
||||
|
||||
// Fill available legacy modes in video_func_static table
|
||||
u32 modes = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
|
||||
u16 mode = GET_GLOBAL(vga_modes[i].mode);
|
||||
if (mode <= 0x13)
|
||||
modes |= 1<<mode;
|
||||
}
|
||||
SET_VGA(static_functionality.modes, modes);
|
||||
}
|
||||
|
||||
void
|
||||
stdvga_override_crtc(int mode, u8 *crtc)
|
||||
{
|
||||
struct vgamode_s *vmode_g = stdvga_find_mode(mode);
|
||||
if (!vmode_g)
|
||||
return;
|
||||
struct stdvga_mode_s *stdmode_g = container_of(
|
||||
vmode_g, struct stdvga_mode_s, info);
|
||||
SET_VGA(stdmode_g->crtc_regs, crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_screen(struct vgamode_s *curmode_g)
|
||||
{
|
||||
switch (GET_GLOBAL(curmode_g->memmodel)) {
|
||||
case MM_TEXT:
|
||||
memset16_far(GET_GLOBAL(curmode_g->sstart), 0, 0x0720, 32*1024);
|
||||
break;
|
||||
case MM_CGA:
|
||||
memset16_far(GET_GLOBAL(curmode_g->sstart), 0, 0x0000, 32*1024);
|
||||
break;
|
||||
default:
|
||||
memset16_far(GET_GLOBAL(curmode_g->sstart), 0, 0x0000, 64*1024);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
|
||||
{
|
||||
if (! is_stdvga_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(0xff);
|
||||
|
||||
// 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_many(get_global_seg(), palette_g, 0, palsize);
|
||||
int i;
|
||||
for (i = palsize; i < 0x0100; i++) {
|
||||
struct vbe_palette_entry rgb = { };
|
||||
stdvga_dac_write(i, rgb);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Load the standard palette associated with 8bpp packed pixel vga modes.
|
||||
void
|
||||
stdvga_set_packed_palette(void)
|
||||
{
|
||||
stdvga_dac_write_many(get_global_seg(), pal_vga, 0, sizeof(pal_vga) / 3);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// Common svga mode definitions
|
||||
//
|
||||
// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2011 Julian Pidancet <julian.pidancet@citrix.com>
|
||||
// Copyright (C) 2002 Jeroen Janssen
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "stdvga.h" // SEG_GRAPH
|
||||
#include "vgabios.h" // VAR16
|
||||
|
||||
#include "svgamodes.h"
|
||||
|
||||
struct generic_svga_mode svga_modes[] VAR16 = {
|
||||
/* standard modes */
|
||||
{ 0x100, { MM_PACKED, 640, 400, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x101, { MM_PACKED, 640, 480, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x102, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH } },
|
||||
{ 0x103, { MM_PACKED, 800, 600, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x104, { MM_PLANAR, 1024, 768, 4, 8, 16, SEG_GRAPH } },
|
||||
{ 0x105, { MM_PACKED, 1024, 768, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x106, { MM_PLANAR, 1280, 1024, 4, 8, 16, SEG_GRAPH } },
|
||||
{ 0x107, { MM_PACKED, 1280, 1024, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x10D, { MM_DIRECT, 320, 200, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x10E, { MM_DIRECT, 320, 200, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x10F, { MM_DIRECT, 320, 200, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x110, { MM_DIRECT, 640, 480, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x111, { MM_DIRECT, 640, 480, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x112, { MM_DIRECT, 640, 480, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x113, { MM_DIRECT, 800, 600, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x114, { MM_DIRECT, 800, 600, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x115, { MM_DIRECT, 800, 600, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x116, { MM_DIRECT, 1024, 768, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x117, { MM_DIRECT, 1024, 768, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x118, { MM_DIRECT, 1024, 768, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x119, { MM_DIRECT, 1280, 1024, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x11A, { MM_DIRECT, 1280, 1024, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x11B, { MM_DIRECT, 1280, 1024, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x11C, { MM_PACKED, 1600, 1200, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x11D, { MM_DIRECT, 1600, 1200, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x11E, { MM_DIRECT, 1600, 1200, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x11F, { MM_DIRECT, 1600, 1200, 24, 8, 16, SEG_GRAPH } },
|
||||
/* other modes */
|
||||
{ 0x140, { MM_DIRECT, 320, 200, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x141, { MM_DIRECT, 640, 400, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x142, { MM_DIRECT, 640, 480, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x143, { MM_DIRECT, 800, 600, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x144, { MM_DIRECT, 1024, 768, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x145, { MM_DIRECT, 1280, 1024, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x146, { MM_PACKED, 320, 200, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x147, { MM_DIRECT, 1600, 1200, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x148, { MM_PACKED, 1152, 864, 8, 8, 16, SEG_GRAPH } },
|
||||
{ 0x149, { MM_DIRECT, 1152, 864, 15, 8, 16, SEG_GRAPH } },
|
||||
{ 0x14a, { MM_DIRECT, 1152, 864, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x14b, { MM_DIRECT, 1152, 864, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x14c, { MM_DIRECT, 1152, 864, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x175, { MM_DIRECT, 1280, 768, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x176, { MM_DIRECT, 1280, 768, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x177, { MM_DIRECT, 1280, 768, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x178, { MM_DIRECT, 1280, 800, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x179, { MM_DIRECT, 1280, 800, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x17a, { MM_DIRECT, 1280, 800, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x17b, { MM_DIRECT, 1280, 960, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x17c, { MM_DIRECT, 1280, 960, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x17d, { MM_DIRECT, 1280, 960, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x17e, { MM_DIRECT, 1440, 900, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x17f, { MM_DIRECT, 1440, 900, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x180, { MM_DIRECT, 1440, 900, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x181, { MM_DIRECT, 1400, 1050, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x182, { MM_DIRECT, 1400, 1050, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x183, { MM_DIRECT, 1400, 1050, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x184, { MM_DIRECT, 1680, 1050, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x185, { MM_DIRECT, 1680, 1050, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x186, { MM_DIRECT, 1680, 1050, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x187, { MM_DIRECT, 1920, 1200, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x188, { MM_DIRECT, 1920, 1200, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x189, { MM_DIRECT, 1920, 1200, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x18a, { MM_DIRECT, 2560, 1600, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x18b, { MM_DIRECT, 2560, 1600, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x18c, { MM_DIRECT, 2560, 1600, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x18d, { MM_DIRECT, 1280, 720, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x18e, { MM_DIRECT, 1280, 720, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x18f, { MM_DIRECT, 1280, 720, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x190, { MM_DIRECT, 1920, 1080, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x191, { MM_DIRECT, 1920, 1080, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x192, { MM_DIRECT, 1920, 1080, 32, 8, 16, SEG_GRAPH } },
|
||||
|
||||
/* custom resolutions for 16:9 displays */
|
||||
{ 0x193, { MM_DIRECT, 1600, 900, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x194, { MM_DIRECT, 1600, 900, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x195, { MM_DIRECT, 1600, 900, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x196, { MM_DIRECT, 2560, 1440, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x197, { MM_DIRECT, 2560, 1440, 24, 8, 16, SEG_GRAPH } },
|
||||
{ 0x198, { MM_DIRECT, 2560, 1440, 32, 8, 16, SEG_GRAPH } },
|
||||
|
||||
/* 4k modes */
|
||||
{ 0x199, { MM_DIRECT, 3840, 2160, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x19a, { MM_DIRECT, 3840, 2160, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x19b, { MM_DIRECT, 4096, 2160, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x19c, { MM_DIRECT, 4096, 2160, 32, 8, 16, SEG_GRAPH } },
|
||||
{ 0x19d, { MM_DIRECT, 5120, 2160, 16, 8, 16, SEG_GRAPH } },
|
||||
{ 0x19e, { MM_DIRECT, 5120, 2160, 32, 8, 16, SEG_GRAPH } },
|
||||
};
|
||||
unsigned int svga_mcount VAR16 = ARRAY_SIZE(svga_modes);
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef __SVGAMODES_H
|
||||
#define __SVGAMODES_H
|
||||
|
||||
struct generic_svga_mode {
|
||||
u16 mode;
|
||||
struct vgamode_s info;
|
||||
};
|
||||
|
||||
extern struct generic_svga_mode svga_modes[];
|
||||
extern unsigned int svga_mcount;
|
||||
|
||||
#endif /* __SVGAMODES_H */
|
||||
@@ -0,0 +1,96 @@
|
||||
// Virtual software based cursor support
|
||||
//
|
||||
// Copyright (C) 2014-2016 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_BDA
|
||||
#include "bregs.h" // struct bregs
|
||||
#include "vgabios.h" // get_cursor_pos
|
||||
#include "vgafb.h" // handle_gfx_op
|
||||
#include "vgautil.h" // swcursor_check_event
|
||||
|
||||
// Draw/undraw a cursor on the framebuffer by xor'ing the cursor cell
|
||||
static void
|
||||
gfx_set_swcursor(struct vgamode_s *curmode_g, int enable, struct cursorpos cp)
|
||||
{
|
||||
u16 cursor_type = get_cursor_shape();
|
||||
u8 start = cursor_type >> 8, end = cursor_type & 0xff;
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.x = cp.x * 8;
|
||||
int cheight = GET_BDA(char_height);
|
||||
op.y = cp.y * cheight + start;
|
||||
|
||||
int i;
|
||||
for (i = start; i < cheight && i <= end; i++, op.y++) {
|
||||
op.op = GO_READ8;
|
||||
handle_gfx_op(&op);
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
op.pixels[j] ^= 0x07;
|
||||
op.op = GO_WRITE8;
|
||||
handle_gfx_op(&op);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw/undraw a cursor on the screen
|
||||
static void
|
||||
set_swcursor(int enable)
|
||||
{
|
||||
u8 flags = GET_BDA_EXT(flags);
|
||||
if (!!(flags & BF_SWCURSOR) == enable)
|
||||
// Already in requested mode.
|
||||
return;
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return;
|
||||
struct cursorpos cp = get_cursor_pos(GET_BDA(video_page));
|
||||
if (cp.x >= GET_BDA(video_cols) || cp.y > GET_BDA(video_rows)
|
||||
|| GET_BDA(cursor_type) >= 0x2000)
|
||||
// Cursor not visible
|
||||
return;
|
||||
|
||||
SET_BDA_EXT(flags, (flags & ~BF_SWCURSOR) | (enable ? BF_SWCURSOR : 0));
|
||||
|
||||
if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
|
||||
gfx_set_swcursor(curmode_g, enable, cp);
|
||||
return;
|
||||
}
|
||||
|
||||
// In text mode, swap foreground and background attributes for cursor
|
||||
void *dest_far = text_address(cp) + 1;
|
||||
u8 attr = GET_FARVAR(GET_GLOBAL(curmode_g->sstart), *(u8*)dest_far);
|
||||
attr = (attr >> 4) | (attr << 4);
|
||||
SET_FARVAR(GET_GLOBAL(curmode_g->sstart), *(u8*)dest_far, attr);
|
||||
}
|
||||
|
||||
// Disable virtual cursor if a vgabios call accesses the framebuffer
|
||||
void
|
||||
swcursor_pre_handle10(struct bregs *regs)
|
||||
{
|
||||
if (!vga_emulate_text())
|
||||
return;
|
||||
switch (regs->ah) {
|
||||
case 0x4f:
|
||||
if (!CONFIG_VGA_VBE || regs->al != 0x02)
|
||||
break;
|
||||
// NO BREAK
|
||||
case 0x00 ... 0x02:
|
||||
case 0x05 ... 0x0e:
|
||||
case 0x13:
|
||||
set_swcursor(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Called by periodic (18.2hz) timer
|
||||
void
|
||||
swcursor_check_event(void)
|
||||
{
|
||||
if (!vga_emulate_text())
|
||||
return;
|
||||
set_swcursor(GET_BDA(timer_counter) % 18 < 9);
|
||||
}
|
||||
+517
@@ -0,0 +1,517 @@
|
||||
// Video Bios Extensions handlers
|
||||
//
|
||||
// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2011 Julian Pidancet <julian.pidancet@citrix.com>
|
||||
// Copyright (C) 2001-2008 the LGPL VGABios developers Team
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "biosvar.h" // GET_GLOBAL
|
||||
#include "bregs.h" // struct bregs
|
||||
#include "config.h" // CONFIG_*
|
||||
#include "output.h" // dprintf
|
||||
#include "std/vbe.h" // struct vbe_info
|
||||
#include "string.h" // memset_far
|
||||
#include "vgabios.h" // get_current_mode
|
||||
#include "vgahw.h" // vgahw_set_mode
|
||||
#include "vgautil.h" // handle_104f
|
||||
|
||||
#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"
|
||||
|
||||
u32 VBE_total_memory VAR16 = 256 * 1024;
|
||||
u32 VBE_capabilities VAR16;
|
||||
u32 VBE_framebuffer VAR16;
|
||||
u16 VBE_win_granularity VAR16;
|
||||
u8 VBE_edid[256] VAR16;
|
||||
|
||||
static void
|
||||
vbe_104f00(struct bregs *regs)
|
||||
{
|
||||
u16 seg = regs->es;
|
||||
struct vbe_info *info = (void*)(regs->di+0);
|
||||
size_t info_size = offsetof(struct vbe_info, oem_data);
|
||||
|
||||
if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) {
|
||||
dprintf(4, "Get VBE Controller: VBE2 Signature found\n");
|
||||
info_size = sizeof(*info);
|
||||
} 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, info_size);
|
||||
|
||||
SET_FARVAR(seg, info->signature, VESA_SIGNATURE);
|
||||
|
||||
SET_FARVAR(seg, info->version, 0x0300);
|
||||
|
||||
SET_FARVAR(seg, info->oem_string,
|
||||
SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING));
|
||||
SET_FARVAR(seg, info->capabilities, GET_GLOBAL(VBE_capabilities));
|
||||
|
||||
/* We generate our mode list in the reserved field of the info block */
|
||||
u16 *destmode = (void*)info->reserved;
|
||||
SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode));
|
||||
|
||||
/* Total memory (in 64k blocks) */
|
||||
SET_FARVAR(seg, info->total_memory
|
||||
, GET_GLOBAL(VBE_total_memory) / (64*1024));
|
||||
|
||||
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 */
|
||||
u16 *last = (void*)&info->reserved[sizeof(info->reserved)];
|
||||
vgahw_list_modes(seg, destmode, last - 1);
|
||||
|
||||
regs->ax = 0x004f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f01(struct bregs *regs)
|
||||
{
|
||||
u16 seg = regs->es;
|
||||
struct vbe_mode_info *info = (void*)(regs->di+0);
|
||||
u16 mode = regs->cx;
|
||||
|
||||
dprintf(1, "VBE mode info request: %x\n", mode);
|
||||
|
||||
struct vgamode_s *vmode_g = vgahw_find_mode(mode & ~MF_VBEFLAGS);
|
||||
if (! vmode_g) {
|
||||
dprintf(1, "VBE mode %x not found\n", mode);
|
||||
regs->ax = 0x014f;
|
||||
return;
|
||||
}
|
||||
|
||||
memset_far(seg, info, 0, sizeof(*info));
|
||||
|
||||
// Basic information about video controller.
|
||||
u32 win_granularity = GET_GLOBAL(VBE_win_granularity);
|
||||
SET_FARVAR(seg, info->winA_attributes,
|
||||
(win_granularity ? VBE_WINDOW_ATTRIBUTE_RELOCATABLE : 0) |
|
||||
VBE_WINDOW_ATTRIBUTE_READABLE |
|
||||
VBE_WINDOW_ATTRIBUTE_WRITEABLE);
|
||||
SET_FARVAR(seg, info->winB_attributes, 0);
|
||||
SET_FARVAR(seg, info->win_granularity, win_granularity);
|
||||
SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */
|
||||
SET_FARVAR(seg, info->winA_seg, GET_GLOBAL(vmode_g->sstart));
|
||||
SET_FARVAR(seg, info->winB_seg, 0x0);
|
||||
extern void entry_104f05(void);
|
||||
SET_FARVAR(seg, info->win_func_ptr
|
||||
, SEGOFF(get_global_seg(), (u32)entry_104f05));
|
||||
// Basic information about mode.
|
||||
int width = GET_GLOBAL(vmode_g->width);
|
||||
int height = GET_GLOBAL(vmode_g->height);
|
||||
int linesize = vgahw_minimum_linelength(vmode_g);
|
||||
SET_FARVAR(seg, info->bytes_per_scanline, linesize);
|
||||
SET_FARVAR(seg, info->xres, width);
|
||||
SET_FARVAR(seg, info->yres, height);
|
||||
SET_FARVAR(seg, info->xcharsize, GET_GLOBAL(vmode_g->cwidth));
|
||||
SET_FARVAR(seg, info->ycharsize, GET_GLOBAL(vmode_g->cheight));
|
||||
int depth = GET_GLOBAL(vmode_g->depth);
|
||||
SET_FARVAR(seg, info->bits_per_pixel, depth);
|
||||
u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
|
||||
SET_FARVAR(seg, info->mem_model, memmodel);
|
||||
SET_FARVAR(seg, info->reserved0, 1);
|
||||
|
||||
// Mode specific info.
|
||||
u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED |
|
||||
VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE |
|
||||
VBE_MODE_ATTRIBUTE_COLOR_MODE |
|
||||
VBE_MODE_ATTRIBUTE_GRAPHICS_MODE |
|
||||
VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE;
|
||||
u32 framebuffer = 0;
|
||||
int planes = 1, banks = 1;
|
||||
u32 pages = GET_GLOBAL(VBE_total_memory) / ALIGN(height * linesize, 64*1024);
|
||||
switch (memmodel) {
|
||||
case MM_TEXT:
|
||||
mode_attr &= ~VBE_MODE_ATTRIBUTE_GRAPHICS_MODE;
|
||||
mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT;
|
||||
if (GET_GLOBAL(vmode_g->sstart) == SEG_MTEXT)
|
||||
mode_attr &= ~VBE_MODE_ATTRIBUTE_COLOR_MODE;
|
||||
pages = 1;
|
||||
break;
|
||||
case MM_CGA:
|
||||
pages = 1;
|
||||
banks = 2;
|
||||
SET_FARVAR(seg, info->bank_size, 8);
|
||||
break;
|
||||
case MM_PLANAR:
|
||||
planes = 4;
|
||||
pages /= 4;
|
||||
break;
|
||||
default:
|
||||
framebuffer = GET_GLOBAL(VBE_framebuffer);
|
||||
if (framebuffer)
|
||||
mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE;
|
||||
break;
|
||||
}
|
||||
if (pages > 128)
|
||||
pages = 128;
|
||||
if (pages < 2)
|
||||
pages++;
|
||||
SET_FARVAR(seg, info->mode_attributes, mode_attr);
|
||||
SET_FARVAR(seg, info->planes, planes);
|
||||
SET_FARVAR(seg, info->pages, pages - 1);
|
||||
SET_FARVAR(seg, info->banks, banks);
|
||||
|
||||
// Pixel color breakdown
|
||||
u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos;
|
||||
switch (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;
|
||||
SET_FARVAR(seg, info->directcolor_info,
|
||||
VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE);
|
||||
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);
|
||||
|
||||
// Linear framebuffer info.
|
||||
if (framebuffer) {
|
||||
SET_FARVAR(seg, info->phys_base, framebuffer);
|
||||
|
||||
SET_FARVAR(seg, info->reserved1, 0);
|
||||
SET_FARVAR(seg, info->reserved2, 0);
|
||||
SET_FARVAR(seg, info->linear_bytes_per_scanline, linesize);
|
||||
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);
|
||||
}
|
||||
|
||||
regs->ax = 0x004f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f02(struct bregs *regs)
|
||||
{
|
||||
dprintf(1, "VBE mode set: %x\n", regs->bx);
|
||||
|
||||
int mode = regs->bx & ~MF_VBEFLAGS;
|
||||
int flags = regs->bx & MF_VBEFLAGS;
|
||||
int ret = vga_set_mode(mode, flags);
|
||||
|
||||
regs->ah = ret;
|
||||
regs->al = 0x4f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f03(struct bregs *regs)
|
||||
{
|
||||
regs->bx = GET_BDA_EXT(vbe_mode);
|
||||
dprintf(1, "VBE current mode=%x\n", regs->bx);
|
||||
regs->ax = 0x004f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f04(struct bregs *regs)
|
||||
{
|
||||
u16 seg = regs->es;
|
||||
void *data = (void*)(regs->bx+0);
|
||||
u16 states = regs->cx;
|
||||
u8 cmd = regs->dl;
|
||||
if (states & ~0x0f || cmd > 2)
|
||||
goto fail;
|
||||
int ret = vgahw_save_restore(states | (cmd<<8), seg, data);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
if (cmd == 0)
|
||||
regs->bx = DIV_ROUND_UP(ret, 64);
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
fail:
|
||||
regs->ax = 0x014f;
|
||||
}
|
||||
|
||||
void VISIBLE16
|
||||
vbe_104f05(struct bregs *regs)
|
||||
{
|
||||
if (regs->bh > 1 || regs->bl > 1)
|
||||
goto fail;
|
||||
if (GET_BDA_EXT(vbe_mode) & MF_LINEARFB) {
|
||||
regs->ah = VBE_RETURN_STATUS_INVALID;
|
||||
return;
|
||||
}
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (! curmode_g)
|
||||
goto fail;
|
||||
if (regs->bh) {
|
||||
int ret = vgahw_get_window(curmode_g, regs->bl);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
regs->dx = ret;
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
}
|
||||
int ret = vgahw_set_window(curmode_g, regs->bl, regs->dx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
fail:
|
||||
regs->ax = 0x014f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f06(struct bregs *regs)
|
||||
{
|
||||
if (regs->bl > 0x02)
|
||||
goto fail;
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (! curmode_g)
|
||||
goto fail;
|
||||
int bpp = vga_bpp(curmode_g);
|
||||
|
||||
if (regs->bl == 0x00) {
|
||||
int ret = vgahw_set_linelength(curmode_g
|
||||
, DIV_ROUND_UP(regs->cx * bpp, 8));
|
||||
if (ret)
|
||||
goto fail;
|
||||
} else if (regs->bl == 0x02) {
|
||||
int ret = vgahw_set_linelength(curmode_g, regs->cx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
int linelength = vgahw_get_linelength(curmode_g);
|
||||
if (linelength < 0)
|
||||
goto fail;
|
||||
|
||||
regs->bx = linelength;
|
||||
regs->cx = (linelength * 8) / bpp;
|
||||
regs->dx = GET_GLOBAL(VBE_total_memory) / linelength;
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
fail:
|
||||
regs->ax = 0x014f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f07(struct bregs *regs)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (! curmode_g)
|
||||
goto fail;
|
||||
int bpp = vga_bpp(curmode_g);
|
||||
int linelength = vgahw_get_linelength(curmode_g);
|
||||
if (linelength < 0)
|
||||
goto fail;
|
||||
|
||||
int ret;
|
||||
switch (regs->bl) {
|
||||
case 0x80:
|
||||
case 0x00:
|
||||
ret = vgahw_set_displaystart(
|
||||
curmode_g, DIV_ROUND_UP(regs->cx * bpp, 8) + linelength * regs->dx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
break;
|
||||
case 0x01:
|
||||
ret = vgahw_get_displaystart(curmode_g);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
regs->dx = ret / linelength;
|
||||
regs->cx = (ret % linelength) * 8 / bpp;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
fail:
|
||||
regs->ax = 0x014f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f08(struct bregs *regs)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (! curmode_g)
|
||||
goto fail;
|
||||
u8 memmodel = GET_GLOBAL(curmode_g->memmodel);
|
||||
if (memmodel == MM_DIRECT || memmodel == MM_YUV) {
|
||||
regs->ax = 0x034f;
|
||||
return;
|
||||
}
|
||||
if (regs->bl > 1)
|
||||
goto fail;
|
||||
if (regs->bl == 0) {
|
||||
int ret = vgahw_set_dacformat(curmode_g, regs->bh);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
int ret = vgahw_get_dacformat(curmode_g);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
regs->bh = ret;
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
fail:
|
||||
regs->ax = 0x014f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f09(struct bregs *regs)
|
||||
{
|
||||
if (!CONFIG_VGA_STDVGA_PORTS) {
|
||||
// DAC palette support only available on devices with stdvga ports
|
||||
regs->ax = 0x0100;
|
||||
return;
|
||||
}
|
||||
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (! curmode_g)
|
||||
goto fail;
|
||||
u8 memmodel = GET_GLOBAL(curmode_g->memmodel);
|
||||
u8 depth = GET_GLOBAL(curmode_g->depth);
|
||||
if (memmodel == MM_DIRECT || memmodel == MM_YUV || depth > 8) {
|
||||
regs->ax = 0x034f;
|
||||
return;
|
||||
}
|
||||
if (regs->dh)
|
||||
goto fail;
|
||||
u8 start = regs->dl;
|
||||
int count = regs->cx;
|
||||
int max_colors = 1 << depth;
|
||||
if (start + count > max_colors)
|
||||
goto fail;
|
||||
u16 seg = regs->es;
|
||||
struct vbe_palette_entry *data_far = (void*)(regs->di+0);
|
||||
int i;
|
||||
switch (regs->bl) {
|
||||
case 0x80:
|
||||
case 0x00:
|
||||
for (i = 0; i < count; i++) {
|
||||
struct vbe_palette_entry rgb = GET_FARVAR(seg, data_far[i]);
|
||||
stdvga_dac_write(start + i, rgb);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
for (i = 0; i < count; i++) {
|
||||
struct vbe_palette_entry rgb = stdvga_dac_read(start + i);
|
||||
SET_FARVAR(seg, data_far[i], rgb);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
regs->ax = 0x004f;
|
||||
return;
|
||||
fail:
|
||||
regs->ax = 0x014f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f0a(struct bregs *regs)
|
||||
{
|
||||
debug_stub(regs);
|
||||
regs->ax = 0x0100;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f10(struct bregs *regs)
|
||||
{
|
||||
switch (regs->bl) {
|
||||
case 0x00:
|
||||
regs->bx = 0x0f30;
|
||||
break;
|
||||
case 0x01:
|
||||
MASK_BDA_EXT(flags, BF_PM_MASK, regs->bh & BF_PM_MASK);
|
||||
break;
|
||||
case 0x02:
|
||||
regs->bh = GET_BDA_EXT(flags) & BF_PM_MASK;
|
||||
break;
|
||||
default:
|
||||
regs->ax = 0x014f;
|
||||
return;
|
||||
}
|
||||
regs->ax = 0x004f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104f15(struct bregs *regs)
|
||||
{
|
||||
int offset;
|
||||
|
||||
switch (regs->bl) {
|
||||
case 0x00:
|
||||
if (GET_GLOBAL(VBE_edid[0]) != 0x00 ||
|
||||
GET_GLOBAL(VBE_edid[1]) != 0xff)
|
||||
goto err;
|
||||
regs->bx = 0x0103;
|
||||
break;
|
||||
case 0x01:
|
||||
offset = regs->dx * 128;
|
||||
if (offset >= sizeof(VBE_edid))
|
||||
goto err;
|
||||
memcpy_far(regs->es, (void*)(regs->di+0),
|
||||
get_global_seg(), VBE_edid + offset,
|
||||
128);
|
||||
break;
|
||||
err:
|
||||
default:
|
||||
regs->ax = 0x014f;
|
||||
return;
|
||||
}
|
||||
regs->ax = 0x004f;
|
||||
}
|
||||
|
||||
static void
|
||||
vbe_104fXX(struct bregs *regs)
|
||||
{
|
||||
debug_stub(regs);
|
||||
regs->ax = 0x0100;
|
||||
}
|
||||
|
||||
void noinline
|
||||
handle_104f(struct bregs *regs)
|
||||
{
|
||||
if (!CONFIG_VGA_VBE) {
|
||||
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 0x09: vbe_104f09(regs); break;
|
||||
case 0x0a: vbe_104f0a(regs); break;
|
||||
case 0x10: vbe_104f10(regs); break;
|
||||
case 0x15: vbe_104f15(regs); break;
|
||||
default: vbe_104fXX(regs); break;
|
||||
}
|
||||
}
|
||||
+1133
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,88 @@
|
||||
#ifndef __VGABIOS_H
|
||||
#define __VGABIOS_H
|
||||
|
||||
#include "config.h" // CONFIG_VGA_EMULATE_TEXT
|
||||
#include "farptr.h" // GET_FARVAR
|
||||
#include "types.h" // u8
|
||||
|
||||
// Save/Restore flags
|
||||
#define SR_HARDWARE 0x0001
|
||||
#define SR_BDA 0x0002
|
||||
#define SR_DAC 0x0004
|
||||
#define SR_REGISTERS 0x0008
|
||||
#define SR_SAVE 0x0100
|
||||
#define SR_RESTORE 0x0200
|
||||
|
||||
// Mode flags
|
||||
#define MF_LEGACY 0x0001
|
||||
#define MF_GRAYSUM 0x0002
|
||||
#define MF_NOPALETTE 0x0008
|
||||
#define MF_CUSTOMCRTC 0x0800
|
||||
#define MF_LINEARFB 0x4000
|
||||
#define MF_NOCLEARMEM 0x8000
|
||||
#define MF_VBEFLAGS 0xfe00
|
||||
|
||||
// Memory model types
|
||||
#define MM_TEXT 0x00
|
||||
#define MM_CGA 0x01
|
||||
#define MM_HERCULES 0x02
|
||||
#define MM_PLANAR 0x03
|
||||
#define MM_PACKED 0x04
|
||||
#define MM_NON_CHAIN_4_256 0x05
|
||||
#define MM_DIRECT 0x06
|
||||
#define MM_YUV 0x07
|
||||
|
||||
struct vgamode_s {
|
||||
u8 memmodel;
|
||||
u16 width;
|
||||
u16 height;
|
||||
u8 depth;
|
||||
u8 cwidth;
|
||||
u8 cheight;
|
||||
u16 sstart;
|
||||
};
|
||||
|
||||
// Custom internal storage in BDA (don't change here without also
|
||||
// updating vgaentry.S)
|
||||
#define VGA_CUSTOM_BDA 0xb9
|
||||
|
||||
struct vga_bda_s {
|
||||
u8 flags;
|
||||
u16 vbe_mode;
|
||||
u16 vgamode_offset;
|
||||
} PACKED;
|
||||
|
||||
#define BF_PM_MASK 0x0f
|
||||
#define BF_EMULATE_TEXT 0x10
|
||||
#define BF_SWCURSOR 0x20
|
||||
#define BF_EXTRA_STACK 0x40
|
||||
|
||||
#define GET_BDA_EXT(var) \
|
||||
GET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var)
|
||||
#define SET_BDA_EXT(var, val) \
|
||||
SET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var, (val))
|
||||
#define MASK_BDA_EXT(var, off, on) \
|
||||
SET_BDA_EXT(var, (GET_BDA_EXT(var) & ~(off)) | (on))
|
||||
|
||||
static inline int vga_emulate_text(void) {
|
||||
return CONFIG_VGA_EMULATE_TEXT && GET_BDA_EXT(flags) & BF_EMULATE_TEXT;
|
||||
}
|
||||
|
||||
// Write to global variables (during "post" phase only)
|
||||
#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val))
|
||||
|
||||
// Debug settings
|
||||
#define DEBUG_VGA_POST 1
|
||||
#define DEBUG_VGA_10 9
|
||||
|
||||
// vgabios.c
|
||||
int vga_bpp(struct vgamode_s *vmode_g);
|
||||
u16 calc_page_size(u8 memmodel, u16 width, u16 height);
|
||||
u16 get_cursor_shape(void);
|
||||
struct cursorpos get_cursor_pos(u8 page);
|
||||
int bda_save_restore(int cmd, u16 seg, void *data);
|
||||
struct vgamode_s *get_current_mode(void);
|
||||
int vga_set_mode(int mode, int flags);
|
||||
extern struct video_func_static static_functionality;
|
||||
|
||||
#endif // vgabios.h
|
||||
@@ -0,0 +1,164 @@
|
||||
// Rom layout and bios assembler to C interface.
|
||||
//
|
||||
// Copyright (C) 2009-2013 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
|
||||
#include "asm-offsets.h" // BREGS_*
|
||||
#include "config.h" // CONFIG_*
|
||||
#include "entryfuncs.S" // ENTRY_*
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Rom Header
|
||||
****************************************************************/
|
||||
|
||||
.section .rom.header
|
||||
.code16
|
||||
.global _rom_header, _rom_header_size, _rom_header_checksum
|
||||
_rom_header:
|
||||
.word 0xaa55
|
||||
_rom_header_size:
|
||||
.byte 0
|
||||
_rom_header_entry:
|
||||
jmp _optionrom_entry
|
||||
_rom_header_checksum:
|
||||
.byte 0
|
||||
_rom_header_other:
|
||||
.space 17
|
||||
_rom_header_pcidata:
|
||||
#if CONFIG_VGA_PCI == 1
|
||||
.word rom_pci_data
|
||||
#else
|
||||
.word 0
|
||||
#endif
|
||||
_rom_header_pnpdata:
|
||||
.word 0
|
||||
_rom_header_other2:
|
||||
.word 0
|
||||
_rom_header_signature:
|
||||
.asciz "IBM"
|
||||
|
||||
#if CONFIG_VGA_ATI
|
||||
#include "ati-tables.S"
|
||||
#endif
|
||||
|
||||
/****************************************************************
|
||||
* Entry points
|
||||
****************************************************************/
|
||||
|
||||
// This macro implements a call while avoiding instructions
|
||||
// that old versions of x86emu have problems with.
|
||||
.macro VGA_CALLL cfunc
|
||||
#if CONFIG_VGA_FIXUP_ASM
|
||||
pushw %ax
|
||||
callw \cfunc
|
||||
#else
|
||||
calll \cfunc
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// This macro is the same as ENTRY_ARG except VGA_CALLL is used.
|
||||
.macro ENTRY_ARG_VGA cfunc
|
||||
cli
|
||||
cld
|
||||
PUSHBREGS
|
||||
movw %ss, %ax // Move %ss to %ds
|
||||
movw %ax, %ds
|
||||
movl %esp, %ebx // Backup %esp, then zero high bits
|
||||
movzwl %sp, %esp
|
||||
movl %esp, %eax // First arg is pointer to struct bregs
|
||||
VGA_CALLL \cfunc
|
||||
movl %ebx, %esp // Restore %esp (including high bits)
|
||||
POPBREGS
|
||||
.endm
|
||||
|
||||
DECLFUNC entry_104f05
|
||||
entry_104f05:
|
||||
ENTRY_ARG_VGA vbe_104f05
|
||||
lretw
|
||||
|
||||
DECLFUNC _optionrom_entry
|
||||
_optionrom_entry:
|
||||
ENTRY_ARG_VGA vga_post
|
||||
lretw
|
||||
|
||||
DECLFUNC entry_10
|
||||
entry_10:
|
||||
ENTRY_ARG_VGA handle_10
|
||||
iretw
|
||||
|
||||
#define VGA_CUSTOM_BDA_FLAGS 0xb9
|
||||
#define BF_EXTRA_STACK 0x40
|
||||
|
||||
// Entry point using extra stack
|
||||
DECLFUNC entry_10_extrastack
|
||||
entry_10_extrastack:
|
||||
cli
|
||||
cld
|
||||
pushw %ds
|
||||
pushl %eax
|
||||
|
||||
movw $SEG_BDA, %ax // Check if extra stack is enabled
|
||||
movw %ax, %ds
|
||||
testb $BF_EXTRA_STACK, VGA_CUSTOM_BDA_FLAGS
|
||||
jz 1f
|
||||
|
||||
movw %cs:ExtraStackSeg, %ds // Set %ds:%eax to space on ExtraStack
|
||||
movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-16), %eax
|
||||
SAVEBREGS_POP_DSEAX // Save registers on extra stack
|
||||
movl %esp, PUSHBREGS_size+8(%eax)
|
||||
movw %ss, PUSHBREGS_size+12(%eax)
|
||||
popl BREGS_code(%eax)
|
||||
popw BREGS_flags(%eax)
|
||||
|
||||
movw %ds, %dx // Setup %ss/%esp and call function
|
||||
movw %dx, %ss
|
||||
movl %eax, %esp
|
||||
VGA_CALLL handle_10
|
||||
|
||||
movl %esp, %eax // Restore registers and return
|
||||
movw PUSHBREGS_size+12(%eax), %ss
|
||||
movl PUSHBREGS_size+8(%eax), %esp
|
||||
popl %edx
|
||||
popw %dx
|
||||
pushw BREGS_flags(%eax)
|
||||
pushl BREGS_code(%eax)
|
||||
RESTOREBREGS_DSEAX
|
||||
iretw
|
||||
|
||||
1: // Use regular entry point if the extra stack is disabled
|
||||
popl %eax
|
||||
popw %ds
|
||||
jmp entry_10
|
||||
|
||||
// Timer irq handling
|
||||
DECLFUNC entry_timer_hook
|
||||
entry_timer_hook:
|
||||
ENTRY handle_timer_hook
|
||||
ljmpw *%cs:Timer_Hook_Resume
|
||||
|
||||
// Timer irq handling on extra stack
|
||||
DECLFUNC entry_timer_hook_extrastack
|
||||
entry_timer_hook_extrastack:
|
||||
cli
|
||||
cld
|
||||
pushw %ds // Set %ds:%eax to space on ExtraStack
|
||||
pushl %eax
|
||||
movw %cs:ExtraStackSeg, %ds
|
||||
movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-8), %eax
|
||||
SAVEBREGS_POP_DSEAX
|
||||
movl %esp, PUSHBREGS_size(%eax)
|
||||
movw %ss, PUSHBREGS_size+4(%eax)
|
||||
|
||||
movw %ds, %dx // Setup %ss/%esp and call function
|
||||
movw %dx, %ss
|
||||
movl %eax, %esp
|
||||
calll handle_timer_hook
|
||||
|
||||
movl %esp, %eax // Restore registers and return
|
||||
movw PUSHBREGS_size+4(%eax), %ss
|
||||
movl PUSHBREGS_size(%eax), %esp
|
||||
RESTOREBREGS_DSEAX
|
||||
ljmpw *%cs:Timer_Hook_Resume
|
||||
+660
@@ -0,0 +1,660 @@
|
||||
// Code for manipulating VGA framebuffers.
|
||||
//
|
||||
// Copyright (C) 2009-2014 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 "biosvar.h" // GET_BDA
|
||||
#include "byteorder.h" // cpu_to_be16
|
||||
#include "output.h" // dprintf
|
||||
#include "stdvga.h" // stdvga_planar4_plane
|
||||
#include "string.h" // memset_far
|
||||
#include "vgabios.h" // get_current_mode
|
||||
#include "vgafb.h" // vgafb_write_char
|
||||
#include "vgahw.h" // vgahw_get_linelength
|
||||
#include "vgautil.h" // VBE_framebuffer
|
||||
|
||||
static inline void
|
||||
memmove_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines)
|
||||
{
|
||||
if (src < dst) {
|
||||
dst += stride * (lines - 1);
|
||||
src += stride * (lines - 1);
|
||||
stride = -stride;
|
||||
}
|
||||
for (; lines; lines--, dst+=stride, src+=stride)
|
||||
memcpy_far(seg, dst, seg, src, copylen);
|
||||
}
|
||||
|
||||
static inline void
|
||||
memset_stride(u16 seg, void *dst, u8 val, int setlen, int stride, int lines)
|
||||
{
|
||||
for (; lines; lines--, dst+=stride)
|
||||
memset_far(seg, dst, val, setlen);
|
||||
}
|
||||
|
||||
static inline void
|
||||
memset16_stride(u16 seg, void *dst, u16 val, int setlen, int stride, int lines)
|
||||
{
|
||||
for (; lines; lines--, dst+=stride)
|
||||
memset16_far(seg, dst, val, setlen);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Basic stdvga graphic manipulation
|
||||
****************************************************************/
|
||||
|
||||
static void
|
||||
gfx_planar(struct gfx_op *op)
|
||||
{
|
||||
if (!CONFIG_VGA_STDVGA_PORTS)
|
||||
return;
|
||||
void *dest_far = (void*)(op->y * op->linelength + op->x / 8);
|
||||
int plane;
|
||||
switch (op->op) {
|
||||
default:
|
||||
case GO_READ8:
|
||||
memset(op->pixels, 0, sizeof(op->pixels));
|
||||
for (plane = 0; plane < 4; plane++) {
|
||||
stdvga_planar4_plane(plane);
|
||||
u8 data = GET_FARVAR(SEG_GRAPH, *(u8*)dest_far);
|
||||
int pixel;
|
||||
for (pixel=0; pixel<8; pixel++)
|
||||
op->pixels[pixel] |= ((data>>(7-pixel)) & 1) << plane;
|
||||
}
|
||||
break;
|
||||
case GO_WRITE8:
|
||||
for (plane = 0; plane<4; plane++) {
|
||||
stdvga_planar4_plane(plane);
|
||||
u8 data = 0;
|
||||
int pixel;
|
||||
for (pixel=0; pixel<8; pixel++)
|
||||
data |= ((op->pixels[pixel]>>plane) & 1) << (7-pixel);
|
||||
SET_FARVAR(SEG_GRAPH, *(u8*)dest_far, data);
|
||||
}
|
||||
break;
|
||||
case GO_MEMSET:
|
||||
for (plane = 0; plane < 4; plane++) {
|
||||
stdvga_planar4_plane(plane);
|
||||
u8 data = (op->pixels[0] & (1<<plane)) ? 0xff : 0x00;
|
||||
memset_stride(SEG_GRAPH, dest_far, data
|
||||
, op->xlen / 8, op->linelength, op->ylen);
|
||||
}
|
||||
break;
|
||||
case GO_MEMMOVE: ;
|
||||
void *src_far = (void*)(op->srcy * op->linelength + op->x / 8);
|
||||
for (plane = 0; plane < 4; plane++) {
|
||||
stdvga_planar4_plane(plane);
|
||||
memmove_stride(SEG_GRAPH, dest_far, src_far
|
||||
, op->xlen / 8, op->linelength, op->ylen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
stdvga_planar4_plane(-1);
|
||||
}
|
||||
|
||||
static void
|
||||
gfx_cga(struct gfx_op *op)
|
||||
{
|
||||
int bpp = GET_GLOBAL(op->curmode_g->depth);
|
||||
void *dest_far = (void*)(op->y / 2 * op->linelength + op->x / 8 * bpp);
|
||||
switch (op->op) {
|
||||
default:
|
||||
case GO_READ8:
|
||||
if (op->y & 1)
|
||||
dest_far += 0x2000;
|
||||
if (bpp == 1) {
|
||||
u8 data = GET_FARVAR(SEG_CTEXT, *(u8*)dest_far);
|
||||
int pixel;
|
||||
for (pixel=0; pixel<8; pixel++)
|
||||
op->pixels[pixel] = (data >> (7-pixel)) & 1;
|
||||
} else {
|
||||
u16 data = GET_FARVAR(SEG_CTEXT, *(u16*)dest_far);
|
||||
data = be16_to_cpu(data);
|
||||
int pixel;
|
||||
for (pixel=0; pixel<8; pixel++)
|
||||
op->pixels[pixel] = (data >> ((7-pixel)*2)) & 3;
|
||||
}
|
||||
break;
|
||||
case GO_WRITE8:
|
||||
if (op->y & 1)
|
||||
dest_far += 0x2000;
|
||||
if (bpp == 1) {
|
||||
u8 data = 0;
|
||||
int pixel;
|
||||
for (pixel=0; pixel<8; pixel++)
|
||||
data |= (op->pixels[pixel] & 1) << (7-pixel);
|
||||
SET_FARVAR(SEG_CTEXT, *(u8*)dest_far, data);
|
||||
} else {
|
||||
u16 data = 0;
|
||||
int pixel;
|
||||
for (pixel=0; pixel<8; pixel++)
|
||||
data |= (op->pixels[pixel] & 3) << ((7-pixel) * 2);
|
||||
data = cpu_to_be16(data);
|
||||
SET_FARVAR(SEG_CTEXT, *(u16*)dest_far, data);
|
||||
}
|
||||
break;
|
||||
case GO_MEMSET: ;
|
||||
u8 data = op->pixels[0];
|
||||
if (bpp == 1)
|
||||
data = (data&1) | ((data&1)<<1);
|
||||
data &= 3;
|
||||
data |= (data<<2) | (data<<4) | (data<<6);
|
||||
memset_stride(SEG_CTEXT, dest_far, data
|
||||
, op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
|
||||
memset_stride(SEG_CTEXT, dest_far + 0x2000, data
|
||||
, op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
|
||||
break;
|
||||
case GO_MEMMOVE: ;
|
||||
void *src_far = (void*)(op->srcy / 2 * op->linelength + op->x / 8 * bpp);
|
||||
memmove_stride(SEG_CTEXT, dest_far, src_far
|
||||
, op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
|
||||
memmove_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000
|
||||
, op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gfx_packed(struct gfx_op *op)
|
||||
{
|
||||
void *dest_far = (void*)(op->y * op->linelength + op->x);
|
||||
switch (op->op) {
|
||||
default:
|
||||
case GO_READ8:
|
||||
memcpy_far(GET_SEG(SS), op->pixels, SEG_GRAPH, dest_far, 8);
|
||||
break;
|
||||
case GO_WRITE8:
|
||||
memcpy_far(SEG_GRAPH, dest_far, GET_SEG(SS), op->pixels, 8);
|
||||
break;
|
||||
case GO_MEMSET:
|
||||
memset_stride(SEG_GRAPH, dest_far, op->pixels[0]
|
||||
, op->xlen, op->linelength, op->ylen);
|
||||
break;
|
||||
case GO_MEMMOVE: ;
|
||||
void *src_far = (void*)(op->srcy * op->linelength + op->x);
|
||||
memmove_stride(SEG_GRAPH, dest_far, src_far
|
||||
, op->xlen, op->linelength, op->ylen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Direct framebuffers in high mem
|
||||
****************************************************************/
|
||||
|
||||
// Use int 1587 call to copy memory to/from the framebuffer.
|
||||
void memcpy_high(void *dest, void *src, u32 len)
|
||||
{
|
||||
u64 gdt[6];
|
||||
gdt[2] = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)src);
|
||||
gdt[3] = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)dest);
|
||||
|
||||
// Call int 1587 to copy data.
|
||||
len/=2;
|
||||
u32 flags;
|
||||
u32 eax = 0x8700;
|
||||
u32 si = (u32)&gdt;
|
||||
SET_SEG(ES, GET_SEG(SS));
|
||||
asm volatile(
|
||||
"stc\n"
|
||||
"int $0x15\n"
|
||||
"cli\n"
|
||||
"cld\n"
|
||||
"pushfl\n"
|
||||
"popl %0\n"
|
||||
: "=r" (flags), "+a" (eax), "+S" (si), "+c" (len)
|
||||
: : "cc", "memory");
|
||||
}
|
||||
|
||||
static void
|
||||
memmove_stride_high(void *dst, void *src, int copylen, int stride, int lines)
|
||||
{
|
||||
if (src < dst) {
|
||||
dst += stride * (lines - 1);
|
||||
src += stride * (lines - 1);
|
||||
stride = -stride;
|
||||
}
|
||||
for (; lines; lines--, dst+=stride, src+=stride)
|
||||
memcpy_high(dst, src, copylen);
|
||||
}
|
||||
|
||||
// Map a CGA color to a "direct" mode rgb value.
|
||||
static u32
|
||||
get_color(int depth, u8 attr)
|
||||
{
|
||||
int rbits, gbits, bbits;
|
||||
switch (depth) {
|
||||
case 15: rbits=5; gbits=5; bbits=5; break;
|
||||
case 16: rbits=5; gbits=6; bbits=5; break;
|
||||
default:
|
||||
case 24: rbits=8; gbits=8; bbits=8; break;
|
||||
}
|
||||
int h = (attr&8) ? 1 : 0;
|
||||
int r = (attr&4) ? 2 : 0, g = (attr&2) ? 2 : 0, b = (attr&1) ? 2 : 0;
|
||||
if ((attr & 0xf) == 6)
|
||||
g = 1;
|
||||
int rv = DIV_ROUND_CLOSEST(((1<<rbits) - 1) * (r + h), 3);
|
||||
int gv = DIV_ROUND_CLOSEST(((1<<gbits) - 1) * (g + h), 3);
|
||||
int bv = DIV_ROUND_CLOSEST(((1<<bbits) - 1) * (b + h), 3);
|
||||
return (rv << (gbits+bbits)) + (gv << bbits) + bv;
|
||||
}
|
||||
|
||||
// Find the closest attribute for a given framebuffer color
|
||||
static u8
|
||||
reverse_color(int depth, u32 color)
|
||||
{
|
||||
int rbits, gbits, bbits;
|
||||
switch (depth) {
|
||||
case 15: rbits=5; gbits=5; bbits=5; break;
|
||||
case 16: rbits=5; gbits=6; bbits=5; break;
|
||||
default:
|
||||
case 24: rbits=8; gbits=8; bbits=8; break;
|
||||
}
|
||||
int rv = (color >> (gbits+bbits)) & ((1<<rbits)-1);
|
||||
int gv = (color >> bbits) & ((1<<gbits)-1);
|
||||
int bv = color & ((1<<bbits)-1);
|
||||
int r = DIV_ROUND_CLOSEST(rv * 3, (1<<rbits) - 1);
|
||||
int g = DIV_ROUND_CLOSEST(gv * 3, (1<<gbits) - 1);
|
||||
int b = DIV_ROUND_CLOSEST(bv * 3, (1<<bbits) - 1);
|
||||
int h = r && g && b && (r != 2 || g != 2 || b != 2);
|
||||
return (h ? 8 : 0) | ((r-h) ? 4 : 0) | ((g-h) ? 2 : 0) | ((b-h) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gfx_direct(struct gfx_op *op)
|
||||
{
|
||||
void *fb = (void*)GET_GLOBAL(VBE_framebuffer);
|
||||
if (!fb)
|
||||
return;
|
||||
int depth = GET_GLOBAL(op->curmode_g->depth);
|
||||
int bypp = DIV_ROUND_UP(depth, 8);
|
||||
void *dest_far = (fb + op->displaystart + op->y * op->linelength
|
||||
+ op->x * bypp);
|
||||
u8 data[64];
|
||||
int i;
|
||||
switch (op->op) {
|
||||
default:
|
||||
case GO_READ8:
|
||||
memcpy_high(MAKE_FLATPTR(GET_SEG(SS), data), dest_far, bypp * 8);
|
||||
for (i=0; i<8; i++)
|
||||
op->pixels[i] = reverse_color(depth, *(u32*)&data[i*bypp]);
|
||||
break;
|
||||
case GO_WRITE8:
|
||||
for (i=0; i<8; i++)
|
||||
*(u32*)&data[i*bypp] = get_color(depth, op->pixels[i]);
|
||||
memcpy_high(dest_far, MAKE_FLATPTR(GET_SEG(SS), data), bypp * 8);
|
||||
break;
|
||||
case GO_MEMSET: ;
|
||||
u32 color = get_color(depth, op->pixels[0]);
|
||||
for (i=0; i<8; i++)
|
||||
*(u32*)&data[i*bypp] = color;
|
||||
memcpy_high(dest_far, MAKE_FLATPTR(GET_SEG(SS), data), bypp * 8);
|
||||
memcpy_high(dest_far + bypp * 8, dest_far, op->xlen * bypp - bypp * 8);
|
||||
for (i=1; i < op->ylen; i++)
|
||||
memcpy_high(dest_far + op->linelength * i
|
||||
, dest_far, op->xlen * bypp);
|
||||
break;
|
||||
case GO_MEMMOVE: ;
|
||||
void *src_far = (fb + op->displaystart + op->srcy * op->linelength
|
||||
+ op->x * bypp);
|
||||
memmove_stride_high(dest_far, src_far
|
||||
, op->xlen * bypp, op->linelength, op->ylen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Gfx interface
|
||||
****************************************************************/
|
||||
|
||||
// Prepare a struct gfx_op for use.
|
||||
void
|
||||
init_gfx_op(struct gfx_op *op, struct vgamode_s *curmode_g)
|
||||
{
|
||||
memset(op, 0, sizeof(*op));
|
||||
op->curmode_g = curmode_g;
|
||||
op->linelength = vgahw_get_linelength(curmode_g);
|
||||
op->displaystart = vgahw_get_displaystart(curmode_g);
|
||||
}
|
||||
|
||||
// Issue a graphics operation.
|
||||
void
|
||||
handle_gfx_op(struct gfx_op *op)
|
||||
{
|
||||
switch (GET_GLOBAL(op->curmode_g->memmodel)) {
|
||||
case MM_PLANAR:
|
||||
gfx_planar(op);
|
||||
break;
|
||||
case MM_CGA:
|
||||
gfx_cga(op);
|
||||
break;
|
||||
case MM_PACKED:
|
||||
gfx_packed(op);
|
||||
break;
|
||||
case MM_DIRECT:
|
||||
gfx_direct(op);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Move characters when in graphics mode.
|
||||
static void
|
||||
gfx_move_chars(struct vgamode_s *curmode_g, struct cursorpos dest
|
||||
, struct cursorpos movesize, int lines)
|
||||
{
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.x = dest.x * 8;
|
||||
op.xlen = movesize.x * 8;
|
||||
int cheight = GET_BDA(char_height);
|
||||
op.y = dest.y * cheight;
|
||||
op.ylen = movesize.y * cheight;
|
||||
op.srcy = op.y + lines * cheight;
|
||||
op.op = GO_MEMMOVE;
|
||||
handle_gfx_op(&op);
|
||||
}
|
||||
|
||||
// Clear area of screen in graphics mode.
|
||||
static void
|
||||
gfx_clear_chars(struct vgamode_s *curmode_g, struct cursorpos win
|
||||
, struct cursorpos winsize, struct carattr ca)
|
||||
{
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.x = win.x * 8;
|
||||
op.xlen = winsize.x * 8;
|
||||
int cheight = GET_BDA(char_height);
|
||||
op.y = win.y * cheight;
|
||||
op.ylen = winsize.y * cheight;
|
||||
op.pixels[0] = ca.attr;
|
||||
if (vga_emulate_text())
|
||||
op.pixels[0] = ca.attr >> 4;
|
||||
op.op = GO_MEMSET;
|
||||
handle_gfx_op(&op);
|
||||
}
|
||||
|
||||
// Return the font for a given character
|
||||
struct segoff_s
|
||||
get_font_data(u8 c)
|
||||
{
|
||||
int char_height = GET_BDA(char_height);
|
||||
struct segoff_s font;
|
||||
if (char_height == 8 && c >= 128) {
|
||||
font = GET_IVT(0x1f);
|
||||
c -= 128;
|
||||
} else {
|
||||
font = GET_IVT(0x43);
|
||||
}
|
||||
font.offset += c * char_height;
|
||||
return font;
|
||||
}
|
||||
|
||||
// Write a character to the screen in graphics mode.
|
||||
static void
|
||||
gfx_write_char(struct vgamode_s *curmode_g
|
||||
, struct cursorpos cp, struct carattr ca)
|
||||
{
|
||||
if (cp.x >= GET_BDA(video_cols))
|
||||
return;
|
||||
|
||||
struct segoff_s font = get_font_data(ca.car);
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.x = cp.x * 8;
|
||||
int cheight = GET_BDA(char_height);
|
||||
op.y = cp.y * cheight;
|
||||
u8 fgattr = ca.attr, bgattr = 0x00;
|
||||
int usexor = 0;
|
||||
if (vga_emulate_text()) {
|
||||
if (ca.use_attr) {
|
||||
bgattr = fgattr >> 4;
|
||||
fgattr = fgattr & 0x0f;
|
||||
} else {
|
||||
// Read bottom right pixel of the cell to guess bg color
|
||||
op.op = GO_READ8;
|
||||
op.y += cheight-1;
|
||||
handle_gfx_op(&op);
|
||||
op.y -= cheight-1;
|
||||
bgattr = op.pixels[7];
|
||||
fgattr = bgattr ^ 0x7;
|
||||
}
|
||||
} else if (fgattr & 0x80 && GET_GLOBAL(curmode_g->depth) < 8) {
|
||||
usexor = 1;
|
||||
fgattr &= 0x7f;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < cheight; i++, op.y++) {
|
||||
u8 fontline = GET_FARVAR(font.seg, *(u8*)(font.offset+i));
|
||||
if (usexor) {
|
||||
op.op = GO_READ8;
|
||||
handle_gfx_op(&op);
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
op.pixels[j] ^= (fontline & (0x80>>j)) ? fgattr : 0x00;
|
||||
} else {
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
op.pixels[j] = (fontline & (0x80>>j)) ? fgattr : bgattr;
|
||||
}
|
||||
op.op = GO_WRITE8;
|
||||
handle_gfx_op(&op);
|
||||
}
|
||||
}
|
||||
|
||||
// Read a character from the screen in graphics mode.
|
||||
static struct carattr
|
||||
gfx_read_char(struct vgamode_s *curmode_g, struct cursorpos cp)
|
||||
{
|
||||
u8 lines[16];
|
||||
int cheight = GET_BDA(char_height);
|
||||
if (cp.x >= GET_BDA(video_cols) || cheight > ARRAY_SIZE(lines))
|
||||
goto fail;
|
||||
|
||||
// Read cell from screen
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.op = GO_READ8;
|
||||
op.x = cp.x * 8;
|
||||
op.y = cp.y * cheight;
|
||||
int car = 0;
|
||||
u8 fgattr = 0x00, bgattr = 0x00;
|
||||
if (vga_emulate_text()) {
|
||||
// Read bottom right pixel of the cell to guess bg color
|
||||
op.y += cheight-1;
|
||||
handle_gfx_op(&op);
|
||||
op.y -= cheight-1;
|
||||
bgattr = op.pixels[7];
|
||||
fgattr = bgattr ^ 0x7;
|
||||
// Report space character for blank cells (skip null character check)
|
||||
car = 1;
|
||||
}
|
||||
u8 i, j;
|
||||
for (i=0; i<cheight; i++, op.y++) {
|
||||
u8 line = 0;
|
||||
handle_gfx_op(&op);
|
||||
for (j=0; j<8; j++)
|
||||
if (op.pixels[j] != bgattr) {
|
||||
line |= 0x80 >> j;
|
||||
fgattr = op.pixels[j];
|
||||
}
|
||||
lines[i] = line;
|
||||
}
|
||||
|
||||
// Determine font
|
||||
for (; car<256; car++) {
|
||||
struct segoff_s font = get_font_data(car);
|
||||
if (memcmp_far(GET_SEG(SS), lines
|
||||
, font.seg, (void*)(font.offset+0), cheight) == 0)
|
||||
return (struct carattr){car, fgattr | (bgattr << 4), 0};
|
||||
}
|
||||
fail:
|
||||
return (struct carattr){0, 0, 0};
|
||||
}
|
||||
|
||||
// Set the pixel at the given position.
|
||||
void
|
||||
vgafb_write_pixel(u8 color, u16 x, u16 y)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return;
|
||||
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.x = ALIGN_DOWN(x, 8);
|
||||
op.y = y;
|
||||
op.op = GO_READ8;
|
||||
handle_gfx_op(&op);
|
||||
|
||||
int usexor = color & 0x80 && GET_GLOBAL(curmode_g->depth) < 8;
|
||||
if (usexor)
|
||||
op.pixels[x & 0x07] ^= color & 0x7f;
|
||||
else
|
||||
op.pixels[x & 0x07] = color;
|
||||
op.op = GO_WRITE8;
|
||||
handle_gfx_op(&op);
|
||||
}
|
||||
|
||||
// Return the pixel at the given position.
|
||||
u8
|
||||
vgafb_read_pixel(u16 x, u16 y)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return 0;
|
||||
|
||||
struct gfx_op op;
|
||||
init_gfx_op(&op, curmode_g);
|
||||
op.x = ALIGN_DOWN(x, 8);
|
||||
op.y = y;
|
||||
op.op = GO_READ8;
|
||||
handle_gfx_op(&op);
|
||||
|
||||
return op.pixels[x & 0x07];
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Text ops
|
||||
****************************************************************/
|
||||
|
||||
// Return the fb offset for the given character address when in text mode.
|
||||
void *
|
||||
text_address(struct cursorpos cp)
|
||||
{
|
||||
int stride = GET_BDA(video_cols) * 2;
|
||||
u32 pageoffset = GET_BDA(video_pagesize) * cp.page;
|
||||
return (void*)pageoffset + cp.y * stride + cp.x * 2;
|
||||
}
|
||||
|
||||
// Move characters on screen.
|
||||
static void
|
||||
vgafb_move_chars(struct cursorpos dest, struct cursorpos movesize, int lines)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return;
|
||||
|
||||
if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
|
||||
gfx_move_chars(curmode_g, dest, movesize, lines);
|
||||
return;
|
||||
}
|
||||
|
||||
int stride = GET_BDA(video_cols) * 2;
|
||||
void *dest_addr = text_address(dest), *src_addr = dest_addr + lines * stride;
|
||||
memmove_stride(GET_GLOBAL(curmode_g->sstart), dest_addr, src_addr
|
||||
, movesize.x * 2, stride, movesize.y);
|
||||
}
|
||||
|
||||
// Clear area of screen.
|
||||
static void
|
||||
vgafb_clear_chars(struct cursorpos win, struct cursorpos winsize
|
||||
, struct carattr ca)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return;
|
||||
|
||||
if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
|
||||
gfx_clear_chars(curmode_g, win, winsize, ca);
|
||||
return;
|
||||
}
|
||||
|
||||
int stride = GET_BDA(video_cols) * 2;
|
||||
u16 attr = ((ca.use_attr ? ca.attr : 0x07) << 8) | ca.car;
|
||||
memset16_stride(GET_GLOBAL(curmode_g->sstart), text_address(win), attr
|
||||
, winsize.x * 2, stride, winsize.y);
|
||||
}
|
||||
|
||||
// Scroll characters within a window on the screen
|
||||
void
|
||||
vgafb_scroll(struct cursorpos win, struct cursorpos winsize
|
||||
, int lines, struct carattr ca)
|
||||
{
|
||||
if (!lines) {
|
||||
// Clear window
|
||||
vgafb_clear_chars(win, winsize, ca);
|
||||
} else if (lines > 0) {
|
||||
// Scroll the window up (eg, from page down key)
|
||||
winsize.y -= lines;
|
||||
vgafb_move_chars(win, winsize, lines);
|
||||
|
||||
win.y += winsize.y;
|
||||
winsize.y = lines;
|
||||
vgafb_clear_chars(win, winsize, ca);
|
||||
} else {
|
||||
// Scroll the window down (eg, from page up key)
|
||||
win.y -= lines;
|
||||
winsize.y += lines;
|
||||
vgafb_move_chars(win, winsize, lines);
|
||||
|
||||
win.y += lines;
|
||||
winsize.y = -lines;
|
||||
vgafb_clear_chars(win, winsize, ca);
|
||||
}
|
||||
}
|
||||
|
||||
// Write a character to the screen.
|
||||
void
|
||||
vgafb_write_char(struct cursorpos cp, struct carattr ca)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return;
|
||||
|
||||
if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
|
||||
gfx_write_char(curmode_g, cp, ca);
|
||||
return;
|
||||
}
|
||||
|
||||
void *dest_far = text_address(cp);
|
||||
if (ca.use_attr) {
|
||||
u16 dummy = (ca.attr << 8) | ca.car;
|
||||
SET_FARVAR(GET_GLOBAL(curmode_g->sstart), *(u16*)dest_far, dummy);
|
||||
} else {
|
||||
SET_FARVAR(GET_GLOBAL(curmode_g->sstart), *(u8*)dest_far, ca.car);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the character at the given position on the screen.
|
||||
struct carattr
|
||||
vgafb_read_char(struct cursorpos cp)
|
||||
{
|
||||
struct vgamode_s *curmode_g = get_current_mode();
|
||||
if (!curmode_g)
|
||||
return (struct carattr){0, 0, 0};
|
||||
|
||||
if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT)
|
||||
return gfx_read_char(curmode_g, cp);
|
||||
|
||||
u16 *dest_far = text_address(cp);
|
||||
u16 v = GET_FARVAR(GET_GLOBAL(curmode_g->sstart), *dest_far);
|
||||
return (struct carattr){v, v>>8, 0};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef __VGAFB_H
|
||||
#define __VGAFB_H
|
||||
|
||||
// Graphics pixel operations.
|
||||
struct gfx_op {
|
||||
struct vgamode_s *curmode_g;
|
||||
u32 linelength;
|
||||
u32 displaystart;
|
||||
|
||||
u8 op;
|
||||
u16 x, y;
|
||||
|
||||
u8 pixels[8];
|
||||
u16 xlen, ylen;
|
||||
u16 srcy;
|
||||
};
|
||||
|
||||
#define GO_READ8 1
|
||||
#define GO_WRITE8 2
|
||||
#define GO_MEMSET 3
|
||||
#define GO_MEMMOVE 4
|
||||
|
||||
struct cursorpos {
|
||||
u8 x, y, page, pad;
|
||||
};
|
||||
|
||||
struct carattr {
|
||||
u8 car, attr, use_attr, pad;
|
||||
};
|
||||
|
||||
// vgafb.c
|
||||
void memcpy_high(void *dest, void *src, u32 len);
|
||||
void init_gfx_op(struct gfx_op *op, struct vgamode_s *curmode_g);
|
||||
void handle_gfx_op(struct gfx_op *op);
|
||||
void *text_address(struct cursorpos cp);
|
||||
void vgafb_scroll(struct cursorpos win, struct cursorpos winsize
|
||||
, int lines, struct carattr ca);
|
||||
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);
|
||||
|
||||
#endif // vgafb.h
|
||||
@@ -0,0 +1,785 @@
|
||||
#include "vgautil.h" // vgafont8
|
||||
|
||||
/*
|
||||
* These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
|
||||
* The package is (c) by Joseph Gil
|
||||
* The individual fonts are public domain
|
||||
*/
|
||||
u8 vgafont8[256 * 8] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
|
||||
0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,
|
||||
0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
|
||||
0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00,
|
||||
0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
|
||||
0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
|
||||
0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,
|
||||
0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
|
||||
0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff,
|
||||
0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
|
||||
0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,
|
||||
0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
|
||||
0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0,
|
||||
0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
|
||||
0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00,
|
||||
0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
|
||||
0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
|
||||
0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00,
|
||||
0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00,
|
||||
0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
|
||||
0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
|
||||
0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00,
|
||||
0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
|
||||
0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
|
||||
0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
|
||||
0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,
|
||||
0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
|
||||
0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00,
|
||||
0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
|
||||
0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
|
||||
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
|
||||
0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
|
||||
0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
|
||||
0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
|
||||
0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00,
|
||||
0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
|
||||
0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00,
|
||||
0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
|
||||
0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00,
|
||||
0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
|
||||
0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
|
||||
0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
|
||||
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
|
||||
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
|
||||
0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00,
|
||||
0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
|
||||
0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00,
|
||||
0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
|
||||
0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00,
|
||||
0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
|
||||
0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00,
|
||||
0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
|
||||
0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00,
|
||||
0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
|
||||
0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
|
||||
0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00,
|
||||
0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
|
||||
0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00,
|
||||
0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
|
||||
0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
|
||||
0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
|
||||
0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00,
|
||||
0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
|
||||
0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
|
||||
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
|
||||
0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
|
||||
0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00,
|
||||
0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
|
||||
0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00,
|
||||
0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
|
||||
0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00,
|
||||
0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
|
||||
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
|
||||
0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00,
|
||||
0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
|
||||
0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00,
|
||||
0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
|
||||
0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
|
||||
0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00,
|
||||
0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78,
|
||||
0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
|
||||
0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
|
||||
0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
|
||||
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0,
|
||||
0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
|
||||
0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
|
||||
0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
|
||||
0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00,
|
||||
0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
|
||||
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
|
||||
0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
|
||||
0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
|
||||
0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78,
|
||||
0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
|
||||
0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
|
||||
0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00,
|
||||
0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
|
||||
0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
|
||||
0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
|
||||
0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38,
|
||||
0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
|
||||
0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
|
||||
0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
|
||||
0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
|
||||
0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
|
||||
0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00,
|
||||
0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00,
|
||||
0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00,
|
||||
0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
|
||||
0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
|
||||
0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
|
||||
0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00,
|
||||
0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
|
||||
0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00,
|
||||
0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30,
|
||||
0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7,
|
||||
0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
|
||||
0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
|
||||
0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
|
||||
0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00,
|
||||
0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00,
|
||||
0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
|
||||
0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00,
|
||||
0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f,
|
||||
0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03,
|
||||
0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00,
|
||||
0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
|
||||
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
|
||||
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
|
||||
0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00,
|
||||
0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0,
|
||||
0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00,
|
||||
0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
|
||||
0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00,
|
||||
0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0,
|
||||
0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc,
|
||||
0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00,
|
||||
0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00,
|
||||
0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00,
|
||||
0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0,
|
||||
0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00,
|
||||
0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
|
||||
0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00,
|
||||
0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00,
|
||||
0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00,
|
||||
0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
|
||||
0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00,
|
||||
0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
|
||||
0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c,
|
||||
0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
||||
0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
u8 vgafont14[256 * 14] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
|
||||
0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00,
|
||||
0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
|
||||
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
|
||||
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00,
|
||||
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
u8 vgafont16[256 * 16] VAR16 = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
|
||||
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
|
||||
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
|
||||
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
u8 vgafont14alt[1] VAR16;
|
||||
u8 vgafont16alt[1] VAR16;
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
#ifndef __VGAHW_H
|
||||
#define __VGAHW_H
|
||||
|
||||
#include "types.h" // u8
|
||||
#include "config.h" // CONFIG_*
|
||||
|
||||
#include "bochsvga.h" // bochsvga_set_mode
|
||||
#include "stdvga.h" // stdvga_set_mode
|
||||
#include "geodevga.h" // geodevga_setup
|
||||
#include "vgautil.h" // stdvga_list_modes
|
||||
|
||||
static inline struct vgamode_s *vgahw_find_mode(int mode) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_find_mode(mode);
|
||||
if (CONFIG_VGA_ATI)
|
||||
return ati_find_mode(mode);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_find_mode(mode);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_find_mode(mode);
|
||||
return stdvga_find_mode(mode);
|
||||
}
|
||||
|
||||
static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_set_mode(vmode_g, flags);
|
||||
if (CONFIG_VGA_ATI)
|
||||
return ati_set_mode(vmode_g, flags);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_set_mode(vmode_g, flags);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_set_mode(vmode_g, flags);
|
||||
return stdvga_set_mode(vmode_g, flags);
|
||||
}
|
||||
|
||||
static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
clext_list_modes(seg, dest, last);
|
||||
else if (CONFIG_VGA_ATI)
|
||||
ati_list_modes(seg, dest, last);
|
||||
else if (CONFIG_VGA_BOCHS)
|
||||
bochsvga_list_modes(seg, dest, last);
|
||||
else if (CONFIG_VGA_EMULATE_TEXT)
|
||||
cbvga_list_modes(seg, dest, last);
|
||||
else
|
||||
stdvga_list_modes(seg, dest, last);
|
||||
}
|
||||
|
||||
static inline int vgahw_setup(void) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_setup();
|
||||
if (CONFIG_VGA_ATI)
|
||||
return ati_setup();
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_setup();
|
||||
if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX)
|
||||
return geodevga_setup();
|
||||
if (CONFIG_VGA_COREBOOT)
|
||||
return cbvga_setup();
|
||||
if (CONFIG_DISPLAY_BOCHS)
|
||||
return bochs_display_setup();
|
||||
if (CONFIG_VGA_RAMFB)
|
||||
return ramfb_setup();
|
||||
return stdvga_setup();
|
||||
}
|
||||
|
||||
static inline int vgahw_get_window(struct vgamode_s *curmode_g, int window) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_get_window(curmode_g, window);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_get_window(curmode_g, window);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_get_window(curmode_g, window);
|
||||
return stdvga_get_window(curmode_g, window);
|
||||
}
|
||||
|
||||
static inline int vgahw_set_window(struct vgamode_s *curmode_g, int window
|
||||
, int val) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_set_window(curmode_g, window, val);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_set_window(curmode_g, window, val);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_set_window(curmode_g, window, val);
|
||||
return stdvga_set_window(curmode_g, window, val);
|
||||
}
|
||||
|
||||
static inline int vgahw_get_linelength(struct vgamode_s *curmode_g) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_get_linelength(curmode_g);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_get_linelength(curmode_g);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_get_linelength(curmode_g);
|
||||
return stdvga_get_linelength(curmode_g);
|
||||
}
|
||||
|
||||
static inline int vgahw_minimum_linelength(struct vgamode_s *vmode_g) {
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_minimum_linelength(vmode_g);
|
||||
return stdvga_minimum_linelength(vmode_g);
|
||||
}
|
||||
|
||||
static inline int vgahw_set_linelength(struct vgamode_s *curmode_g, int val) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_set_linelength(curmode_g, val);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_set_linelength(curmode_g, val);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_set_linelength(curmode_g, val);
|
||||
return stdvga_set_linelength(curmode_g, val);
|
||||
}
|
||||
|
||||
static inline int vgahw_get_displaystart(struct vgamode_s *curmode_g) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_get_displaystart(curmode_g);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_get_displaystart(curmode_g);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_get_displaystart(curmode_g);
|
||||
return stdvga_get_displaystart(curmode_g);
|
||||
}
|
||||
|
||||
static inline int vgahw_set_displaystart(struct vgamode_s *curmode_g, int val) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_set_displaystart(curmode_g, val);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_set_displaystart(curmode_g, val);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_set_displaystart(curmode_g, val);
|
||||
return stdvga_set_displaystart(curmode_g, val);
|
||||
}
|
||||
|
||||
static inline int vgahw_get_dacformat(struct vgamode_s *curmode_g) {
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_get_dacformat(curmode_g);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_get_dacformat(curmode_g);
|
||||
return stdvga_get_dacformat(curmode_g);
|
||||
}
|
||||
|
||||
static inline int vgahw_set_dacformat(struct vgamode_s *curmode_g, int val) {
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_set_dacformat(curmode_g, val);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_set_dacformat(curmode_g, val);
|
||||
return stdvga_set_dacformat(curmode_g, val);
|
||||
}
|
||||
|
||||
static inline int vgahw_save_restore(int cmd, u16 seg, void *data) {
|
||||
if (CONFIG_VGA_CIRRUS)
|
||||
return clext_save_restore(cmd, seg, data);
|
||||
if (CONFIG_VGA_BOCHS)
|
||||
return bochsvga_save_restore(cmd, seg, data);
|
||||
if (CONFIG_VGA_EMULATE_TEXT)
|
||||
return cbvga_save_restore(cmd, seg, data);
|
||||
return stdvga_save_restore(cmd, seg, data);
|
||||
}
|
||||
|
||||
#endif // vgahw.h
|
||||
@@ -0,0 +1,202 @@
|
||||
// Main VGA bios initialization
|
||||
//
|
||||
// Copyright (C) 2009-2013 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 "biosvar.h" // SET_BDA
|
||||
#include "bregs.h" // struct bregs
|
||||
#include "hw/pci.h" // pci_config_readw
|
||||
#include "hw/pci_regs.h" // PCI_VENDOR_ID
|
||||
#include "hw/serialio.h" // serial_debug_preinit
|
||||
#include "output.h" // dprintf
|
||||
#include "std/optionrom.h" // struct pci_data
|
||||
#include "std/pmm.h" // struct pmmheader
|
||||
#include "string.h" // checksum_far
|
||||
#include "vgabios.h" // SET_VGA
|
||||
#include "vgahw.h" // vgahw_setup
|
||||
#include "vgautil.h" // swcursor_check_event
|
||||
|
||||
// Type of emulator platform - for dprintf with certain compile options.
|
||||
int PlatformRunningOn VAR16;
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* PCI Data
|
||||
****************************************************************/
|
||||
|
||||
struct pci_data rom_pci_data VAR16 VISIBLE16 = {
|
||||
.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,
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* PMM call and extra stack setup
|
||||
****************************************************************/
|
||||
|
||||
u32
|
||||
allocate_pmm(u32 size, int highmem, int aligned)
|
||||
{
|
||||
u32 pmmscan;
|
||||
for (pmmscan=0; pmmscan < BUILD_BIOS_SIZE; pmmscan+=16) {
|
||||
struct pmmheader *pmm = (void*)pmmscan;
|
||||
if (GET_FARVAR(SEG_BIOS, pmm->signature) != PMM_SIGNATURE)
|
||||
continue;
|
||||
if (checksum_far(SEG_BIOS, pmm, GET_FARVAR(SEG_BIOS, pmm->length)))
|
||||
continue;
|
||||
struct segoff_s entry = GET_FARVAR(SEG_BIOS, pmm->entry);
|
||||
dprintf(1, "Attempting to allocate %u bytes %s via pmm call to %04x:%04x\n"
|
||||
, size, highmem ? "highmem" : "lowmem"
|
||||
, entry.seg, entry.offset);
|
||||
u16 res1, res2;
|
||||
u16 flags = 8 |
|
||||
( highmem ? 2 : 1 )|
|
||||
( aligned ? 4 : 0 );
|
||||
size >>= 4;
|
||||
asm volatile(
|
||||
"pushl %0\n"
|
||||
"pushw %2\n" // flags
|
||||
"pushl $0xffffffff\n" // Anonymous handle
|
||||
"pushl %1\n" // size
|
||||
"pushw $0x00\n" // PMM allocation request
|
||||
"lcallw *12(%%esp)\n"
|
||||
"addl $16, %%esp\n"
|
||||
"cli\n"
|
||||
"cld\n"
|
||||
: "+r" (entry.segoff), "+r" (size), "+r" (flags),
|
||||
"=a" (res1), "=d" (res2) : : "cc", "memory");
|
||||
u32 res = res1 | (res2 << 16);
|
||||
if (!res || res == PMM_FUNCTION_NOT_SUPPORTED)
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 ExtraStackSeg VAR16 VISIBLE16;
|
||||
|
||||
static void
|
||||
allocate_extra_stack(void)
|
||||
{
|
||||
if (!CONFIG_VGA_ALLOCATE_EXTRA_STACK)
|
||||
return;
|
||||
u32 res = allocate_pmm(CONFIG_VGA_EXTRA_STACK_SIZE, 0, 0);
|
||||
if (!res)
|
||||
return;
|
||||
dprintf(1, "VGA stack allocated at %x\n", res);
|
||||
SET_VGA(ExtraStackSeg, res >> 4);
|
||||
extern void entry_10_extrastack(void);
|
||||
SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10_extrastack));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Timer hook
|
||||
****************************************************************/
|
||||
|
||||
struct segoff_s Timer_Hook_Resume VAR16 VISIBLE16;
|
||||
|
||||
void VISIBLE16
|
||||
handle_timer_hook(void)
|
||||
{
|
||||
swcursor_check_event();
|
||||
}
|
||||
|
||||
static void
|
||||
hook_timer_irq(void)
|
||||
{
|
||||
if (!CONFIG_VGA_EMULATE_TEXT)
|
||||
return;
|
||||
extern void entry_timer_hook(void);
|
||||
extern void entry_timer_hook_extrastack(void);
|
||||
struct segoff_s oldirq = GET_IVT(0x08);
|
||||
struct segoff_s newirq = SEGOFF(get_global_seg(), (u32)entry_timer_hook);
|
||||
if (CONFIG_VGA_ALLOCATE_EXTRA_STACK && GET_GLOBAL(ExtraStackSeg))
|
||||
newirq = SEGOFF(get_global_seg(), (u32)entry_timer_hook_extrastack);
|
||||
dprintf(1, "Hooking hardware timer irq (old=%x new=%x)\n"
|
||||
, oldirq.segoff, newirq.segoff);
|
||||
SET_VGA(Timer_Hook_Resume, oldirq);
|
||||
SET_IVT(0x08, newirq);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* VGA post
|
||||
****************************************************************/
|
||||
|
||||
static void
|
||||
init_bios_area(void)
|
||||
{
|
||||
// init detected hardware BIOS Area
|
||||
// set 80x25 color (not clear from RBIL but usual)
|
||||
set_equipment_flags(0x30, 0x20);
|
||||
|
||||
// Set the basic modeset options
|
||||
SET_BDA(modeset_ctl, 0x51);
|
||||
|
||||
SET_BDA(dcc_index, CONFIG_VGA_STDVGA_PORTS ? 0x08 : 0xff);
|
||||
|
||||
// FIXME
|
||||
SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
|
||||
SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
|
||||
}
|
||||
|
||||
int VgaBDF VAR16 = -1;
|
||||
int HaveRunInit VAR16;
|
||||
|
||||
void VISIBLE16
|
||||
vga_post(struct bregs *regs)
|
||||
{
|
||||
serial_debug_preinit();
|
||||
dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION);
|
||||
dprintf(1, "VGABUILD: %s\n", BUILDINFO);
|
||||
debug_enter(regs, DEBUG_VGA_POST);
|
||||
|
||||
if (CONFIG_VGA_PCI && !GET_GLOBAL(HaveRunInit)) {
|
||||
u16 bdf = regs->ax;
|
||||
if ((pci_config_readw(bdf, PCI_VENDOR_ID)
|
||||
== GET_GLOBAL(rom_pci_data.vendor))
|
||||
&& (pci_config_readw(bdf, PCI_DEVICE_ID)
|
||||
== GET_GLOBAL(rom_pci_data.device)))
|
||||
SET_VGA(VgaBDF, bdf);
|
||||
}
|
||||
|
||||
int ret = vgahw_setup();
|
||||
if (ret) {
|
||||
dprintf(1, "Failed to initialize VGA hardware. Exiting.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GET_GLOBAL(HaveRunInit))
|
||||
return;
|
||||
|
||||
init_bios_area();
|
||||
|
||||
if (CONFIG_VGA_STDVGA_PORTS)
|
||||
stdvga_build_video_param();
|
||||
|
||||
extern void entry_10(void);
|
||||
SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
|
||||
|
||||
allocate_extra_stack();
|
||||
|
||||
hook_timer_irq();
|
||||
|
||||
SET_VGA(HaveRunInit, 1);
|
||||
|
||||
// Fixup checksum
|
||||
extern u8 _rom_header_size, _rom_header_checksum;
|
||||
SET_VGA(_rom_header_checksum, 0);
|
||||
u8 sum = -checksum_far(get_global_seg(), 0,
|
||||
GET_GLOBAL(_rom_header_size) * 512);
|
||||
SET_VGA(_rom_header_checksum, sum);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Linker definitions for an option rom
|
||||
//
|
||||
// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH("i386")
|
||||
ENTRY(_optionrom_entry)
|
||||
SECTIONS
|
||||
{
|
||||
.text 0 : {
|
||||
KEEP(*(.rom.header))
|
||||
*(.text.*)
|
||||
_rodata = . ;
|
||||
*(.rodata*)
|
||||
*(.data16.*)
|
||||
}
|
||||
|
||||
// Discard regular data sections to force a link error if
|
||||
// 16bit code attempts to access data not marked with VAR16.
|
||||
/DISCARD/ : {
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.data*)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
*(.note*)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Misc function and variable declarations.
|
||||
#ifndef __VGAUTIL_H
|
||||
#define __VGAUTIL_H
|
||||
|
||||
#include "types.h" // u8
|
||||
|
||||
// cbvga.c
|
||||
struct vgamode_s *cbvga_find_mode(int mode);
|
||||
void cbvga_list_modes(u16 seg, u16 *dest, u16 *last);
|
||||
int cbvga_get_window(struct vgamode_s *curmode_g, int window);
|
||||
int cbvga_set_window(struct vgamode_s *curmode_g, int window, int val);
|
||||
int cbvga_minimum_linelength(struct vgamode_s *vmode_g);
|
||||
int cbvga_get_linelength(struct vgamode_s *curmode_g);
|
||||
int cbvga_set_linelength(struct vgamode_s *curmode_g, int val);
|
||||
int cbvga_get_displaystart(struct vgamode_s *curmode_g);
|
||||
int cbvga_set_displaystart(struct vgamode_s *curmode_g, int val);
|
||||
int cbvga_get_dacformat(struct vgamode_s *curmode_g);
|
||||
int cbvga_set_dacformat(struct vgamode_s *curmode_g, int val);
|
||||
int cbvga_save_restore(int cmd, u16 seg, void *data);
|
||||
int cbvga_set_mode(struct vgamode_s *vmode_g, int flags);
|
||||
void cbvga_setup_modes(u64 addr, u8 bpp, u32 xlines, u32 ylines, u32 linelength);
|
||||
int cbvga_setup(void);
|
||||
|
||||
// bochsdisplay.c
|
||||
int bochs_display_setup(void);
|
||||
|
||||
// ramfb.c
|
||||
int ramfb_setup(void);
|
||||
|
||||
// clext.c
|
||||
struct vgamode_s *clext_find_mode(int mode);
|
||||
void clext_list_modes(u16 seg, u16 *dest, u16 *last);
|
||||
int clext_get_window(struct vgamode_s *curmode_g, int window);
|
||||
int clext_set_window(struct vgamode_s *curmode_g, int window, int val);
|
||||
int clext_get_linelength(struct vgamode_s *curmode_g);
|
||||
int clext_set_linelength(struct vgamode_s *curmode_g, int val);
|
||||
int clext_get_displaystart(struct vgamode_s *curmode_g);
|
||||
int clext_set_displaystart(struct vgamode_s *curmode_g, int val);
|
||||
int clext_save_restore(int cmd, u16 seg, void *data);
|
||||
int clext_set_mode(struct vgamode_s *vmode_g, int flags);
|
||||
struct bregs;
|
||||
void clext_1012(struct bregs *regs);
|
||||
int clext_setup(void);
|
||||
|
||||
// atiext.c
|
||||
struct vgamode_s *ati_find_mode(int mode);
|
||||
void ati_list_modes(u16 seg, u16 *dest, u16 *last);
|
||||
int ati_set_mode(struct vgamode_s *vmode_g, int flags);
|
||||
int ati_setup(void);
|
||||
|
||||
// stdvgamodes.c
|
||||
struct vgamode_s *stdvga_find_mode(int mode);
|
||||
void stdvga_list_modes(u16 seg, u16 *dest, u16 *last);
|
||||
void stdvga_build_video_param(void);
|
||||
void stdvga_override_crtc(int mode, u8 *crtc);
|
||||
int stdvga_set_mode(struct vgamode_s *vmode_g, int flags);
|
||||
void stdvga_set_packed_palette(void);
|
||||
|
||||
// swcursor.c
|
||||
void swcursor_pre_handle10(struct bregs *regs);
|
||||
void swcursor_check_event(void);
|
||||
|
||||
// vbe.c
|
||||
extern u32 VBE_total_memory;
|
||||
extern u32 VBE_capabilities;
|
||||
extern u32 VBE_framebuffer;
|
||||
extern u16 VBE_win_granularity;
|
||||
extern u8 VBE_edid[256];
|
||||
void handle_104f(struct bregs *regs);
|
||||
|
||||
// vgafonts.c
|
||||
extern u8 vgafont8[];
|
||||
extern u8 vgafont14[];
|
||||
extern u8 vgafont16[];
|
||||
extern u8 vgafont14alt[];
|
||||
extern u8 vgafont16alt[];
|
||||
|
||||
// vgainit.c
|
||||
extern int VgaBDF;
|
||||
extern int HaveRunInit;
|
||||
u32 allocate_pmm(u32 size, int highmem, int aligned);
|
||||
|
||||
// vgaversion.c
|
||||
extern const char VERSION[], BUILDINFO[];
|
||||
|
||||
#endif // vgautil.h
|
||||
@@ -0,0 +1,6 @@
|
||||
// Place build generated version into a C variable
|
||||
#include "autovgaversion.h"
|
||||
#include "types.h"
|
||||
|
||||
char VERSION[] VAR16 = BUILD_VERSION;
|
||||
char BUILDINFO[] VAR16 = BUILD_TOOLS;
|
||||
Reference in New Issue
Block a user