• R/O
  • SSH
  • HTTPS

nos: 提交


Commit MetaInfo

修訂365 (tree)
時間2009-10-25 12:46:11
作者uchan_nos

Log Message

コンソールをスクロールしすぎるとだめになるバグを修正
そのためにバッファクラスを作成した

Change Summary

差異

--- bitnos5/trunk/kernel/console.cpp (revision 364)
+++ bitnos5/trunk/kernel/console.cpp (revision 365)
@@ -11,6 +11,7 @@
1111 #include <bitnos/window.h>
1212 #include <string.h>
1313 #include <stdio.h>
14+#include <stdlib.h>
1415 #include <bitnos/memory.h>
1516 #include <bitnos/timer.h>
1617 #include <bitnos/specialtask.h>
@@ -18,6 +19,94 @@
1819 namespace TaskConsole
1920 {
2021
22+/* class ScreenBuffer */
23+void ScreenBuffer::Init(int width, int height)
24+{
25+ this->width = width;
26+ this->height = height;
27+ buf = new char[(this->width + 1) * this->height];
28+
29+ begin = 0;
30+}
31+
32+void ScreenBuffer::Dispose()
33+{
34+ delete[] buf;
35+ buf = 0;
36+}
37+
38+void ScreenBuffer::Write(Point pos, char ch)
39+{
40+ if (IsAvailable(pos)) {
41+ pos = Calculate(pos);
42+ buf[pos.Y * (width + 1) + pos.X] = ch;
43+ buf[pos.Y * (width + 1) + pos.X + 1] = '\0';
44+ }
45+}
46+
47+void ScreenBuffer::Write(Point pos, const char* str)
48+{
49+ if (IsAvailable(pos)) {
50+ pos = Calculate(pos);
51+ char* p = buf + pos.Y * (width + 1) + pos.X;
52+ int x;
53+ for (x = pos.X; x < width && *str != '\0'; x++) {
54+ *p++ = *str++;
55+ }
56+ *p = '\0';
57+ }
58+}
59+
60+char ScreenBuffer::Read(Point pos) const
61+{
62+ if (IsAvailable(pos)) {
63+ pos = Calculate(pos);
64+ return buf[pos.Y * (width + 1) + pos.X];
65+ }
66+ return 0;
67+}
68+
69+void ScreenBuffer::Scroll(int lines)
70+{
71+ begin += lines;
72+ if (begin < 0) {
73+ begin += height;
74+ } else if (begin >= height) {
75+ begin -= height;
76+ }
77+}
78+
79+const char* ScreenBuffer::GetPointer(Point pos) const
80+{
81+ if (IsAvailable(pos)) {
82+ pos = Calculate(pos);
83+ return buf + pos.Y * (width + 1) + pos.X;
84+ }
85+ return 0;
86+}
87+
88+bool ScreenBuffer::IsAvailable(Point pos) const
89+{
90+ if (pos.X < 0 || width <= pos.X ||
91+ pos.Y < 0 || height <= pos.Y) {
92+ return false;
93+ }
94+ return true;
95+}
96+
97+Point ScreenBuffer::Calculate(Point pos) const
98+{
99+ pos.Y += begin;
100+
101+ if (pos.Y >= height) {
102+ pos.Y -= height;
103+ }
104+
105+ return pos;
106+}
107+/* end of class ScreenBuffer */
108+
109+
21110 struct Valiables
22111 {
23112 Console cons;
@@ -30,6 +119,8 @@
30119 Timer* tim;
31120 bool cursor;
32121 bool active;
122+
123+ Timer* timBeep;
33124 };
34125
35126 // コマンド実行機能なし
@@ -49,6 +140,9 @@
49140 void ShowCursor(Valiables* o);
50141 void EraseCursor(Valiables* o);
51142
143+void WriteBuffer(Valiables* o, int x, int y, char ch);
144+char ReadBuffer(Valiables* o, int x, int y);
145+
52146 void Init(void* obj)
53147 {
54148 Valiables* o = (Valiables*)obj;
@@ -58,16 +152,16 @@
58152 Debug::WriteLine("Console Init");
59153
60154 //o->cons.height = 10;
61- o->cons.height = 16;
155+ o->cons.height = 10;
62156 // o->cons.width = 29;
63- o->cons.width = 50;
64- //o->cons.bufHeight = 100;
65- o->cons.bufHeight = o->cons.height;
157+ o->cons.width = 29;
158+ o->cons.bufHeight = 20;
66159 //o->cons.bufWidth = 29;
67160 o->cons.bufWidth = o->cons.width;
68161 o->cons.buf = new char[o->cons.bufHeight * o->cons.bufWidth];
69162 o->cons.startLine = o->cons.endLine = 0;
70163 o->cons.xPos = 0;
164+ o->cons.printYPos = 0;
71165 o->cons.backColor = ConvRGB16(0, 0, 0);
72166 o->cons.textColor = ConvRGB16(255, 255, 255);
73167 o->cmdlineBegin = 0;
@@ -74,6 +168,10 @@
74168 o->cursor = false;
75169 o->active = SpecialTask::Get(SpecialTask::Active) == task;
76170
171+ o->cons.sbuf.Init(29, 20);
172+ o->cons.wPos = Point(0, 0);
173+ o->cons.pPos = Point(0, 0);
174+
77175 o->img = new Image(
78176 8 + fontHankaku->GetWidth() * o->cons.width,
79177 25 + 8 + fontHankaku->GetHeight() * o->cons.height);
@@ -88,7 +186,9 @@
88186 o->tim = timman->Alloc(task, 1);
89187 o->tim->SetTime(80);
90188
91- PutChar(o, '>');
189+ o->timBeep = timman->Alloc(task, 2);
190+
191+ PutChar0(o, '>');
92192 }
93193
94194 void Proc(void* obj, Message* msg)
@@ -97,9 +197,9 @@
97197
98198 if (msg->from == Message::From::Keyboard) {
99199 if (msg->arg1 != 0) {
100- if (o->cursor) {
200+ //if (o->cursor) {
101201 EraseCursor(o);
102- }
202+ //}
103203 PutChar(o, msg->arg1);
104204 if (o->cursor) {
105205 ShowCursor(o);
@@ -117,6 +217,12 @@
117217 o->cursor = true;
118218 }
119219 }
220+ } else if (msg->arg1 == 2) {
221+ uint8_t reg = io_in8(0x0061);
222+ //reg |= 0x03;
223+ //reg &= 0x0f;
224+ reg &= 0x0d;
225+ io_out8(0x0061, reg);
120226 }
121227 } else if (msg->from == Message::From::System) {
122228 if (msg->arg1 == Message::System::WindowActivated) {
@@ -130,11 +236,29 @@
130236 }
131237 }
132238
239+void NewLine(Valiables* o)
240+{
241+ if (o->cons.wPos.Y < o->cons.sbuf.GetHeight() - 1) {
242+ o->cons.wPos.Y++;
243+ } else {
244+ o->cons.sbuf.Scroll(1);
245+ o->cons.sbuf.Write(Point(0, o->cons.sbuf.GetHeight() - 1), '\0');
246+ o->cmdlineBegin--;
247+ }
248+ o->cons.wPos.X = 0;
249+ o->cons.pPos.X = 0;
250+ if (o->cons.pPos.Y < o->cons.height - 1) {
251+ o->cons.pPos.Y++;
252+ }
253+}
254+
133255 void PutChar0(Valiables* o, char ch)
134256 {
257+#if 0
135258 // バッファに格納
136259 if (0x20 <= ch && ch < 0x80) {
137- o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = ch;
260+ //o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = ch;
261+ WriteBuffer(o, o->cons.xPos, o->cons.endLine, ch);
138262 o->cons.xPos++;
139263 }
140264 if (ch == '\b') {
@@ -143,43 +267,54 @@
143267 if (o->cons.xPos < 0) {
144268 o->cons.xPos = o->cons.bufWidth - 1;
145269 o->cons.endLine--;
270+ if (o->cons.endLine < 0) {
271+ o->cons.endLine = o->cons.height - 1;
272+ }
273+ if (o->cons.printYPos > 0) {
274+ o->cons.printYPos--;
275+ }
146276 }
147277 } else if (o->cons.endLine == o->cmdlineBegin && o->cons.xPos > 1) {
148278 o->cons.xPos--;
149279 }
150- o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0';
280+ //o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0';
281+ WriteBuffer(o, o->cons.xPos, o->cons.endLine, '\0');
151282 // 1文字だけ消去する
152- int end = o->cons.endLine;
153- if (end >= o->cons.height) {
154- end = o->cons.height - 1;
155- }
156283 o->sht->DrawRectangleFill(
157284 o->cons.backColor,
158285 Point(
159286 4 + fontHankaku->GetWidth() * o->cons.xPos,
160- 25 + 4 + fontHankaku->GetHeight() * end),
287+ 25 + 4 + fontHankaku->GetHeight() * o->cons.printYPos),
161288 Point(
162289 4 + fontHankaku->GetWidth() * (o->cons.xPos + 1) - 1,
163- 25 + 4 + fontHankaku->GetHeight() * (end + 1) - 1)
290+ 25 + 4 + fontHankaku->GetHeight() * (o->cons.printYPos + 1) - 1)
164291 );
165292 } else if (o->cons.bufWidth <= o->cons.xPos || ch == '\n') {
166293 // バッファの右端まで行った、またはエンターキーが押されたから改行
167294 if (o->cons.xPos < o->cons.bufWidth - 1) {
168- o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0';
295+ //o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0';]
296+ WriteBuffer(o, o->cons.xPos, o->cons.endLine, '\0');
169297 }
298+ if (o->cons.printYPos < o->cons.height - 1) {
299+ o->cons.printYPos++;
300+ }
170301 o->cons.xPos = 0;
171302 o->cons.endLine++;
303+ if (o->cons.endLine == o->cons.bufHeight) {
304+ o->cons.endLine = 0;
305+ }
172306 if (o->cons.endLine == o->cons.startLine) {
307+ memset(o->cons.buf + o->cons.endLine * o->cons.bufWidth, '\0', o->cons.bufWidth);
173308 o->cons.startLine++;
309+ if (o->cons.startLine == o->cons.bufHeight) {
310+ o->cons.startLine = 0;
311+ }
174312 }
313+ Debug::WriteLine("start=%d,end=%d", o->cons.startLine, o->cons.endLine);
175314 // 画面全体を描画しなおす
176315 ConsoleRefreshScreen(o, o->cons.endLine - o->cons.height + 1);
177316 } else {
178317 // 改行しなかった
179- int end = o->cons.endLine;
180- if (end >= o->cons.height) {
181- end = o->cons.height - 1;
182- }
183318 // 1文字だけ描画する
184319 o->sht->DrawChar(
185320 o->cons.textColor,
@@ -186,9 +321,54 @@
186321 ch,
187322 Point(
188323 4 + fontHankaku->GetWidth() * (o->cons.xPos - 1),
189- 25 + 4 + fontHankaku->GetHeight() * end),
324+ 25 + 4 + fontHankaku->GetHeight() * o->cons.printYPos),
190325 fontHankaku);
191326 }
327+#endif
328+ if (0x20 <= ch && ch < 0x80) {
329+ o->cons.sbuf.Write(o->cons.wPos, ch);
330+ o->cons.wPos.X++;
331+ if (o->cons.pPos.X < o->cons.width - 1) {
332+ o->cons.pPos.X++;
333+ }
334+ }
335+ if (ch == '\b') {
336+ if ((o->cons.wPos.Y != o->cmdlineBegin && o->cons.wPos.X > 0) ||
337+ (o->cons.wPos.Y == o->cmdlineBegin && o->cons.wPos.X > 1)) {
338+ o->cons.wPos.X--;
339+ if (o->cons.pPos.X > 0) {
340+ o->cons.pPos.X--;
341+ }
342+ } else if (o->cons.wPos.Y != o->cmdlineBegin && o->cons.wPos.X == 0) {
343+ o->cons.wPos.X = o->cons.sbuf.GetWidth() - 1;
344+ o->cons.wPos.Y--;
345+ o->cons.pPos.X = o->cons.width - 1;
346+ if (o->cons.pPos.Y > 0) {
347+ o->cons.pPos.Y--;
348+ }
349+ }
350+ o->cons.sbuf.Write(o->cons.wPos, '\0');
351+ o->sht->DrawRectangleFill(
352+ o->cons.backColor,
353+ Point(
354+ 4 + fontHankaku->GetWidth() * o->cons.pPos.X,
355+ 25 + 4 + fontHankaku->GetHeight() * o->cons.pPos.Y),
356+ Point(
357+ 4 + fontHankaku->GetWidth() * (o->cons.pPos.X + 1) - 1,
358+ 25 + 4 + fontHankaku->GetHeight() * (o->cons.pPos.Y + 1) - 1)
359+ );
360+ } else if (ch == '\n' || o->cons.wPos.X >= o->cons.sbuf.GetWidth()) {
361+ NewLine(o);
362+ ConsoleRefreshScreen(o, -1);
363+ } else {
364+ o->sht->DrawChar(
365+ o->cons.textColor,
366+ ch,
367+ Point(
368+ 4 + fontHankaku->GetWidth() * (o->cons.pPos.X - 1),
369+ 25 + 4 + fontHankaku->GetHeight() * o->cons.pPos.Y),
370+ fontHankaku);
371+ }
192372 }
193373
194374 void PutChar(Valiables* o, char ch)
@@ -266,6 +446,7 @@
266446 }
267447 #endif
268448 PutChar0(o, ch);
449+#if 0
269450 if (ch == '\n') {
270451 // コマンドラインを取得
271452 int i = 0;
@@ -281,13 +462,29 @@
281462 }
282463 o->cmdline[i] = '\0';
283464
284- Debug::WriteLine(o->cmdline);
465+ //Debug::WriteLine(o->cmdline);
285466 RunCommand(o);
286467
287468 o->cmdlineBegin = o->cons.endLine;
288469 PutChar0(o, '>');
289470 }
471+#endif
472+ if (ch == '\n') {
473+ int i = 0;
474+ char c;
475+ for (int line = o->cmdlineBegin, x = 1; line <= o->cons.wPos.Y; line++) {
476+ for (; (c = o->cons.sbuf.Read(Point(x, line))) != '\0'; x++) {
477+ o->cmdline[i++] = c;
478+ }
479+ x = 0;
480+ }
481+ o->cmdline[i] = '\0';
290482
483+ RunCommand(o);
484+
485+ o->cmdlineBegin = o->cons.wPos.Y;
486+ PutChar0(o, '>');
487+ }
291488 }
292489
293490 void PutString0(Valiables* o, const char* str)
@@ -307,6 +504,7 @@
307504
308505 void ConsoleRefreshScreen(Valiables* o, int begin)
309506 {
507+#if 0
310508 int lines = o->cons.height;
311509 if (begin < 0) {
312510 // 自動計算モード
@@ -327,7 +525,7 @@
327525 begin = o->cons.startLine;
328526 } else {
329527 lines = o->cons.height;
330- begin = o->cons.endLine - o->cons.height;
528+ begin = o->cons.endLine - o->cons.height + 1;
331529 if (begin < 0) {
332530 begin += o->cons.bufHeight;
333531 }
@@ -336,9 +534,11 @@
336534 o->img->DrawRectangleFill(
337535 o->cons.backColor, Point(0, 25), Point(o->img->width - 1, o->img->height - 1));
338536 int line = begin;
537+ Debug::WriteLine("refreshing l=%d,ls=%d", line, lines);
339538 for (int y = 0; y < lines; y++) {
340539 for (int x = 0; x < o->cons.width; x++) {
341- char ch = o->cons.buf[line * o->cons.bufWidth + x];
540+ //char ch = o->cons.buf[line * o->cons.bufWidth + x];
541+ char ch = ReadBuffer(o, x, line);
342542 if (ch == '\0') {
343543 break;
344544 }
@@ -357,12 +557,43 @@
357557 }
358558 }
359559 o->sht->Refresh();
560+#endif
561+ if (begin < 0) {
562+ begin = o->cons.wPos.Y - o->cons.height + 1;
563+ if (begin < 0) {
564+ begin = 0;
565+ }
566+ }
567+ o->img->DrawRectangleFill(
568+ o->cons.backColor, Point(0, 25), Point(o->img->width - 1, o->img->height - 1));
569+ for (int lines = 0; begin + lines <= o->cons.sbuf.GetHeight() && lines < o->cons.height; lines++) {
570+ o->img->DrawString(
571+ o->cons.textColor,
572+ o->cons.sbuf.GetPointer(Point(0, begin + lines)),
573+ Point(4, 25 + 4 + lines * fontHankaku->GetHeight()),
574+ fontHankaku);
575+ }
576+ o->sht->Refresh();
360577 }
361578
362579 void RunCommand(Valiables* o)
363580 {
364581 char s[256];
365- if (strncmp(o->cmdline, "mem", 4) == 0) {
582+ char* command = o->cmdline;
583+ char* args;
584+ int i = 0;
585+ while (command[i] != ' ' && command[i] != '\0') {
586+ i++;
587+ }
588+ if (command[i] == ' ') {
589+ command[i] = '\0';
590+ i++;
591+ while (command[i] == ' ') {
592+ i++;
593+ }
594+ }
595+ args = command + i;
596+ if (strncmp(command, "mem", 4) == 0) {
366597 PutString0(o, "mem : ");
367598 sprintf(s, "%10d", physicalMemorySize);
368599 if ((physicalMemorySize >> 30) != 0) {
@@ -397,7 +628,7 @@
397628 }
398629 PutString0(o, s + 7, 3);
399630 PutString0(o, " B\n");
400- } else if (strncmp(o->cmdline, "opencons", 9) == 0) {
631+ } else if (strncmp(command, "opencons", 9) == 0) {
401632 Task* consTask = taskman->Alloc();
402633 uintptr_t stackTop;
403634 uint32_t stackSize;
@@ -406,23 +637,39 @@
406637 TaskConsole::Init, DummyFunc, TaskConsole::Proc);
407638 consTask->InitQueue(128);
408639 taskman->Run(consTask, 1, 2);
640+ } else if (strncmp(command, "echo", 5) == 0) {
641+ PutString0(o, args);
642+ PutChar0(o, '\n');
643+ } else if (strncmp(command, "beep", 5) == 0) {
644+ int cnt = 2712;
645+ int freq = 1193180;
646+ if (args[0] != '\0') {
647+ cnt = ((freq << 10) / strtol(args, 0, 0) + 512) >> 10;
648+ }
649+ // freq = 1.19318MHz / cnt
650+ io_out8(0x0043, 0xb6);
651+ io_out8(0x0042, (cnt & 0x00ff));
652+ io_out8(0x0042, ((cnt >> 8) & 0x00ff));
653+ uint8_t reg = io_in8(0x0061);
654+ reg |= 0x03;
655+ reg &= 0x0f;
656+ io_out8(0x0061, reg);
657+ o->timBeep->SetTime(100);
658+ } else if (strncmp(command, "eco", 4) == 0) {
659+ PutString0(o, " tree \n");
660+ PutString0(o, " tree tree \n");
661+ PutString0(o, "tree tree tree\n");
409662 } else {
410- PutString0(o, "unknown command\n");
663+ if (strlen(command) > 0) {
664+ PutString0(o, "unknown command\n");
665+ }
411666 }
412667 }
413668
414669 void ShowCursor(Valiables* o)
415670 {
416- int end = o->cons.endLine;
417- if (end >= o->cons.height) {
418- end = o->cons.height - 1;
419- }
420671 Point pos;
421- if (o->cons.xPos > 0) {
422- pos = Point(4 + o->cons.xPos * fontHankaku->GetWidth(), 25 + 4 + end * fontHankaku->GetHeight());
423- } else {
424- pos = Point(4 + o->cons.width * fontHankaku->GetWidth(), 25 + 4 + (end - 1) * fontHankaku->GetHeight());
425- }
672+ pos = Point(4 + o->cons.pPos.X * fontHankaku->GetWidth(), 25 + 4 + o->cons.pPos.Y * fontHankaku->GetHeight());
426673 o->sht->DrawRectangleFill(
427674 o->cons.textColor,
428675 pos,
@@ -431,21 +678,34 @@
431678
432679 void EraseCursor(Valiables* o)
433680 {
434- int end = o->cons.endLine;
435- if (end >= o->cons.height) {
436- end = o->cons.height - 1;
437- }
438681 Point pos;
439- if (o->cons.xPos > 0) {
440- pos = Point(4 + o->cons.xPos * fontHankaku->GetWidth(), 25 + 4 + end * fontHankaku->GetHeight());
441- } else {
442- pos = Point(4 + o->cons.width * fontHankaku->GetWidth(), 25 + 4 + (end - 1) * fontHankaku->GetHeight());
443- }
682+ pos = Point(4 + o->cons.pPos.X * fontHankaku->GetWidth(), 25 + 4 + o->cons.pPos.Y * fontHankaku->GetHeight());
444683 o->sht->DrawRectangleFill(
445684 o->cons.backColor,
446685 pos,
447- pos + Point(1, fontHankaku->GetHeight() - 1));
686+ pos + Point(0, fontHankaku->GetHeight() - 1));
448687 }
449688
689+void WriteBuffer(Valiables* o, int x, int y, char ch)
690+{
691+ if (x < 0 || o->cons.bufWidth <= x) {
692+ Debug::WriteLine("write : x is wrong.");
693+ }
694+ if (y < 0 || o->cons.bufHeight <= y) {
695+ Debug::WriteLine("write : y is wrong.");
696+ }
697+ o->cons.buf[y * o->cons.bufWidth + x] = ch;
698+}
699+char ReadBuffer(Valiables* o, int x, int y)
700+{
701+ if (x < 0 || o->cons.bufWidth <= x) {
702+ Debug::WriteLine("read : x is wrong.");
703+ }
704+ if (y < 0 || o->cons.bufHeight <= y) {
705+ Debug::WriteLine("read : y is wrong.");
706+ }
707+ return o->cons.buf[y * o->cons.bufWidth + x];
708+}
450709
710+
451711 }
--- bitnos5/trunk/include/bitnos/console.h (revision 364)
+++ bitnos5/trunk/include/bitnos/console.h (revision 365)
@@ -9,7 +9,49 @@
99 #define CONSOLE_H_
1010
1111 #include <stdint.h>
12+#include <bitnos/point.h>
1213
14+namespace TaskConsole
15+{
16+// charの2次元配列リングバッファ
17+class ScreenBuffer
18+{
19+ char* buf;
20+ int width, height;
21+ int begin; // データの先頭位置
22+
23+public:
24+ void Init(int width, int height);
25+
26+ void Dispose();
27+
28+ void Write(Point pos, char ch);
29+
30+ void Write(Point pos, const char* str);
31+
32+ char Read(Point pos) const;
33+
34+ const char* GetPointer(Point pos) const;
35+
36+ void Scroll(int lines);
37+
38+ int GetWidth() const
39+ {
40+ return width;
41+ }
42+
43+ int GetHeight() const
44+ {
45+ return height;
46+ }
47+
48+private:
49+ bool IsAvailable(Point pos) const;
50+
51+ Point Calculate(Point pos) const;
52+};
53+
54+
1355 struct Console
1456 {
1557 int width; // 横の文字数
@@ -21,10 +63,16 @@
2163 int startLine; // バッファの開始行
2264 int endLine; // バッファの終了行(書き込み行)
2365 int xPos; // 書き込みの横位置
66+ int printYPos; // 表示の縦位置
2467
2568 uint16_t backColor; // 背景色
2669 uint16_t textColor; // 前景色
70+
71+ ScreenBuffer sbuf;
72+ Point wPos; // 書き込みの位置
73+ Point pPos; // 表示の位置
2774 };
75+}
2876
2977 class Message;
3078
Show on old repository browser