int fputc(int ch, FILE *f) { if(f == &__stdout){ telnet_putchar_all(ch); return (console_putchar(ch)); }else if( f == &__stderr){ telnet_putchar_all(ch); return (console_puterr(ch)); }else if( f == &__lcdout){ return (lcd_terminal_char(ch)); }else if( f == &__uartout){ return (console_putchar(ch)); }else return telnet_putchar(f,ch); }
void terminal_get_char(uint8_t ch) { console_color = make_color(COLOR_LIGHT_GREY, COLOR_BLACK); if (ch == 0x08) { // backspace \b if (terminal_buf_count > 0) { terminal_buf_count--; terminal_buffer[terminal_buf_count] = ' '; console_putchar(' '); console_column--; console_column--; console_putchar(CURSOR); // input cursor console_column--; } } // else if (ch == 0x0A) { // line feed \n // // // TODO: push content to user process waiting for input // } else { // normal char if (terminal_buf_count < MAX_BUFF) { terminal_buffer[terminal_buf_count] = ch; terminal_buf_count++; //judge whether or not to local_echo user input if (user_input == 1) { if (ch == '\n') { console_putchar(' '); } console_putchar(ch); console_putchar(CURSOR); // input cursor ¦ console_column--; } //dprintf("char is %c, buffer count is %d\n", ch, terminal_buf_count); } else { printf("Terminal buffer is full!! And will be cleared !\n"); memset(terminal_buffer, 0, MAX_BUFF); terminal_buf_count = 0; // __asm__ __volatile("hlt"); } } //terminal_local_echo(); }
//显示文件内容的函数 void cmd_type(CONSOLE *console, int *fat, char *cmdline) { MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR; FILEINFO *finfo = file_search(cmdline + 5, (FILEINFO *)(ADR_DISKIMG + 0x002600), 224); char *img_adr; int i; //文件找到的情况,把内容逐字打印出来 if(0 != finfo) { //文件内容开始的地址赋值给img_adr img_adr = (char *)memmanage_alloc_4K(memmanage, finfo->size); //把可能有间断的文件内容复制到一块儿连续的内存中去,这样就可以直接到这块儿内存进行连续的读取了 file_loadfile(finfo->clusterno, finfo->size, img_adr, fat, (char *)(0x003e00 + ADR_DISKIMG)); for(i = 0; i < finfo->size; i++) { console_putchar(console, img_adr[i], 1); } memmanage_free_4K(memmanage, (int)img_adr, finfo->size); } //文件没有找到的情况,打印出错误信息 else { displayStrings_atLayer(console->layer, 8, console->cursor_y, COL8_FFFFFF, COL8_000000, "File not found!"); console_newline(console); } console_newline(console); return ; }
void commands_loop() { char input[256]; int index = 0; while (1) { char key = keyboard_read(); console_putchar(key); if (key == 13 || key == 10) { // execute command input[index] = '\0'; commands_run(input); memset(input, 0, 256); index = 0; } else { input[index] = key; index++; } } }
void console_putstr1(console_t* console, char* str, int len) { int i; for (i = 0; i < len; ++i) console_putchar(console, str[i], 1); }
int console_putbytes(const char *s, int len) { int i; for (i = 0; i < len; i++) console_putchar(s[i]); return 0; }
void console_putstring( const char *s ) { while(*s) { console_putchar(*s); s++; } }
void isr_handler(registers_t regs) { // Dummy interrupt handler just dumps a status message to the screen ubyte attribute = ATTRIB(VGA_BLK, VGA_WHI); if(interrupt_handlers[regs.interrupt_number] != 0) { isr_t handler = interrupt_handlers[regs.interrupt_number]; handler(regs); } else { console_putstr(attribute, "Interrupt encountered: "); if (regs.interrupt_number >= 19) { console_putstr(attribute, "System reserved interrupt "); } else { console_putstr(attribute, interrupt_types[regs.interrupt_number]); } console_putstr(attribute, "("); console_putint(attribute, regs.interrupt_number); console_putstr(attribute, ")\n"); console_putstr(attribute, "Error code supplied: "); console_putint(attribute, regs.error_code); console_putchar(attribute, '\n'); } }
void console_erase(void) { int l, c, car; car= ' ' | make_colors(BLACK, BLACK); for(l=0; l < CRT_ROWS; l++) for(c=0; c < CRT_COLS; c++) console_putchar(c, l, car); }
//显示整个字符串的函数 void console_putstring_toend(CONSOLE *console, char *string) { for(; 0 != *string ; string++) { console_putchar(console, *string, 1); } return ; }
int console_write(int unit, const void *buffer, int length, int offset) { char *cbuffer = (char *)buffer; while (length > 0) { console_putchar(*cbuffer); cbuffer++; length--; } return 1; }
//显示指定长度字符串的函数 void console_putstring_length(CONSOLE *console, char *string, int length) { int i; for(i = 0; i < length; i++) { console_putchar(console, string[i], 1); } return ; }
void panic (const char *msg, ...) { va_list ap; va_start (ap, msg); console_puts (syscon, "\033[0;31mpanic: "); console_vprintf (syscon, msg, ap); console_putchar (syscon, '\n'); }
int console_puts(const char *str) { int rc; int len = strlen(str); if ((rc = console_putbytes(str, len)) == EOF) return EOF; else return console_putchar('\n'); }
/* * This is more efficient for console output, and allows similar treatment * in usermode where character based output is really bad. */ int console_putbytes(const char *s, int len) { base_critical_enter(); while (len) { console_putchar(*s++); len--; } base_critical_leave(); return 0; }
static OSKIT_COMDECL read(oskit_ttystream_t *si, void *buf, oskit_u32_t len, oskit_u32_t *out_actual) { int i = 0, c; char *str = (char *) buf; /* implement simple line discipline */ while (i < len) { c = console_getchar(); if (c == EOF) break; if (my_termios.c_lflag & ICANON) { if (c == '\r') c = '\n'; else if (c == '\b') { if (i > 0) { if (my_termios.c_lflag & ECHO) { console_putchar(c); console_putchar(' '); console_putchar(c); } i--; } continue; } else if (c == '\025') { /* ^U -- kill line */ while (i) { if (my_termios.c_lflag & ECHO) { console_putchar('\b'); console_putchar(' '); console_putchar('\b'); } i--; } str[0] = '\0'; continue; } } if (my_termios.c_lflag & ECHO) console_putchar(c); str[i++] = c; if (c == '\n' && (my_termios.c_lflag & ICANON)) break; } if (i < len && (my_termios.c_lflag & ICANON)) str[i] = '\0'; *out_actual = i; return 0; }
/** * @brief Prints contents of a single file * @param fname Name of file to be printed */ void cat_file(const char *fname) { char abs_path[WORKING_DIRECTORY_PATH_BUFFER_SIZE]; char c; get_abs_path(fname, abs_path); struct iso_file *file = iso_fopen(abs_path, 3); if (!file) { console_printf("cat: %s does not exist\n", fname); iso_fclose(file); return; } while (!file->at_EOF) { iso_fread(&c, 1, 1, file); console_putchar(c); } iso_fclose(file); }
//书上P414有详解 int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax) { int cs_base = *((int *) 0xfe8); CONSOLE *console = (CONSOLE *) *((int *) 0x0fec); TASK *task = task_now(); if (edx == 1) { console_putchar(console, eax & 0xff, 1); } else if (edx == 2) { console_putstring_toend(console, (char *) ebx + cs_base); } else if (edx == 3) { console_putstring_length(console, (char *) ebx + cs_base, ecx); } //设置为,如果传入的edx值为4,则退出这个程序 else if(edx == 4) { return &(task->tss.esp0); } return 0; }
int console_putstring(char *str) { while (*str) console_putchar(*str++); return 0; }
static void put(int x, int y, int c) { console_putchar(x, y, (c | colors) & CH_MASK); }
/* * Note dependency on the kernel library. */ int putchar(int c) { return console_putchar(c); }
void _ttywrch(int ch) { // sendchar (ch); telnet_putchar_all(ch); console_putchar(ch); }
void console_puts(volatile char *str) { while(*str != 0) { console_putchar(*str); str++; } }
void console_task(layer_t* layer, unsigned int memtotal) { #define INPUT_BEG_POS_X (16) #define INPUT_BEG_POS_Y (28) timer_t* timer; task_t* task = task_now(); mem_mgr_t* memmgr = (mem_mgr_t*)MEMMGR_ADDR; int data, fifobuf[128]; int* fat = (int*)mem_mgr_alloc_4k(memmgr, 4 * 2880); char cmdline[32]; console_t console; console.layer = layer; console.cur_x = 8; console.cur_y = INPUT_BEG_POS_Y; console.cur_c = -1; *((int*)0x0fec) = (int)&console; fifo_init(&task->fifo, fifobuf, 128, task); timer = timer_alloc(); timer_init(timer, &task->fifo, 1); timer_settimer(timer, 50); file_readfat(fat, (unsigned char*)(ADR_DISKIMG + 0x000200)); /* display the prompt of console window */ console_putchar(&console, '>', 1); for ( ; ; ) { io_cli(); if (0 == fifo_size(&task->fifo)) { task_sleep(task); io_sti(); } else { data = fifo_get(&task->fifo); io_sti(); if (data <= 1) { /* timer for cursor */ if (0 != data) { timer_init(timer, &task->fifo, 0); if (console.cur_c >= 0) console.cur_c = COLOR8_FFFFFF; } else { timer_init(timer, &task->fifo, 1); if (console.cur_c >= 0) console.cur_c = COLOR8_000000; } timer_settimer(timer, 50); } if (2 == data) /* cursor ON */ console.cur_c = COLOR8_FFFFFF; if (3 == data) { /* cursor OFF */ fill_box8(layer->buf, layer->w_size, COLOR8_000000, console.cur_x, console.cur_y, console.cur_x + 7, console.cur_y + 15); console.cur_c = -1; } if (256 <= data && data <= 511) { /* keyboard data */ if ((8 + 256) == data) { /* backspace */ if (console.cur_x > INPUT_BEG_POS_X) { /* erase the cursor and move forward one character */ console_putchar(&console, ' ', 0); console.cur_x -= 8; } } else if ((10 + 256) == data) { /* Enter Key */ /* erase cursor by space */ console_putchar(&console, ' ', 0); cmdline[console.cur_x / 8 - 2] = 0; console_newline(&console); console_runcmd(&console, cmdline, fat, memtotal); /* show the prompt */ console_putchar(&console, '>', 1); } else { /* general character */ if (console.cur_x < 240) { /* display one character and move backward one character */ cmdline[console.cur_x / 8 - 2] = data - 256; console_putchar(&console, data - 256, 1); } } } /* show the cursor again */ if (console.cur_c >= 0) { fill_box8(layer->buf, layer->w_size, console.cur_c, console.cur_x, console.cur_y, console.cur_x + 7, console.cur_y + 15); } layers_refresh(layer, console.cur_x, console.cur_y, console.cur_x + 8, console.cur_y + 16); } } }
int* toy_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax) { int ds_base = *((int*)0x0fe8); task_t* task = task_now(); console_t* console = (console_t*)(*((int*)0x0fec)); layer_mgr_t* layermgr = (layer_mgr_t*)(*((int*)0x0fe4)); layer_t* layer; int* reg = &eax + 1; /* address after eax */ /* * force to modify value of pushad * reg[0] : edi, reg[1] : esi, reg[2] : ebp, reg[3] : esp * reg[4] : ebx, reg[5] : edx, reg[6] : ecx, reg[7] : eax */ switch (edx) { case 1: console_putchar(console, eax & 0xff, 1); break; case 2: console_putstr0(console, (char*)ebx + ds_base); break; case 3: console_putstr1(console, (char*)ebx + ds_base, ecx); break; case 4: return &(task->tss.esp0); case 5: { layer = layer_alloc(layermgr); layer_setbuf(layer, (char*)ebx + ds_base, esi, edi, eax); make_window8((char*)ebx + ds_base, esi, edi, (char*)ecx + ds_base, 0); layer_slide(layer, 100, 50); layer_updown(layer, 3); reg[7] = (int)layer; } break; case 6: { layer = (layer_t*)ebx; draw_font8_asc(layer->buf, layer->w_size, esi, edi, eax, (char*)ebp + ds_base); layers_refresh(layer, esi, edi, esi + ecx * 8, edi + 16); } break; case 7: { layer = (layer_t*)ebx; fill_box8(layer->buf, layer->w_size, ebp, eax, ecx, esi, edi); layers_refresh(layer, eax, ecx, esi + 1, edi + 1); } break; case 8: { mem_mgr_init((mem_mgr_t*)(ebx + ds_base)); ecx &= 0xfffffff0; /* unit: 16bytes */ mem_mgr_free((mem_mgr_t*)(ebx + ds_base), eax, ecx); } break; case 9: { ecx = (ecx + 0x0f) & 0xfffffff0; reg[7] = mem_mgr_alloc((mem_mgr_t*)(ebx + ds_base), ecx); } break; case 10: { ecx = (ecx + 0x0f) & 0xfffffff0; mem_mgr_free((mem_mgr_t*)(ebx + ds_base), eax, ecx); } break; } return 0; }
//命令行窗口任务 void console_task(LAYER *layer, unsigned int mem_total) { TIMER *timer; TASK *task = task_now(); int i, fifobuf[128]; MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR; int *fat = (int *)memmanage_alloc_4K(memmanage, 4 * 2880); //用来存储FAT表的内存地址 char cmdline[30]; //cmdline用来记录在命令行中输入的命令 CONSOLE console; console.layer = layer; console.cursor_x = 16; console.cursor_y = 28; console.cursor_color = -1; *((int *) 0x0fec) = (int)&console; file_readfat(fat, (unsigned char *)(ADR_DISKIMG + 0x000200)); //FAT表从第3个扇区开始,占用了共9个扇区 init_fifo(&task->fifo, 128, fifobuf, task); timer = timer_alloc(); timer_init(timer, &task->fifo, 1); timer_set(timer, 50); //显示提示字符 displayStrings_atLayer(layer, 8, 28, COL8_FFFFFF, COL8_000000, ">"); for(;;) { io_cli(); if(0 == fifo_status(&task->fifo)) { task_sleep(task); io_sti(); } else { //这里传出来的i直接就是键盘的对应键的字符加上一个键盘偏移量,不需要再转化了,只需要减去偏移量即可 i = fifo_get(&task->fifo); io_sti(); //计时器的中断数据处理(在这里就是光标的闪烁) if(1 == i || 0 == i) //等于1或者0 { if(1 == i) { if(console.cursor_color >= 0) { console.cursor_color = COL8_FFFFFF; } timer_init(timer, &task->fifo, 0); } else { if(console.cursor_color >= 0) { console.cursor_color = COL8_000000; } timer_init(timer, &task->fifo, 1); } timer_set(timer, 50); } //光标ON if(2 == i) { console.cursor_color = COL8_FFFFFF; } //光标OFF if(3 == i) { drawRectangle(layer->buffer, layer->length, COL8_000000, console.cursor_x, console.cursor_y, 2, 15); console.cursor_color = -1; } //键盘数据的处理(主要是命令的处理) if(keyboard_offset <= i && i <= keyboard_offset + 255) { //如果是“退格键”的情况 if(8 + keyboard_offset == i) { //不能删除最前面的提示符,而且只能在有字符的时候才能删除 if(console.cursor_x > 16) { //首先用空格擦除光标,光标横坐标减8之后,再把要删除的那个字符用空格擦除 console_putchar(&console, ' ', 0); console.cursor_x -= 8; console_putchar(&console, ' ', 0); } } //如果是“回车键”的情况 else if(10 + keyboard_offset == i) { console_putchar(&console, ' ', 0); cmdline[console.cursor_x / 8 - 2] = 0; console_newline(&console); //运行命令 console_runcmd(cmdline, &console, fat, mem_total); //显示提示字符 console_putchar(&console, '>', 1); } //如果是一般字符的情况 else { if(console.cursor_x < 240) { cmdline[console.cursor_x / 8 - 2] = i - keyboard_offset; console_putchar(&console, i - keyboard_offset, 1); } } } //重新显示光标 if(console.cursor_color >= 0) { drawRectangle(layer->buffer, layer->length, console.cursor_color, console.cursor_x, console.cursor_y, 2, 15); } layer_part_refresh(layer, console.cursor_x, console.cursor_y, console.cursor_x + 8, console.cursor_y + 16); } } }
void console_putstr0(console_t* console, char* str) { for ( ; 0 != *str; ++str) console_putchar(console, *str, 1); }
/* * Sends a character via the "debug TX" USART. */ void debug_putchar(const char message) { #ifndef NDEBUG console_putchar(message); #endif }