📄 cons_textmode.cxx
字号:
/* * Copyright (C) 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* Implementation of the kernel frame buffer console logic. We make * the simplifying assumption here that the console is a VGA * (640x480x256) display. If the machine-specific initialization code * has somehow placed the display buffer in some other state (e.g. we * have a large VESA display or some such), then it is the * responsibility of the machine-specific code to suitably place a * 640x480 bitmap somewhere on the tube. Remember that this console * isn't going to get used for very long -- only until the user-mode * console driver takes over the world. */#include <kerninc/kernel.hxx>#include <kerninc/Console.hxx>#include <kerninc/MsgLog.hxx>#include <eros/i486/io.h>#define SCREEN_START PTOV(0xb8000u)#define SCREEN_ROWS 25#define SCREEN_COLS 80#define SCREEN_END (SCREEN_START + 2*SCREEN_COLS*SCREEN_ROWS)/* The implementation of the console frame buffer is inherently * video card specific... */struct ConsTextMode: public Console { void Clear(); void Put(uint8_t c); void SetFrameBuffer(kva_t);};ConsTextMode TheConsTextMode;static uint32_t StartAddressReg = 0; /* as seen by the display hardware */static uint16_t *screen = (uint16_t *) SCREEN_START;enum AsciiChars { Space = 0x20,}; enum VGAColors { Black = 0, Blue = 1, Green = 2, Cyan = 3, Red = 4, Magenta = 5, Brown = 6, White = 7, Gray = 8, LightBlue = 9, LightGreen = 10, LightCyan = 11, LightRed = 12, LightMagenta = 13, LightBrown = 14, /* yellow */ BrightWhite = 15, /* Combinations used by the console driver: */ WhiteOnBlack = 0x7, blank = 0,};boolConsole::InitTextMode(){ outb(0xc, 0x3d4); /* start address hi register addr */ uint8_t hi = inb(0x3d5); outb(0xd, 0x3d4); /* start address lo register addr */ uint8_t lo = inb(0x3d5); StartAddressReg = hi << 8 | lo; TheConsTextMode.offset = 0; TheConsTextMode.Clear(); MsgLog::RegisterSink(&TheConsTextMode); return true;}static voidSetPosition(uint32_t pos, uint8_t c, Attr::Type attr){ uint16_t vgaAttrs = WhiteOnBlack << 8; switch (attr) { default: break; } screen[pos] = ((uint16_t) c) | vgaAttrs;}static voidShowCursorAt(uint32_t pos){ uint32_t cursAddr = (uint32_t) pos; cursAddr += StartAddressReg; outb(0xE, 0x3D4); outb((cursAddr >> 8) & 0xFFu, 0x3D5); outb(0xF, 0x3D4); outb((cursAddr & 0xFFu), 0x3D5);}static voidScroll(uint32_t startPos, uint32_t endPos, int amount){ if (amount > 0) { uint32_t gap = amount; for (uint32_t p = startPos + gap; p < endPos; p++) screen[p] = screen[p - gap]; for (uint32_t p = startPos; p < startPos + gap; p++) screen[p] = (WhiteOnBlack << 8); } else { uint32_t gap = -amount; for (uint32_t p = startPos; p < endPos - gap; p++) screen[p] = screen[p + gap]; for (uint32_t p = endPos - gap; p < endPos; p++) screen[p] = (WhiteOnBlack << 8); }}static void Beep() {}/* FIX: This is NOT RIGHT!! */voidConsTextMode::Put(uint8_t c){ const unsigned cols = SCREEN_COLS; const unsigned rows = SCREEN_ROWS; const int TABSTOP = 8; uint32_t posCol = offset % cols; /* On newline, clear to EOL: */ if (c == ASCII::CR) if (offset % cols) Scroll (offset, offset + (cols - posCol), (cols - posCol)); if (IsPrint(c)) { SetPosition(offset, c, Attr::Normal); offset++; } else { /* Handle the non-printing characters: */ switch(c) { case ASCII::BEL: Beep(); break; case ASCII::BS: /* backspace is NONDESTRUCTIVE */ if ( offset % cols ) offset--; break; case ASCII::TAB: /* NONDESTRUCTIVE until we know how */ while (offset % TABSTOP) { SetPosition(offset, ' ', Attr::Normal); offset++; } break; case ASCII::LF: offset += cols; break; case ASCII::VT: /* reverse line feed */ if (offset > cols) offset -= cols; break;#if 0 case ASCII::FF: /* reverse line feed */ offset = 0; ClearScreen(); break;#endif case ASCII::CR: offset -= (offset % cols); break; } } if (offset >= rows * cols) { Scroll(0, rows * cols, - (int) cols); offset -= cols; } assert (offset < rows * cols); ShowCursorAt(offset); return;}voidConsTextMode::Clear(){ for (uint32_t wpos = 0; wpos < SCREEN_ROWS * SCREEN_COLS; wpos++) SetPosition(wpos, ' ', Attr::Normal);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -