@@ -56,10 +56,21 @@ static const int CONSOLE_COLS = 80;
5656 */
5757static const int CONSOLE_ROWS = 25 ;
5858
59+ /**
60+ * @def N_HISTORY
61+ * @brief コンソールの最大保存容量
62+ */
63+ #define N_HISTORY 100
64+ static char history [N_HISTORY ][80 ];
65+ static int history_lines = 0 ;
66+ static int history_offset = 0 ;
67+
5968void console_init () {
6069 clear_screen ();
6170 cursor_row = 0 ;
6271 cursor_col = 0 ;
72+ history_lines = 0 ;
73+ history_offset = 0 ;
6374}
6475
6576/**
@@ -72,7 +83,22 @@ void new_line() {
7283 if (cursor_row >= CONSOLE_ROWS ) {
7384 // スクロール処理
7485 uint8_t * video = (uint8_t * )VIDEO_MEMORY ;
75- uint8_t attr = COLOR ;
86+ int last = (CONSOLE_ROWS - 1 ) * CONSOLE_COLS ;
87+ char linebuf [CONSOLE_COLS ];
88+ for (int c = 0 ; c < CONSOLE_COLS ; c ++ ) {
89+ linebuf [c ] = (char )video [(last + c ) * 2 ];
90+ }
91+
92+ if (history_lines < N_HISTORY ) {
93+ for (int i = 0 ; i < CONSOLE_COLS ; ++ i ) history [history_lines ][i ] = linebuf [i ];
94+ history_lines ++ ;
95+ } else {
96+ for (int i = 0 ; i < N_HISTORY - 1 ; ++ i ) {
97+ for (int c = 0 ; c < CONSOLE_COLS ; ++ c ) history [i ][c ] = history [i + 1 ][c ];
98+ }
99+ for (int c = 0 ; c < CONSOLE_COLS ; ++ c ) history [N_HISTORY - 1 ][c ] = linebuf [c ];
100+ }
101+
76102 for (int r = 0 ; r < CONSOLE_ROWS - 1 ; r ++ ) {
77103 for (int c = 0 ; c < CONSOLE_COLS ; c ++ ) {
78104 int dst = (r * CONSOLE_COLS + c ) * 2 ;
@@ -81,14 +107,14 @@ void new_line() {
81107 video [dst + 1 ] = video [src + 1 ];
82108 }
83109 }
84-
85- // 一番下の行をスペースでクリア
86- int last = (CONSOLE_ROWS - 1 ) * CONSOLE_COLS ;
110+
111+ uint8_t attr = COLOR ;
87112 for (int c = 0 ; c < CONSOLE_COLS ; c ++ ) {
88113 video [(last + c ) * 2 ] = ' ' ;
89114 video [(last + c ) * 2 + 1 ] = attr ;
90115 }
91116 cursor_row = CONSOLE_ROWS - 1 ;
117+ history_offset = (history_lines > CONSOLE_ROWS ) ? history_lines - CONSOLE_ROWS : 0 ;
92118 }
93119}
94120
@@ -116,6 +142,46 @@ static void console_putc(char ch) {
116142 }
117143}
118144
145+ /* history_offsetからコンソールを再描画 */
146+ static void redraw_from_history (void ) {
147+ uint8_t * video = (uint8_t * )VIDEO_MEMORY ;
148+ /* clear screen */
149+ uint8_t attr = COLOR ;
150+ for (int r = 0 ; r < CONSOLE_ROWS ; ++ r ) {
151+ for (int c = 0 ; c < CONSOLE_COLS ; ++ c ) {
152+ int pos = (r * CONSOLE_COLS + c ) * 2 ;
153+ video [pos ] = ' ' ;
154+ video [pos + 1 ] = attr ;
155+ }
156+ }
157+
158+ int start = history_offset ;
159+ for (int r = 0 ; r < CONSOLE_ROWS ; ++ r ) {
160+ int idx = start + r ;
161+ if (idx < 0 || idx >= history_lines ) continue ;
162+ for (int c = 0 ; c < CONSOLE_COLS ; ++ c ) {
163+ int pos = (r * CONSOLE_COLS + c ) * 2 ;
164+ video [pos ] = (uint8_t )history [idx ][c ];
165+ video [pos + 1 ] = attr ;
166+ }
167+ }
168+ }
169+
170+ void console_scroll_page_up (void ) {
171+ if (history_lines <= CONSOLE_ROWS ) return ;
172+ history_offset -= CONSOLE_ROWS ;
173+ if (history_offset < 0 ) history_offset = 0 ;
174+ redraw_from_history ();
175+ }
176+
177+ void console_scroll_page_down (void ) {
178+ if (history_lines <= CONSOLE_ROWS ) return ;
179+ int max_offset = history_lines - CONSOLE_ROWS ;
180+ history_offset += CONSOLE_ROWS ;
181+ if (history_offset > max_offset ) history_offset = max_offset ;
182+ redraw_from_history ();
183+ }
184+
119185/**
120186 * @fn console_write
121187 * @brief 文字列を書き込む
0 commit comments