mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
VGA for Sparc64
Added 8x16 font, low-level VGA register programming and mode switching functions from LinuxBIOS. Fixed incorrect VGA_BASE. git-svn-id: svn://coreboot.org/openbios/openbios-devel@69 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "openbios/config.h"
|
||||
#include "openbios/kernel.h"
|
||||
#include "openbios.h"
|
||||
#include "video_subr.h"
|
||||
|
||||
#ifdef CONFIG_DEBUG_CONSOLE
|
||||
|
||||
@@ -122,7 +123,8 @@ static void serial_cls(void)
|
||||
#define ATTRIBUTE 7 /* The attribute of an character. */
|
||||
|
||||
#define APB_MEM_BASE 0x1ff00000000ULL
|
||||
#define VGA_BASE (APB_MEM_BASE + 0x4b8000ULL) /* The video memory address. */
|
||||
#define VGA_BASE (APB_MEM_BASE + 0x4a0000ULL) /* Beginning of video memory address. */
|
||||
#define TEXT_BASE (VGA_BASE + 0x18000ULL) /* The text memory address. */
|
||||
|
||||
/* VGA Index and Data Registers */
|
||||
#define VGA_REG_INDEX 0x03D4 /* VGA index register */
|
||||
@@ -137,7 +139,7 @@ static void serial_cls(void)
|
||||
/* Save the X and Y position. */
|
||||
static int xpos, ypos;
|
||||
/* Point to the video memory. */
|
||||
static volatile unsigned char *video = (unsigned char *) VGA_BASE;
|
||||
static unsigned char *video = (unsigned char *) TEXT_BASE;
|
||||
|
||||
static void video_initcursor(void)
|
||||
{
|
||||
@@ -236,9 +238,19 @@ static void video_cls(void)
|
||||
video_poscursor(xpos, ypos);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRIVER_VGA
|
||||
#include "../../modules/font_8x16.c"
|
||||
#endif
|
||||
|
||||
void video_init(void)
|
||||
{
|
||||
video=(unsigned char *)VGA_BASE;
|
||||
video=(unsigned char *)TEXT_BASE;
|
||||
|
||||
#ifdef CONFIG_DRIVER_VGA
|
||||
vga_load_regs();
|
||||
vga_font_load((unsigned char *)VGA_BASE, fontdata_8x16, 16, 256);
|
||||
vga_set_amode();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<option name="CONFIG_IDE_NUM_CHANNELS" type="integer" value="4"/>
|
||||
<option name="CONFIG_DEBUG_IDE" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/>
|
||||
|
||||
</config>
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<option name="CONFIG_IDE_NUM_CHANNELS" type="integer" value="4"/>
|
||||
<option name="CONFIG_DEBUG_IDE" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/>
|
||||
|
||||
</config>
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
<object source="sbus.c" condition="DRIVER_SBUS"/>
|
||||
<object source="esp.c" condition="DRIVER_ESP"/>
|
||||
<object source="obio.c" condition="DRIVER_OBIO"/>
|
||||
<object source="vga_load_regs.c" condition="DRIVER_VGA"/>
|
||||
<object source="vga_set_mode.c" condition="DRIVER_VGA"/>
|
||||
</library>
|
||||
|
||||
<dictionary name="openbios" target="forth">
|
||||
|
||||
228
drivers/vga.h
Normal file
228
drivers/vga.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
*
|
||||
* modified
|
||||
* by Steve M. Gehlbach <steve@kesa.com>
|
||||
*
|
||||
* Originally from linux/drivers/video/vga16.c by
|
||||
* Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
|
||||
* Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
|
||||
* Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
|
||||
* Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VGA_H_INCL
|
||||
#define VGA_H_INCL 1
|
||||
|
||||
//#include <cpu/p5/io.h>
|
||||
|
||||
#define u8 unsigned char
|
||||
#define u16 unsigned short
|
||||
#define u32 unsigned int
|
||||
#define __u32 u32
|
||||
|
||||
#define VERROR -1
|
||||
#define CHAR_HEIGHT 16
|
||||
#define LINES 25
|
||||
#define COLS 80
|
||||
|
||||
// macros for writing to vga regs
|
||||
#define write_crtc(data,addr) outb(addr,CRT_IC); outb(data,CRT_DC)
|
||||
#define write_att(data,addr) inb(IS1_RC); inb(0x80); outb(addr,ATT_IW); inb(0x80); outb(data,ATT_IW); inb(0x80)
|
||||
#define write_seq(data,addr) outb(addr,SEQ_I); outb(data,SEQ_D)
|
||||
#define write_gra(data,addr) outb(addr,GRA_I); outb(data,GRA_D)
|
||||
u8 read_seq_b(u16 addr);
|
||||
u8 read_gra_b(u16 addr);
|
||||
u8 read_crtc_b(u16 addr);
|
||||
u8 read_att_b(u16 addr);
|
||||
|
||||
|
||||
#ifdef VGA_HARDWARE_FIXUP
|
||||
void vga_hardware_fixup(void);
|
||||
#else
|
||||
#define vga_hardware_fixup() do{} while(0)
|
||||
#endif
|
||||
|
||||
#define SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
|
||||
#define SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
|
||||
#define SYNC_EXT 4 /* external sync */
|
||||
#define SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
|
||||
#define SYNC_BROADCAST 16 /* broadcast video timings */
|
||||
/* vtotal = 144d/288n/576i => PAL */
|
||||
/* vtotal = 121d/242n/484i => NTSC */
|
||||
|
||||
#define SYNC_ON_GREEN 32 /* sync on green */
|
||||
|
||||
#define VMODE_NONINTERLACED 0 /* non interlaced */
|
||||
#define VMODE_INTERLACED 1 /* interlaced */
|
||||
#define VMODE_DOUBLE 2 /* double scan */
|
||||
#define VMODE_MASK 255
|
||||
|
||||
#define VMODE_YWRAP 256 /* ywrap instead of panning */
|
||||
#define VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
|
||||
#define VMODE_CONUPDATE 512 /* don't update x/yoffset */
|
||||
|
||||
/* VGA data register ports */
|
||||
#define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
|
||||
#define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
|
||||
#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
|
||||
#define GRA_D 0x3CF /* Graphics Controller Data Register */
|
||||
#define SEQ_D 0x3C5 /* Sequencer Data Register */
|
||||
|
||||
#define MIS_R 0x3CC // Misc Output Read Register
|
||||
#define MIS_W 0x3C2 // Misc Output Write Register
|
||||
|
||||
#define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
|
||||
#define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
|
||||
#define PEL_D 0x3C9 /* PEL Data Register */
|
||||
#define PEL_MSK 0x3C6 /* PEL mask register */
|
||||
|
||||
/* EGA-specific registers */
|
||||
#define GRA_E0 0x3CC /* Graphics enable processor 0 */
|
||||
#define GRA_E1 0x3CA /* Graphics enable processor 1 */
|
||||
|
||||
|
||||
/* VGA index register ports */
|
||||
#define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
|
||||
#define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
|
||||
#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
|
||||
#define GRA_I 0x3CE /* Graphics Controller Index */
|
||||
#define SEQ_I 0x3C4 /* Sequencer Index */
|
||||
#define PEL_IW 0x3C8 /* PEL Write Index */
|
||||
#define PEL_IR 0x3C7 /* PEL Read Index */
|
||||
|
||||
/* standard VGA indexes max counts */
|
||||
#define CRTC_C 25 /* 25 CRT Controller Registers sequentially set*/
|
||||
// the remainder are not in the par array
|
||||
#define ATT_C 21 /* 21 Attribute Controller Registers */
|
||||
#define GRA_C 9 /* 9 Graphics Controller Registers */
|
||||
#define SEQ_C 5 /* 5 Sequencer Registers */
|
||||
#define MIS_C 1 /* 1 Misc Output Register */
|
||||
|
||||
#define CRTC_H_TOTAL 0
|
||||
#define CRTC_H_DISP 1
|
||||
#define CRTC_H_BLANK_START 2
|
||||
#define CRTC_H_BLANK_END 3
|
||||
#define CRTC_H_SYNC_START 4
|
||||
#define CRTC_H_SYNC_END 5
|
||||
#define CRTC_V_TOTAL 6
|
||||
#define CRTC_OVERFLOW 7
|
||||
#define CRTC_PRESET_ROW 8
|
||||
#define CRTC_MAX_SCAN 9
|
||||
#define CRTC_CURSOR_START 0x0A
|
||||
#define CRTC_CURSOR_END 0x0B
|
||||
#define CRTC_START_HI 0x0C
|
||||
#define CRTC_START_LO 0x0D
|
||||
#define CRTC_CURSOR_HI 0x0E
|
||||
#define CRTC_CURSOR_LO 0x0F
|
||||
#define CRTC_V_SYNC_START 0x10
|
||||
#define CRTC_V_SYNC_END 0x11
|
||||
#define CRTC_V_DISP_END 0x12
|
||||
#define CRTC_OFFSET 0x13
|
||||
#define CRTC_UNDERLINE 0x14
|
||||
#define CRTC_V_BLANK_START 0x15
|
||||
#define CRTC_V_BLANK_END 0x16
|
||||
#define CRTC_MODE 0x17
|
||||
#define CRTC_LINE_COMPARE 0x18
|
||||
|
||||
#define ATC_MODE 0x10
|
||||
#define ATC_OVERSCAN 0x11
|
||||
#define ATC_PLANE_ENABLE 0x12
|
||||
#define ATC_PEL 0x13
|
||||
#define ATC_COLOR_PAGE 0x14
|
||||
|
||||
#define SEQ_CLOCK_MODE 0x01
|
||||
#define SEQ_PLANE_WRITE 0x02
|
||||
#define SEQ_CHARACTER_MAP 0x03
|
||||
#define SEQ_MEMORY_MODE 0x04
|
||||
|
||||
#define GDC_SR_VALUE 0x00
|
||||
#define GDC_SR_ENABLE 0x01
|
||||
#define GDC_COMPARE_VALUE 0x02
|
||||
#define GDC_DATA_ROTATE 0x03
|
||||
#define GDC_PLANE_READ 0x04
|
||||
#define GDC_MODE 0x05
|
||||
#define GDC_MISC 0x06
|
||||
#define GDC_COMPARE_MASK 0x07
|
||||
#define GDC_BIT_MASK 0x08
|
||||
|
||||
// text attributes
|
||||
#define VGA_ATTR_CLR_RED 0x4
|
||||
#define VGA_ATTR_CLR_GRN 0x2
|
||||
#define VGA_ATTR_CLR_BLU 0x1
|
||||
#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN)
|
||||
#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
|
||||
#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED)
|
||||
#define VGA_ATTR_CLR_BLK 0
|
||||
#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
|
||||
#define VGA_ATTR_BNK 0x80
|
||||
#define VGA_ATTR_ITN 0x08
|
||||
|
||||
/*
|
||||
* vga register parameters
|
||||
* these are copied to the
|
||||
* registers.
|
||||
*
|
||||
*/
|
||||
struct vga_par {
|
||||
u8 crtc[CRTC_C];
|
||||
u8 atc[ATT_C];
|
||||
u8 gdc[GRA_C];
|
||||
u8 seq[SEQ_C];
|
||||
u8 misc; // the misc register, MIS_W
|
||||
u8 vss;
|
||||
};
|
||||
|
||||
|
||||
/* Interpretation of offset for color fields: All offsets are from the right,
|
||||
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
|
||||
* can use the offset as right argument to <<). A pixel afterwards is a bit
|
||||
* stream and is written to video memory as that unmodified. This implies
|
||||
* big-endian byte order if bits_per_pixel is greater than 8.
|
||||
*/
|
||||
struct fb_bitfield {
|
||||
__u32 offset; /* beginning of bitfield */
|
||||
__u32 length; /* length of bitfield */
|
||||
__u32 msb_right; /* != 0 : Most significant bit is */
|
||||
/* right */
|
||||
};
|
||||
|
||||
struct screeninfo {
|
||||
__u32 xres; /* visible resolution */
|
||||
__u32 yres;
|
||||
__u32 xres_virtual; /* virtual resolution */
|
||||
__u32 yres_virtual;
|
||||
__u32 xoffset; /* offset from virtual to visible */
|
||||
__u32 yoffset; /* resolution */
|
||||
|
||||
__u32 bits_per_pixel; /* guess what */
|
||||
__u32 grayscale; /* != 0 Graylevels instead of colors */
|
||||
|
||||
struct fb_bitfield red; /* bitfield in fb mem if true color, */
|
||||
struct fb_bitfield green; /* else only length is significant */
|
||||
struct fb_bitfield blue;
|
||||
struct fb_bitfield transp; /* transparency */
|
||||
|
||||
__u32 nonstd; /* != 0 Non standard pixel format */
|
||||
|
||||
__u32 activate; /* see FB_ACTIVATE_* */
|
||||
|
||||
__u32 height; /* height of picture in mm */
|
||||
__u32 width; /* width of picture in mm */
|
||||
|
||||
__u32 accel_flags; /* acceleration flags (hints) */
|
||||
|
||||
/* Timing: All values in pixclocks, except pixclock (of course) */
|
||||
__u32 pixclock; /* pixel clock in ps (pico seconds) */
|
||||
__u32 left_margin; /* time from sync to picture */
|
||||
__u32 right_margin; /* time from picture to sync */
|
||||
__u32 upper_margin; /* time from sync to picture */
|
||||
__u32 lower_margin;
|
||||
__u32 hsync_len; /* length of horizontal sync */
|
||||
__u32 vsync_len; /* length of vertical sync */
|
||||
__u32 sync; /* sync polarity */
|
||||
__u32 vmode; /* interlaced etc */
|
||||
__u32 reserved[6]; /* Reserved for future compatibility */
|
||||
};
|
||||
|
||||
#endif
|
||||
427
drivers/vga_load_regs.c
Normal file
427
drivers/vga_load_regs.c
Normal file
@@ -0,0 +1,427 @@
|
||||
#include "asm/io.h"
|
||||
#include "video_subr.h"
|
||||
#include "string.h"
|
||||
#include "vga.h"
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
* $Source$
|
||||
*
|
||||
* from the Linux kernel code base.
|
||||
* orig by Ben Pfaff and Petr Vandrovec.
|
||||
*
|
||||
* modified by
|
||||
* Steve M. Gehlbach <steve@kesa.com>
|
||||
*
|
||||
* NOTE: to change the horiz and vertical pixels,
|
||||
* change the xres,yres,xres_virt,yres_virt setting
|
||||
* in the screeninfo structure below. You may also need
|
||||
* to change the border settings as well.
|
||||
*
|
||||
* Convert the screeninfo structure to data for
|
||||
* writing to the vga registers
|
||||
*
|
||||
*/
|
||||
|
||||
// prototypes
|
||||
static int vga_decode_var(const struct screeninfo *var, struct vga_par *par);
|
||||
static int vga_set_regs(const struct vga_par *par);
|
||||
|
||||
extern const u8 VgaLookupTable[];
|
||||
|
||||
u8 read_seq_b(u16 addr) {
|
||||
outb(addr,SEQ_I);
|
||||
return inb(SEQ_D);
|
||||
}
|
||||
u8 read_gra_b(u16 addr) {
|
||||
outb(addr,GRA_I);
|
||||
return inb(GRA_D);
|
||||
}
|
||||
u8 read_crtc_b(u16 addr) {
|
||||
outb(addr,CRT_IC);
|
||||
return inb(CRT_DC);
|
||||
}
|
||||
u8 read_att_b(u16 addr) {
|
||||
inb(IS1_RC);
|
||||
inb(0x80);
|
||||
outb(addr,ATT_IW);
|
||||
return inb(ATT_R);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
From: The Frame Buffer Device
|
||||
by Geert Uytterhoeven <geert@linux-m68k.org>
|
||||
in the linux kernel docs.
|
||||
|
||||
The following picture summarizes all timings. The horizontal retrace time is
|
||||
the sum of the left margin, the right margin and the hsync length, while the
|
||||
vertical retrace time is the sum of the upper margin, the lower margin and the
|
||||
vsync length.
|
||||
|
||||
+----------+---------------------------------------------+----------+-------+
|
||||
| | ^ | | |
|
||||
| | |upper_margin | | |
|
||||
| | | | | |
|
||||
+----------###############################################----------+-------+
|
||||
| # ^ # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| left # | # right | hsync |
|
||||
| margin # | xres # margin | len |
|
||||
|<-------->#<---------------+--------------------------->#<-------->|<----->|
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # |yres # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
| # | # | |
|
||||
+----------###############################################----------+-------+
|
||||
| | ^ | | |
|
||||
| | |lower_margin | | |
|
||||
| | | | | |
|
||||
+----------+---------------------------------------------+----------+-------+
|
||||
| | ^ | | |
|
||||
| | |vsync_len | | |
|
||||
| | | | | |
|
||||
+----------+---------------------------------------------+----------+-------+
|
||||
|
||||
All horizontal timings are in number of dotclocks
|
||||
(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.
|
||||
|
||||
The vga uses the following fields:
|
||||
|
||||
- pixclock: pixel clock in ps (pico seconds)
|
||||
- xres,yres,xres_v,yres_v
|
||||
- left_margin: time from sync to picture
|
||||
- right_margin: time from picture to sync
|
||||
- upper_margin: time from sync to picture
|
||||
- lower_margin: time from picture to sync
|
||||
- hsync_len: length of horizontal sync
|
||||
- vsync_len: length of vertical sync
|
||||
|
||||
*/
|
||||
|
||||
/* our display parameters per the above */
|
||||
|
||||
static const struct screeninfo vga_settings = {
|
||||
640,400,640,400,/* xres,yres,xres_virt,yres_virt */
|
||||
0,0, /* xoffset,yoffset */
|
||||
4, /* bits_per_pixel NOT USED*/
|
||||
0, /* greyscale ? */
|
||||
{0,0,0}, /* R */
|
||||
{0,0,0}, /* G */
|
||||
{0,0,0}, /* B */
|
||||
{0,0,0}, /* transparency */
|
||||
0, /* standard pixel format */
|
||||
0, // activate now
|
||||
-1,-1, // height and width in mm
|
||||
0, // accel flags
|
||||
39721, // pixclock: 79442 -> 12.587 Mhz (NOT USED)
|
||||
// 70616 -> 14.161
|
||||
// 39721 -> 25.175
|
||||
// 35308 -> 28.322
|
||||
|
||||
48, 16, 39, 8, // margins left,right,upper,lower
|
||||
96, // hsync length
|
||||
2, // vsync length
|
||||
0, // sync polarity
|
||||
0, // non interlaced, single mode
|
||||
{0,0,0,0,0,0} // compatibility
|
||||
};
|
||||
|
||||
// ALPHA-MODE
|
||||
// Hard coded to BIOS VGA mode 3 (alpha color text)
|
||||
// screen size settable in screeninfo structure
|
||||
|
||||
static int vga_decode_var(const struct screeninfo *var,
|
||||
struct vga_par *par)
|
||||
{
|
||||
u8 VgaAttributeTable[16] =
|
||||
{ 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x014, 0x007, 0x038, 0x039, 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x03F};
|
||||
|
||||
u32 xres, right, hslen, left, xtotal;
|
||||
u32 yres, lower, vslen, upper, ytotal;
|
||||
u32 vxres, xoffset, vyres, yoffset;
|
||||
u32 pos;
|
||||
u8 r7, rMode;
|
||||
int i;
|
||||
|
||||
xres = (var->xres + 7) & ~7;
|
||||
vxres = (var->xres_virtual + 0xF) & ~0xF;
|
||||
xoffset = (var->xoffset + 7) & ~7;
|
||||
left = (var->left_margin + 7) & ~7;
|
||||
right = (var->right_margin + 7) & ~7;
|
||||
hslen = (var->hsync_len + 7) & ~7;
|
||||
|
||||
if (vxres < xres)
|
||||
vxres = xres;
|
||||
if (xres + xoffset > vxres)
|
||||
xoffset = vxres - xres;
|
||||
|
||||
xres >>= 3;
|
||||
right >>= 3;
|
||||
hslen >>= 3;
|
||||
left >>= 3;
|
||||
vxres >>= 3;
|
||||
xtotal = xres + right + hslen + left;
|
||||
if (xtotal >= 256)
|
||||
return VERROR; //xtotal too big
|
||||
if (hslen > 32)
|
||||
return VERROR; //hslen too big
|
||||
if (right + hslen + left > 64)
|
||||
return VERROR; //hblank too big
|
||||
par->crtc[CRTC_H_TOTAL] = xtotal - 5;
|
||||
par->crtc[CRTC_H_BLANK_START] = xres - 1;
|
||||
par->crtc[CRTC_H_DISP] = xres - 1;
|
||||
pos = xres + right;
|
||||
par->crtc[CRTC_H_SYNC_START] = pos;
|
||||
pos += hslen;
|
||||
par->crtc[CRTC_H_SYNC_END] = (pos & 0x1F) | 0x20 ; //<--- stpc text mode p178
|
||||
pos += left - 2; /* blank_end + 2 <= total + 5 */
|
||||
par->crtc[CRTC_H_BLANK_END] = (pos & 0x1F) | 0x80;
|
||||
if (pos & 0x20)
|
||||
par->crtc[CRTC_H_SYNC_END] |= 0x80;
|
||||
|
||||
yres = var->yres;
|
||||
lower = var->lower_margin;
|
||||
vslen = var->vsync_len;
|
||||
upper = var->upper_margin;
|
||||
vyres = var->yres_virtual;
|
||||
yoffset = var->yoffset;
|
||||
|
||||
if (yres > vyres)
|
||||
vyres = yres;
|
||||
if (vxres * vyres > 65536) {
|
||||
vyres = 65536 / vxres;
|
||||
if (vyres < yres)
|
||||
return VERROR; // out of memory
|
||||
}
|
||||
if (yoffset + yres > vyres)
|
||||
yoffset = vyres - yres;
|
||||
|
||||
if (var->vmode & VMODE_DOUBLE) {
|
||||
yres <<= 1;
|
||||
lower <<= 1;
|
||||
vslen <<= 1;
|
||||
upper <<= 1;
|
||||
}
|
||||
ytotal = yres + lower + vslen + upper;
|
||||
if (ytotal > 1024) {
|
||||
ytotal >>= 1;
|
||||
yres >>= 1;
|
||||
lower >>= 1;
|
||||
vslen >>= 1;
|
||||
upper >>= 1;
|
||||
rMode = 0x04;
|
||||
} else
|
||||
rMode = 0x00;
|
||||
if (ytotal > 1024)
|
||||
return VERROR; //ytotal too big
|
||||
if (vslen > 16)
|
||||
return VERROR; //vslen too big
|
||||
par->crtc[CRTC_V_TOTAL] = ytotal - 2;
|
||||
r7 = 0x10; /* disable linecompare */
|
||||
if (ytotal & 0x100) r7 |= 0x01;
|
||||
if (ytotal & 0x200) r7 |= 0x20;
|
||||
par->crtc[CRTC_PRESET_ROW] = 0;
|
||||
|
||||
|
||||
// GMODE <--> ALPHA-MODE
|
||||
// default using alpha mode so we need to set char rows= CHAR_HEIGHT-1
|
||||
par->crtc[CRTC_MAX_SCAN] = 0x40 | (CHAR_HEIGHT-1); /* 16 scanlines, linecmp max*/
|
||||
|
||||
if (var->vmode & VMODE_DOUBLE)
|
||||
par->crtc[CRTC_MAX_SCAN] |= 0x80;
|
||||
par->crtc[CRTC_CURSOR_START] = 0x00; // curs enabled, start line = 0
|
||||
par->crtc[CRTC_CURSOR_END] = CHAR_HEIGHT-1; // end line = 12
|
||||
pos = yoffset * vxres + (xoffset >> 3);
|
||||
par->crtc[CRTC_START_HI] = pos >> 8;
|
||||
par->crtc[CRTC_START_LO] = pos & 0xFF;
|
||||
par->crtc[CRTC_CURSOR_HI] = 0x00;
|
||||
par->crtc[CRTC_CURSOR_LO] = 0x00;
|
||||
pos = yres - 1;
|
||||
par->crtc[CRTC_V_DISP_END] = pos & 0xFF;
|
||||
par->crtc[CRTC_V_BLANK_START] = pos & 0xFF;
|
||||
if (pos & 0x100)
|
||||
r7 |= 0x0A; /* 0x02 -> DISP_END, 0x08 -> BLANK_START */
|
||||
if (pos & 0x200) {
|
||||
r7 |= 0x40; /* 0x40 -> DISP_END */
|
||||
par->crtc[CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */
|
||||
}
|
||||
pos += lower;
|
||||
par->crtc[CRTC_V_SYNC_START] = pos & 0xFF;
|
||||
if (pos & 0x100)
|
||||
r7 |= 0x04;
|
||||
if (pos & 0x200)
|
||||
r7 |= 0x80;
|
||||
pos += vslen;
|
||||
par->crtc[CRTC_V_SYNC_END] = (pos & 0x0F) & ~0x10; /* disabled reg write prot, IRQ */
|
||||
pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */
|
||||
par->crtc[CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA,
|
||||
but some SVGA chips requires all 8 bits to set */
|
||||
if (vxres >= 512)
|
||||
return VERROR; //vxres too long
|
||||
par->crtc[CRTC_OFFSET] = vxres >> 1;
|
||||
|
||||
// put the underline off of the character, necessary in alpha color mode
|
||||
par->crtc[CRTC_UNDERLINE] = 0x1f;
|
||||
|
||||
par->crtc[CRTC_MODE] = rMode | 0xA3; // word mode
|
||||
par->crtc[CRTC_LINE_COMPARE] = 0xFF;
|
||||
par->crtc[CRTC_OVERFLOW] = r7;
|
||||
|
||||
|
||||
// not used ??
|
||||
par->vss = 0x00; /* 3DA */
|
||||
|
||||
for (i = 0x00; i < 0x10; i++) {
|
||||
par->atc[i] = VgaAttributeTable[i];
|
||||
}
|
||||
// GMODE <--> ALPHA-MODE
|
||||
par->atc[ATC_MODE] = 0x0c; // text mode
|
||||
|
||||
par->atc[ATC_OVERSCAN] = 0x00; // no border
|
||||
par->atc[ATC_PLANE_ENABLE] = 0x0F;
|
||||
par->atc[ATC_PEL] = xoffset & 7;
|
||||
par->atc[ATC_COLOR_PAGE] = 0x00;
|
||||
|
||||
par->misc = 0x67; /* enable CPU, ports 0x3Dx, positive sync*/
|
||||
if (var->sync & SYNC_HOR_HIGH_ACT)
|
||||
par->misc &= ~0x40;
|
||||
if (var->sync & SYNC_VERT_HIGH_ACT)
|
||||
par->misc &= ~0x80;
|
||||
|
||||
par->seq[SEQ_CLOCK_MODE] = 0x01; //8-bit char; 0x01=alpha mode
|
||||
par->seq[SEQ_PLANE_WRITE] = 0x03; // just char/attr plane
|
||||
par->seq[SEQ_CHARACTER_MAP] = 0x00;
|
||||
par->seq[SEQ_MEMORY_MODE] = 0x02; // A/G bit not used in stpc; O/E on, C4 off
|
||||
|
||||
par->gdc[GDC_SR_VALUE] = 0x00;
|
||||
// bits set in the SR_EN regs will enable set/reset action
|
||||
// based on the bit settings in the SR_VAL register
|
||||
par->gdc[GDC_SR_ENABLE] = 0x00;
|
||||
par->gdc[GDC_COMPARE_VALUE] = 0x00;
|
||||
par->gdc[GDC_DATA_ROTATE] = 0x00;
|
||||
par->gdc[GDC_PLANE_READ] = 0;
|
||||
par->gdc[GDC_MODE] = 0x10; //Okay
|
||||
|
||||
// GMODE <--> ALPHA-MMODE
|
||||
par->gdc[GDC_MISC] = 0x0e; // b0=0 ->alpha mode; memory at 0xb8000
|
||||
|
||||
par->gdc[GDC_COMPARE_MASK] = 0x00;
|
||||
par->gdc[GDC_BIT_MASK] = 0xFF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* From the Linux kernel.
|
||||
* orig by Ben Pfaff and Petr Vandrovec.
|
||||
* see the note in the vga.h for attribution.
|
||||
*
|
||||
* modified by
|
||||
* Steve M. Gehlbach <steve@kesa.com>
|
||||
* for the linuxbios project
|
||||
*
|
||||
* Write the data in the vga parameter structure
|
||||
* to the vga registers, along with other default
|
||||
* settings.
|
||||
*
|
||||
*/
|
||||
static int vga_set_regs(const struct vga_par *par)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* update misc output register */
|
||||
outb(par->misc, MIS_W);
|
||||
|
||||
/* synchronous reset on */
|
||||
outb(0x00, SEQ_I);
|
||||
outb(0x00, SEQ_D);
|
||||
|
||||
/* write sequencer registers */
|
||||
outb(1, SEQ_I);
|
||||
outb(par->seq[1] | 0x20, SEQ_D); // blank display
|
||||
for (i = 2; i < SEQ_C; i++) {
|
||||
outb(i, SEQ_I);
|
||||
outb(par->seq[i], SEQ_D);
|
||||
}
|
||||
|
||||
/* synchronous reset off */
|
||||
outb(0x00, SEQ_I);
|
||||
outb(0x03, SEQ_D);
|
||||
|
||||
/* deprotect CRT registers 0-7 */
|
||||
outb(0x11, CRT_IC);
|
||||
outb(par->crtc[0x11], CRT_DC);
|
||||
|
||||
/* write CRT registers */
|
||||
for (i = 0; i < CRTC_C; i++) {
|
||||
outb(i, CRT_IC);
|
||||
outb(par->crtc[i], CRT_DC);
|
||||
}
|
||||
/* write graphics controller registers */
|
||||
for (i = 0; i < GRA_C; i++) {
|
||||
outb(i, GRA_I);
|
||||
outb(par->gdc[i], GRA_D);
|
||||
}
|
||||
|
||||
/* write attribute controller registers */
|
||||
for (i = 0; i < ATT_C; i++) {
|
||||
inb(IS1_RC); /* reset flip-flop */
|
||||
inb(0x80); //delay
|
||||
outb(i, ATT_IW);
|
||||
inb(0x80); //delay
|
||||
|
||||
outb(par->atc[i], ATT_IW);
|
||||
inb(0x80); //delay
|
||||
}
|
||||
|
||||
// initialize the color table
|
||||
outb(0, PEL_IW);
|
||||
i = 0;
|
||||
// length is a magic number right now
|
||||
while ( i < (0x3f*3 + 3) ) {
|
||||
outb(VgaLookupTable[i++], PEL_D);
|
||||
outb(VgaLookupTable[i++], PEL_D);
|
||||
outb(VgaLookupTable[i++], PEL_D);
|
||||
}
|
||||
|
||||
outb(0x0ff, PEL_MSK); // palette mask
|
||||
|
||||
// very important
|
||||
// turn on video, disable palette access
|
||||
inb(IS1_RC); /* reset flip-flop */
|
||||
inb(0x80); //delay
|
||||
outb(0x20, ATT_IW);
|
||||
|
||||
/* Wait for screen to stabilize. */
|
||||
//for(i=0;i<1000;i++) { inb(0x80); }
|
||||
|
||||
outb(0x01, SEQ_I); // unblank display
|
||||
outb(par->seq[1], SEQ_D);
|
||||
|
||||
// turn on display, disable access to attr palette
|
||||
inb(IS1_RC);
|
||||
outb(0x20, ATT_IW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
vga_load_regs(void)
|
||||
{
|
||||
struct vga_par par;
|
||||
|
||||
vga_decode_var(&vga_settings, &par);
|
||||
vga_set_regs(&par);
|
||||
}
|
||||
148
drivers/vga_set_mode.c
Normal file
148
drivers/vga_set_mode.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Source$
|
||||
*
|
||||
* by
|
||||
* Steve M. Gehlbach <steve@kesa.com>
|
||||
*
|
||||
* These routines set graphics mode and alpha mode
|
||||
* for switching back and forth.
|
||||
*
|
||||
* Register settings are
|
||||
* more or less as follows:
|
||||
*
|
||||
* Register Graphics Alpha
|
||||
* 16 color
|
||||
* ------------------------------------------------
|
||||
* GDC_MODE 0x00 0x10
|
||||
* GDC_MISC 0x05 0x0e
|
||||
* SEQ_MEMORY_MODE 0x06 0x02
|
||||
* SEQ_PLANE_WRITE 0x0f 0x03
|
||||
* CRTC_CURSOR_START 0x20 0x00
|
||||
* CRTC_CURSOR_END 0x00 CHAR_HEIGHT-1
|
||||
* CRTC_MODE 0xe3 0xa3
|
||||
* CRTC_MAX_SCAN 0x40 0x40 | CHAR_HEIGHT-1
|
||||
* ATC_MODE 0x01 0x0c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "asm/io.h"
|
||||
#include "vga.h"
|
||||
|
||||
void vga_set_gmode (void) {
|
||||
u8 byte;
|
||||
|
||||
byte = read_att_b(ATC_MODE) & ~0x0f;
|
||||
write_att(byte|0x1, ATC_MODE);
|
||||
//
|
||||
// display is off at this point
|
||||
|
||||
byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
|
||||
write_seq(byte|0xf,SEQ_PLANE_WRITE); // all planes
|
||||
byte = read_seq_b(SEQ_MEMORY_MODE);
|
||||
write_seq(byte|4,SEQ_MEMORY_MODE);
|
||||
|
||||
byte = read_gra_b(GDC_MODE) & ~0x10;
|
||||
write_gra(byte,GDC_MODE);
|
||||
write_gra(0x05, GDC_MISC);
|
||||
|
||||
write_crtc(0x20, CRTC_CURSOR_START);
|
||||
write_crtc(0x00, CRTC_CURSOR_END);
|
||||
byte = read_crtc_b(CRTC_MODE) & ~0xe0;
|
||||
write_crtc(byte|0xe0, CRTC_MODE);
|
||||
byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f;
|
||||
write_crtc(byte, CRTC_MAX_SCAN);
|
||||
|
||||
byte = inb(MIS_R); // get 3c2 value by reading 3cc
|
||||
outb(byte & ~0xc,MIS_W); // clear last bits to set 25Mhz clock and low page
|
||||
|
||||
|
||||
// turn on display, disable access to attr palette
|
||||
inb(IS1_RC);
|
||||
outb(0x20, ATT_IW);
|
||||
}
|
||||
|
||||
void vga_set_amode (void) {
|
||||
u8 byte;
|
||||
write_att(0x0c, ATC_MODE);
|
||||
|
||||
//reset palette to normal in the case it was changed
|
||||
write_att(0x0, ATC_COLOR_PAGE);
|
||||
//
|
||||
// display is off at this point
|
||||
|
||||
write_seq(0x3,SEQ_PLANE_WRITE); // planes 0 & 1
|
||||
byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x04;
|
||||
write_seq(byte,SEQ_MEMORY_MODE);
|
||||
|
||||
byte = read_gra_b(GDC_MODE) & ~0x60;
|
||||
write_gra(byte|0x10,GDC_MODE);
|
||||
|
||||
write_gra(0x0e, GDC_MISC);
|
||||
|
||||
write_crtc(0x00, CRTC_CURSOR_START);
|
||||
write_crtc(CHAR_HEIGHT-1, CRTC_CURSOR_END);
|
||||
|
||||
byte = read_crtc_b(CRTC_MODE) & ~0xe0;
|
||||
write_crtc(byte|0xa0, CRTC_MODE);
|
||||
byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f;
|
||||
write_crtc(byte | (CHAR_HEIGHT-1), CRTC_MAX_SCAN);
|
||||
|
||||
|
||||
// turn on display, disable access to attr palette
|
||||
inb(IS1_RC);
|
||||
outb(0x20, ATT_IW);
|
||||
}
|
||||
|
||||
/*
|
||||
* by Steve M. Gehlbach, Ph.D. <steve@kesa.com>
|
||||
*
|
||||
* vga_font_load loads a font into font memory. It
|
||||
* assumes alpha mode has been set.
|
||||
*
|
||||
* The font load code follows technique used
|
||||
* in the tiara project, which came from
|
||||
* the Universal Talkware Boot Loader,
|
||||
* http://www.talkware.net.
|
||||
*/
|
||||
|
||||
void vga_font_load(unsigned char *vidmem, const unsigned char *font, int height, int num_chars) {
|
||||
|
||||
/* Note: the font table is 'height' long but the font storage area
|
||||
* is 32 bytes long.
|
||||
*/
|
||||
|
||||
int i,j;
|
||||
u8 byte;
|
||||
|
||||
// set sequencer map 2, odd/even off
|
||||
byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
|
||||
write_seq(byte|4,SEQ_PLANE_WRITE);
|
||||
byte = read_seq_b(SEQ_MEMORY_MODE);
|
||||
write_seq(byte|4,SEQ_MEMORY_MODE);
|
||||
|
||||
// select graphics map 2, odd/even off, map starts at 0xa0000
|
||||
write_gra(2,GDC_PLANE_READ);
|
||||
byte = read_gra_b(GDC_MODE) & ~0x10;
|
||||
write_gra(byte,GDC_MODE);
|
||||
write_gra(0,GDC_MISC);
|
||||
|
||||
for (i = 0 ; i < num_chars ; i++) {
|
||||
for (j = 0 ; j < height ; j++) {
|
||||
vidmem[i*32+j] = font[i*16+j];
|
||||
}
|
||||
}
|
||||
|
||||
// set sequencer back to maps 0,1, odd/even on
|
||||
byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
|
||||
write_seq(byte|3,SEQ_PLANE_WRITE);
|
||||
byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x4;
|
||||
write_seq(byte,SEQ_MEMORY_MODE);
|
||||
|
||||
// select graphics back to map 0,1, odd/even on
|
||||
write_gra(0,GDC_PLANE_READ);
|
||||
byte = read_gra_b(GDC_MODE);
|
||||
write_gra(byte|0x10,GDC_MODE);
|
||||
write_gra(0xe,GDC_MISC);
|
||||
|
||||
}
|
||||
11
include/video_subr.h
Normal file
11
include/video_subr.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef VIDEO_SUBR_H
|
||||
#define VIDEO_SUBR_H
|
||||
|
||||
void video_tx_byte(unsigned char byte);
|
||||
void vga_load_regs(void);
|
||||
void vga_set_amode (void);
|
||||
void vga_set_gmode (void);
|
||||
void vga_font_load(unsigned char *vidmem, const unsigned char *font, int height, int num_chars);
|
||||
extern const unsigned char fontdata_8x16[];
|
||||
|
||||
#endif /* VIDEO_SUBR_H */
|
||||
4693
modules/font_8x16.c
Normal file
4693
modules/font_8x16.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user