diff --git a/20_day/bootpack.h b/20_day/bootpack.h index 91618b5..bea8757 100644 --- a/20_day/bootpack.h +++ b/20_day/bootpack.h @@ -228,8 +228,19 @@ void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c); void make_wtitle8(unsigned char *buf, int xsize, char *title, char act); /* console.c */ +struct CONSOLE { + struct SHEET *sht; + int cur_x, cur_y, cur_c; +}; void console_task(struct SHEET *sheet, unsigned int memtotal); -int cons_newline(int cursor_y, struct SHEET *sheet); +void cons_putchar(struct CONSOLE *cons, int chr, char move); +void cons_newline(struct CONSOLE *cons); +void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, unsigned int memtotal); +void cmd_mem(struct CONSOLE *cons, unsigned int memtotal); +void cmd_cls(struct CONSOLE *cons); +void cmd_dir(struct CONSOLE *cons); +void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline); +void cmd_hlt(struct CONSOLE *cons, int *fat); /* file.c */ struct FILEINFO { @@ -240,3 +251,4 @@ struct FILEINFO { }; void file_readfat(int *fat, unsigned char *img); void file_loadfile(int clustno, int size, char *buf, int *fat, char *img); +struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max); diff --git a/20_day/console.c b/20_day/console.c index b77b299..3eec55c 100644 --- a/20_day/console.c +++ b/20_day/console.c @@ -8,13 +8,14 @@ void console_task(struct SHEET *sheet, unsigned int memtotal) { struct TIMER *timer; struct TASK *task = task_now(); - int i, fifobuf[128], cursor_x = 16, cursor_y = 28, cursor_c = -1; - char s[30], cmdline[30], *p; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; - int x, y; - struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); - int *fat = (int *) memman_alloc_4k(memman, 4 * 2880); - struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; + int i, fifobuf[128], *fat = (int *) memman_alloc_4k(memman, 4 * 2880); + struct CONSOLE cons; + char cmdline[30]; + cons.sht = sheet; + cons.cur_x = 8; + cons.cur_y = 28; + cons.cur_c = -1; fifo32_init(&task->fifo, 128, fifobuf, task); timer = timer_alloc(); @@ -23,12 +24,11 @@ void console_task(struct SHEET *sheet, unsigned int memtotal) file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); /*显示提示符*/ - putfonts8_asc_sht(sheet, 8, 28, COL8_FFFFFF, COL8_000000, ">", 1); - + cons_putchar(&cons, '>', 1); for (;;) { io_cli(); if (fifo32_status(&task->fifo) == 0) { - task_sleep(task); + task_sleep(task); io_sti(); } else { i = fifo32_get(&task->fifo); @@ -36,230 +36,98 @@ void console_task(struct SHEET *sheet, unsigned int memtotal) if (i <= 1) { /*光标用定时器*/ if (i != 0) { timer_init(timer, &task->fifo, 0); /*下次置0 */ - if (cursor_c >= 0) { - cursor_c = COL8_FFFFFF; + if (cons.cur_c >= 0) { + cons.cur_c = COL8_FFFFFF; } } else { timer_init(timer, &task->fifo, 1); /*下次置1 */ - if (cursor_c >= 0) { - cursor_c = COL8_000000; + if (cons.cur_c >= 0) { + cons.cur_c = COL8_000000; } } timer_settime(timer, 50); } if (i == 2) { /*光标ON */ - cursor_c = COL8_FFFFFF; + cons.cur_c = COL8_FFFFFF; } if (i == 3) { /*光标OFF */ - boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); - cursor_c = -1; + boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15); + cons.cur_c = -1; } - if (256 <= i && i <= 511) { /*键盘数据(通过任务A) */ + if (256 <= i && i <= 511) { /*键盘数据(通过任务A)*/ if (i == 8 + 256) { /*退格键*/ - if (cursor_x > 16) { - /*用空白擦除光标后将光标前移一位*/ - putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); - cursor_x -= 8; + if (cons.cur_x > 16) { + /*用空格擦除光标后将光标前移一位*/ + cons_putchar(&cons, ' ', 0); + cons.cur_x -= 8; } } else if (i == 10 + 256) { /*回车键*/ - /*用空格将光标擦除*/ - putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); - cmdline[cursor_x / 8 - 2] = 0; - cursor_y = cons_newline(cursor_y, sheet); - /*执行命令*/ - if (strcmp(cmdline, "mem") == 0) { - /* mem命令*/ - sprintf(s, "total %dMB", memtotal / (1024 * 1024)); - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); - cursor_y = cons_newline(cursor_y, sheet); - sprintf(s, "free %dKB", memman_total(memman) / 1024); - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); - cursor_y = cons_newline(cursor_y, sheet); - cursor_y = cons_newline(cursor_y, sheet); - } else if (strcmp(cmdline, "cls") == 0) { - /* cls命令*/ - for (y = 28; y < 28 + 128; y++) { - for (x = 8; x < 8 + 240; x++) { - sheet->buf[x + y * sheet->bxsize] = COL8_000000; - } - } - sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); - cursor_y = 28; - } else if (strcmp(cmdline, "dir") == 0 || strcmp(cmdline, "ls") == 0) { - /* dir命令 */ - for (x = 0; x < 224; x++) { - if (finfo[x].name[0] == 0x00) { - break; - } - if (finfo[x].name[0] != 0xe5) { - if ((finfo[x].type & 0x18) == 0) { - sprintf(s, "filename.ext %7d", finfo[x].size); - for (y = 0; y < 8; y++) { - s[y] = finfo[x].name[y]; - } - s[ 9] = finfo[x].ext[0]; - s[10] = finfo[x].ext[1]; - s[11] = finfo[x].ext[2]; - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); - cursor_y = cons_newline(cursor_y, sheet); - } - } - } - cursor_y = cons_newline(cursor_y, sheet); - } else if (strncmp(cmdline, "type ", 5) == 0 ) { - /* type命令*/ - /*准备文件名*/ - for (y = 0; y < 11; y++) { - s[y] = ' '; - } - y = 0; - for (x = 5; y < 11 && cmdline[x] != 0; x++) { - if (cmdline[x] == '.' && y <= 8) { - y = 8; - } else { - s[y] = cmdline[x]; - if ('a' <= s[y] && s[y] <= 'z') { - /*将小写字母转换成大写字母 */ - s[y] -= 0x20; - } - y++; - } - } - /*寻找文件*/ - for (x = 0; x < 224; ) { - if (finfo[x].name[0] == 0x00) { - break; - } - if ((finfo[x].type & 0x18) == 0) { - for (y = 0; y < 11; y++) { - if (finfo[x].name[y] != s[y]) { - goto type_next_file; - } - } - break; /*找到文件*/ - } - type_next_file: - x++; - } - if (x < 224 && finfo[x].name[0] != 0x00) { - /*找到文件的情况*/ - y = finfo[x].size; - p = (char *) memman_alloc_4k(memman, finfo[x].size); - file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); - cursor_x = 8; - for (y = 0; y < finfo[x].size; y++) { - /*逐字输出*/ - s[0] = p[y]; - s[1] = 0; - if (s[0] == 0x09) { /*制表符*/ - for (;;) { - putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); - cursor_x += 8; - if (cursor_x == 8 + 240) { - cursor_x = 8; - cursor_y = cons_newline(cursor_y, sheet); - } - if (((cursor_x - 8) & 0x1f) == 0) { - break; /*被32整除则break */ - } - } - } else if (s[0] == 0x0a) { /*换行*/ - cursor_x = 8; - cursor_y = cons_newline(cursor_y, sheet); - } else if (s[0] == 0x0d) { /*回车*/ - /*这里暂且不进行任何操作*/ - } else { /*一般字符*/ - putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); - cursor_x += 8; - if (cursor_x == 8 + 240) { - cursor_x = 8; - cursor_y = cons_newline(cursor_y, sheet); - } - } - } - memman_free_4k(memman, (int) p, finfo[x].size); - } else { - /*没有找到文件的情况*/ - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); - cursor_y = cons_newline(cursor_y, sheet); - } - cursor_y = cons_newline(cursor_y, sheet); - } else if (strcmp(cmdline, "hlt") == 0) { - /*启动应用程序hlt.hrb */ - for (y = 0; y < 11; y++) { - s[y] = ' '; - } - s[0] = 'H'; - s[1] = 'L'; - s[2] = 'T'; - s[8] = 'H'; - s[9] = 'R'; - s[10] = 'B'; - for (x = 0; x < 224; ) { - if (finfo[x].name[0] == 0x00) { - break; - } - if ((finfo[x].type & 0x18) == 0) { - for (y = 0; y < 11; y++) { - if (finfo[x].name[y] != s[y]) { - goto hlt_next_file; - } - } - break; /*找到文件*/ - } - hlt_next_file: - x++; - } - if (x < 224 && finfo[x].name[0] != 0x00) { - /*找到文件的情况*/ - p = (char *) memman_alloc_4k(memman, finfo[x].size); - file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); - set_segmdesc(gdt + 1003, finfo[x].size - 1, (int) p, AR_CODE32_ER); - farjmp(0, 1003 * 8); - memman_free_4k(memman, (int) p, finfo[x].size); - } else { - /*没有找到文件的情况*/ - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); - cursor_y = cons_newline(cursor_y, sheet); - } - cursor_y = cons_newline(cursor_y, sheet); - } else if (cmdline[0] != 0) { - /*不是命令,也不是空行 */ - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "Bad command.", 12); - cursor_y = cons_newline(cursor_y, sheet); - cursor_y = cons_newline(cursor_y, sheet); - } + /*将光标用空格擦除后换行 */ + cons_putchar(&cons, ' ', 0); + cmdline[cons.cur_x / 8 - 2] = 0; + cons_newline(&cons); + cons_runcmd(cmdline, &cons, fat, memtotal); /*运行命令*/ /*显示提示符*/ - putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); - cursor_x = 16; + cons_putchar(&cons, '>', 1); } else { /*一般字符*/ - if (cursor_x < 240) { - /*显示一个字符之后将光标后移一位 */ - s[0] = i - 256; - s[1] = 0; - cmdline[cursor_x / 8 - 2] = i - 256; - putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); - cursor_x += 8; + if (cons.cur_x < 240) { + /*显示一个字符之后将光标后移一位*/ + cmdline[cons.cur_x / 8 - 2] = i - 256; + cons_putchar(&cons, i - 256, 1); } } } /*重新显示光标*/ - if (cursor_c >= 0) { - boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); + if (cons.cur_c >= 0) { + boxfill8(sheet->buf, sheet->bxsize, cons.cur_c, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15); + } + sheet_refresh(sheet, cons.cur_x, cons.cur_y, cons.cur_x + 8, cons.cur_y + 16); + } + } +} + +void cons_putchar(struct CONSOLE *cons, int chr, char move) +{ + char s[2]; + s[0] = chr; + s[1] = 0; + if (s[0] == 0x09) { /*制表符*/ + for (;;) { + putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, " ", 1); + cons->cur_x += 8; + if (cons->cur_x == 8 + 240) { + cons_newline(cons); + } + if (((cons->cur_x - 8) & 0x1f) == 0) { + break; /*被32整除则break*/ + } + } + } else if (s[0] == 0x0a) { /*换行*/ + cons_newline(cons); + } else if (s[0] == 0x0d) { /*回车*/ + /*先不做任何操作*/ + } else { /*一般字符*/ + putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 1); + if (move != 0) { + /* move为0时光标不后移*/ + cons->cur_x += 8; + if (cons->cur_x == 8 + 240) { + cons_newline(cons); } - sheet_refresh(sheet, cursor_x, cursor_y, cursor_x + 8, cursor_y + 16); } } + return; } -int cons_newline(int cursor_y, struct SHEET *sheet) +void cons_newline(struct CONSOLE *cons) { int x, y; - if (cursor_y < 28 + 112) { - cursor_y += 16; /*换行*/ + struct SHEET *sheet = cons->sht; + if (cons->cur_y < 28 + 112) { + cons->cur_y += 16; /*到下一行*/ } else { /*滚动*/ for (y = 28; y < 28 + 112; y++) { @@ -274,5 +142,126 @@ int cons_newline(int cursor_y, struct SHEET *sheet) } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); } - return cursor_y; + cons->cur_x = 8; + return; +} + +void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, unsigned int memtotal) +{ + if (strcmp(cmdline, "mem") == 0) { + cmd_mem(cons, memtotal); + } else if (strcmp(cmdline, "cls") == 0) { + cmd_cls(cons); + } else if (strcmp(cmdline, "dir") == 0 || strcmp(cmdline, "ls") == 0) { + cmd_dir(cons); + } else if (strncmp(cmdline, "type ", 5) == 0) { + cmd_type(cons, fat, cmdline); + } else if (strcmp(cmdline, "hlt") == 0) { + cmd_hlt(cons, fat); + } else if (cmdline[0] != 0) { + /*不是命令,也不是空行*/ + putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, "Bad command.", 12); + cons_newline(cons); + cons_newline(cons); + } + return; +} + +void cmd_mem(struct CONSOLE *cons, unsigned int memtotal) +{ + struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; + char s[30]; + sprintf(s, "total %dMB", memtotal / (1024 * 1024)); + putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 30); + cons_newline(cons); sprintf(s, "free %dKB", memman_total(memman) / 1024); + putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 30); + cons_newline(cons); + cons_newline(cons); + return; +} + +void cmd_cls(struct CONSOLE *cons) +{ + int x, y; + struct SHEET *sheet = cons->sht; + for (y = 28; y < 28 + 128; y++) { + for (x = 8; x < 8 + 240; x++) { + sheet->buf[x + y * sheet->bxsize] = COL8_000000; + } + } + sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); + cons->cur_y = 28; + return; +} + +void cmd_dir(struct CONSOLE *cons) +{ + struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); + int i, j; + char s[30]; + for (i = 0; i < 224; i++) { + if (finfo[i].name[0] == 0x00) { + break; + } + if (finfo[i].name[0] != 0xe5) { + if ((finfo[i].type & 0x18) == 0) { + sprintf(s, "filename.ext %7d", finfo[i].size); + for (j = 0; j < 8; j++) { + s[j] = finfo[i].name[j]; + } + s[ 9] = finfo[i].ext[0]; + s[10] = finfo[i].ext[1]; + s[11] = finfo[i].ext[2]; + putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 30); + cons_newline(cons); + } + } + } + cons_newline(cons); + return; +} + +void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline) +{ + struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; + struct FILEINFO *finfo = file_search(cmdline + 5, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); + char *p; + int i; + if (finfo != 0) { + /*找到文件的情况*/ + p = (char *) memman_alloc_4k(memman, finfo->size); + file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); + for (i = 0; i < finfo->size; i++) { + cons_putchar(cons, p[i], 1); + } + memman_free_4k(memman, (int) p, finfo->size); + } else { + /*没有找到文件的情况*/ + putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); + cons_newline(cons); + } + cons_newline(cons); + return; +} + +void cmd_hlt(struct CONSOLE *cons, int *fat) +{ + struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; + struct FILEINFO *finfo = file_search("HLT.HRB", (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); + struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; + char *p; + if (finfo != 0) { + /*找到文件的情况*/ + p = (char *) memman_alloc_4k(memman, finfo->size); + file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); + set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER); + farjmp(0, 1003 * 8); + memman_free_4k(memman, (int) p, finfo->size); + } else { + /*没有找到文件的情况*/ + putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); + cons_newline(cons); + } + cons_newline(cons); + return; } diff --git a/20_day/file.c b/20_day/file.c index c743de9..c289350 100644 --- a/20_day/file.c +++ b/20_day/file.c @@ -33,3 +33,42 @@ void file_loadfile(int clustno, int size, char *buf, int *fat, char *img) } return; } + +struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max) +{ + int i, j; + char s[12]; + for (j = 0; j < 11; j++) { + s[j] = ' '; + } + j = 0; + for (i = 0; name[i] != 0; i++) { + if (j >= 11) { return 0; /*没有找到*/ } + if (name[i] == '.' && j <= 8) { + j = 8; + } else { + s[j] = name[i]; + if ('a' <= s[j] && s[j] <= 'z') { + /*将小写字母转换为大写字母*/ + s[j] -= 0x20; + } + j++; + } + } + for (i = 0; i < max; ) { + if (finfo[i].name[0] == 0x00) { + break; + } + if ((finfo[i].type & 0x18) == 0) { + for (j = 0; j < 11; j++) { + if (finfo[i].name[j] != s[j]) { + goto next; + } + } + return finfo + i; /*找到文件*/ + } + next: + i++; + } + return 0; /*没有找到*/ +}