KraKern

C++ Kernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/KraKern

Io.cpp (5794B)


      1 #include <Io.hpp>
      2 
      3 Io		__io;
      4 Io		*Io::last_io = &__io;
      5 Io		*Io::current_io = &__io;
      6 char	*Io::_vidmem = (char *)RAM_SCREEN;
      7 
      8 Io::Io(void) {
      9 	this->_real_screen = (char *)RAM_SCREEN;
     10 	this->_gline_ready = 0;
     11 }
     12 
     13 Io::~Io(void) {
     14 	this->_real_screen = (char *)this->_screen;
     15 }
     16 
     17 void	Io::init(void) {
     18 	this->_real_screen = (char *)RAM_SCREEN;
     19 	this->clear();
     20 	this->_kattr = COLOR_BLACK;
     21 }
     22 
     23 void	Io::scrollup(u32 n) {
     24 	u8	*video, *tmp;
     25 
     26 	for (video = (u8 *)this->_real_screen; video < (u8 *)SCREENLIM; video += 2) {
     27 		tmp = (u8 *)(video + n * 160);
     28 		if (tmp < (u8 *)SCREENLIM) {
     29 			*video = *tmp;
     30 			*(video + 1) = *(tmp + 1);
     31 		} else {
     32 			*video = 0x0;
     33 			*(video + 1) = 0x07;
     34 		}
     35 	}
     36 	this->_y -= n;
     37 	if (this->_y < 0)
     38 		this->_y = 0;
     39 }
     40 
     41 void	Io::save_screen(void) {
     42 	memcpy(this->_screen, (char *)RAM_SCREEN, SIZE_SCREEN);
     43 	this->_real_screen = (char *)this->_screen;
     44 }
     45 
     46 void	Io::load_screen(void) {
     47 	memcpy((char *)RAM_SCREEN, this->_screen, SIZE_SCREEN);
     48 	this->_real_screen = (char *)RAM_SCREEN;
     49 }
     50 
     51 void	Io::switch_tty(void) {
     52 	current_io->save_screen();
     53 	load_screen();
     54 	last_io = current_io;
     55 	current_io = this;
     56 }
     57 
     58 void	Io::puts(const char *s) {
     59 	while (s && *s) {
     60 		this->putc(*s++);
     61 	}
     62 }
     63 
     64 void	Io::putc(char c) {
     65 	u8		*video;
     66 
     67 	video = (u8 *)(this->_real_screen + 2 * this->_x + 160 * this->_y);
     68 	if (c == 10) {
     69 		this->_x = 0;
     70 		this->_y++;
     71 	} else if (c == 8 && this->_x) {
     72 		*(video + 1) = 0x0;
     73 		*video = ' ';
     74 		this->_x--;
     75 	} else if (c == 9) {
     76 		this->_x = this->_x + 8 - (this->_x % 8);
     77 	} else if (c == 13) {
     78 		this->_x = 0;
     79 	} else {
     80 		*video = c;
     81 		*(video + 1) = this->_kattr;
     82 		this->_x++;
     83 		if (this->_x > 79) {
     84 			this->_x = 0;
     85 			this->_y++;
     86 		}
     87 	}
     88 	if (this->_y > 24)
     89 		scrollup(this->_y - 24);
     90 	this->_move_cursor();
     91 }
     92 
     93 void	Io::printk(const char *s, ...) {
     94 	va_list		arg;
     95 	char		buf[16];
     96 	u32			size;
     97 
     98 	va_start(arg, s);
     99 	for (; *s; s++) {
    100 		size = 0;
    101 		if (*s == '%' && *(s + 1)) {
    102 			s++;
    103 			if (*s >= '0' && *s <= '9') {
    104 				size = *s - '0';
    105 				s++;
    106 			} if (*s == 's') {
    107 				this->puts(va_arg(arg, char *));
    108 			} else if (*s == 'd' || *s == 'u') {
    109 				int		tmp = va_arg(arg, int);
    110 				if (tmp < 0) {
    111 					this->putc('-');
    112 					tmp = ~tmp + 1;
    113 				}
    114 				itoa(buf, tmp, 10);
    115 				if (strlen(buf) < size)
    116 					for (int j = strlen(buf), i = size; i >= 0; i--, j--)
    117 						buf[i] = (j >= 0 ? buf[j] : '0');
    118 				this->puts(buf);
    119 			} else if (*s == 'x') {
    120 				itoa(buf, va_arg(arg, int), 16);
    121 				if (strlen(buf) < size)
    122 					for (int j = strlen(buf), i = size; i >= 0; i--, j--)
    123 						buf[i] = (j >= 0 ? buf[j] : '0');
    124 				this->puts(buf);
    125 			} else if (*s == 'p') {
    126 				itoa(buf, va_arg(arg, int), 16);
    127 				if (strlen(buf) < 4)
    128 					for (int j = strlen(buf), i = 4; i >= 0; i--, j--)
    129 						buf[i] = (j >= 0 ? buf[j] : '0');
    130 				this->puts("0x");
    131 				this->puts(buf);
    132 			} else if (*s == 'c') {
    133 				this->putc(va_arg(arg, int));
    134 			} else if (*s == 'e') {
    135 				this->set_color(va_arg(arg, int));
    136 			}
    137 		} else {
    138 			this->putc(*s);
    139 		}
    140 	}
    141 	this->set_color(COLOR_LIGHT_GREY);
    142 }
    143 
    144 void	Io::clear(void) {
    145 	this->_x = 0;
    146 	this->_y = 0;
    147 	memset((char *)RAM_SCREEN, 0, SIZE_SCREEN);
    148 }
    149 
    150 void	Io::putctty(char c) {
    151 	if (this->_keystate == BUFFERED) {
    152 		if (c == 8 && this->_keypos > 0) {
    153 			this->_inbuf[this->_keypos--] = 0x0;
    154 		} else if (c == 10) {
    155 			this->_inbuf[this->_keypos++] = c;
    156 			this->_inbuf[this->_keypos] = 0x0;
    157 			this->_inlock = this->_keypos = 0;
    158 		} else {
    159 			this->_inbuf[this->_keypos++] = c;
    160 		}
    161 	} else if (this->_keystate == GETCHAR) {
    162 		this->_inbuf[0] = c;
    163 		this->_inbuf[1] = 0;
    164 		this->_inlock = this->_keypos = 0;
    165 	}
    166 }
    167 
    168 u32		Io::read(char *buf, u32 count) {
    169 	if (count > 1)
    170 		this->_keystate = BUFFERED;
    171 	else
    172 		this->_keystate = GETCHAR;
    173 	asm("sti");
    174 	this->_inlock = 1;
    175 	while (this->_inlock);
    176 	asm("cli");
    177 	strncpy(buf, this->_inbuf, count);
    178 	return strlen(buf);
    179 }
    180 
    181 void	Io::loading(const char *s) {
    182 	this->printk("%e%s%e", COLOR_LIGHT_GREY, s, COLOR_WHITE);
    183 	for (int padding = 81 - strlen(s) - 10; padding > 0; padding--, this->puts(" "));
    184 	this->_in_loading = 1;
    185 }
    186 
    187 void	Io::done(void) {
    188 	this->printk("%e[%e DONE %e]\n", COLOR_LIGHT_GREY, COLOR_GREEN, COLOR_LIGHT_GREY);
    189 	this->_in_loading = 0;
    190 }
    191 
    192 void	Io::panic(const char *s) {
    193 	if (this->_in_loading)
    194 		this->printk("[%e FAIL %e]", COLOR_RED, COLOR_WHITE);
    195 	this->printk("\n[%e PANIC %e]: %s\n", COLOR_RED, COLOR_WHITE, s);
    196 	__kern.is_panic = 1;
    197 	asm("hlt");
    198 	while (1);
    199 	// Reboot
    200 }
    201 
    202 void	Io::key_callback(char c) {
    203 	static int		pos = 0;
    204 	
    205 	if (c == '\n') {
    206 		this->_gline_ready = 1;
    207 		this->_line[pos++] = '\n';
    208 		this->_line[pos + 1] = 0;
    209 		pos = 0;
    210 	} else {
    211 		this->_line[pos++] = c;
    212 		this->_line[pos + 1] = 0;
    213 	}
    214 }
    215 
    216 int		Io::get_line(char *c) {
    217 	int		tmp;
    218 
    219 	if (this->_gline_ready) {
    220 		bzero(c);
    221 		tmp = strlen(this->_line);
    222 		strcpy(c, this->_line);
    223 		bzero(this->_line);
    224 		this->_gline_ready = 0;
    225 		return tmp;
    226 	}
    227 	return 0;
    228 }
    229 
    230 void	Io::_move_cursor(void) {
    231 	u16 c_pos;
    232 
    233 	c_pos = this->_y * 80 + this->_x;
    234 
    235 	this->obyte(0x3d4, 0x0f);
    236 	this->obyte(0x3d5, (u8) c_pos);
    237 	this->obyte(0x3d4, 0x0e);
    238 	this->obyte(0x3d5, (u8) (c_pos >> 8));
    239 }
    240 
    241 // Output
    242 void	Io::obyte(u32 a, u8 v) { asmv("outb %%al, %%dx" :: "d" (a), "a" (v));; };
    243 void	Io::oword(u32 a, u16 v) { asmv("outw %%ax, %%dx" :: "d" (a), "a" (v));; };
    244 void	Io::oline(u32 a, u32 v) { asmv("outl %%ax, %%dx" :: "d" (a), "a" (v));; };
    245 
    246 // Input
    247 u8		Io::ibyte(u32 a) { u8 v; asmv("inb %%dx, %%al" : "=a" (v) : "d" (a)); return v; };
    248 u16		Io::iword(u32 a) { u16 v; asmv("inw %%dx, %%ax" : "=a" (v) : "d" (a)); return v; };
    249 u32		Io::iline(u32 a) { u32 v; asmv("inl %%dx, %%eax" : "=a" (v) : "d" (a)); return v; };
    250 
    251 u32		Io::getX(void) { return (u32)this->_x; };
    252 u32		Io::getY(void) { return (u32)this->_y; };
    253 
    254 void	Io::set_color(char color) { this->_kattr = color; };
    255 void	Io::setXY(char xc, char yc) { this->_x = xc; this->_y = yc; };