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

📄 x86_videomem.c

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 C
字号:
/* Copyright (C) 2004  David Decotigny   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   of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,   USA.*/#include <sos/klibc.h>#include <hwcore/ioports.h>#include "x86_videomem.h"/* The text video memory starts at address 0xB8000. Odd bytes are the   ASCII value of the character, even bytes are attribute for the   preceding character. */#define VIDEO   0xb8000/* Console screen size */#define LINES   25#define COLUMNS 80/* * VGA ports and commands. *  * @see Ralf Brown's interrupt (and port) list	  * http://www-2.cs.cmu.edu/~ralf/files.html	  *//* VGA ports */#define VGA_COMMAND_PORT 0x3D4#define VGA_DATA_PORT    0x3D5/* VGA commands */#define VGA_SET_CURSOR_START 0xA#define VGA_SET_CURSOR_END   0xB#define VGA_SET_CURSOR_HIGH  0xE#define VGA_SET_CURSOR_LOW   0xF/** The structure of a character element in the video memory. @see    http://webster.cs.ucr.edu/AoA DOS edition chapter 23 */typedef struct {  unsigned char character;  unsigned char attribute;} __attribute__ ((packed)) x86_video_mem[LINES*COLUMNS];/** The base pointer for the video memory */static volatile x86_video_mem *video = (volatile x86_video_mem*)VIDEO;sos_ret_t sos_x86_videomem_setup(void){  /* CRT index port => ask for access to register 0xa ("cursor     start") */  outb(0x0a, VGA_COMMAND_PORT);  /* (RBIL Tables 708 & 654) CRT Register 0xa => bit 5 = cursor OFF */  outb(1 << 5, VGA_DATA_PORT);  return SOS_OK;}sos_ret_t sos_x86_videomem_cls(unsigned char attribute){  /* Clears the screen */  int i;  for(i = 0 ; i < LINES*COLUMNS ; i++)    {      (*video)[i].character = 0;      (*video)[i].attribute = attribute;    }  return SOS_OK;}sos_ret_t sos_x86_videomem_putstring(unsigned char row, unsigned char col,				     unsigned char attribute,				     const char *str){  unsigned video_offs = row*COLUMNS + col;  if (video_offs >= LINES*COLUMNS)    return -SOS_EINVAL;  for ( ; str && *str && (video_offs < LINES*COLUMNS) ; str++, video_offs++)    {      (*video)[video_offs].character = (unsigned char)*str;      (*video)[video_offs].attribute = attribute;    }  return SOS_OK;}sos_ret_t sos_x86_videomem_putchar(unsigned char row, unsigned char col,				   unsigned char attribute,				   unsigned char c){  unsigned video_offs = row*COLUMNS + col;  if (video_offs >= LINES*COLUMNS)    return -SOS_EINVAL;  (*video)[video_offs].character = c;  (*video)[video_offs].attribute = attribute;  return SOS_OK;}sos_ret_t sos_x86_videomem_printf(unsigned char row, unsigned char col,				  unsigned char attribute,				  const char *format, /* args */...){  char buff[256];  va_list ap;  va_start(ap, format);  vsnprintf(buff, sizeof(buff), format, ap);  va_end(ap);  return sos_x86_videomem_putstring(row, col, attribute, buff);}/* * Console that supports scrolling, based on the low-level code * above. This console only takes part of the screen, starting at row * CONSOLE_ROW_START. The rows before that one are free for use by the * kernel debugging messages. *//* Current row in the high-level console. Must be signed, because of   computations inside sos_screen_putchar() */static int row;/* Current column in the high-level console. Must be signed, because   of computations inside sos_screen_putchar() */static int col;/* The limit between the low-level console, accessible to the kernel,   and the high-level console, accessible to the user applications   through the sos_screen_putchar() function. */#define CONSOLE_ROW_START 12static void sos_screen_set_cursor (unsigned int row, unsigned int col){  unsigned int pos;  pos = (row * COLUMNS + col);  outb(VGA_SET_CURSOR_HIGH, VGA_COMMAND_PORT);  outb( (pos >> 8), VGA_DATA_PORT);  outb(VGA_SET_CURSOR_LOW, VGA_COMMAND_PORT);  outb( (pos & 0xFF), VGA_DATA_PORT);}sos_ret_t sos_screen_putchar (char c){  if (c == '\r')    {      /* Go to first row */      col = 0;    }  /* New line */  else if (c == '\n')    {      /* Go to next line */      col = 0;      row ++;    }  /* Remove the last character */  else if (c == '\b')    {      /* Next character should be displayed instead of the current	 one */      col --;      /* Handle the case where we're at the beginning of a line */      if (col < 0)	{	  row --;	  col = COLUMNS-1;	  if (row < CONSOLE_ROW_START)	    {	      row = CONSOLE_ROW_START;	      col = 0;	    }	}      /* Replace the current character with a space */      sos_x86_videomem_putchar	(row, col, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, ' ');    }  else if (c != 0)    {      sos_x86_videomem_putchar	(row, col, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, c);      col++;      if (col == COLUMNS)	{	  col = 0;	  row++;	}    }  /* Need to scroll ? */  if (row == LINES)    {      int i;      /* Copy each line in the previous line */      for (i = CONSOLE_ROW_START; i < LINES; i++)	memcpy ((char*) video + i * COLUMNS * 2,		(char*) video + ((i + 1) * COLUMNS * 2),		COLUMNS * 2);      /* Reset the last line of the console */      for (i = 0; i < COLUMNS; i++)	sos_x86_videomem_putchar	  (LINES-1, i, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, ' ');      row--;    }  sos_screen_set_cursor (row, col);  return SOS_OK;}sos_ret_t sos_screen_init (void){  int i, j;  row = CONSOLE_ROW_START;  col = 0;  /* Set the first scan line for the cursor, and the blinking     mode. First scan line is 11, so that we have a visible     cursor. */  outb(VGA_SET_CURSOR_START, VGA_COMMAND_PORT);  outb(((0x2 << 5) | 14), VGA_DATA_PORT);  for (i = CONSOLE_ROW_START; i < LINES; i++)    {      for (j = 0; j < COLUMNS; j++)	sos_x86_videomem_putchar	  (i, j, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, ' ');    }  sos_screen_set_cursor (row, col);  return SOS_OK;}

⌨️ 快捷键说明

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