📄 vgatext.c
字号:
/** Snixos Project version 1.0, 2003.6* (C) Copyright 2003,2004,2005 Jockeyson,KeqiangGao <Snallie@tom.com>* All Rights Reserved.* Distributed under the terms of the GNU General Public License.** This program is a free and open source software and you can redistribute * it and/or modify it under the terms of the GNU General Public License as* published by the Free Software Foundation. As no any liability is assumed * for any incidental or consequential damages in connection with the * information or program fragments contained herein,so any exception arised* is at your own risk. It is ABSOLUTELY WITHOUT ANY WARRANTY.* Bug report please send to Snallie@tom.com .*//* vgatext.c: driver for VGA text mode 80x25 in SNIXOS project c function printf() implemented here Author : snallie@tom.com Time : 2003.6 printf escape sequence: %c = char %d = signed int %x = unpaded hex %s = string %0x = padded hex %o = octal %b = binary*/#include "stdarg.h"#include "stdio.h"#include "ctype.h"#include "io.h"#include "mem.h"#include "fatfs.h"#define RESERVEDLINES 1 /* head line reserved as status bar, 0 means the whole screen */ /* will be scrolled */#define XUPPER 1#define XLOWER 0/* Video Card I/O ports */#define TEXT_INDEX 0x03D4#define TEXT_DATA 0x03D5/* Video Card Index Registers */#define TEXT_CURSOR_LO 0x0F#define TEXT_CURSOR_HI 0x0Estatic void printChar(char **str, int *len, char c);static void printStr(char **str, int *len, char *pstr);static void printInt(char **str, int *len, int num, int width);static void printHex(char **str, int *len, unsigned int hex, int padded, int style);static void vaPrintf(char **str, int *len, char *fmt, va_list pvar);static unsigned char getChar(int x, int y);static unsigned char getAttrib(int x, int y);static void scrollup(void);static void writeChar(char c);static void TXTWriteChar(char c);static int intLen(int i, int radix);static unsigned char *vidmem; /* VGA video buffer for 80*25 color text mode */static int vidx; /* current cursor X position on screen */static int vidy; /* current cursor Y position on screen */static unsigned char curAttrib; /* current screent text attribute */extern int videoMode; /* defined in kernel.c *//* * console output functions */void print_char(char c){ int i = -1; printChar(NULL, &i, c);}void print_str(char *str){ int i = -1; printStr(NULL, &i, str);}void print_int(int num){ int i = -1; printInt(NULL, &i, num, 0);}void print_hex(unsigned int hex, int padded){ int i = -1; printHex(NULL, &i, hex, padded, XLOWER);}void printf(char *fmt, ...){ int i = -1; va_list pvar; va_start(pvar, fmt); vaPrintf(NULL, &i, fmt, pvar); va_end(pvar);}void sprintf(char *str, char *fmt, ...){ int i = -1; va_list pvar; va_start(pvar, fmt); vaPrintf(&str, &i, fmt, pvar); va_end(pvar);}void snprintf(char *str, int len, char *fmt, ...){ va_list pvar; va_start(pvar, fmt); vaPrintf(&str, &len, fmt, pvar); va_end(pvar);}int fprintf(FILE * fp, char *fmt, ...){ char nstr[500]; // buffer for fprintf int i = -1; char *str = nstr; va_list pvar; va_start(pvar, fmt); vaPrintf(&str, &i, fmt, pvar); va_end(pvar); i = 0; while (*(nstr + i)) { Mfputc(*(nstr + i), fp); printf("%c", *(nstr + i)); /* also output to screen */ i++; } return i;}/* * base functions for printf implementation */static void printChar(char **str, int *len, char c){ if (str) { if (*len != 0) { *(*str)++ = c; (*len)--; } } else { writeChar(c); }}static void printStr(char **str, int *len, char *pstr){ while (*pstr) { printChar(str, len, *pstr); pstr++; }}/* printInt()print the num in decimal mode*/static void printInt(char **str, int *len, int num, int width){ char nstr[12]; int i = 10, j = 0; if (num < 0) { printChar(str, len, '-'); printInt(str, len, -1 * num, width - 1); return; } nstr[11] = '\0'; while (i > 0) { nstr[i % 11] = '0' + (num % 10); num /= 10; i--; if ((j >= width - 1) && (num <= 0)) break; else j++; } printStr(str, len, nstr + i + 1);}/* printHex()printf the hex in hexadecimal mode */static void printHex(char **str, int *len, unsigned int hex, int pad, int style){ char nstr[14]; int i = 12, j; nstr[13] = '\0'; pad--; for (j = 0; j < 8; j++) { if ((hex % 16) < 10) nstr[i] = '0' + (hex % 16); else nstr[i] = ((style == XLOWER) ? 'a' : 'A') + ((hex % 16) - 10); hex /= 16; i--; if ((j >= pad) && (hex <= 0)) break; } printStr(str, len, nstr + i + 1);}/* void printOct(char **str, int *len, unsigned int num)print the integer num in octal mode */static void printOct(char **str, int *len, unsigned int num){ int octLen = intLen(num, 8), i; char *octbuf = (char *) malloc((octLen + 1) * sizeof(char)); if (octbuf == NULL) { printf("malloc failed in printOct\n"); return; } i = octLen - 1; octbuf[octLen] = '\0'; while (num) { octbuf[i % octLen] = num % 8 + '0'; num /= 8; i--; } printStr(str, len, octbuf + i + 1); free(octbuf);}/* void printBin(char **str, int *len, unsigned int num)print the integer num in binary mode */static void printBin(char **str, int *len, unsigned int num){ int len2; int binLen = intLen(num, 2), i; char *binbuf = (char *) malloc(((binLen - 1) / 8 + 1) * 8 * sizeof(char) + sizeof(char)); if (binbuf == NULL) { printf("malloc failed in printBin\n"); return; } len2 = ((binLen - 1) / 8 + 1) * 8 * sizeof(char) + sizeof(char); i = ((binLen - 1) / 8 + 1) * 8 * sizeof(char) - 1; binbuf[((binLen - 1) / 8 + 1) * 8 * sizeof(char)] = '\0'; while (i >= 0) { binbuf[i % len2] = num % 2 + '0'; num /= 2; i--; } printStr(str, len, binbuf + i + 1); free(binbuf);}static void vaPrintf(char **str, int *len, char *fmt, va_list pvar){ while (*fmt) { if (*fmt == '%') { fmt++; if (!*fmt) { if (str) { /* add end of line to array tp for sprintf(tp,char * ,...) */ printChar(str, len, '\0'); } return; } switch (*fmt) { case 's': /* %s */ printStr(str, len, va_arg(pvar, char *)); break; case 'c': /* %c */ printChar(str, len, va_arg(pvar, char)); break; case 'd': /* %d */ printInt(str, len, va_arg(pvar, int), 0); break; case 'x': case 'X': /* %x or %X */ printHex(str, len, va_arg(pvar, unsigned int), 0, (*fmt == 'x') ? XLOWER : XUPPER); break; case 'o': /* %o */ printOct(str, len, va_arg(pvar, unsigned int)); break; case 'b': /* %b , binary output for number */ printBin(str, len, va_arg(pvar, unsigned int)); break; case '0': /* %0x %0X %0d */ fmt++; switch (*fmt) { case 'x': case 'X': printHex(str, len, va_arg(pvar, unsigned int), 8, (*fmt == 'x') ? XLOWER : XUPPER); goto ret1; case 'd': printInt(str, len, va_arg(pvar, int), 10); goto ret1; } if (isdigit(*fmt)) { int width = 0; while (isdigit(*fmt)) { width = (width * 10 + (*fmt) - '0'); fmt++; } if (*fmt == 'x' || *fmt == 'X') { printHex(str, len, va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER); } else if (*fmt == 'd') { printInt(str, len, va_arg(pvar, int), width); } } ret1: break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* %12x %12X %12d %12s %12c */ if (isdigit(*fmt)) { int width; for (width = 0; isdigit(*fmt); fmt++) { width = (width * 10 + (*fmt) - '0'); } if (*fmt == 'x' || *fmt == 'X') { printHex(str, len, va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER); } else if (*fmt == 'd') { int num = va_arg(pvar, int); int length = intLen(num, 10); while (width > length) { printChar(str, len, ' '); width--; } printInt(str, len, num, length); } else if (*fmt == 's') { char *strs = va_arg(pvar, char *); int strSize = strlen(strs); while (width - strSize > 0) { printChar(str, len, ' '); strSize++; } printStr(str, len, strs); } else if (*fmt == 'c') { width -= 1; while (width > 0) { printChar(str, len, ' '); width--; } printChar(str, len, va_arg(pvar, char)); } } break; case '-': /* %-12s %-12d %-12c , left aligned */ fmt++; if (isdigit(*fmt)) { int width = 0; while (isdigit(*fmt)) { width = (width * 10 + (*fmt) - '0'); fmt++; } if (*fmt == 's') { char *strs = va_arg(pvar, char *); int strSize = strlen(strs); printStr(str, len, strs); while (width - strSize > 0) { printChar(str, len, ' '); strSize++; } } else if (*fmt == 'd') { int num = va_arg(pvar, int); int length = intLen(num, 10); printInt(str, len, num, length); while (width - length > 0) { printChar(str, len, ' '); length++; } } else if (*fmt == 'c') { printChar(str, len, va_arg(pvar, char)); width -= 1; while (width > 0) { printChar(str, len, ' '); width--; } } } break; case '%': /* %% */ printChar(str, len, '%'); fmt++; break; default: break; } } else { printChar(str, len, *fmt); } fmt++; } /* while(*fmt) */ if (str) { /* add end of line to array tp for sprintf(tp,char *fmt, ...) */ printChar(str, len, '\0'); }}/* int intLen(int i, int radix) return the count of i's digit which is beneath the most significant digit in the desired radix. */static int intLen(int i, int radix){ int len = 0; if (i < 0) { return intLen(-i, radix); } do { i /= radix; len++; } while (i); return len;}/* VGA screen manipulation */void screen_init(void){ int i, j; vidmem = (unsigned char *) 0xb8000; set_attrib(ATTRIB_WHITE | ATTRIB_BLACK_BG); for (i = 0; i < 80; i++) { for (j = 0; j < 25; j++) { screen_putchar(i, j, ' ', curAttrib); } } /* line 1 reserved as status bar */ screen_gotoxy(0, 0 + RESERVEDLINES);}void screen_gotoxy(int x, int y){ short pos = y * 80 + x; vidx = x; vidy = y; outb(TEXT_CURSOR_LO, TEXT_INDEX); /* access lo cursor data reg */ outb((char) pos, TEXT_DATA); outb(TEXT_CURSOR_HI, TEXT_INDEX); /* access hi cursor data reg */ outb((unsigned char) (pos >> 8), TEXT_DATA);}void screen_putchar(int x, int y, unsigned char c, unsigned char attrib){ vidmem[((x) + (y) * 80) * 2] = c; vidmem[(((x) + (y) * 80) * 2) + 1] = attrib;}static unsigned char getChar(int x, int y){ return vidmem[((x) + (y) * 80) * 2];}static unsigned char getAttrib(int x, int y){ return vidmem[(((x) + (y) * 80) * 2) + 1];}static void scrollup(void){ unsigned int org = (unsigned int) vidmem + (RESERVEDLINES + 1) * 160; unsigned int dst = (unsigned int) vidmem + RESERVEDLINES * 160; unsigned int cnt = 2000 - 80 * (RESERVEDLINES + 1); unsigned int cnt2 = 80; /* characters to be displaed at the bottom line on screen */ unsigned int dst2 = (unsigned int) vidmem + 24 * 80 * 2; /* bottom line address in vidram */ asm("cld\n\t" "rep\n\t" "movsl\n\t"::"c"(cnt), "D"(dst), "S"(org)); asm("cld\n\t" "rep\n\t" "stosw\n\t"::"a"(0x0720), "c"(cnt2), "D"(dst2), "S"(org));}static void writeChar(char c){ switch (videoMode) { case VIDTEXT_80X25: TXTWriteChar(c); break; case VIDGRAPH_640X480: VGAWriteChar(c); break; }}static void TXTWriteChar(char c){ if (c == '\n') { /* CR LF */ screen_gotoxy(0, ++vidy); /* screen_gotoxy(ycord,xcord) */ } else if (c == '\t') { /* horizontal Tab */ screen_gotoxy(vidx += 4, vidy); } else if (c == '\b') { /* backspace */ screen_gotoxy(vidx -= 1, vidy); writeChar(' '); screen_gotoxy(vidx -= 1, vidy); return; } else { screen_putchar(vidx, vidy, (unsigned char) c, curAttrib); screen_gotoxy(++vidx, vidy); } /* off right edge */ if (vidx > 79) { screen_gotoxy(0, ++vidy); } /* off bottom */ if (vidy > 24) { scrollup(); screen_gotoxy(vidx, 24); }}void set_attrib(unsigned char attrib){ curAttrib = attrib;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -