📄 console.c
字号:
cons->c_row -= n;
flush(cons);
break;
case 'B': /* ESC [nB moves down n lines */
n = (value == 0 ? 1 : value);
cons->c_row += n;
flush(cons);
break;
case 'C': /* ESC [nC moves right n spaces */
n = (value == 0 ? 1 : value);
cons->c_column += n;
flush(cons);
break;
case 'D': /* ESC [nD moves left n spaces */
n = (value == 0 ? 1 : value);
cons->c_column -= n;
flush(cons);
break;
case 'H': /* ESC [m;nH" moves cursor to (m,n) */
cons->c_row = cons->c_esc_parmv[0] - 1;
cons->c_column = cons->c_esc_parmv[1] - 1;
flush(cons);
break;
case 'J': /* ESC [sJ clears in display */
switch (value) {
case 0: /* Clear from cursor to end of screen */
count = scr_size - (cons->c_cur - cons->c_org);
dst = cons->c_cur;
break;
case 1: /* Clear from start of screen to cursor */
count = cons->c_cur - cons->c_org;
dst = cons->c_org;
break;
case 2: /* Clear entire screen */
count = scr_size;
dst = cons->c_org;
break;
default: /* Do nothing */
count = 0;
dst = cons->c_org;
}
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, dst, count);
break;
case 'K': /* ESC [sK clears line from cursor */
switch (value) {
case 0: /* Clear from cursor to end of line */
count = scr_width - cons->c_column;
dst = cons->c_cur;
break;
case 1: /* Clear from beginning of line to cursor */
count = cons->c_column;
dst = cons->c_cur - cons->c_column;
break;
case 2: /* Clear entire line */
count = scr_width;
dst = cons->c_cur - cons->c_column;
break;
default: /* Do nothing */
count = 0;
dst = cons->c_cur;
}
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, dst, count);
break;
case 'L': /* ESC [nL inserts n lines at cursor */
n = value;
if (n < 1) n = 1;
if (n > (scr_lines - cons->c_row))
n = scr_lines - cons->c_row;
src = cons->c_org + cons->c_row * scr_width;
dst = src + n * scr_width;
count = (scr_lines - cons->c_row - n) * scr_width;
vid_vid_copy(src, dst, count);
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, src, n * scr_width);
break;
case 'M': /* ESC [nM deletes n lines at cursor */
n = value;
if (n < 1) n = 1;
if (n > (scr_lines - cons->c_row))
n = scr_lines - cons->c_row;
dst = cons->c_org + cons->c_row * scr_width;
src = dst + n * scr_width;
count = (scr_lines - cons->c_row - n) * scr_width;
vid_vid_copy(src, dst, count);
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, dst + count, n * scr_width);
break;
case '@': /* ESC [n@ inserts n chars at cursor */
n = value;
if (n < 1) n = 1;
if (n > (scr_width - cons->c_column))
n = scr_width - cons->c_column;
src = cons->c_cur;
dst = src + n;
count = scr_width - cons->c_column - n;
vid_vid_copy(src, dst, count);
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, src, n);
break;
case 'P': /* ESC [nP deletes n chars at cursor */
n = value;
if (n < 1) n = 1;
if (n > (scr_width - cons->c_column))
n = scr_width - cons->c_column;
dst = cons->c_cur;
src = dst + n;
count = scr_width - cons->c_column - n;
vid_vid_copy(src, dst, count);
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, dst + count, n);
break;
case 'm': /* ESC [nm enables rendition n */
switch (value) {
case 1: /* BOLD */
if (color) {
/* Can't do bold, so use yellow */
cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0E00;
} else {
/* Set intensity bit */
cons->c_attr |= 0x0800;
}
break;
case 4: /* UNDERLINE */
if (color) {
/* Use light green */
cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0A00;
} else {
cons->c_attr = (cons->c_attr & 0x8900);
}
break;
case 5: /* BLINKING */
if (color) {
/* Use magenta */
cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0500;
} else {
/* Set the blink bit */
cons->c_attr |= 0x8000;
}
break;
case 7: /* REVERSE */
if (color) {
/* Swap fg and bg colors */
cons->c_attr =
((cons->c_attr & 0xf000) >> 4) |
((cons->c_attr & 0x0f00) << 4);
} else
if ((cons->c_attr & 0x7000) == 0) {
cons->c_attr = (cons->c_attr & 0x8800) | 0x7000;
} else {
cons->c_attr = (cons->c_attr & 0x8800) | 0x0700;
}
break;
default: /* COLOR */
if (30 <= value && value <= 37) {
cons->c_attr =
(cons->c_attr & 0xf0ff) |
(ansi_colors[(value - 30)] << 8);
cons->c_blank =
(cons->c_blank & 0xf0ff) |
(ansi_colors[(value - 30)] << 8);
} else
if (40 <= value && value <= 47) {
cons->c_attr =
(cons->c_attr & 0x0fff) |
(ansi_colors[(value - 40)] << 12);
cons->c_blank =
(cons->c_blank & 0x0fff) |
(ansi_colors[(value - 40)] << 12);
} else {
cons->c_attr = cons->c_blank;
}
break;
}
break;
}
}
cons->c_esc_state = 0;
}
/*===========================================================================*
* set_6845 *
*===========================================================================*/
PRIVATE void set_6845(reg, val)
int reg; /* which register pair to set */
unsigned val; /* 16-bit value to set it to */
{
/* Set a register pair inside the 6845.
* Registers 12-13 tell the 6845 where in video ram to start
* Registers 14-15 tell the 6845 where to put the cursor
*/
lock(); /* try to stop h/w loading in-between value */
out_byte(vid_port + INDEX, reg); /* set the index register */
out_byte(vid_port + DATA, (val>>8) & BYTE); /* output high byte */
out_byte(vid_port + INDEX, reg + 1); /* again */
out_byte(vid_port + DATA, val&BYTE); /* output low byte */
unlock();
}
/*===========================================================================*
* beep *
*===========================================================================*/
PRIVATE void beep()
{
/* Making a beeping sound on the speaker (output for CRTL-G).
* This routine works by turning on the bits 0 and 1 in port B of the 8255
* chip that drive the speaker.
*/
message mess;
if (beeping) return;
out_byte(TIMER_MODE, 0xB6); /* set up timer channel 2 (square wave) */
out_byte(TIMER2, BEEP_FREQ & BYTE); /* load low-order bits of frequency */
out_byte(TIMER2, (BEEP_FREQ >> 8) & BYTE); /* now high-order bits */
lock(); /* guard PORT_B from keyboard intr handler */
out_byte(PORT_B, in_byte(PORT_B) | 3); /* turn on beep bits */
unlock();
beeping = TRUE;
mess.m_type = SET_ALARM;
mess.CLOCK_PROC_NR = TTY;
mess.DELTA_TICKS = B_TIME;
mess.FUNC_TO_CALL = (sighandler_t) stop_beep;
sendrec(CLOCK, &mess);
}
/*===========================================================================*
* stop_beep *
*===========================================================================*/
PRIVATE void stop_beep()
{
/* Turn off the beeper by turning off bits 0 and 1 in PORT_B. */
lock(); /* guard PORT_B from keyboard intr handler */
out_byte(PORT_B, in_byte(PORT_B) & ~3);
beeping = FALSE;
unlock();
}
/*===========================================================================*
* scr_init *
*===========================================================================*/
PUBLIC void scr_init(tp)
tty_t *tp;
{
/* Initialize the screen driver. */
console_t *cons;
phys_bytes vid_base;
u16_t bios_crtbase;
int line;
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);
/* Output functions. */
tp->tty_devwrite = cons_write;
tp->tty_echo = cons_echo;
/* Get the BIOS parameters that tells the VDU I/O base register. */
phys_copy(0x463L, vir2phys(&bios_crtbase), 2L);
vid_port = bios_crtbase;
if (color) {
vid_base = COLOR_BASE;
vid_size = COLOR_SIZE;
} else {
vid_base = MONO_BASE;
vid_size = MONO_SIZE;
}
if (ega) vid_size = EGA_SIZE;
wrap = !ega;
vid_seg = protected_mode ? VIDEO_SELECTOR : physb_to_hclick(vid_base);
init_dataseg(&gdt[VIDEO_INDEX], vid_base, (phys_bytes) vid_size,
TASK_PRIVILEGE);
vid_size >>= 1; /* word count */
vid_mask = vid_size - 1;
/* 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_org = cons->c_start;
cons->c_attr = cons->c_blank = BLANK_COLOR;
/* Clear the screen. */
blank_color = BLANK_COLOR;
mem_vid_copy(BLANK_MEM, cons->c_start, scr_size);
select_console(0);
}
/*===========================================================================*
* putk *
*===========================================================================*/
PUBLIC void putk(c)
int c; /* character to print */
{
/* This procedure is used by the version of printf() that is linked with
* the kernel itself. The one in the library sends a message to FS, which is
* not what is needed for printing within the kernel. This version just queues
* the character and starts the output.
*/
if (c != 0) {
if (c == '\n') 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(current);
}
/*===========================================================================*
* 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;
current = 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(user_phys)
phys_bytes user_phys;
{
/* Load a font into the EGA or VGA adapter. */
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 (!ega) return(ENOTTY);
lock();
ga_program(seq1); /* bring font memory into view */
phys_copy(user_phys, (phys_bytes)GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);
ga_program(seq2); /* restore */
unlock();
return(OK);
}
/*===========================================================================*
* ga_program *
*===========================================================================*/
PRIVATE void ga_program(seq)
struct sequence *seq;
{
int len= 7;
do {
out_byte(seq->index, seq->port);
out_byte(seq->index+1, seq->value);
seq++;
} while (--len > 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -