📄 vga.c
字号:
/* DPMI Driver for FD32: VGA calls * by Hanzac Chen * * Ref: http://www.nongnu.org/vgabios * Copyright (C) 2001,2002 the LGPL VGABios developers Team * * This is free software; see GPL.txt */#include <ll/i386/hw-data.h>#include <ll/i386/hw-instr.h>#include <ll/i386/cons.h>#include <logger.h>#include "vga.h"static VGAMODE vga_modes[MODE_MAX+1]= { /*mode vesa class model pg bits sw sh tw th cw ch sstart slength misc pelm crtc actl gdc sequ dac */ {0x00, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, {0x01, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, {0x02, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, {0x03, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, {0x04, 0xFFFF, GRAPH, CGA, 4, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, {0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, {0x06, 0xFFFF, GRAPH, CGA, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, {0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00}, {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x2000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, {0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x4000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01}, {0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00}, {0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02}, {0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02}, {0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02}, {0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03}, /*{0x6A, 0xFFFF, GRAPH, PLANAR4, 1, 4, 800, 600,100, 37, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x0A, 0x06, 0x04, 0x05, 0x02} */ };/* CRTC */#define CRTC_MAX_REG 0x18#define CRTC_MAX_MODEL 0x0Astatic BYTE crtc_regs[CRTC_MAX_MODEL+1][CRTC_MAX_REG+1]= { /* Model 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */ /* 00 */ { 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}, /* 01 */ { 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}, /* 02 */ { 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}, /* 03 */ { 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}, /* 04 */ { 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}, /* 05 */ { 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}, /* 06 */ { 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}, /* 07 */ { 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}, /* 08 */ { 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}, /* 09 */ { 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}, /* 0A */ { 0x7f,0x63,0x63,0x83,0x6b,0x1b,0x72,0xf0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x0d,0x57,0x32,0x00,0x57,0x73,0xe3,0xff} };/* Attribute Controler 0x3c0 */#define ACTL_MAX_REG 0x14#define ACTL_MAX_MODEL 0x08static BYTE actl_regs[ACTL_MAX_MODEL+1][ACTL_MAX_REG+1]= { /* Model 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */ /* 00 */ { 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x0c,0x00,0x0f,0x08,0x00}, /* 01 */ { 0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x03,0x00,0x00}, /* 02 */ { 0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x01,0x00,0x01,0x00,0x00}, /* 03 */ { 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x0e,0x00,0x0f,0x08,0x00}, /* 04 */ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x0f,0x00,0x00}, /* 05 */ { 0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x0b,0x00,0x05,0x00,0x00}, /* 06 */ { 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x01,0x00,0x0f,0x00,0x00}, /* 07 */ { 0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x01,0x00,0x01,0x00,0x00}, /* 08 */ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x41,0x00,0x0f,0x00,0x00} };/* Sequencer 0x3c4 */#define SEQU_MAX_REG 0x04#define SEQU_MAX_MODEL 0x06static BYTE sequ_regs[SEQU_MAX_MODEL+1][SEQU_MAX_REG+1]= { /* Model 00 01 02 03 04 */ /* 00 */ { 0x03,0x08,0x03,0x00,0x02}, /* 01 */ { 0x03,0x00,0x03,0x00,0x02}, /* 02 */ { 0x03,0x09,0x03,0x00,0x02}, /* 03 */ { 0x03,0x01,0x01,0x00,0x06}, /* 04 */ { 0x03,0x09,0x0f,0x00,0x06}, /* 05 */ { 0x03,0x01,0x0f,0x00,0x06}, /* 06 */ { 0x03,0x01,0x0f,0x00,0x0e} };/* Graphic ctl 0x3ce */#define GRDC_MAX_REG 0x08#define GRDC_MAX_MODEL 0x05static BYTE grdc_regs[GRDC_MAX_MODEL+1][GRDC_MAX_REG+1]= { /* Model 00 01 02 03 04 05 06 07 08 */ /* 00 */ { 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x0f,0xff}, /* 01 */ { 0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x0f,0xff}, /* 02 */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x0f,0xff}, /* 03 */ { 0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x0f,0xff}, /* 04 */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,0xff}, /* 05 */ { 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,0xff} };static BYTE *biosmem_p = (BYTE *)0x400;void vga_set_all_palette_reg(BYTE *pal){ inp(VGAREG_ACTL_RESET); /* First the colors */ #define VGAREG_WRITE_COLOR(c) outp(VGAREG_ACTL_ADDRESS, c); outp(VGAREG_ACTL_WRITE_DATA, pal[0]); pal++ VGAREG_WRITE_COLOR(0x00); VGAREG_WRITE_COLOR(0x01); VGAREG_WRITE_COLOR(0x02); VGAREG_WRITE_COLOR(0x03); VGAREG_WRITE_COLOR(0x04); VGAREG_WRITE_COLOR(0x05); VGAREG_WRITE_COLOR(0x06); VGAREG_WRITE_COLOR(0x07); VGAREG_WRITE_COLOR(0x08); VGAREG_WRITE_COLOR(0x09); VGAREG_WRITE_COLOR(0x0A); VGAREG_WRITE_COLOR(0x0B); VGAREG_WRITE_COLOR(0x0C); VGAREG_WRITE_COLOR(0x0D); VGAREG_WRITE_COLOR(0x0E); VGAREG_WRITE_COLOR(0x0F); #undef VGAREG_WRITE_COLOR /* Then the border */ outp(VGAREG_ACTL_ADDRESS, 0x11); outp(VGAREG_ACTL_WRITE_DATA, pal[0]); outp(VGAREG_ACTL_ADDRESS, 0x20);}void vga_get_all_palette_reg(BYTE *pal){ /* First the colors */ #define VGAREG_READ_COLOR(c) inp(VGAREG_ACTL_RESET); outp(VGAREG_ACTL_ADDRESS, c); pal[0] = inp(VGAREG_ACTL_READ_DATA); pal++ VGAREG_READ_COLOR(0x00); VGAREG_READ_COLOR(0x01); VGAREG_READ_COLOR(0x02); VGAREG_READ_COLOR(0x03); VGAREG_READ_COLOR(0x04); VGAREG_READ_COLOR(0x05); VGAREG_READ_COLOR(0x06); VGAREG_READ_COLOR(0x07); VGAREG_READ_COLOR(0x08); VGAREG_READ_COLOR(0x09); VGAREG_READ_COLOR(0x0A); VGAREG_READ_COLOR(0x0B); VGAREG_READ_COLOR(0x0C); VGAREG_READ_COLOR(0x0D); VGAREG_READ_COLOR(0x0E); VGAREG_READ_COLOR(0x0F); #undef VGAREG_READ_COLOR /* Then the border */ inp(VGAREG_ACTL_RESET); outp(VGAREG_ACTL_ADDRESS, 0x11); pal[0] = inp(VGAREG_ACTL_READ_DATA); outp(VGAREG_ACTL_ADDRESS, 0x20);}void vga_toggle_intensity(BYTE state) { DWORD value; inp(VGAREG_ACTL_RESET); outp(VGAREG_ACTL_ADDRESS, 0x10); value = inp(VGAREG_ACTL_READ_DATA); value &= 0xF7; value |= (state&0x01)<<3; outp(VGAREG_ACTL_WRITE_DATA, value); outp(VGAREG_ACTL_ADDRESS, 0x20);}BYTE vga_get_single_palette_reg(BYTE reg){ BYTE value = 0; if(reg <= ACTL_MAX_REG) { inp(VGAREG_ACTL_RESET); outp(VGAREG_ACTL_ADDRESS, reg); value = inp(VGAREG_ACTL_READ_DATA); inp(VGAREG_ACTL_RESET); outp(VGAREG_ACTL_ADDRESS, 0x20); } return value;}void vga_set_single_palette_reg(BYTE reg, BYTE value){ if(reg <= ACTL_MAX_REG) { inp(VGAREG_ACTL_RESET); outp(VGAREG_ACTL_ADDRESS, reg); outp(VGAREG_ACTL_WRITE_DATA, value); outp(VGAREG_ACTL_ADDRESS, 0x20); }}BYTE vga_get_video_mode(BYTE *colsnum, BYTE *activepage){ colsnum[0] = biosmem_p[BIOSMEM_NB_COLS]; activepage[0] = biosmem_p[BIOSMEM_CURRENT_PAGE]; return (biosmem_p[BIOSMEM_VIDEO_CTL] & 0x80) | biosmem_p[BIOSMEM_CURRENT_MODE];}BYTE vga_set_video_mode(BYTE modenum){/* mode: Bit 7 is 1 if no clear screen */ VGAMODE *mode; DWORD i, ret = 0x20; WORD crtc_addr; BYTE modeset_ctl, video_ctl, vga_switches; fd32_log_printf("[INT10] Set mode to %x\n", modenum); if (modenum < 0x08) { if (modenum == 6) ret = 0x3F; else ret = 0x30; mode = vga_modes+modenum; } else if (modenum > 0x0C) { mode = vga_modes+modenum-5; } else { return ret; } /* Read the bios vga control */ video_ctl = biosmem_p[BIOSMEM_VIDEO_CTL]; /* Read the bios vga switches */ vga_switches = biosmem_p[BIOSMEM_SWITCHES]; /* Read the bios mode set control */ modeset_ctl = biosmem_p[BIOSMEM_MODESET_CTL]; /* Reset Attribute Ctl flip-flop */ inp(VGAREG_ACTL_RESET); /* Set Attribute Ctl */ for(i=0;i<=ACTL_MAX_REG;i++) { outp(VGAREG_ACTL_ADDRESS, i); outp(VGAREG_ACTL_WRITE_DATA, actl_regs[mode[0].actlmodel][i]); } /* Set Sequencer Ctl */ for(i=0;i<=SEQU_MAX_REG;i++) { outp(VGAREG_SEQU_ADDRESS, i); outp(VGAREG_SEQU_DATA, sequ_regs[mode[0].sequmodel][i]); } /* Set Grafx Ctl */ for(i=0;i<=GRDC_MAX_REG;i++) { outp(VGAREG_GRDC_ADDRESS, i); outp(VGAREG_GRDC_DATA, grdc_regs[mode[0].grdcmodel][i]); } /* Set CRTC address VGA or MDA */ crtc_addr = mode[0].memmodel == MTEXT ? VGAREG_MDA_CRTC_ADDRESS : VGAREG_VGA_CRTC_ADDRESS; /* Set CRTC regs */ for(i=0;i<=CRTC_MAX_REG;i++) { outp(crtc_addr, i); outp(crtc_addr+1, crtc_regs[mode[0].crtcmodel][i]); } /* Set the misc register */ outp(VGAREG_WRITE_MISC_OUTPUT, mode[0].miscreg); /* Enable video */ outp(VGAREG_ACTL_ADDRESS, 0x20); inp(VGAREG_ACTL_RESET); /* Set cursor shape */ if(mode[0].class==TEXT) { cursor(0x06, 0x07); } /* Set cursor pos for page 0..7 */ place(0, 0); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -