⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 consolestream.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* * 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. *//* This is a (poor) implementation of a text-mode kernel frame buffer * for use in diagnostics and debugger output. It assumes that the * display has been left in the standard VGA text mode by the * bootstrap code. */#include <kerninc/kernel.hxx>#include <kerninc/KernStream.hxx>#include <kerninc/Machine.hxx>#include <kerninc/IRQ.hxx>#include <kerninc/util.h>#include <eros/i486/io.h>#include <eros/i486/fixregs.h>#include "IDT.hxx"#define SCREEN_START PTOV(0xb8000u)#define SCREEN_ROWS 25#define SCREEN_COLS 80#define SCREEN_END (SCREEN_START + 2*SCREEN_COLS*SCREEN_ROWS)/* This class has a singleton instance! */struct ConsoleStream: public KernStream {  void Init();  void Put(uint8_t c);#ifdef OPTION_DDB  uint8_t Get();  void SetDebugging(bool onoff);  void EnableDebuggerInput();#endif};struct ConsoleStream TheConsoleStream;KernStream* KernStream::ConsoleStream = &TheConsoleStream;static void ClearTextConsole();static unsigned long offset;  static uint32_t StartAddressReg = 0;	/* as seen by the display hardware */static uint16_t *screen = (uint16_t *) SCREEN_START;voidConsoleStream::Init(){  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;  offset = 0;  ClearTextConsole();}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,};static voidSetPosition(uint32_t pos, uint8_t c){  uint16_t vgaAttrs = WhiteOnBlack << 8;  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 voidClearTextConsole(){  for (uint32_t wpos = 0; wpos < SCREEN_ROWS * SCREEN_COLS; wpos++)    SetPosition(wpos, ' ');}static void Beep() {}/* FIX: This is NOT RIGHT!! */voidConsoleStream::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);    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, ' ');	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;}/************************************************************************* * * EVERYTHING FROM HERE DOWN IS KEYBOARD DRIVER!!!! * * The keyboard logic is enabled only if the debugger is running on * the console. * *************************************************************************/#if defined(OPTION_DDB_ON_CONSOLE)const uint8_t KbdDataPort    = 0x60u;const uint8_t KbdCtrlPort   = 0x64u;const uint8_t KbdStatusPort = 0x64u;struct KeyCmd {  enum {    SetLed = 0xedu,  } ;};struct KbdStatus {  enum {    BufFull = 0x1,    Ready   = 0x2,  };};struct KeyMod {  enum {    /* Note that the first three values correspond to the bitmask for the     * keyboard LED's -- this is not an accident!     */    ScrlLock  = 0x01u,    NumLock   = 0x02u,    AlphaLock = 0x04u,    Shift     = 0x10u,    Ctrl      = 0x20u,    Alt       = 0x40u,    Extended  = 0x100u,		/* key is an "extended" key */    IsAlpha   = 0x200u,		/* key is modified by alpha lock key */    IsPad     = 0x400u,		/* key is modified by num lock key */    Meta      = 0x800u,		/* key can be meta'd */  } ;};static uint32_t ShiftState = 0;/* kbd_wait -- wait for a character to be available from the keyboard. */static void KbdWait(void){  int i = 100;  while (i--) {    if ((inb(KbdStatusPort) & KbdStatus::Ready) == 0)       break;    Machine::SpinWaitUs(10);  }#if 0  printf("KbdWait fails\n");#endif}static void KbdCmd(uint8_t command){  int retry = 5;  do {    int i = 100000;    KbdWait();    old_outb(KbdDataPort, command);    while (i--) {      if (inb(KbdStatusPort) & KbdStatus::BufFull) {	int val;	/* DELAY(10); */	val = inb(KbdDataPort);	if (val == 0xfa)	  return;	if (val == 0xfe)	  break;      }    }  } while (retry--);  printf("KbdCmd fails\n");}static boolReadKbd(uint8_t& c){  KbdWait();  while ( (inb(KbdStatusPort) & KbdStatus::BufFull) == 0 )    return false;    c = inb(KbdDataPort);  return true;}static voidUpdateKbdLeds(){  KbdCmd(KeyCmd::SetLed);  KbdCmd(ShiftState & 0x7u);}	       /* Keyboard interpretation proceeds in two phases.  First, the scan * code is converted into a virtual key code, performing any necessary * keyboard escape translation.  Then the key code translation table * is consulted to decide what character to return and whether to * update the shift state (if at all). */#define NOP 256#define NOCHAR(name) {{ NOP, NOP, NOP, NOP },   0 }#define ALPHA(X) {{ X+32, X, X - 64, X - 64 }, KeyMod::Meta|KeyMod::IsAlpha }#define KEY(X, Y) {{ X, Y, X, Y },   KeyMod::Meta }#define PAD(X, Y) {{ X, Y, X, Y },   KeyMod::IsPad }#define F(X) (X + 256)const uint32_t num_scan = 0x59;struct KeyInfo {  uint16_t value[4];		/* base, shift, ctrl, shift-ctrl */  uint16_t flags;} key_table[num_scan] = {  NOCHAR(None),			/* 0x00 */  KEY('\027', '\027'),		/* 0x01 */  KEY('1', '!'),		/* 0x02 */  { { '2', '@', '\0', '\0'}, 0 }, /* 0x03 -- generate NUL */  KEY('3', '#'),		/* 0x04 */  KEY('4', '$'),		/* 0x05 */  KEY('5', '%'),		/* 0x06 */  KEY('6', '^'),		/* 0x07 */  KEY('7', '&'),		/* 0x08 */  KEY('8', '*'),		/* 0x09 */  KEY('9', '('),		/* 0x0a */  KEY('0', ')'),		/* 0x0b */  KEY('-',  '_'),		/* 0x0c */  KEY('=',  '+'),		/* 0x0d */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -