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

📄 cons_vesa.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
字号:
/* * Copyright (C) 2001, Jonathan S. Shapiro, Michael Hilsdale. * * 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 <disk/DiskKey.hxx>#include <kerninc/BootInfo.h>#include <kerninc/Machine.hxx>#include "oslogo.h"#include "logosm.h"#define cursor() if(TheConsVESA.curOn) Put(TheConsVESA.cursor, col, row, true)#ifdef OLD_SCREEN/*1024x768x32 = VMware mode 0x4022*/#define XRES 1024#define YRES 768#define BPP  32#define BPSL 6400#define BASE 0x40151C80;static uint8_t *screen = (uint8_t *) PTOV(0xA0000u);#define PIX(x, y, c) (*((uint32_t *) (screen + ((uint32_t) (y) * TheConsVESA.bpsl + (x) * ((TheConsVESA.bpp + 7) / 8)))) = c)#else#define PIX(x, y, c) (*((uint32_t *) (Machine::frameBuffer + ((uint32_t) (y) * TheConsVESA.bpsl + (x) * ((TheConsVESA.bpp + 7) / 8)))) = c)#define XORPIX(x, y, c) (*((uint32_t *) (Machine::frameBuffer + ((uint32_t) (y) * TheConsVESA.bpsl + (x) * ((TheConsVESA.bpp + 7) / 8)))) ^= c)#endifvoid drawHeader();void drawLogo(const uint16_t x, const uint16_t y);void drawLogo2(const uint16_t x, const uint16_t y);void animate();void putPixel(const uint16_t x, const uint16_t y, const uint32_t color);/*#define STABLE_CONFIG*/struct ConsVESA: public Console{  /* screen information */  uint16_t xres;  uint16_t yres;  uint16_t bpp;  uint16_t bpsl;  /*uint16_t base;*/  /* 1-based indexing */  uint8_t col;  uint8_t row;  /* screen borders */  /* (not hard-coding them allows future flexibility) */  uint16_t baseCol;  uint16_t baseRow;  uint16_t maxCol;  uint16_t maxRow;   /* fb type */  uint8_t linfb;  /* 0 = windowed; 1 = linear */  /* cursor info */  uint8_t curOn;  /* 0 = cursor off; 1 = cursor on */  uint8_t cursor; /* ASCII char of cursor */  void Clear();  void Put(uint8_t c);  void Put(uint8_t c, uint16_t c, uint16_t r, bool xor = false);  void SetFrameBuffer(kva_t);  void Scroll();  /* FIX: Make toggle separate from glyph change */  void SetCursor(uint8_t toggle, int16_t c = -1);  int16_t GetCursor();};ConsVESA TheConsVESA;  /* common cursors:     1   smiley     95  underscore      177 hash     255 custom  */struct cursor {  enum {    smiley = 1,    underscore = 95,    /*    hash = 177, */    block = 219,    custom = 255,    kangaroo = 255,  };};boolConsole::InitVESA(){#ifdef OPTION_VESA_CONSOLE  /* hack: make logos work correctly */  /* Gimp macro resets the header_data pointers each time it uses it. */  /* Thus, pointer needs to be reset each time the logo is redrawn. */  orig_header_data = header_data;  orig_header_data2 = header_data2;  if (!BootInfoPtr->useGraphicsFB)      return false;  if (BootInfoPtr->consInfo->isBanked)    {      TheConsVESA.linfb = 0;      return false; /* temporary; might even need to remove for debug */    }  else    TheConsVESA.linfb = 1;  /* set cursor information */  TheConsVESA.SetCursor(1, cursor::block);  /* set the screen parameters */#ifdef OLD_SCREEN  screen = (unsigned char *) TheConsVESA.base;#else  Machine::frameBuffer = BootInfoPtr->consInfo->frameBuffer;  TheConsVESA.xres = BootInfoPtr->consInfo->Xlimit;  TheConsVESA.yres = BootInfoPtr->consInfo->Ylimit;  TheConsVESA.bpp = BootInfoPtr->consInfo->bpp;  TheConsVESA.bpsl = BootInfoPtr->consInfo->bytesPerScanLine;#endif  TheConsVESA.baseCol = 1;  TheConsVESA.baseRow = 1;  TheConsVESA.maxCol = TheConsVESA.xres/8;  TheConsVESA.maxRow = TheConsVESA.yres/16;  TheConsVESA.col = TheConsVESA.baseCol;  TheConsVESA.row = TheConsVESA.baseRow;  TheConsVESA.Clear();  drawHeader();#if 0  {    unsigned a;    /* run through the entire font */    for (a = 0; a < 0xff; a++) {      TheConsVESA.Put(a);    }  }#endif  MsgLog::RegisterSink(&TheConsVESA);  /*MsgLog::printf("baseCol: %d\n",TheConsVESA.baseCol);  MsgLog::printf("baseRow: %d\n",TheConsVESA.baseRow);  MsgLog::printf("maxCol : %d\n",TheConsVESA.maxCol);  MsgLog::printf("maxRow : %d\n",TheConsVESA.maxRow);*/  return true;#else  return false;#endif}voidConsVESA::Put(uint8_t c){  int16_t oldCursor = GetCursor();  /* Erase cursor */  if(TheConsVESA.curOn)    cursor();  /* special handling for LF so that CR LF doesn't     overwrite first char of previous line with cursor */  if(c==ASCII::LF) /* LF */    {      if(row==TheConsVESA.maxRow)	Scroll();      else	row++;      TheConsVESA.SetCursor(1, cursor::kangaroo);      cursor();      return;    }  /* Until otherwise proven: */  TheConsVESA.SetCursor(1, cursor::block);  /* Handle special chars here */  switch(c)    {    case ASCII::NUL:  /* NUL */      TheConsVESA.SetCursor(1, oldCursor);      cursor();      return;    case ASCII::BEL:  /* BEL */      /* TODO: handle BEL */      TheConsVESA.SetCursor(1, oldCursor);      cursor();      return;    case ASCII::BS:  /* BS */      if (col != TheConsVESA.baseCol)	col--; /* we're not going to jump up lines  */      /* Wrongo, moose breath. Backspace impacts the cursor. Only. */#if 0      Put(ASCII::SPC, col, row); /* needed in case cursor is disabled */#endif      cursor();      return;    case ASCII::TAB:  /* HT */      col += 5;      if(col > TheConsVESA.maxCol)	{	  col -= TheConsVESA.maxCol;	  if(row==TheConsVESA.maxRow)	    Scroll();	  else	    row++;	}      TheConsVESA.SetCursor(1, oldCursor);      cursor();      return;#if 0    case ASCII::SPC:      {	if (TheConsVESA.GetCursor() == cursor::kangaroo && !(col % 8))	  c = '.';		/* kangaroo turds :-) */	break;      }#endif    case ASCII::CR: /* CR */      col = TheConsVESA.baseCol;      cursor();      return;#if 0    case 255: /* why the heck is ASCII 255 a space?  You are the weakest link...goodbye. (tm) */      cursor();      return;#endif    default:      if(c < 32 || c > 255) /* should probably not keep this in code */	{	  TheConsVESA.SetCursor(1, oldCursor);	  cursor();	  return;	}    }  /* Draw the actual character */  Put(c, col, row);  /* Increment cursor position */  col++;  /* col should never be > (TheConsVESA.maxCol + 1) at this point */  if(col == TheConsVESA.maxCol+1)    {      col = TheConsVESA.baseCol;      if(row==TheConsVESA.maxRow)	Scroll();      else	row++;    }  /* Print cursor */  TheConsVESA.SetCursor(1, oldCursor);  cursor();}voidConsVESA::Put(uint8_t c, uint16_t cl, uint16_t rw, bool xor){  uint16_t i, j;  uint16_t x, y;  signed long int l;  if(cl < TheConsVESA.baseCol || cl > TheConsVESA.maxCol ||     rw < TheConsVESA.baseRow || rw > TheConsVESA.maxRow)    return; /* out of bounds */  /* remember that cl & rw use 1-based indexing */  x = (cl - 1) * 8;  y = (rw - 1) * 16;  for (i = 0; i < 16; i++)    {      for (j = 0; j < 8; j++)	{	  l = (uint8_t) console_font[c * 16 + i];	  l <<= 24 + j;	  signed pixcolor = (l >> 31);#if 1	  if (c == GetCursor()) {	    unsigned red = ~0u;	    red <<= BootInfoPtr->consInfo->redMask;	    red = ~red;		/* correct low bits now 1 */	    red <<= BootInfoPtr->consInfo->redShift;	    pixcolor = pixcolor ? red : 0;	  }#endif#ifdef STABLE_CONFIG	  if (xor)	    XORPIX(x, y, (unsigned) pixcolor);	  else	    PIX(x, y, (unsigned) pixcolor);#else	  if(xor)	    /*FIXME*/;	  else	    putPixel(x, y, (unsigned) pixcolor);#endif	  /* Color Alternatives: */	  /* grey font: */	  /* PIX(x, y, (unsigned) ((l>>31) == 0 ? 0 : 0xc0c0c0)); */	  /* black on white: */	  /* PIX(x, y, (unsigned) ~(l>>31)); */	  x++;	}      x = (cl - 1) * 8;      y++;    }}voidConsVESA::Clear(){  bzero((char *) Machine::frameBuffer, TheConsVESA.bpsl*TheConsVESA.yres);  cursor();#if 0  uint16_t i;  /* This is screamingly inefficient... */  TheConsVESA.SetCursor(0);  col = TheConsVESA.baseCol;  row = TheConsVESA.baseRow;  /* TODO: should probably use memcopy instead */  for (i = 0; i < (TheConsVESA.maxRow * TheConsVESA.maxCol); i++)    {      Put(32); /* automatically increments col & row appropriately */    }  col = TheConsVESA.baseCol;  row = TheConsVESA.baseRow;  TheConsVESA.SetCursor(1);#endif}voidvideo_bcopy(const void *src, void *dest, size_t len){  uint8_t *pdest = (uint8_t *) dest;  const uint8_t *psrc = (uint8_t *) src;  while (len--)    *pdest++ = *psrc++;}voidConsVESA::Scroll(){  /* Scroll display down one line */  uint16_t a;  a=a;  if(linfb)    goto lin;  else    goto win; lin:  /* #define video_bcopy bcopy */  /* scroll up */  video_bcopy((const char *) Machine::frameBuffer + bpsl*16 + (baseRow-1)*bpsl*16,	      (char *)       Machine::frameBuffer + (baseRow-1)*bpsl*16,	      bpsl*16*(maxRow-baseRow));  /* erase last line */  bzero((char *) Machine::frameBuffer + bpsl*16*(maxRow-1),bpsl*16);  return;#if 0  /* inefficient; should zero memory instead */  for(a = 1; a<=maxCol; a++)    {      Put(ASCII::SPC, a, maxRow);    }  return;#endif win:  return;}voidConsVESA::SetCursor(uint8_t toggle, int16_t c = -1){  if(toggle)    TheConsVESA.curOn = 1;  else    TheConsVESA.curOn = 0;  if(c!= -1)    TheConsVESA.cursor = (uint8_t) c;}int16_tConsVESA::GetCursor(){  return TheConsVESA.cursor;}voiddrawHeader(){#if 0  /* Issue: cute, but..., well, cute at least. */  animate();#endif  drawLogo(0,0);  drawLogo2(TheConsVESA.xres-width2,TheConsVESA.yres-height2);  /* Define new scren margins */  TheConsVESA.baseRow = height/16 + 2;  TheConsVESA.maxRow  -= height2/16 +1;  /* Do I really need any of the following lines? */  /*TheConsVESA.row += TheConsVESA.baseRow - 1;    TheConsVESA.row = TheConsVESA.baseRow;*/}voidredrawLogos(){  drawLogo(0,0);  drawLogo2(TheConsVESA.xres-width2,0);}voiddrawLogo(const uint16_t x, const uint16_t y){  uint16_t lx, ly;  uint8_t p[3];  header_data = orig_header_data;  for(ly = y; ly < (height + y); ly++)    {      for(lx = x; lx < (width + x); lx++)	{	  HEADER_PIXEL(header_data, p);	  PIX(lx, ly, ((p[0] << 16) + (p[1] << 8) + (p[2]))); /* R+G+B */	}    }}voiddrawLogo2(const uint16_t x, const uint16_t y){  uint16_t lx, ly;  uint8_t p[3];  header_data2 = orig_header_data2;  for(ly = y; ly < (height2 + y); ly++)    {      for(lx = x; lx < (width2 + x); lx++)	{	  HEADER_PIXEL2(header_data2, p);	  PIX(lx, ly, ((p[0] << 16) + (p[1] << 8) + (p[2]))); /* R+G+B */	}    }}voidanimate(){  uint16_t x, y;  uint16_t i, j;  /* left -> right */  for (x = 0; x <= TheConsVESA.xres - width; x++)    {      drawLogo(x,0);      if(x!=0)	{	  for(j = 0; j < height; j++)	    {	      PIX(x-1, j, (uint32_t) 0);	    }	}    }  /* top -> bottom */  for (y = 0; y <= TheConsVESA.yres - height; y++)    {      drawLogo(TheConsVESA.xres-width,y);      if(y!=0)	{	  for(i = 0; i < width; i++)	    {	      PIX(i+(TheConsVESA.xres-width), y-1, (uint32_t) 0);	    }	}    }  /* right -> left */  for (x = 0; x <= TheConsVESA.xres - width; x++)    {      drawLogo(TheConsVESA.xres-width-x,TheConsVESA.yres-height);      if(x!=0)	{	  for(j = 0; j < height; j++)	    {	      PIX(TheConsVESA.xres-(x), j+(TheConsVESA.yres-height), (uint32_t) 0);	    }	}    }  /* bottom -> top */  for (y = 0; y <= TheConsVESA.yres - height; y++)    {      drawLogo(0,TheConsVESA.yres-height-y);      if(y!=0)	{	  for(i = 0; i < width; i++)	    {	      PIX(i, TheConsVESA.yres-(y), (uint32_t) 0);	    }	}    }}void putPixel(const uint16_t x, const uint16_t y, const uint32_t color){  /* Issue: if bits per pixel is not a multiple of 8, then the naive     computation fails. */  uint32_t offset =     (uint32_t) y * TheConsVESA.bpsl + x * ((TheConsVESA.bpp + 7) / 8);  /* Assume 64k banks for the moment */  if(!TheConsVESA.linfb) {    /*setBank(offset >> 16);*/        /* Note: general thing here would be offset -= (curBank * BankSize); */    offset &= 0xffffu;  }  /* Logically: effectiveAddress = frameBufferBase + (BankOffset + BankRelativeOffset); */  /* Issue: absence of funny cases (like 15 bits per pixel) was     causing drawing to be entirely suppressed. */  /* *(frameBufferBase + (offset & 0xFFFF)) = (char) color; */  if (TheConsVESA.bpp <= 8) {    /* 7, 8 bit modes use bytes */    *((uint8_t *) (Machine::frameBuffer + offset)) = color;  }  else if (TheConsVESA.bpp <= 16) {    /* 15, 16 bit modes use 16 bit values */    *((uint16_t *) (Machine::frameBuffer + offset)) = color;  }  else {    /* >16 bit modes use 32 bit values in the frame buffer. */    *((uint32_t *) (Machine::frameBuffer + offset)) = color;  }}

⌨️ 快捷键说明

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