Skip to content
This repository was archived by the owner on Jan 14, 2026. It is now read-only.

Commit ebbe61b

Browse files
committed
fix vga text error
1 parent 6b47699 commit ebbe61b

3 files changed

Lines changed: 132 additions & 102 deletions

File tree

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ K_OUT_DIR = $(OUT_DIR)/kernel
2020
B_OUT_DIR = $(OUT_DIR)/boot
2121
F_OUT_DIR = $(K_OUT_DIR)/fonts
2222
IMG_OUT_DIR = $(OUT_DIR)
23+
README = $(OUT_DIR)/README.txt
2324

2425
CFLAGS = -O2 -Wimplicit-function-declaration -Wunused-but-set-variable -ffreestanding -m64 -c -Wall -Wextra -I$(INCLUDE) -mcmodel=large -mno-red-zone -fno-pic
2526
LDFLAGS = -m elf_x86_64 -z max-page-size=0x1000
@@ -45,7 +46,7 @@ ESP_DIR = esp
4546
.PHONY: all run run-console run-vga clean bootloader kernel ext2
4647
.DEFAULT_GOAL := all
4748

48-
all: bootloader kernel $(F_OUT_DIR)/ter-u12b.bdf $(ESP_IMG) $(EXT2_IMG)
49+
all: bootloader kernel $(F_OUT_DIR)/ter-u12b.bdf $(README) $(ESP_IMG) $(EXT2_IMG)
4950

5051
$(K_OUT_DIR):
5152
@mkdir -p $(K_OUT_DIR)
@@ -80,6 +81,10 @@ $(F_OUT_DIR)/ter-u12b.bdf: $(FONTS)
8081
@mkdir -p $(F_OUT_DIR)
8182
@cp $< $@
8283

84+
$(README):
85+
@mkdir -p $(OUT_DIR)
86+
@cp README.md $(README)
87+
8388
$(ESP_IMG): $(BOOTX64) $(KERNEL)
8489
@rm -f $(ESP_IMG)
8590
@echo "Creating UEFI ESP image..."

src/kernel/util/console.c

