📄 vgacon.c
字号:
{ u8 attr = color; if (vga_can_do_color) { if (underline) attr = (attr & 0xf0) | c->vc_ulcolor; else if (intensity == 0) attr = (attr & 0xf0) | c->vc_halfcolor; } if (reverse) attr = ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) & 0x77); if (blink) attr ^= 0x80; if (intensity == 2) attr ^= 0x08; if (!vga_can_do_color) { if (underline) attr = (attr & 0xf8) | 0x01; else if (intensity == 0) attr = (attr & 0xf0) | 0x08; } return attr;}static void vgacon_invert_region(struct vc_data *c, u16 * p, int count){ int col = vga_can_do_color; while (count--) { u16 a = scr_readw(p); if (col) a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4); else a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700; scr_writew(a, p++); }}static void vgacon_set_cursor_size(int xpos, int from, int to){ unsigned long flags; int curs, cure;#ifdef TRIDENT_GLITCH if (xpos < 16) from--, to--;#endif if ((from == cursor_size_lastfrom) && (to == cursor_size_lastto)) return; cursor_size_lastfrom = from; cursor_size_lastto = to; spin_lock_irqsave(&vga_lock, flags); outb_p(0x0a, vga_video_port_reg); /* Cursor start */ curs = inb_p(vga_video_port_val); outb_p(0x0b, vga_video_port_reg); /* Cursor end */ cure = inb_p(vga_video_port_val); curs = (curs & 0xc0) | from; cure = (cure & 0xe0) | to; outb_p(0x0a, vga_video_port_reg); /* Cursor start */ outb_p(curs, vga_video_port_val); outb_p(0x0b, vga_video_port_reg); /* Cursor end */ outb_p(cure, vga_video_port_val); spin_unlock_irqrestore(&vga_lock, flags);}static void vgacon_cursor(struct vc_data *c, int mode){ if (c->vc_origin != c->vc_visible_origin) vgacon_scrolldelta(c, 0); switch (mode) { case CM_ERASE: write_vga(14, (vga_vram_end - vga_vram_base - 1) / 2); break; case CM_MOVE: case CM_DRAW: write_vga(14, (c->vc_pos - vga_vram_base) / 2); switch (c->vc_cursor_type & 0x0f) { case CUR_UNDERLINE: vgacon_set_cursor_size(c->vc_x, c->vc_font.height - (c->vc_font.height < 10 ? 2 : 3), c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2)); break; case CUR_TWO_THIRDS: vgacon_set_cursor_size(c->vc_x, c->vc_font.height / 3, c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2)); break; case CUR_LOWER_THIRD: vgacon_set_cursor_size(c->vc_x, (c->vc_font.height * 2) / 3, c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2)); break; case CUR_LOWER_HALF: vgacon_set_cursor_size(c->vc_x, c->vc_font.height / 2, c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2)); break; case CUR_NONE: vgacon_set_cursor_size(c->vc_x, 31, 30); break; default: vgacon_set_cursor_size(c->vc_x, 1, c->vc_font.height); break; } break; }}static int vgacon_switch(struct vc_data *c){ /* * We need to save screen size here as it's the only way * we can spot the screen has been resized and we need to * set size of freshly allocated screens ourselves. */ vga_video_num_columns = c->vc_cols; vga_video_num_lines = c->vc_rows; if (!vga_is_gfx) scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size); return 0; /* Redrawing not needed */}static void vga_set_palette(struct vc_data *vc, unsigned char *table){ int i, j; for (i = j = 0; i < 16; i++) { vga_w(state.vgabase, VGA_PEL_IW, table[i]); vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); }}static int vgacon_set_palette(struct vc_data *vc, unsigned char *table){#ifdef CAN_LOAD_PALETTE if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked || !CON_IS_VISIBLE(vc)) return -EINVAL; vga_set_palette(vc, table); return 0;#else return -EINVAL;#endif}/* structure holding original VGA register settings */static struct { unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ unsigned char CrtMiscIO; /* Miscellaneous register */ unsigned char HorizontalTotal; /* CRT-Controller:00h */ unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ unsigned char StartHorizRetrace; /* CRT-Controller:04h */ unsigned char EndHorizRetrace; /* CRT-Controller:05h */ unsigned char Overflow; /* CRT-Controller:07h */ unsigned char StartVertRetrace; /* CRT-Controller:10h */ unsigned char EndVertRetrace; /* CRT-Controller:11h */ unsigned char ModeControl; /* CRT-Controller:17h */ unsigned char ClockingMode; /* Seq-Controller:01h */} vga_state;static void vga_vesa_blank(struct vgastate *state, int mode){ /* save original values of VGA controller registers */ if (!vga_vesa_blanked) { spin_lock_irq(&vga_lock); vga_state.SeqCtrlIndex = vga_r(state->vgabase, VGA_SEQ_I); vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg); vga_state.CrtMiscIO = vga_r(state->vgabase, VGA_MIS_R); spin_unlock_irq(&vga_lock); outb_p(0x00, vga_video_port_reg); /* HorizontalTotal */ vga_state.HorizontalTotal = inb_p(vga_video_port_val); outb_p(0x01, vga_video_port_reg); /* HorizDisplayEnd */ vga_state.HorizDisplayEnd = inb_p(vga_video_port_val); outb_p(0x04, vga_video_port_reg); /* StartHorizRetrace */ vga_state.StartHorizRetrace = inb_p(vga_video_port_val); outb_p(0x05, vga_video_port_reg); /* EndHorizRetrace */ vga_state.EndHorizRetrace = inb_p(vga_video_port_val); outb_p(0x07, vga_video_port_reg); /* Overflow */ vga_state.Overflow = inb_p(vga_video_port_val); outb_p(0x10, vga_video_port_reg); /* StartVertRetrace */ vga_state.StartVertRetrace = inb_p(vga_video_port_val); outb_p(0x11, vga_video_port_reg); /* EndVertRetrace */ vga_state.EndVertRetrace = inb_p(vga_video_port_val); outb_p(0x17, vga_video_port_reg); /* ModeControl */ vga_state.ModeControl = inb_p(vga_video_port_val); vga_state.ClockingMode = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); } /* assure that video is enabled */ /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */ spin_lock_irq(&vga_lock); vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode | 0x20); /* test for vertical retrace in process.... */ if ((vga_state.CrtMiscIO & 0x80) == 0x80) vga_w(state->vgabase, VGA_MIS_W, vga_state.CrtMiscIO & 0xEF); /* * Set <End of vertical retrace> to minimum (0) and * <Start of vertical Retrace> to maximum (incl. overflow) * Result: turn off vertical sync (VSync) pulse. */ if (mode & VESA_VSYNC_SUSPEND) { outb_p(0x10, vga_video_port_reg); /* StartVertRetrace */ outb_p(0xff, vga_video_port_val); /* maximum value */ outb_p(0x11, vga_video_port_reg); /* EndVertRetrace */ outb_p(0x40, vga_video_port_val); /* minimum (bits 0..3) */ outb_p(0x07, vga_video_port_reg); /* Overflow */ outb_p(vga_state.Overflow | 0x84, vga_video_port_val); /* bits 9,10 of vert. retrace */ } if (mode & VESA_HSYNC_SUSPEND) { /* * Set <End of horizontal retrace> to minimum (0) and * <Start of horizontal Retrace> to maximum * Result: turn off horizontal sync (HSync) pulse. */ outb_p(0x04, vga_video_port_reg); /* StartHorizRetrace */ outb_p(0xff, vga_video_port_val); /* maximum */ outb_p(0x05, vga_video_port_reg); /* EndHorizRetrace */ outb_p(0x00, vga_video_port_val); /* minimum (0) */ } /* restore both index registers */ vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex); outb_p(vga_state.CrtCtrlIndex, vga_video_port_reg); spin_unlock_irq(&vga_lock);}static void vga_vesa_unblank(struct vgastate *state){ /* restore original values of VGA controller registers */ spin_lock_irq(&vga_lock); vga_w(state->vgabase, VGA_MIS_W, vga_state.CrtMiscIO); outb_p(0x00, vga_video_port_reg); /* HorizontalTotal */ outb_p(vga_state.HorizontalTotal, vga_video_port_val); outb_p(0x01, vga_video_port_reg); /* HorizDisplayEnd */ outb_p(vga_state.HorizDisplayEnd, vga_video_port_val); outb_p(0x04, vga_video_port_reg); /* StartHorizRetrace */ outb_p(vga_state.StartHorizRetrace, vga_video_port_val); outb_p(0x05, vga_video_port_reg); /* EndHorizRetrace */ outb_p(vga_state.EndHorizRetrace, vga_video_port_val); outb_p(0x07, vga_video_port_reg); /* Overflow */ outb_p(vga_state.Overflow, vga_video_port_val); outb_p(0x10, vga_video_port_reg); /* StartVertRetrace */ outb_p(vga_state.StartVertRetrace, vga_video_port_val); outb_p(0x11, vga_video_port_reg); /* EndVertRetrace */ outb_p(vga_state.EndVertRetrace, vga_video_port_val); outb_p(0x17, vga_video_port_reg); /* ModeControl */ outb_p(vga_state.ModeControl, vga_video_port_val); /* ClockingMode */ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode); /* restore index/control registers */ vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex); outb_p(vga_state.CrtCtrlIndex, vga_video_port_reg); spin_unlock_irq(&vga_lock);}static void vga_pal_blank(struct vgastate *state){ int i; for (i = 0; i < 16; i++) { vga_w(state->vgabase, VGA_PEL_IW, i); vga_w(state->vgabase, VGA_PEL_D, 0); vga_w(state->vgabase, VGA_PEL_D, 0); vga_w(state->vgabase, VGA_PEL_D, 0); }}static int vgacon_blank(struct vc_data *c, int blank, int mode_switch){ switch (blank) { case 0: /* Unblank */ if (vga_vesa_blanked) { vga_vesa_unblank(&state); vga_vesa_blanked = 0; } if (vga_palette_blanked) { vga_set_palette(c, color_table); vga_palette_blanked = 0; return 0; } vga_is_gfx = 0; /* Tell console.c that it has to restore the screen itself */ return 1; case 1: /* Normal blanking */ case -1: /* Obsolete */ if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) { vga_pal_blank(&state); vga_palette_blanked = 1; return 0; } vgacon_set_origin(c); scr_memsetw((void *) vga_vram_base, BLANK, c->vc_screenbuf_size); if (mode_switch) vga_is_gfx = 1; return 1; default: /* VESA blanking */ if (vga_video_type == VIDEO_TYPE_VGAC) { vga_vesa_blank(&state, blank - 1); vga_vesa_blanked = blank; } return 0; }}/* * PIO_FONT support. * * The font loading code goes back to the codepage package by * Joel Hoffman (joel@wam.umd.edu). (He reports that the original * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2 * Video Systems_ by Richard Wilton. 1987. Microsoft Press".) * * Change for certain monochrome monitors by Yury Shevchuck * (sizif@botik.yaroslavl.su). */#ifdef CAN_LOAD_EGA_FONTS#define colourmap 0xa0000/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we should use 0xA0000 for the bwmap as well.. */#define blackwmap 0xa0000#define cmapsz 8192static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512){ unsigned short video_port_status = vga_video_port_reg + 6; int font_select = 0x00, beg, i; char *charmap; if (vga_video_type != VIDEO_TYPE_EGAM) { charmap = (char *) VGA_MAP_MEM(colourmap); beg = 0x0e;#ifdef VGA_CAN_DO_64KB if (vga_video_type == VIDEO_TYPE_VGAC) beg = 0x06;#endif } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -