2 创建命令行窗口(harib14b)

所谓命令行窗口,就是大家在运行“make run”的时候所使用的那个黑底白字的,在里面输入文件名就可以运行程序的东西。接下来我们就做一个试试看。

“这玩意儿能算是命令行窗口吗?”我们一开始做出来的东西很可能带来这样的疑问,不过没关系,我们会让它逐步发展壮大,最终实现可以启动应用程序的功能。你看,是不是越来越像个操作系统的样子了呢?大家一定迫不及待了吧。

我们并不打算将命令行窗口作为任务A的一部分,而是单独做成一个新的任务。这样一来,就像任务B0~B2一样,我们可以很容易地创建多个命令行窗口。

我们对任务B的程序进行一些修改,并将任务A程序的一部分融合进去,就写成了下面这个样子。计数我们已经玩腻了,所以把计数的代码从任务B中删除。

本次的bootpack.c节选

  1. void HariMain(void)
  2. {
  3. (中略)
  4. /* sht_cons */
  5. sht_cons = sheet_alloc(shtctl);
  6. buf_cons = (unsigned char *) memman_alloc_4k(memman, 256 * 165);
  7. sheet_setbuf(sht_cons, buf_cons, 256, 165, -1); /*无透明色*/
  8. make_window8(buf_cons, 256, 165, "console", 0);
  9. make_textbox8(sht_cons, 8, 28, 240, 128, COL8_000000);
  10. task_cons = task_alloc();
  11. task_cons->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;
  12. task_cons->tss.eip = (int) &console_task;
  13. task_cons->tss.es = 1 * 8;
  14. task_cons->tss.cs = 2 * 8;
  15. task_cons->tss.ss = 1 * 8;
  16. task_cons->tss.ds = 1 * 8;
  17. task_cons->tss.fs = 1 * 8;
  18. task_cons->tss.gs = 1 * 8;
  19. *((int *) (task_cons->tss.esp + 4)) = (int) sht_cons;
  20. task_run(task_cons, 2, 2); /* level=2, priority=2 */
  21. (中略)
  22. sheet_slide(sht_back, 0, 0);
  23. sheet_slide(sht_cons, 32, 4);
  24. sheet_slide(sht_win, 64, 56);
  25. sheet_slide(sht_mouse, mx, my);
  26. sheet_updown(sht_back, 0);
  27. sheet_updown(sht_cons, 1);
  28. sheet_updown(sht_win, 2);
  29. sheet_updown(sht_mouse, 3);
  30. (中略)
  31. }
  32. void console_task(struct SHEET *sheet)
  33. {
  34. struct FIFO32 fifo;
  35. struct TIMER *timer;
  36. struct TASK *task = task_now();
  37. int i, fifobuf[128], cursor_x = 8, cursor_c = COL8_000000;
  38. fifo32_init(&fifo, 128, fifobuf, task);
  39. timer = timer_alloc();
  40. timer_init(timer, &fifo, 1);
  41. timer_settime(timer, 50);
  42. for (;;) {
  43. io_cli();
  44. if (fifo32_status(&fifo) == 0) {
  45. task_sleep(task);
  46. io_sti();
  47. } else {
  48. i = fifo32_get(&fifo);
  49. io_sti();
  50. if (i <= 1) { /*光标用定时器*/
  51. if (i != 0) {
  52. timer_init(timer, &fifo, 0); /*下次置0 */
  53. cursor_c = COL8_FFFFFF;
  54. } else {
  55. timer_init(timer, &fifo, 1); /*下次置1 */
  56. cursor_c = COL8_000000;
  57. }
  58. timer_settime(timer, 50);
  59. boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
  60. sheet_refresh(sheet, cursor_x, 28, cursor_x + 8, 44);
  61. }
  62. }
  63. }
  64. }

有一个地方需要解释一下,就是console_task中task = task_now(); 这里。在console_task中需要执行休眠,因此必须要知道自己本身的TASK结构所在的内存地址。由于HariMain中准备了task_cons,可以像sheet那样从HariMain传入这个地址,但那样也有点过于繁琐了。忽然想到在mtask.c中不是有个task_now函数吗,就用它来获取TASK地址好了。

■■■■■

我们来“make run”,结果如下。

2 创建命令行窗口(harib14b) - 图1

看上去像不像命令行窗口的样子?

作为我们的命令行窗口雏形,看上去还不赖。