Lines changed: 125 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -230,20 +230,19 @@ static int history_offset = 0;
230230
void console_init() {
231231
serial_init(); // シリアルポートを初期化
232232

233-
// VGA テキストモードをクリア
234-
uint8_t *video = (uint8_t *)VIDEO_MEMORY;
235-
uint8_t attr = COLOR;
236-
237-
for (int i = 0; i < 80 * 25; i++) {
238-
*video++ = ' ';
239-
*video++ = attr;
233+
allocate_gfx_buf_if_needed();
234+
235+
if (gfx_buf && gfx_cols > 0 && gfx_rows > 0) {
236+
uint32_t size = (uint32_t)(gfx_cols * gfx_rows);
237+
for (uint32_t i = 0; i < size; ++i)
238+
gfx_buf[i] = ' ';
240239
}
241240

242-
// GOP フレームバッファをクリア(黒で塗りつぶし)
243-
if (use_framebuffer) {
244-
for (uint32_t y = 0; y < fb_height; y++) {
245-
for (uint32_t x = 0; x < fb_width; x++) {
246-
framebuffer[y * fb_pitch + x] = 0x000000;
241+
if (use_framebuffer && framebuffer) {
242+
uint32_t color = fb_bg_color;
243+
for (uint32_t y = 0; y < fb_height; ++y) {
244+
for (uint32_t x = 0; x < fb_width; ++x) {
245+
framebuffer[y * fb_pitch + x] = color;
247246
}
248247
}
249248
}
@@ -278,52 +277,23 @@ void new_line() {
278277
cursor_row = gfx_rows - 1;
279278
console_render_text_to_fb();
280279
}
281-
} else {
282-
if (cursor_row >= CONSOLE_ROWS) {
283-
/* スクロール処理 (テキストモード) */
284-
uint8_t *video = (uint8_t *)VIDEO_MEMORY;
285-
int last = (CONSOLE_ROWS - 1) * CONSOLE_COLS;
286-
char linebuf[CONSOLE_COLS];
287-
for (int c = 0; c < CONSOLE_COLS; c++) {
288-
linebuf[c] = (char)video[(last + c) * 2];
289-
}
290-
291-
if (history_lines < N_HISTORY) {
292-
for (int i = 0; i < CONSOLE_COLS; ++i)
293-
history[history_lines][i] = linebuf[i];
294-
history_lines++;
295-
} else {
296-
for (int i = 0; i < N_HISTORY - 1; ++i) {
297-
for (int c = 0; c < CONSOLE_COLS; ++c)
298-
history[i][c] =
299-
history[i + 1][c];
300-
}
301-
for (int c = 0; c < CONSOLE_COLS; ++c)
302-
history[N_HISTORY - 1][c] = linebuf[c];
303-
}
304-
305-
for (int r = 0; r < CONSOLE_ROWS - 1; r++) {
306-
for (int c = 0; c < CONSOLE_COLS; c++) {
307-
int dst = (r * CONSOLE_COLS + c) * 2;
308-
int src = ((r + 1) * CONSOLE_COLS + c) *
309-
2;
310-
video[dst] = video[src];
311-
video[dst + 1] = video[src + 1];
280+
} else if (use_framebuffer && !gfx_buf) {
281+
const bdf_font_t *font = bdf_get_font();
282+
int fh = font ? (int)font->height : 16;
283+
int fb_rows = (fh > 0) ? (int)(fb_height / fh) : CONSOLE_ROWS;
284+
if (cursor_row >= fb_rows) {
285+
if (use_framebuffer && framebuffer) {
286+
for (uint32_t y = 0; y < fb_height; y++) {
287+
for (uint32_t x = 0; x < fb_width; x++) {
288+
framebuffer[y * fb_pitch + x] = fb_bg_color;
289+
}
312290
}
313291
}
314-
315-
uint8_t attr = COLOR;
316-
for (int c = 0; c < CONSOLE_COLS; c++) {
317-
video[(last + c) * 2] = ' ';
318-
video[(last + c) * 2 + 1] = attr;
319-
}
292+
cursor_row = fb_rows - 1;
293+
}
294+
} else {
295+
if (cursor_row >= CONSOLE_ROWS) {
320296
cursor_row = CONSOLE_ROWS - 1;
321-
history_offset = (history_lines > CONSOLE_ROWS) ?
322-
history_lines - CONSOLE_ROWS :
323-
0;
324-
if (use_framebuffer) {
325-
console_render_text_to_fb();
326-
}
327297
}
328298
}
329299
}
@@ -333,7 +303,6 @@ void new_line() {
333303
* @brief 位置文字表示
334304
*/
335305
static void console_putc(char ch) {
336-
uint8_t *video = (uint8_t *)VIDEO_MEMORY;
337306
uint8_t attr = COLOR;
338307

339308
if (ch == '\n') {
@@ -380,50 +349,78 @@ static void console_putc(char ch) {
380349
new_line();
381350
}
382351
} else {
383-
int pos = (cursor_row * CONSOLE_COLS + cursor_col) * 2;
384-
video[pos] = (uint8_t)ch;
385-
video[pos + 1] = attr;
386-
// GOP フレームバッファに出力
387-
if (use_framebuffer) {
352+
if (use_framebuffer && !gfx_buf) {
353+
const bdf_font_t *font = bdf_get_font();
354+
int fw = font ? (int)font->width : 8;
355+
int fb_cols = (fw > 0) ? (int)(fb_width / fw) : CONSOLE_COLS;
356+
388357
draw_char_fb(cursor_col, cursor_row, ch);
389-
}
390-
cursor_col++;
391-
serial_putc(ch);
392-
if (cursor_col >= CONSOLE_COLS) {
393-
new_line();
358+
cursor_col++;
359+
serial_putc(ch);
360+
if (cursor_col >= fb_cols) {
361+
new_line();
362+
}
363+
} else {
364+
/* No VGA/text-mode support: if framebuffer not available,
365+
* just emit to serial. */
366+
serial_putc(ch);
367+
cursor_col++;
368+
if (cursor_col >= CONSOLE_COLS) {
369+
new_line();
370+
}
394371
}
395372
}
396373
}
397374

398375
/* history_offsetからコンソールを再描画 */
399376
static void redraw_from_history(void) {
400-
uint8_t *video = (uint8_t *)VIDEO_MEMORY;
401-
/* clear screen */
402-
uint8_t attr = COLOR;
403-
for (int r = 0; r < CONSOLE_ROWS; ++r) {
404-
for (int c = 0; c < CONSOLE_COLS; ++c) {
405-
int pos = (r * CONSOLE_COLS + c) * 2;
406-
video[pos] = ' ';
407-
video[pos + 1] = attr;
377+
/* When using gfx_buf, copy history into it and render. If using direct
378+
* framebuffer rendering (no gfx_buf), draw characters directly. If no
379+
* framebuffer, do nothing (no VGA support). */
380+
if (use_framebuffer && gfx_buf && gfx_cols > 0 && gfx_rows > 0) {
381+
uint32_t gsize = (uint32_t)(gfx_cols * gfx_rows);
382+
for (uint32_t i = 0; i < gsize; ++i)
383+
gfx_buf[i] = ' ';
384+
385+
int start = history_offset;
386+
for (int r = 0; r < gfx_rows; ++r) {
387+
int idx = start + r;
388+
if (idx < 0 || idx >= history_lines)
389+
continue;
390+
for (int c = 0; c < gfx_cols; ++c) {
391+
if (c < CONSOLE_COLS)
392+
gfx_buf[r * gfx_cols + c] = history[idx][c];
393+
else
394+
gfx_buf[r * gfx_cols + c] = ' ';
395+
}
408396
}
397+
console_render_text_to_fb();
398+
return;
409399
}
410400

411-
int start = history_offset;
412-
for (int r = 0; r < CONSOLE_ROWS; ++r) {
413-
int idx = start + r;
414-
if (idx < 0 || idx >= history_lines)
415-
continue;
416-
for (int c = 0; c < CONSOLE_COLS; ++c) {
417-
int pos = (r * CONSOLE_COLS + c) * 2;
418-
video[pos] = (uint8_t)history[idx][c];
419-
video[pos + 1] = attr;
401+
if (use_framebuffer && !gfx_buf) {
402+
/* Direct framebuffer rendering: paint from history lines */
403+
const bdf_font_t *font = bdf_get_font();
404+
if (!font)
405+
return;
406+
int fw = (int)font->width;
407+
int fh = (int)font->height;
408+
int fb_cols = (fw > 0) ? (int)(fb_width / fw) : CONSOLE_COLS;
409+
int rows = (fh > 0) ? (int)(fb_height / fh) : CONSOLE_ROWS;
410+
int start = history_offset;
411+
for (int r = 0; r < rows; ++r) {
412+
for (int c = 0; c < fb_cols; ++c) {
413+
char ch = ' ';
414+
int idx = start + r;
415+
if (idx >= 0 && idx < history_lines && c < CONSOLE_COLS)
416+
ch = history[idx][c];
417+
draw_char_fb(c, r, ch);
418+
}
420419
}
420+
return;
421421
}
422422

423-
if (use_framebuffer) {
424-
/* If we have a gfx_buf, render that; otherwise render video memory */
425-
console_render_text_to_fb();
426-
}
423+
/* No framebuffer: nothing to redraw (VGA/text-mode support removed) */
427424
}
428425

429426
void console_scroll_page_up(void) {
@@ -467,14 +464,17 @@ void console_render_text_to_fb(void) {
467464
if (fb_cols <= 0 || fb_rows <= 0)
468465
return;
469466

470-
int cols = (fb_cols < CONSOLE_COLS) ? fb_cols : CONSOLE_COLS;
471-
int rows = (fb_rows < CONSOLE_ROWS) ? fb_rows : CONSOLE_ROWS;
467+
int cols = fb_cols;
468+
int rows = fb_rows;
472469

473-
uint8_t *video = (uint8_t *)VIDEO_MEMORY;
470+
/* Render from history (if any) or blank when no gfx_buf exists. */
474471
for (int r = 0; r < rows; ++r) {
475472
for (int c = 0; c < cols; ++c) {
476-
int pos = (r * CONSOLE_COLS + c) * 2;
477-
char ch = (char)video[pos];
473+
char ch = ' ';
474+
int idx = history_offset + r;
475+
if (idx >= 0 && idx < history_lines && c < CONSOLE_COLS) {
476+
ch = history[idx][c];
477+
}
478478
draw_char_fb(c, r, ch);
479479
}
480480
}
@@ -483,16 +483,16 @@ void console_render_text_to_fb(void) {
483483
void console_post_font_init(void) {
484484
allocate_gfx_buf_if_needed();
485485
if (gfx_buf && gfx_cols > 0 && gfx_rows > 0) {
486-
uint8_t *video = (uint8_t *)VIDEO_MEMORY;
487-
int copy_rows = (gfx_rows < CONSOLE_ROWS) ? gfx_rows :
488-
CONSOLE_ROWS;
489-
int copy_cols = (gfx_cols < CONSOLE_COLS) ? gfx_cols :
490-
CONSOLE_COLS;
486+
/* Initialize gfx_buf from history if available, otherwise blank */
487+
int copy_rows = (gfx_rows < CONSOLE_ROWS) ? gfx_rows : CONSOLE_ROWS;
488+
int copy_cols = (gfx_cols < CONSOLE_COLS) ? gfx_cols : CONSOLE_COLS;
491489
for (int r = 0; r < copy_rows; ++r) {
490+
int idx = history_offset + r;
492491
for (int c = 0; c < copy_cols; ++c) {
493-
int vpos = (r * CONSOLE_COLS + c) * 2;
494-
char ch = (char)video[vpos];
495-
gfx_buf[r * gfx_cols + c] = ch;
492+
if (idx >= 0 && idx < history_lines)
493+
gfx_buf[r * gfx_cols + c] = history[idx][c];
494+
else
495+
gfx_buf[r * gfx_cols + c] = ' ';
496496
}
497497
for (int c = copy_cols; c < gfx_cols; ++c) {
498498
gfx_buf[r * gfx_cols + c] = ' ';
@@ -503,11 +503,35 @@ void console_post_font_init(void) {
503503
gfx_buf[r * gfx_cols + c] = ' ';
504504
}
505505

506-
/* Render to framebuffer */
507506
console_render_text_to_fb();
508507
}
509508
}
510509

510+
/**
511+
* @brief 画面全体をクリア
512+
*/
513+
void console_clear_screen(void) {
514+
/* Clear gfx buffer (if any) and framebuffer. Legacy VGA text buffer
515+
* is not used in UEFI builds. */
516+
if (gfx_buf && gfx_cols > 0 && gfx_rows > 0) {
517+
uint32_t size = (uint32_t)(gfx_cols * gfx_rows);
518+
for (uint32_t i = 0; i < size; ++i)
519+
gfx_buf[i] = ' ';
520+
}
521+
522+
if (use_framebuffer && framebuffer) {
523+
uint32_t color = fb_bg_color;
524+
for (uint32_t y = 0; y < fb_height; ++y) {
525+
for (uint32_t x = 0; x < fb_width; ++x) {
526+
framebuffer[y * fb_pitch + x] = color;
527+
}
528+
}
529+
}
530+
531+
cursor_row = 0;
532+
cursor_col = 0;
533+
}
534+
511535
/**
512536
* @fn console_write
513537
* @brief 文字列を書き込む

src/kernel/util/console.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ void console_scroll_page_up(void);
1313
void console_scroll_page_down(void);
1414
void console_render_text_to_fb(void);
1515
void console_post_font_init(void);
16+
void console_clear_screen(void);
1617

1718
/* シリアル入力関数 */
1819
int serial_received(void);

0 commit comments

Comments
 (0)