vga_support.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,450 行 · 第 1/3 页
C
1,450 行
unsigned long *pix; if ((x < 0) || (x >= VISIBLE_SCREEN_WIDTH) || (y < 0) || (y >= screen_height)) return; for (l = 0; l < FONT_HEIGHT; l++) { bits = font_table[c-FIRST_CHAR][l]; yoff = y*FONT_HEIGHT + l; xoff = x*FONT_WIDTH;#if 0 // Render font characters one bit at a time for (p = 0; p < FONT_WIDTH; p++) {#ifdef FONT_LEFT_TO_RIGHT set_pixel(yoff, xoff + p, (bits & 0x80) ? fg : bg); bits <<= 1;#else set_pixel(yoff, xoff + p, (bits & 0x01) ? fg : bg); bits >>= 1;#endif }#else // Render characters 4 bits at a time pix = (unsigned long *)vga_fb(yoff, xoff);#ifdef FONT_LEFT_TO_RIGHT *pix++ = _bitmap[(bits & 0xF0) >> 4]; *pix++ = _bitmap[(bits & 0x0F)];#else *pix++ = _bitmap[(bits & 0x0F)]; *pix++ = _bitmap[(bits & 0xF0) >> 4];#endif#endif }}static voidvga_refresh(void){ int row, col; for (row = screen_start; row < screen_height; row++) { for (col = 0; col < VISIBLE_SCREEN_WIDTH; col++) { if ((col+screen_pan) < screen_width) { vga_drawc(screen[row][col+screen_pan], col, row); } else { vga_drawc(' ', col, row); } } } if (cursor_enable) { vga_drawc(CURSOR_ON, curX-screen_pan, curY); }}static voidvga_scroll(void){ int col; cyg_uint8 *c1; cyg_uint32 *lc0, *lc1, *lcn; cyg_uint32 *fb_row0, *fb_row1, *fb_rown; // First scroll up the virtual screen#if ((SCREEN_WIDTH%4) != 0)#error Scroll code optimized for screen with multiple of 4 columns#endif lc0 = (cyg_uint32 *)&screen[0][0]; lc1 = (cyg_uint32 *)&screen[1][0]; lcn = (cyg_uint32 *)&screen[screen_height][0]; while (lc1 != lcn) { *lc0++ = *lc1++; } c1 = &screen[screen_height-1][0]; for (col = 0; col < screen_width; col++) { *c1++ = 0x20; }#if 0 // Scrolling like this is *relly* slow fb_row0 = (cyg_uint32 *)vga_fb(screen_start*FONT_HEIGHT, 0); fb_row1 = (cyg_uint32 *)vga_fb((screen_start+1)*FONT_HEIGHT, 0); fb_rown = (cyg_uint32 *)vga_fb(screen_end*FONT_HEIGHT, 0);#if 0 while (fb_row1 != fb_rown) { *fb_row0++ = *fb_row1++; }#else // Optimized ARM assembly "move" code asm __volatile( "mov r0,%0;" "mov r1,%1;" "mov r2,%2;" "10: ldmia r1!,{r3-r6};" "stmia r0!,{r3-r6};" "ldmia r1!,{r3-r6};" "stmia r0!,{r3-r6};" "cmp r1,r2;" "bne 10b" : : "r"(fb_row0), "r"(fb_row1), "r"(fb_rown) : "r0","r1","r2","r3","r4","r5","r6" );#endif // Erase bottom line for (col = 0; col < screen_width; col++) { vga_drawc(' ', col, screen_end-1); }#else // Clear & redraw is faster! vga_refresh();#endif}// Draw one character at the current positionvoidvga_putc(cyg_uint8 c){ if (cursor_enable) { vga_drawc(screen[curY][curX], curX-screen_pan, curY); } switch (c) { case '\r': curX = 0; break; case '\n': curY++; break; case '\b': curX--; if (curX < 0) { curY--; if (curY < 0) curY = 0; curX = screen_width-1; } break; default: if (((int)c < FIRST_CHAR) || ((int)c > LAST_CHAR)) c = '.'; screen[curY][curX] = c; vga_drawc(c, curX-screen_pan, curY); curX++; if (curX == screen_width) { curY++; curX = 0; } } if (curY >= screen_height) { vga_scroll(); curY = (screen_height-1); } if (cursor_enable) { vga_drawc(CURSOR_ON, curX-screen_pan, curY); }}// Basic VGA 'printf()' support#include <stdarg.h>#define is_digit(c) ((c >= '0') && (c <= '9'))static int_cvt(unsigned long val, char *buf, long radix, char *digits){ char temp[80]; char *cp = temp; int length = 0; if (val == 0) { /* Special case */ *cp++ = '0'; } else { while (val) { *cp++ = digits[val % radix]; val /= radix; } } while (cp != temp) { *buf++ = *--cp; length++; } *buf = '\0'; return (length);}static intvga_vprintf(void (*putc)(cyg_uint8), const char *fmt0, va_list ap){ char c, sign, *cp; int left_prec, right_prec, zero_fill, length, pad, pad_on_right; char buf[32]; long val; while ((c = *fmt0++)) { cp = buf; length = 0; if (c == '%') { c = *fmt0++; left_prec = right_prec = pad_on_right = 0; if (c == '-') { c = *fmt0++; pad_on_right++; } if (c == '0') { zero_fill = TRUE; c = *fmt0++; } else { zero_fill = FALSE; } while (is_digit(c)) { left_prec = (left_prec * 10) + (c - '0'); c = *fmt0++; } if (c == '.') { c = *fmt0++; zero_fill++; while (is_digit(c)) { right_prec = (right_prec * 10) + (c - '0'); c = *fmt0++; } } else { right_prec = left_prec; } sign = '\0'; switch (c) { case 'd': case 'x': case 'X': val = va_arg(ap, long); switch (c) { case 'd': if (val < 0) { sign = '-'; val = -val; } length = _cvt(val, buf, 10, "0123456789"); break; case 'x': length = _cvt(val, buf, 16, "0123456789abcdef"); break; case 'X': length = _cvt(val, buf, 16, "0123456789ABCDEF"); break; } break; case 's': cp = va_arg(ap, char *); length = strlen(cp); break; case 'c': c = va_arg(ap, long /*char*/); (*putc)(c); continue; default: (*putc)('?'); } pad = left_prec - length; if (sign != '\0') { pad--; } if (zero_fill) { c = '0'; if (sign != '\0') { (*putc)(sign); sign = '\0'; } } else { c = ' '; } if (!pad_on_right) { while (pad-- > 0) { (*putc)(c); } } if (sign != '\0') { (*putc)(sign); } while (length-- > 0) { (*putc)(c = *cp++); if (c == '\n') { (*putc)('\r'); } } if (pad_on_right) { while (pad-- > 0) { (*putc)(' '); } } } else { (*putc)(c); if (c == '\n') { (*putc)('\r'); } } } // FIXME return 0;}int_vga_printf(char const *fmt, ...){ int ret; va_list ap; va_start(ap, fmt); ret = vga_vprintf(vga_putc, fmt, ap); va_end(ap); return (ret);}//// Support VGA/keyboard (PS2) as a virtual I/O channel// Adapted from i386/pcmb_screen.c////-----------------------------------------------------------------------------// Keyboard definitions#define KBDATAPORT 0x0060 // data I/O port#define KBCMDPORT 0x0064 // command port (write)#define KBSTATPORT 0x0064 // status port (read)#define KBINRDY 0x01#define KBOUTRDY 0x02#define KBTXTO 0x40 // Transmit timeout - nothing there#define KBTEST 0xAB// Scan codes#define LSHIFT 0x2a#define RSHIFT 0x36#define CTRL 0x1d#define ALT 0x38#define CAPS 0x3a#define NUMS 0x45#define BREAK 0x80// Bits for KBFlags#define KBNormal 0x0000#define KBShift 0x0001#define KBCtrl 0x0002#define KBAlt 0x0004#define KBIndex 0x0007 // mask for the above#define KBExtend 0x0010#define KBAck 0x0020#define KBResend 0x0040#define KBShiftL (0x0080 | KBShift)#define KBShiftR (0x0100 | KBShift)#define KBCtrlL (0x0200 | KBCtrl)#define KBCtrlR (0x0400 | KBCtrl)#define KBAltL (0x0800 | KBAlt)#define KBAltR (0x1000 | KBAlt)#define KBCapsLock 0x2000#define KBNumLock 0x4000#define KBArrowUp 0x48#define KBArrowRight 0x4D#define KBArrowLeft 0x4B#define KBArrowDown 0x50//-----------------------------------------------------------------------------// Keyboard Variablesstatic int KBFlags = 0;static CYG_BYTE KBPending = 0xFF;static CYG_BYTE KBScanTable[128][4] = {// Normal Shift Control Alt// 0x00 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0x1b, 0x1b, 0x1b, 0xFF, }, { '1', '!', 0xFF, 0xFF, }, { '2', '"', 0xFF, 0xFF, }, { '3', '#', 0xFF, 0xFF, }, { '4', '$', 0xFF, 0xFF, }, { '5', '%', 0xFF, 0xFF, }, { '6', '^', 0xFF, 0xFF, }, { '7', '&', 0xFF, 0xFF, }, { '8', '*', 0xFF, 0xFF, }, { '9', '(', 0xFF, 0xFF, }, { '0', ')', 0xFF, 0xFF, }, { '-', '_', 0xFF, 0xFF, }, { '=', '+', 0xFF, 0xFF, }, { '\b', '\b', 0xFF, 0xFF, }, { '\t', '\t', 0xFF, 0xFF, },// 0x10 { 'q', 'Q', 0x11, 0xFF, }, { 'w', 'W', 0x17, 0xFF, }, { 'e', 'E', 0x05, 0xFF, }, { 'r', 'R', 0x12, 0xFF, }, { 't', 'T', 0x14, 0xFF, }, { 'y', 'Y', 0x19, 0xFF, }, { 'u', 'U', 0x15, 0xFF, }, { 'i', 'I', 0x09, 0xFF, }, { 'o', 'O', 0x0F, 0xFF, }, { 'p', 'P', 0x10, 0xFF, }, { '[', '{', 0x1b, 0xFF, }, { ']', '}', 0x1d, 0xFF, }, { '\r', '\r', '\n', 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 'a', 'A', 0x01, 0xFF, }, { 's', 'S', 0x13, 0xFF, },// 0x20 { 'd', 'D', 0x04, 0xFF, }, { 'f', 'F', 0x06, 0xFF, }, { 'g', 'G', 0x07, 0xFF, }, { 'h', 'H', 0x08, 0xFF, }, { 'j', 'J', 0x0a, 0xFF, }, { 'k', 'K', 0x0b, 0xFF, }, { 'l', 'L', 0x0c, 0xFF, }, { ';', ':', 0xFF, 0xFF, }, { 0x27, '@', 0xFF, 0xFF, }, { '#', '~', 0xFF, 0xFF, }, { '`', '~', 0xFF, 0xFF, }, { '\\', '|', 0x1C, 0xFF, }, { 'z', 'Z', 0x1A, 0xFF, }, { 'x', 'X', 0x18, 0xFF, }, { 'c', 'C', 0x03, 0xFF, }, { 'v', 'V', 0x16, 0xFF, },// 0x30 { 'b', 'B', 0x02, 0xFF, }, { 'n', 'N', 0x0E, 0xFF, }, { 'm', 'M', 0x0D, 0xFF, }, { ',', '<', 0xFF, 0xFF, }, { '.', '>', 0xFF, 0xFF, }, { '/', '?', 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { ' ', ' ', ' ', ' ', }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xF1, 0xE1, 0xFF, 0xFF, }, { 0xF2, 0xE2, 0xFF, 0xFF, }, { 0xF3, 0xE3, 0xFF, 0xFF, }, { 0xF4, 0xE4, 0xFF, 0xFF, }, { 0xF5, 0xE5, 0xFF, 0xFF, },// 0x40 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0x15, 0x15, 0x15, 0x15, }, { 0x10, 0x10, 0x10, 0x10, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, },// 0x50 { 0x04, 0x04, 0x04, 0x04, }, { 0x0e, 0x0e, 0x0e, 0x0e, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, },// 0x60 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, },
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?