📄 console.c
字号:
}}/*===========================================================================* * stop_beep * *===========================================================================*/PRIVATE void stop_beep(tmrp)timer_t *tmrp;{/* Turn off the beeper by turning off bits 0 and 1 in PORT_B. */ int port_b_val; if (sys_inb(PORT_B, &port_b_val)==OK && sys_outb(PORT_B, (port_b_val & ~3))==OK) beeping = FALSE;}/*===========================================================================* * scr_init * *===========================================================================*/PUBLIC void scr_init(tp)tty_t *tp;{/* Initialize the screen driver. */ console_t *cons; phys_bytes vid_base; u16_t bios_columns, bios_crtbase, bios_fontlines; u8_t bios_rows; int line; int s; static int vdu_initialized = 0; unsigned page_size; /* Associate console and TTY. */ line = tp - &tty_table[0]; if (line >= nr_cons) return; cons = &cons_table[line]; cons->c_tty = tp; tp->tty_priv = cons; /* Initialize the keyboard driver. */ kb_init(tp); /* Fill in TTY function hooks. */ tp->tty_devwrite = cons_write; tp->tty_echo = cons_echo; tp->tty_ioctl = cons_ioctl; /* Get the BIOS parameters that describe the VDU. */ if (! vdu_initialized++) { /* How about error checking? What to do on failure??? */ s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_SCREEN_COLS_ADDR, SELF, D, (vir_bytes) &bios_columns, VDU_SCREEN_COLS_SIZE); s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_CRT_BASE_ADDR, SELF, D, (vir_bytes) &bios_crtbase, VDU_CRT_BASE_SIZE); s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_SCREEN_ROWS_ADDR, SELF, D, (vir_bytes) &bios_rows, VDU_SCREEN_ROWS_SIZE); s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_FONTLINES_ADDR, SELF, D, (vir_bytes) &bios_fontlines, VDU_FONTLINES_SIZE); vid_port = bios_crtbase; scr_width = bios_columns; font_lines = bios_fontlines; scr_lines = machine.vdu_ega ? bios_rows+1 : 25; if (color) { vid_base = COLOR_BASE; vid_size = COLOR_SIZE; } else { vid_base = MONO_BASE; vid_size = MONO_SIZE; } if (machine.vdu_ega) vid_size = EGA_SIZE; wrap = ! machine.vdu_ega; s = sys_segctl(&vid_index, &vid_seg, &vid_off, vid_base, vid_size); vid_size >>= 1; /* word count */ vid_mask = vid_size - 1; /* Size of the screen (number of displayed characters.) */ scr_size = scr_lines * scr_width; /* There can be as many consoles as video memory allows. */ nr_cons = vid_size / scr_size; if (nr_cons > NR_CONS) nr_cons = NR_CONS; if (nr_cons > 1) wrap = 0; page_size = vid_size / nr_cons; } cons->c_start = line * page_size; cons->c_limit = cons->c_start + page_size; cons->c_cur = cons->c_org = cons->c_start; cons->c_attr = cons->c_blank = BLANK_COLOR; if (line != 0) { /* Clear the non-console vtys. */ blank_color = BLANK_COLOR; mem_vid_copy(BLANK_MEM, cons->c_start, scr_size); } else { int i, n; /* Set the cursor of the console vty at the bottom. c_cur * is updated automatically later. */ scroll_screen(cons, SCROLL_UP); cons->c_row = scr_lines - 1; cons->c_column = 0; } select_console(0); cons_ioctl(tp, 0);}/*===========================================================================* * kputc * *===========================================================================*/PUBLIC void kputc(c)int c;{#if 0 cons_putk(c);#else/* Accumulate a single character for a kernel message. Send a notification * the to output driver if an END_OF_KMESS is encountered. */ if (c != 0) { kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */ if (kmess.km_size < KMESS_BUF_SIZE) kmess.km_size += 1; kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE; } else { notify(LOG_PROC_NR); }#endif}/*===========================================================================* * do_new_kmess * *===========================================================================*/PUBLIC void do_new_kmess(m)message *m;{/* Notification for a new kernel message. */ struct kmessages kmess; /* kmessages structure */ static int prev_next = 0; /* previous next seen */ int size, next; int bytes; int r; /* Try to get a fresh copy of the buffer with kernel messages. */#if DEAD_CODE /* During shutdown, the reply is garbled because new notifications arrive * while the system task makes a copy of the kernel messages buffer. * Hence, don't check the return value. */ if ((r=sys_getkmessages(&kmess)) != OK) { printf("TTY: couldn't get copy of kmessages: %d, 0x%x\n", r,r); return; }#endif sys_getkmessages(&kmess); /* Print only the new part. Determine how many new bytes there are with * help of the current and previous 'next' index. Note that the kernel * buffer is circular. This works fine if less then KMESS_BUF_SIZE bytes * is new data; else we miss % KMESS_BUF_SIZE here. * Check for size being positive, the buffer might as well be emptied! */ if (kmess.km_size > 0) { bytes = ((kmess.km_next + KMESS_BUF_SIZE) - prev_next) % KMESS_BUF_SIZE; r=prev_next; /* start at previous old */ while (bytes > 0) { cons_putk( kmess.km_buf[(r%KMESS_BUF_SIZE)] ); bytes --; r ++; } cons_putk(0); /* terminate to flush output */ } /* Almost done, store 'next' so that we can determine what part of the * kernel messages buffer to print next time a notification arrives. */ prev_next = kmess.km_next;}/*===========================================================================* * do_diagnostics * *===========================================================================*/PUBLIC void do_diagnostics(m_ptr)message *m_ptr; /* pointer to request message */{/* Print a string for a server. */ char c; vir_bytes src; int count; int result = OK; int proc_nr = m_ptr->DIAG_PROC_NR; if (proc_nr == SELF) proc_nr = m_ptr->m_source; src = (vir_bytes) m_ptr->DIAG_PRINT_BUF; for (count = m_ptr->DIAG_BUF_COUNT; count > 0; count--) { if (sys_vircopy(proc_nr, D, src++, SELF, D, (vir_bytes) &c, 1) != OK) { result = EFAULT; break; } cons_putk(c); } cons_putk(0); /* always terminate, even with EFAULT */ m_ptr->m_type = result; send(m_ptr->m_source, m_ptr);}/*===========================================================================* * do_get_kmess * *===========================================================================*/PUBLIC void do_get_kmess(m_ptr)message *m_ptr; /* pointer to request message */{/* Provide the log device with debug output */ vir_bytes dst; int r; dst = (vir_bytes) m_ptr->GETKM_PTR; r= OK; if (sys_vircopy(SELF, D, (vir_bytes)&kmess, m_ptr->m_source, D, dst, sizeof(kmess)) != OK) { r = EFAULT; } m_ptr->m_type = r; send(m_ptr->m_source, m_ptr);}/*===========================================================================* * cons_putk * *===========================================================================*/PRIVATE void cons_putk(c)int c; /* character to print */{/* This procedure is used to print a character on the console. */ if (c != 0) { if (c == '\n') cons_putk('\r'); out_char(&cons_table[0], (int) c); } else { flush(&cons_table[0]); }}/*===========================================================================* * toggle_scroll * *===========================================================================*/PUBLIC void toggle_scroll(){/* Toggle between hardware and software scroll. */ cons_org0(); softscroll = !softscroll; printf("%sware scrolling enabled.\n", softscroll ? "Soft" : "Hard");}/*===========================================================================* * cons_stop * *===========================================================================*/PUBLIC void cons_stop(){/* Prepare for halt or reboot. */ cons_org0(); softscroll = 1; select_console(0); cons_table[0].c_attr = cons_table[0].c_blank = BLANK_COLOR;}/*===========================================================================* * cons_org0 * *===========================================================================*/PRIVATE void cons_org0(){/* Scroll video memory back to put the origin at 0. */ int cons_line; console_t *cons; unsigned n; for (cons_line = 0; cons_line < nr_cons; cons_line++) { cons = &cons_table[cons_line]; while (cons->c_org > cons->c_start) { n = vid_size - scr_size; /* amount of unused memory */ if (n > cons->c_org - cons->c_start) n = cons->c_org - cons->c_start; vid_vid_copy(cons->c_org, cons->c_org - n, scr_size); cons->c_org -= n; } flush(cons); } select_console(ccurrent);}/*===========================================================================* * select_console * *===========================================================================*/PUBLIC void select_console(int cons_line){/* Set the current console to console number 'cons_line'. */ if (cons_line < 0 || cons_line >= nr_cons) return; ccurrent = cons_line; curcons = &cons_table[cons_line]; set_6845(VID_ORG, curcons->c_org); set_6845(CURSOR, curcons->c_cur);}/*===========================================================================* * con_loadfont * *===========================================================================*/PUBLIC int con_loadfont(m)message *m;{/* Load a font into the EGA or VGA adapter. */ int result; static struct sequence seq1[7] = { { GA_SEQUENCER_INDEX, 0x00, 0x01 }, { GA_SEQUENCER_INDEX, 0x02, 0x04 }, { GA_SEQUENCER_INDEX, 0x04, 0x07 }, { GA_SEQUENCER_INDEX, 0x00, 0x03 }, { GA_GRAPHICS_INDEX, 0x04, 0x02 }, { GA_GRAPHICS_INDEX, 0x05, 0x00 }, { GA_GRAPHICS_INDEX, 0x06, 0x00 }, }; static struct sequence seq2[7] = { { GA_SEQUENCER_INDEX, 0x00, 0x01 }, { GA_SEQUENCER_INDEX, 0x02, 0x03 }, { GA_SEQUENCER_INDEX, 0x04, 0x03 }, { GA_SEQUENCER_INDEX, 0x00, 0x03 }, { GA_GRAPHICS_INDEX, 0x04, 0x00 }, { GA_GRAPHICS_INDEX, 0x05, 0x10 }, { GA_GRAPHICS_INDEX, 0x06, 0 }, }; seq2[6].value= color ? 0x0E : 0x0A; if (!machine.vdu_ega) return(ENOTTY); result = ga_program(seq1); /* bring font memory into view */ result = sys_physcopy(m->PROC_NR, D, (vir_bytes) m->ADDRESS, NONE, PHYS_SEG, (phys_bytes) GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE); result = ga_program(seq2); /* restore */ return(result);}/*===========================================================================* * ga_program * *===========================================================================*/PRIVATE int ga_program(seq)struct sequence *seq;{ pvb_pair_t char_out[14]; int i; for (i=0; i<7; i++) { pv_set(char_out[2*i], seq->index, seq->port); pv_set(char_out[2*i+1], seq->index+1, seq->value); seq++; } return sys_voutb(char_out, 14);}/*===========================================================================* * cons_ioctl * *===========================================================================*/PRIVATE int cons_ioctl(tp, try)tty_t *tp;int try;{/* Set the screen dimensions. */ tp->tty_winsize.ws_row= scr_lines; tp->tty_winsize.ws_col= scr_width; tp->tty_winsize.ws_xpixel= scr_width * 8; tp->tty_winsize.ws_ypixel= scr_lines * font_lines;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -