3 增加窗口数量(harib13c)

在16.1节中我们已经对任务的新增做了简化,因此接下来我们要为系统增加更多的任务,即形成任务A、任务B0、任务B1和任务B2的格局。

任务B0~B2各自拥有自己的窗口,它们的功能都一样,即进行计数,这有点像在Windows中启动了一个应用程序及其2个副本的感觉。对了,任务A的3秒定时和10秒定时我们已经不需要了,因此将它们删去。

本次的bootpack.c节选

  1. void HariMain(void)
  2. {
  3. (中略)
  4. unsigned char *buf_back, buf_mouse[256], *buf_win, *buf_win_b;
  5. struct SHEET *sht_back, *sht_mouse, *sht_win, *sht_win_b[3];
  6. struct TASK *task_a, *task_b[3];
  7. struct TIMER *timer;
  8. (中略)
  9. init_palette();
  10. shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
  11. task_a = task_init(memman);
  12. fifo.task = task_a;
  13. /* sht_back */
  14. sht_back = sheet_alloc(shtctl);
  15. buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);
  16. sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /*无透明色 */
  17. init_screen8(buf_back, binfo->scrnx, binfo->scrny);
  18. /* sht_win_b */
  19. for (i = 0; i < 3; i++) {
  20. sht_win_b[i] = sheet_alloc(shtctl);
  21. buf_win_b = (unsigned char *) memman_alloc_4k(memman, 144 * 52);
  22. sheet_setbuf(sht_win_b[i], buf_win_b, 144, 52, -1); /*无透明色*/
  23. sprintf(s, "task_b%d", i);
  24. make_window8(buf_win_b, 144, 52, s, 0);
  25. task_b[i] = task_alloc();
  26. task_b[i]->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;
  27. task_b[i]->tss.eip = (int) &task_b_main;
  28. task_b[i]->tss.es = 1 * 8;
  29. task_b[i]->tss.cs = 2 * 8;
  30. task_b[i]->tss.ss = 1 * 8;
  31. task_b[i]->tss.ds = 1 * 8;
  32. task_b[i]->tss.fs = 1 * 8;
  33. task_b[i]->tss.gs = 1 * 8;
  34. *((int *) (task_b[i]->tss.esp + 4)) = (int) sht_win_b[i];
  35. task_run(task_b[i]);
  36. }
  37. /* sht_win */
  38. sht_win = sheet_alloc(shtctl);
  39. buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52);
  40. sheet_setbuf(sht_win, buf_win, 144, 52, -1); /*无透明色*/
  41. make_window8(buf_win, 144, 52, "task_a", 1);
  42. make_textbox8(sht_win, 8, 28, 128, 16, COL8_FFFFFF);
  43. cursor_x = 8;
  44. cursor_c = COL8_FFFFFF;
  45. timer = timer_alloc();
  46. timer_init(timer, &fifo, 1);
  47. timer_settime(timer, 50);
  48. /* sht_mouse */
  49. sht_mouse = sheet_alloc(shtctl);
  50. sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
  51. init_mouse_cursor8(buf_mouse, 99);
  52. mx = (binfo->scrnx - 16) / 2; /*计算坐标使其位于画面中央*/
  53. my = (binfo->scrny - 28 - 16) / 2;
  54. sheet_slide(sht_back, 0, 0);
  55. sheet_slide(sht_win_b[0], 168, 56);
  56. sheet_slide(sht_win_b[1], 8, 116);
  57. sheet_slide(sht_win_b[2], 168, 116);
  58. sheet_slide(sht_win, 8, 56);
  59. sheet_slide(sht_mouse, mx, my);
  60. sheet_updown(sht_back, 0);
  61. sheet_updown(sht_win_b[0], 1);
  62. sheet_updown(sht_win_b[1], 2);
  63. sheet_updown(sht_win_b[2], 3);
  64. sheet_updown(sht_win, 4);
  65. sheet_updown(sht_mouse, 5);
  66. sprintf(s, "(%3d, %3d)", mx, my);
  67. putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10);
  68. sprintf(s, "memory %dMB free : %dKB",
  69. memtotal / (1024 * 1024), memman_total(memman) / 1024);
  70. putfonts8_asc_sht(sht_back, 0, 32, COL8_FFFFFF, COL8_008484, s, 40);
  71. for (;;) {
  72. io_cli();
  73. if (fifo32_status(&fifo) == 0) {
  74. task_sleep(task_a);
  75. io_sti();
  76. } else {
  77. i = fifo32_get(&fifo);
  78. io_sti();
  79. if (256 <= i && i <= 511) { /*键盘数据*/
  80. (中略)
  81. } else if (512 <= i && i <= 767) { /*光标用定时器*/
  82. (中略)
  83. } else if (i <= 1) { /*光标用定时器*/
  84. (中略)
  85. }
  86. }
  87. }
  88. }
  89. void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act)
  90. {
  91. (中略)
  92. char c, tc, tbc;
  93. if (act != 0) {
  94. tc = COL8_FFFFFF;
  95. tbc = COL8_000084;
  96. } else {
  97. tc = COL8_C6C6C6;
  98. tbc = COL8_848484;
  99. }
  100. (中略)
  101. boxfill8(buf, xsize, tbc, 3, 3, xsize - 4, 20 );
  102. boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2);
  103. boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1);
  104. putfonts8_asc(buf, xsize, 24, 4, tc, title);
  105. for (y = 0; y < 14; y++) {
  106. (中略)
  107. }
  108. return;
  109. }
  110. void task_b_main(struct SHEET *sht_win_b)
  111. {
  112. struct FIFO32 fifo;
  113. struct TIMER *timer_1s;
  114. int i, fifobuf[128], count = 0, count0 = 0;
  115. char s[12];
  116. fifo32_init(&fifo, 128, fifobuf, 0);
  117. timer_1s = timer_alloc();
  118. timer_init(timer_1s, &fifo, 100);
  119. timer_settime(timer_1s, 100);
  120. for (;;) {
  121. count++;
  122. io_cli();
  123. if (fifo32_status(&fifo) == 0) {
  124. io_sti();
  125. } else {
  126. i = fifo32_get(&fifo);
  127. io_sti();
  128. if (i == 100) {
  129. sprintf(s, "%11d", count - count0);
  130. putfonts8_asc_sht(sht_win_b, 24, 28, COL8_000000, COL8_C6C6C6, s, 11);
  131. count0 = count;
  132. timer_settime(timer_1s, 100);
  133. }
  134. }
  135. }
  136. }

这次的代码相当长,不过我们只是对之前的程序进行了整理,难度并没有提高。不要被代码的长度吓倒,只要静下心来仔细读一读,应该很快就会理解的。

在make_window8中我们增加了一个act变量。当act为1时,颜色不变,当为0时,窗口的标题栏(就是显示窗口名称的地方)会变成灰色。task_b_main中,去掉了每0.01秒显示一次count的部分,只保留每1秒显示速度的功能。

■■■■■

我们来运行一下,“make run”。怎么样,是不是感觉更像操作系统了呢?对了,现在只有任务A的窗口是可以拖动的(因为移动窗口的部分没有改写进去)。

任务B0~B2这3个任务基本上是以同样的速度在运行。在模拟器环境下它们的速度会有所差异,但在真机环境下还是十分接近的,如下:

4684200   4684800   4684800

3 增加窗口数量(harib13c) - 图1

4个任务在同时工作

看来运行非常成功。