📄 vga.c
字号:
#include <bios/types.h>#include <bios/string.h>#include <bios/pci.h>#include <bios/stdio.h>#include <bios/stdioint.h>#include <bios/vga.h>#include "font.h"static volatile char *io_base;static volatile char *charmap;static volatile char *scrmem;#define NUM_COLS 80#define NUM_ROWS 50/* Write: 0x3c2 Read: 0x3cc */#define VSync_Polarity 0x80#define HSync_Polarity 0x40#define OddEvenPage 0x20#define DisableVideo 0x10#define ClockSel_480 0x0c#define ClockSel_350 0x08#define ClockSel_400 0x04#define EnableRAM 0x02#define IO_Colour 0x01#define FN_ATT 0#define FN_GRPH 1#define FN_CRTC 2#define FN_SEQ 3#define FN_DLUT 4#define FN_MISC 5#define FN_CMAP 6#define FN_CARD 7#define FN_END 8typedef struct { char fn; char reg; char val;} mux_reg_t;#if 0typedef struct { unsigned short vendor; unsigned short device; const mux_reg_t *mux;} card_mux_t;static const mux_reg_t s3trio64_card[] = { { FN_CRTC, 0x38, 0x48 }, /* Unlock 1 */ { FN_CRTC, 0x39, 0xa5 }, /* Unlock 2 */ { FN_CRTC, 0x31, 0x05 }, /* memory config */ { FN_CRTC, 0x32, 0x40 }, /* use standard VGA memory wrapping */ { FN_CRTC, 0x35, 0x00 }, /* unlock CRTC registers */ { FN_CRTC, 0x36, 0x9a }, /* 2MB, enable VGA bios, 2-cycle EDO */ { FN_CRTC, 0x3B, 0x5a }, /* start display fifo fetch */ { FN_CRTC, 0x40, 0x00 }, /* no enhanced register access */ { FN_CRTC, 0x53, 0x00 }, /* extended mem control 1 */ { FN_CRTC, 0x54, 0x58 }, /* extended mem control 2 */ { FN_CRTC, 0x58, 0x00 }, /* no linear address window */ { FN_CRTC, 0x60, 0x07 }, /* streams processor fifo filling */ { FN_CRTC, 0x39, 0x5a }, /* Lock 2 */ { FN_CRTC, 0x38, 0x00 }, /* Lock 1 */ { FN_END, 0x00, 0x00 }};static const card_mux_t cards[] = { { 0x5333, 0x8880, s3trio64_card }, { 0x5333, 0x8901, s3trio64_card }, { 0x0000, 0x0000, NULL },};#endif/* * A 'programme' of writes to set up the video card. * * This is the generic VGA register set. Card-specifics are * loaded at FN_CARD. */static const mux_reg_t list[] = { { FN_SEQ , 0x00, 0x01 }, /* Seq Reset register (seq reset) */// { FN_MISC, 0x00, HSync_Polarity | OddEvenPage | EnableRAM | IO_Colour },// { FN_SEQ , 0x01, 0x00 }, /* Clock mode */ { FN_SEQ , 0x02, 0x04 }, /* Colour plane write enable */// { FN_SEQ , 0x03, 0x00 }, /* Character gen select */ { FN_SEQ , 0x04, 0x07 }, /* Memory mode register */ { FN_SEQ , 0x00, 0x03 }, /* Seq Reset register */// { FN_CARD, 0x00, 0x00 },// { FN_GRPH, 0x00, 0x00 }, /* Set/Reset data planes */// { FN_GRPH, 0x01, 0x00 }, /* Set/Reset enable planes */// { FN_GRPH, 0x02, 0x00 }, /* Colour compare */// { FN_GRPH, 0x03, 0x00 }, /* Data rotate/func select */ { FN_GRPH, 0x04, 0x02 }, /* Read plane select */ { FN_GRPH, 0x05, 0x00 }, /* Mode register */ { FN_GRPH, 0x06, 0x0c }, /* Miscellaneous */// { FN_GRPH, 0x07, 0x00 }, /* Colour don't care plane */// { FN_GRPH, 0x08, 0xff }, /* bitmask */ { FN_CMAP, 0x00, 0x00 }, /* Load char map */ { FN_SEQ , 0x00, 0x01 }, /* Seq Reset register (seq reset) */ { FN_SEQ , 0x02, 0x03 }, /* Colour plane write enable */ { FN_SEQ , 0x04, 0x02 }, /* Memory mode register */ { FN_SEQ , 0x00, 0x03 }, /* Seq Reset register (seq reset) */ { FN_GRPH, 0x04, 0x00 }, /* Read plane select */ { FN_GRPH, 0x05, 0x10 }, /* Mode register */ { FN_GRPH, 0x06, 0x0e }, /* Miscellaneous */ { FN_CRTC, 0x11, 0x0b }, /* unlock CR0-7 */// { FN_CRTC, 0x00, 0x5f }, /* Horiz total */// { FN_CRTC, 0x01, 0x4f }, /* Horiz displayed total */// { FN_CRTC, 0x02, 0x50 }, /* Horiz blank start */// { FN_CRTC, 0x03, 0x82 }, /* Horiz blank end */// { FN_CRTC, 0x04, 0x55 }, /* Horiz retrace start */// { FN_CRTC, 0x05, 0x81 }, /* Horiz retrace end */// { FN_CRTC, 0x06, 0xbf }, /* Vert total */ { FN_CRTC, 0x07, 0x1f }, /* Overflow register */// { FN_CRTC, 0x08, 0x00 }, /* Preset row scan */ { FN_CRTC, 0x09, 0x47 }, /* Max scan line */ { FN_CRTC, 0x0a, 0x07 }, /* Cursor scanline start */ { FN_CRTC, 0x0b, 0x07 }, /* Cursor scanline end */// { FN_CRTC, 0x0c, 0x00 }, /* Start address high */// { FN_CRTC, 0x0d, 0x00 }, /* Start address low */// { FN_CRTC, 0x0e, 0x00 }, /* Cursor high */// { FN_CRTC, 0x0f, 0x00 }, /* Cursor low */// { FN_CRTC, 0x10, 0x9c }, /* Vert retrace start */ { FN_CRTC, 0x11, 0x8e }, /* Vert retrace end */ { FN_CRTC, 0x12, 0x8f }, /* Vert display enable end */// { FN_CRTC, 0x13, 0x28 }, /* Logical screen width */// { FN_CRTC, 0x14, 0x1f }, /* Underline location */// { FN_CRTC, 0x15, 0x96 }, /* Vertical blanking start */// { FN_CRTC, 0x16, 0xb9 }, /* Vertical blanking end */// { FN_CRTC, 0x17, 0xa3 }, /* mode control */// { FN_CRTC, 0x18, 0xff }, /* Compare register */#if 0 { FN_ATT , 0x00, 0x00 }, /* Attrib Palette 0 */ { FN_ATT , 0x01, 0x01 }, { FN_ATT , 0x02, 0x02 }, { FN_ATT , 0x03, 0x03 }, { FN_ATT , 0x04, 0x04 }, { FN_ATT , 0x05, 0x05 }, { FN_ATT , 0x06, 0x06 }, { FN_ATT , 0x07, 0x07 }, { FN_ATT , 0x08, 0x08 }, { FN_ATT , 0x09, 0x09 }, { FN_ATT , 0x0a, 0x0a }, { FN_ATT , 0x0b, 0x0b }, { FN_ATT , 0x0c, 0x0c }, { FN_ATT , 0x0d, 0x0d }, { FN_ATT , 0x0e, 0x0e }, { FN_ATT , 0x0f, 0x0f }, /* Attrib Palette 15 */ { FN_ATT , 0x10, 0x08 }, /* Mode control */ { FN_ATT , 0x11, 0x00 }, /* Screen border */ { FN_ATT , 0x12, 0x0f }, /* Colour plane enable */ { FN_ATT , 0x13, 0x08 }, /* Horizontal panning */ { FN_ATT , 0x14, 0x00 }, /* Colour select */ { FN_DLUT, 0x00, 0x00 }, /* Load DAC LUTs */#endif { FN_END , 0x00, 0x00 }}; static const char DAC[] = { 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42, 42, 0, 0, 42, 0, 42, 42, 42, 0, 42, 42, 42, 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63};static inline void attrib_write(int reg, int val){ int j; j = io_base[0x3da]; io_base[0x3c0] = reg; io_base[0x3c0] = val;}static inline void crtc_write(int reg, int val){ io_base[0x3d4] = reg; io_base[0x3d5] = val;}static inline void seq_write(int reg, int val){ io_base[0x3c4] = reg; io_base[0x3c5] = val;}static inline void grph_write(int reg, int val){ io_base[0x3ce] = reg; io_base[0x3cf] = val;}static void vga_load_regs(const mux_reg_t *reg, struct pci_dev *dev){ int c, r, i; while (reg->fn != FN_END) { switch (reg->fn) { case FN_ATT: attrib_write(reg->reg, reg->val); break; case FN_GRPH: grph_write(reg->reg, reg->val); break; case FN_CRTC: crtc_write(reg->reg, reg->val); break; case FN_SEQ: seq_write(reg->reg, reg->val); break; case FN_DLUT: io_base[0x3c8] = 0; for (i = 0; i < sizeof(DAC); i++) io_base[0x3c9] = DAC[i]; break; case FN_MISC: io_base[0x3c2] = reg->val; break; case FN_CMAP: for (c = 0; c < 256; c++) for (r = 0; r < 32; r++) if (r < 8) charmap[(c << 5) + r] = cmap_80[c][r]; else charmap[(c << 5) + r] = 0; break;#if 0 case FN_CARD: for (i = 0; cards[i].vendor; i++) if (cards[i].vendor == dev->vendor && cards[i].device == dev->device) vga_load_regs(cards[i].mux, NULL); break;#endif } reg++; }}static unsigned char x, y, attrib;static unsigned int vga_offset, vga_max_off;static unsigned char *vga_start, *vga_pos;static void vga_setcursor(void){ int loc = vga_offset + y * NUM_COLS + x; crtc_write(0x0e, loc >> 8); crtc_write(0x0f, loc);}static void set_offset(int off){ if (off >= vga_max_off) off -= vga_max_off; vga_offset = off; vga_start = (unsigned char *)scrmem + off; vga_pos = vga_start + (y * NUM_COLS + x) * 2; crtc_write(0x0c, off >> 8); crtc_write(0x0d, off);}static void vga_clear(void){ int i; set_offset(0); for (i = 0; i < NUM_ROWS * NUM_COLS * 2; i += 2) { vga_start[i] = ' '; vga_start[i+1] = attrib; }}static void vga_write_string(const char *buffer, int len){ int i; for (i = 0; i < len; i++) { switch (buffer[i]) { case 6: break; case 8: if (x > 0) { vga_pos -= 2; x -= 1; } break; case 9: vga_pos -= x * 2; x = (x | 7) + 1; vga_pos += x * 2; break; case '\n': vga_pos += (NUM_COLS - x) * 2; y += 1; x = 0; break; case '\r': vga_pos -= x * 2; x = 0; break; case 12: vga_clear(); vga_pos = vga_start; x = 0; y = 0; break; case 31 ... 255: *vga_pos++ = buffer[i]; *vga_pos++ = attrib; x += 1; break; } if (x >= NUM_COLS) { x = 0; y += 1; } if (y >= NUM_ROWS) { y = NUM_ROWS - 1; set_offset(vga_offset + NUM_COLS * 2); } }}void vga_print(const char *buffer, int len){ vga_write_string(buffer, len); vga_setcursor();}void vga_init(void){ struct pci_dev *dev; dev = pci_lookupclass(NULL, 0x300); if (!dev) dev = pci_lookupclass(NULL, 0x0001); if (!dev) return; if (pci_enable(dev)) return; if (dev->bar[7]) pci_exec_bios(dev); x = 0; y = 0; attrib = 7; io_base = (volatile char *)0x7c000000; charmap = (volatile char *)0x800b8000; scrmem = (volatile char *)0x800b8000; io_base[0x3c3] = 1; vga_load_regs(list, dev); io_base[0x3c0] = 0x20; io_base[0x3c6] = 0xff; vga_max_off = 8192; vga_clear(); vga_setcursor(); stdfn.write = vga_print;}void con_get_params(unsigned long *xp, unsigned long *yp, unsigned long *colsp, unsigned long *rowsp){ *xp = x; *yp = y; *colsp = NUM_COLS; *rowsp = NUM_ROWS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -