📄 vgacon.c
字号:
c->vc_visible_origin = vga_vram_base; vga_set_mem_top(c); con_free_unimap(c->vc_num); } c->vc_uni_pagedir_loc = &c->vc_uni_pagedir; con_set_default_unimap(c->vc_num);}static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse){ 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; static int lastfrom, lastto;#ifdef TRIDENT_GLITCH if (xpos<16) from--, to--;#endif if ((from == lastfrom) && (to == lastto)) return; lastfrom = from; 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, video_font_height - (video_font_height < 10 ? 2 : 3), video_font_height - (video_font_height < 10 ? 1 : 2)); break; case CUR_TWO_THIRDS: vgacon_set_cursor_size(c->vc_x, video_font_height / 3, video_font_height - (video_font_height < 10 ? 1 : 2)); break; case CUR_LOWER_THIRD: vgacon_set_cursor_size(c->vc_x, (video_font_height*2) / 3, video_font_height - (video_font_height < 10 ? 1 : 2)); break; case CUR_LOWER_HALF: vgacon_set_cursor_size(c->vc_x, video_font_height / 2, video_font_height - (video_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, video_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 *c, unsigned char *table){ int i, j ; for (i=j=0; i<16; i++) { outb_p (table[i], dac_reg) ; outb_p (c->vc_palette[j++]>>2, dac_val) ; outb_p (c->vc_palette[j++]>>2, dac_val) ; outb_p (c->vc_palette[j++]>>2, dac_val) ; }}static int vgacon_set_palette(struct vc_data *c, unsigned char *table){#ifdef CAN_LOAD_PALETTE if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked || !CON_IS_VISIBLE(c)) return -EINVAL; vga_set_palette(c, 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(int mode){ /* save original values of VGA controller registers */ if(!vga_vesa_blanked) { spin_lock_irq(&vga_lock); vga_state.SeqCtrlIndex = inb_p(seq_port_reg); vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg); vga_state.CrtMiscIO = inb_p(video_misc_rd); 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); outb_p(0x01,seq_port_reg); /* ClockingMode */ vga_state.ClockingMode = inb_p(seq_port_val); } /* assure that video is enabled */ /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */ spin_lock_irq(&vga_lock); outb_p(0x01,seq_port_reg); outb_p(vga_state.ClockingMode | 0x20,seq_port_val); /* test for vertical retrace in process.... */ if ((vga_state.CrtMiscIO & 0x80) == 0x80) outb_p(vga_state.CrtMiscIO & 0xef,video_misc_wr); /* * 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 */ outb_p(vga_state.SeqCtrlIndex,seq_port_reg); outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg); spin_unlock_irq(&vga_lock);}static void vga_vesa_unblank(void){ /* restore original values of VGA controller registers */ spin_lock_irq(&vga_lock); outb_p(vga_state.CrtMiscIO,video_misc_wr); 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); outb_p(0x01,seq_port_reg); /* ClockingMode */ outb_p(vga_state.ClockingMode,seq_port_val); /* restore index/control registers */ outb_p(vga_state.SeqCtrlIndex,seq_port_reg); outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg); spin_unlock_irq(&vga_lock);}static void vga_pal_blank(void){ int i; for (i=0; i<16; i++) { outb_p (i, dac_reg) ; outb_p (0, dac_val) ; outb_p (0, dac_val) ; outb_p (0, dac_val) ; }}static int vgacon_blank(struct vc_data *c, int blank){ switch (blank) { case 0: /* Unblank */ if (vga_vesa_blanked) { vga_vesa_unblank(); 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 */ if (vga_video_type == VIDEO_TYPE_VGAC) { vga_pal_blank(); vga_palette_blanked = 1; return 0; } vgacon_set_origin(c); scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size); return 1; case -1: /* Entering graphic mode */ scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size); vga_is_gfx = 1; return 1; default: /* VESA blanking */ if (vga_video_type == VIDEO_TYPE_VGAC) { vga_vesa_blank(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 intvgacon_do_font_op(char *arg, int set, int ch512){ int i; char *charmap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -