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

📄 fstdio.h

📁 FritzOS - 简单的C++开发OS的实例// 英文
💻 H
字号:
/* fstdio.h : FritzOS Standard I/O Header File For The FritzOS C++ Kernel   Copyright (C) 2002 Tom Fritz * This program is a part of the FritzOS kernel, and may be freely * copied under the terms of the GNU General Public License (GPL), * version 2, or at your option any later version.   For more info, look at the COPYING file.*/// defines:#ifndef FSTDIO_H#define FSTDIO_H// Includes:#include "types.h"			// need USHORT, and UCHAR#include "x86.h"			// need outportb#include "stdarg.h"			// need va_list, va_end and va_start#include "string.h"			// need strcpy#define WHITE_BLACK	0x07	// white on black text#define RED_GREEN	0x26	// red on green text#define BLUE_BLACK	1	// Blue on black#define RED_BLACK	4	// red on black#define PURPLE_BLACK	0x5	// purple on black#define YELLOW_BLACK	0x6	// yellow on black#define LIGHTBLUE_BLACK	0x9	// light blue on black#define DARKBLUE_BLACK	0x8	// dark blue on black#define GREEN_BLACK		10	// green on black#define MAGENTA_BLACK		12	// magenta on black#define LIGHTESTBLUE_BLACK	0xB	// very light blue on black// For looping so many times:#define	LOOP( x, y )		for ( x = 0; x < ( y ); x++ )// For moving the cursor back to 0, 0#define GOHOME			gotoxy( 0, 0 )#define NULL 0// Printf Defines:#define		PR_LJ	0x01	// left Justify#define		PR_CA	0x02	// Use A-F Instead Of a-f For Hex Numbers#define		PR_SG	0x04	// Signed Numeric Conversion ( %d vs. %u )#define		PR_32	0x08	// Long ( 32-bit ) Numeric Conversion#define		PR_16	0x10	// Short ( 16-bit ) Numeric Conversion#define		PR_WS	0x20	// PR_SG set and num was < 0#define		PR_LZ	0x40	// Pad Left With '0' Instead Of ' '#define		PR_FP	0x80	// Pointers Are Far// Largest number handled is 2 ^ 32 - 1, lowest radix handled is 8.// 2 ^ 32 - 1 in base 8 has 11 digits ( add 5 for trailing NULL and for slop )#define		PR_BUFLEN	16// Typedefs:typedef int ( * fnptr_t ) ( unsigned c, void** helper );// voids:void Freeze();			// freeze the computer//*********// NOTE:	k_printf HAS BEEN REMOVED because printf has more use.//*********// doprintf: printf with hex and other printing optionsint doprintf( const char *fmt, va_list args, fnptr_t fn, void *ptr );// printf - standard printfvoid printf( const char *msg, ... );// printfhelp: help printfstatic int printfhelp( unsigned c, void **ptr );// smprintf - small printf e.g. no args like %svoid smprintf( char* message );// putch - put a single charactervoid putch( UCHAR c );// update_cursor - update the cursor's placevoid update_cursor();// setcolor - set printf & putch colorvoid setcolor( unsigned color );// start textmode stuff that the OS needs to keep track of, and other thingsextern "C" void start_textmode();	// NOTE: I use the extern "C" so that the ASM module can call this..					//  even though start_textmode is defined here.// gotoxy: move the cursor to the x and y positionsvoid gotoxy( int x, int y );// Clear Screen to the current color selected by setcolorvoid clrscr();// Simple Print C++ Functionsvoid Print( char* msg, ... );			// Print Stringsvoid Print( char putch );			// Print Charactersvoid Print( int num );				// Print Numbers// data:int cur_cursorX, cur_cursorY;				// this is for keeping track of the text mode cursorstatic unsigned short *vgaadr;				// the VGA addressstatic unsigned textattrib, scrwidth, scrheight;	// the text color, the screen width, & height////////////////////////////////////////////////////////////////////////////////////////////////////////////////*************************************************************************************************************//// Freeze the computer// example: Freeze();void Freeze(){	while( 1 )		;}//*************************************************************************************************************//// Example: Look at printf for more information on how to use this.int doprintf( const char *fmt, va_list args, fnptr_t fn, void *ptr ){	unsigned state, flags, radix, actual_wd, count, given_wd;	unsigned char *where, buf[ PR_BUFLEN ];	long num;	state = flags = count = given_wd = 0;// Begin scanning format specifier list	for ( ; *fmt; fmt++ )	{		switch ( state )		{		// STATE 0: AWAITING %		case 0:			if ( *fmt != '%' )	// not %...			{				fn ( *fmt, &ptr );	// ...just echo it				count++;				break;			}// Found %, get next character and advance state to check if next char is a flag			state++;			fmt++;			// FALL THROUGH			// STATE 1: AWAITING FLAGS ( % - 0 )		case 1:			if ( *fmt == '%' )	// %%			{				fn ( *fmt, &ptr );				count++;				state = flags = given_wd = 0;				break;			}			if ( *fmt == '-' )			{				if ( flags & PR_LJ )	// %-- is illegal					state = flags = given_wd = 0;				else					flags |= PR_LJ;				break;			}// Not a flag char: advance state to check if it's field width			state++;// Check now for '%0...'			if ( *fmt == '0' )			{				flags |= PR_LZ;				fmt++;			}			// FALL THROUGH			// STATE 2: AWAITING (NUMERIC) FIELD WIDTH		case 2:			if ( *fmt >= '0' && *fmt <= '9' )			{				given_wd = 10 * given_wd +					( *fmt - '0' );				break;			}// Not field width: advance state to check if it's a modifier			state++;			// FALL THROUGH			// STATE 3: AWAITING MODIFIER CHARS ( FNlh )		case 3:			if ( *fmt == 'F' )			{				flags |= PR_FP;				break;			}			if ( *fmt == 'N' )				break;			if ( *fmt == 'l' )			{				flags |= PR_32;				break;			}			if ( *fmt == 'h' )			{				flags |= PR_16;				break;			}// Not modifier: advance state to check if it's a conversion char			state++;			// FALL THROUGH// STATE 4: AWAITING CONVERSION CHARS ( Xxpndiuocs )		case 4:			where = buf + PR_BUFLEN - 1;			*where = '\0';			switch ( *fmt )			{				case 'X':					flags |= PR_CA;				// FALL THROUGH// xxx - far pointers (%Fp, %Fn) not yet supported			case 'x':			case 'p':			case 'n':				radix = 16;				goto DO_NUM;			case 'd':			case 'i':				flags |= PR_SG;				// FALL THROUGH			case 'u':				radix = 10;				goto DO_NUM;			case 'o':				radix = 8;// Load the value to be printed. l=long=32 bits:DO_NUM:				if ( flags & PR_32 )					num = va_arg( args, unsigned long );// h=short=16 bits ( signed or unsigned )				else if ( flags & PR_16 )				{					if ( flags & PR_SG )						num = va_arg( args, short );					else						num = va_arg( args, unsigned short );				}// No h nor l: sizeof(int) bits ( signed or unsigned )				else				{					if ( flags & PR_SG )						num = va_arg( args, int );					else						num = va_arg( args, unsigned int );				}// Take care of sign				if ( flags & PR_SG )				{					if ( num < 0 )					{						flags |= PR_WS;						num = -num;					}				}// Convert binary to octal/decimal/hex ASCII// The math here is ALWAYS unsigned				do				{					unsigned long temp;					temp = ( unsigned long ) num % radix;					where--;					if ( temp < 10 )						*where = temp + '0';					else if ( flags & PR_CA )						*where = temp - 10 + 'A';					else						*where = temp - 10 + 'a';					num = ( unsigned long ) num / radix;				}				while ( num != 0 );				goto EMIT;			case 'c':// Disallow pad-left-with-zeroes for %c				flags &= ~PR_LZ;				where--;				*where = ( unsigned char )va_arg(args, unsigned char);				actual_wd = 1;				goto EMIT2;			case 's':// Disallow pad-left-with-zeroes for %s				flags &= ~PR_LZ;				where = va_arg( args, unsigned char * );EMIT:				actual_wd = strlen( ( char* )where );				if ( flags & PR_WS )					actual_wd++;// If we pad left with ZEROES, do the sign now				if ( ( flags & ( PR_WS | PR_LZ ) ) == ( PR_WS | PR_LZ ) )				{					fn( '-', &ptr );					count++;				}// pad on left with spaces or zeroes ( for right justify )EMIT2:				if ( ( flags & PR_LJ ) == 0 )				{					while ( given_wd > actual_wd )					{						fn( flags & PR_LZ ? '0' :							' ', &ptr );						count++;						given_wd--;					}				}// If we pad left with SPACES, do the sign now				if ( ( flags & ( PR_WS | PR_LZ ) ) == PR_WS )				{					fn( '-' , &ptr );					count++;				}// Emit string/char/converted number				while ( *where != '\0' )				{					fn( *where++, &ptr );					count++;				}// pad on right with spaces ( for left justify )				if ( given_wd < actual_wd )					given_wd = 0;				else					given_wd -= actual_wd;				for ( ; given_wd; given_wd-- )				{					fn( ' ', &ptr );					count++;				}				break;			default:				break;			}		default:			state = flags = given_wd = 0;			break;		}	}	return count;}//*************************************************************************************************************//void putch( UCHAR c ){	unsigned att;	att = textattrib << 8;	// backspace	if ( c == 0x08 )	{		if ( cur_cursorX != 0 )			cur_cursorX--;		else if ( cur_cursorX == 0 && cur_cursorY > 0 )		{			cur_cursorY--;			cur_cursorX = scrwidth - 1;	// minus 1 because it'll be off screen or not move if							//  == scrwidth			update_cursor();			return;		}	}	// tab	else if ( c == 0x09 )	{		cur_cursorX += 4;	// tabs are 4 spaces in FOS	}	// carriage return	else if ( c == '\r' )	{		cur_cursorX = 0;	}	// new line	else if ( c == '\n' )		// in FOS, a '\n' is a new line at the start of the line	{		cur_cursorX = 0;		cur_cursorY++;	}	// ASCII characters - 123...abc...	else if ( c >= ' ' )	{		unsigned short *where;		where = vgaadr + ( cur_cursorY * scrwidth + cur_cursorX );		*where = c | att;		cur_cursorX++;	}	if ( cur_cursorX >= scrwidth )	{		cur_cursorX = 0;		cur_cursorY++;	}	update_cursor();}//*************************************************************************************************************//void start_textmode(){	cur_cursorX = 0;	cur_cursorY = 0;	gotoxy( 0, 0 );	vgaadr = ( unsigned short * ) 0xb8000;	textattrib = WHITE_BLACK;		// white on black	scrwidth = 80;	scrheight = 25;}//*************************************************************************************************************//void gotoxy( int x, int y ){        USHORT	position = ( y * scrwidth + x );        // cursor LOW port to vga INDEX register        outportb( 0x3D4, 0x0F );        outportb( 0x3D5, ( UCHAR ) ( position & 0xFF ) );        // cursor HIGH port to vga INDEX register        outportb( 0x3D4, 0x0E );	outportb( 0x3D5, ( UCHAR ) ( ( position >> 8 ) & 0xFF ) );	cur_cursorX = x;	cur_cursorY = y;}//*************************************************************************************************************//void update_cursor(){	gotoxy( cur_cursorX, cur_cursorY );}//*************************************************************************************************************//void setcolor( unsigned color ){	textattrib = color;}//*************************************************************************************************************//void smprintf( char* message ){	char _curchar = *message;	while ( _curchar != '\0' )	{		// don't check if it's greater or = to ' ' because someone might need to print \n and		//  to keep it small, just print all characters		putch( _curchar );		++message;		_curchar = *message;	}}//*************************************************************************************************************//// Example: Look at printf for more information on how to use this function.static int printfhelp( unsigned c, void **ptr ){	putch( c );	return 0;}//*************************************************************************************************************//void printf( const char *msg, ... ){	va_list printfargs;	va_start( printfargs, msg);	( void ) doprintf ( msg, printfargs, printfhelp, NULL );	va_end( printfargs );}//*************************************************************************************************************//// Example: clrscr();		// Clear Screenvoid clrscr(){	// For checking how many times to put blanks	int i;	// Go back to the first place:	GOHOME;	LOOP (  i, scrwidth * scrheight )		putch( ' ' );	// Put the cursor back to the first place	GOHOME;}//*************************************************************************************************************//// NOTE: C++ Code.// Example: Print( "Your Message and % args" );void Print( char* msg, ... ){	va_list args;	va_start( args, msg );	(void)doprintf( msg, args, printfhelp, NULL );	va_end(args);}// Example: Print( 'C' );void Print( char putc ){	putch( putc );}// Example: Print( 1 );void Print( int num ){	printf( "%d", num );}#endif// End of fstdio.h

⌨️ 快捷键说明

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