📄 lib.c
字号:
footer(); break; case 57: /* SP - set scroll lock */ slock = 1; footer(); break; case 0x26: /* ^L/L - redraw the display */ tty_print_screen(); break; } }}void footer(){ cprint(24, 0, "(ESC)Reboot (c)configuration (SP)scroll_lock (CR)scroll_unlock"); if (slock) { cprint(24, 74, "LOCKED"); } else { cprint(24, 74, " "); }}ulong getval(int x, int y, int result_shift){ unsigned long val; int done; int c; int i, n; int base; int shift; char buf[16]; for(i = 0; i < sizeof(buf)/sizeof(buf[0]); i++ ) { buf[i] = ' '; } buf[sizeof(buf)/sizeof(buf[0]) -1] = '\0'; wait_keyup(); done = 0; n = 0; base = 10; while(!done) { /* Read a new character and process it */ c = get_key(); switch(c) { case 0x26: /* ^L/L - redraw the display */ tty_print_screen(); break; case 0x1c: /* CR */ /* If something has been entered we are done */ if(n) done = 1; break; case 0x19: /* p */ buf[n] = 'p'; break; case 0x22: /* g */ buf[n] = 'g'; break; case 0x32: /* m */ buf[n] = 'm'; break; case 0x25: /* k */ buf[n] = 'k'; break; case 0x2d: /* x */ /* Only allow 'x' after an initial 0 */ if (n == 1 && (buf[0] == '0')) { buf[n] = 'x'; } break; case 0x0e: /* BS */ if (n > 0) { n -= 1; buf[n] = ' '; } break; /* Don't allow entering a number not in our current base */ case 0x0B: if (base >= 1) buf[n] = '0'; break; case 0x02: if (base >= 2) buf[n] = '1'; break; case 0x03: if (base >= 3) buf[n] = '2'; break; case 0x04: if (base >= 4) buf[n] = '3'; break; case 0x05: if (base >= 5) buf[n] = '4'; break; case 0x06: if (base >= 6) buf[n] = '5'; break; case 0x07: if (base >= 7) buf[n] = '6'; break; case 0x08: if (base >= 8) buf[n] = '7'; break; case 0x09: if (base >= 9) buf[n] = '8'; break; case 0x0A: if (base >= 10) buf[n] = '9'; break; case 0x1e: if (base >= 11) buf[n] = 'a'; break; case 0x30: if (base >= 12) buf[n] = 'b'; break; case 0x2e: if (base >= 13) buf[n] = 'c'; break; case 0x20: if (base >= 14) buf[n] = 'd'; break; case 0x12: if (base >= 15) buf[n] = 'e'; break; case 0x21: if (base >= 16) buf[n] = 'f'; break; default: break; } /* Don't allow anything to be entered after a suffix */ if (n > 0 && ( (buf[n-1] == 'p') || (buf[n-1] == 'g') || (buf[n-1] == 'm') || (buf[n-1] == 'k'))) { buf[n] = ' '; } /* If we have entered a character increment n */ if (buf[n] != ' ') { n++; } buf[n] = ' '; /* Print the current number */ cprint(x, y, buf); /* Find the base we are entering numbers in */ base = 10; if ((buf[0] == '0') && (buf[1] == 'x')) { base = 16; } else if (buf[0] == '0') { base = 8; } } /* Compute our current shift */ shift = 0; switch(buf[n-1]) { case 'g': /* gig */ shift = 30; break; case 'm': /* meg */ shift = 20; break; case 'p': /* page */ shift = 12; break; case 'k': /* kilo */ shift = 10; break; } shift -= result_shift; /* Compute our current value */ val = 0; for(i = (base == 16)? 2: 0; i < n; i++) { unsigned long digit = 0; if ((buf[i] >= '0') && (buf[i] <= '9')) { digit = buf[i] - '0'; } else if ((buf[i] >= 'a') && (buf[i] <= 'f')) { digit = buf[i] - 'a' + 10; } else { /* It must be a suffix byte */ break; } val = (val * base) + digit; } if (shift > 0) { if (shift >= 32) { val = 0xffffffff; } else { val <<= shift; } } else { if (-shift >= 32) { val = 0; } else { val >>= -shift; } } return val;}void ttyprint(int y, int x, const char *p){ static char sx[3]; static char sy[3]; sx[0]='\0'; sy[0]='\0'; x++; y++; itoa(sx, x); itoa(sy, y); serial_echo_print("["); serial_echo_print(sy); serial_echo_print(";"); serial_echo_print(sx); serial_echo_print("H"); serial_echo_print(p);}#if defined(SERIAL_BAUD_RATE)#if ((115200%SERIAL_BAUD_RATE) != 0)#error Bad ttys0 baud rate#endif#define SERIAL_DIV (115200/SERIAL_BAUD_RATE)#endif /* SERIAL_BAUD_RATE */void serial_echo_init(void){ int comstat, hi, lo; /* read the Divisor Latch */ comstat = serial_echo_inb(UART_LCR); serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR); hi = serial_echo_inb(UART_DLM); lo = serial_echo_inb(UART_DLL); serial_echo_outb(comstat, UART_LCR); /* now do hardwired init */ serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */#if defined(SERIAL_BAUD_RATE) serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */ serial_echo_outb(SERIAL_DIV & 0xff, UART_DLL); /* baud rate divisor */ serial_echo_outb((SERIAL_DIV>> 8) & 0xff, UART_DLM); serial_echo_outb(0x03, UART_LCR); /* Done with divisor */#endif /* Prior to disabling interrupts, read the LSR and RBR * registers */ comstat = serial_echo_inb(UART_LSR); /* COM? LSR */ comstat = serial_echo_inb(UART_RX); /* COM? RBR */ serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */ clear_screen_buf(); return;}void serial_echo_print(const char *p){ if (!serial_cons) { return; } /* Now, do each character */ while (*p) { WAIT_FOR_XMITR; /* Send the character out. */ serial_echo_outb(*p, UART_TX); if(*p==10) { WAIT_FOR_XMITR; serial_echo_outb(13, UART_TX); } p++; }}/* Except for multi-character key sequences this mapping * table is complete. So it should not need to be updated * when new keys are searched for. However the key handling * should really be turned around and only in get_key should * we worry about the exact keycode that was pressed. Everywhere * else we should switch on the character... */struct ascii_map_str ser_map[] =/*ascii keycode ascii keycode*/{ /* Special cases come first so I can leave * their "normal" mapping in the table, * without it being activated. */ { 27, 0x01}, /* ^[/ESC -> ESC */ { 127, 0x0e}, /* DEL -> BS */ { 8, 0x0e}, /* ^H/BS -> BS */ { 10, 0x1c}, /* ^L/NL -> CR */ { 13, 0x1c}, /* ^M/CR -> CR */ { 9, 0x0f}, /* ^I/TAB -> TAB */ { 19, 0x39}, /* ^S -> SP */ { 17, 28}, /* ^Q -> CR */ { ' ', 0x39}, /* SP -> SP */ { 'a', 0x1e}, { 'A', 0x1e}, { 1, 0x1e}, /* ^A -> A */ { 'b', 0x30}, { 'B', 0x30}, { 2, 0x30}, /* ^B -> B */ { 'c', 0x2e}, { 'C', 0x2e}, { 3, 0x2e}, /* ^C -> C */ { 'd', 0x20}, { 'D', 0x20}, { 4, 0x20}, /* ^D -> D */ { 'e', 0x12}, { 'E', 0x12}, { 5, 0x12}, /* ^E -> E */ { 'f', 0x21}, { 'F', 0x21}, { 6, 0x21}, /* ^F -> F */ { 'g', 0x22}, { 'G', 0x22}, { 7, 0x22}, /* ^G -> G */ { 'h', 0x23}, { 'H', 0x23}, { 8, 0x23}, /* ^H -> H */ { 'i', 0x17}, { 'I', 0x17}, { 9, 0x17}, /* ^I -> I */ { 'j', 0x24}, { 'J', 0x24}, { 10, 0x24}, /* ^J -> J */ { 'k', 0x25}, { 'K', 0x25}, { 11, 0x25}, /* ^K -> K */ { 'l', 0x26}, { 'L', 0x26}, { 12, 0x26}, /* ^L -> L */ { 'm', 0x32}, { 'M', 0x32}, { 13, 0x32}, /* ^M -> M */ { 'n', 0x31}, { 'N', 0x31}, { 14, 0x31}, /* ^N -> N */ { 'o', 0x18}, { 'O', 0x18}, { 15, 0x18}, /* ^O -> O */ { 'p', 0x19}, { 'P', 0x19}, { 16, 0x19}, /* ^P -> P */ { 'q', 0x10}, { 'Q', 0x10}, { 17, 0x10}, /* ^Q -> Q */ { 'r', 0x13}, { 'R', 0x13}, { 18, 0x13}, /* ^R -> R */ { 's', 0x1f}, { 'S', 0x1f}, { 19, 0x1f}, /* ^S -> S */ { 't', 0x14}, { 'T', 0x14}, { 20, 0x14}, /* ^T -> T */ { 'u', 0x16}, { 'U', 0x16}, { 21, 0x16}, /* ^U -> U */ { 'v', 0x2f}, { 'V', 0x2f}, { 22, 0x2f}, /* ^V -> V */ { 'w', 0x11}, { 'W', 0x11}, { 23, 0x11}, /* ^W -> W */ { 'x', 0x2d}, { 'X', 0x2d}, { 24, 0x2d}, /* ^X -> X */ { 'y', 0x15}, { 'Y', 0x15}, { 25, 0x15}, /* ^Y -> Y */ { 'z', 0x2c}, { 'Z', 0x2c}, { 26, 0x2c}, /* ^Z -> Z */ { '-', 0x0c}, { '_', 0x0c}, { 31, 0x0c}, /* ^_ -> _ */ { '=', 0x0c}, { '+', 0x0c}, { '[', 0x1a}, { '{', 0x1a}, { 27, 0x1a}, /* ^[ -> [ */ { ']', 0x1b}, { '}', 0x1b}, { 29, 0x1b}, /* ^] -> ] */ { ';', 0x27}, { ':', 0x27}, { '\'', 0x28}, { '"', 0x28}, { '`', 0x29}, { '~', 0x29}, { '\\', 0x2b}, { '|', 0x2b}, { 28, 0x2b}, /* ^\ -> \ */ { ',', 0x33}, { '<', 0x33}, { '.', 0x34}, { '>', 0x34}, { '/', 0x35}, { '?', 0x35}, { '1', 0x02}, { '!', 0x02}, { '2', 0x03}, { '@', 0x03}, { '3', 0x04}, { '#', 0x04}, { '4', 0x05}, { '$', 0x05}, { '5', 0x06}, { '%', 0x06}, { '6', 0x07}, { '^', 0x07}, { 30, 0x07}, /* ^^ -> 6 */ { '7', 0x08}, { '&', 0x08}, { '8', 0x09}, { '*', 0x09}, { '9', 0x0a}, { '(', 0x0a}, { '0', 0x0b}, { ')', 0x0b}, { 0, 0}};/* * Given an ascii character, return the keycode * * Uses ser_map definition above. * * It would be more efficient to use an array of 255 characters * and directly index into it. */int ascii_to_keycode (int in){ struct ascii_map_str *p; for (p = ser_map; p->ascii; p++) { if (in ==p->ascii) return p->keycode; } return 0;}/* * Call this when you want to wait for the user to lift the * finger off of a key. It is a noop if you are using a * serial console. */void wait_keyup( void ) { /* Check to see if someone lifted the keyboard key */ while (1) { if ((get_key() & 0x80) != 0) { return; } /* Trying to simulate waiting for a key release with * the serial port is to nasty to let live. * In particular some menus don't even display until * you release the key that caused to to get there. * With the serial port this results in double pressing * or something worse for just about every key. */ if (serial_cons) { return; } }}#ifdef LP#define DATA 0x00#define STATUS 0x01#define CONTROL 0x02#define LP_PBUSY 0x80 /* inverted input, active high */#define LP_PERRORP 0x08 /* unchanged input, active low */#define LP_PSELECP 0x08 /* inverted output, active low */#define LP_PINITP 0x04 /* unchanged output, active low */#define LP_PSTROBE 0x01 /* short high output on raising edge */#define DELAY 0x10c6ulvoid lp_wait(ulong xloops){ int d0; __asm__("mull %0" :"=d" (xloops), "=&a" (d0) :"1" (xloops),"0" (current_cpu_data.loops_per_sec)); __delay(xloops);}static void __delay(ulong loops){ int d0; __asm__ __volatile__( "\tjmp 1f\n" ".align 16\n" "1:\tjmp 2f\n" ".align 16\n" "2:\tdecl %0\n\tjns 2b" :"=&a" (d0) :"0" (loops));}put_lp(char c, short port){ unsigned char status; /* Wait for printer to be ready */ while (1) { status = inb(STATUS(port)); if (status & LP_PERRORP) { if (status & LP_PBUSY) { break; } } } outb(d, DATA(c)); lp_wait(DELAY); outb((LP_PSELECP | LP_PINITP | LP_PSTROBE), CONTROL(port)); lp_wait(DELAY); outb((LP_PSELECP | LP_PINITP), CONTROL(port)); lp_wait(DELAY);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -