drivers/vga_textmode: Defer line wrap to next putchar
diff --git a/common/drivers/vga_textmode.c b/common/drivers/vga_textmode.c
index fefb982f..0a5c5961 100644
--- a/common/drivers/vga_textmode.c
+++ b/common/drivers/vga_textmode.c
@@ -162,6 +162,7 @@ static void text_set_cursor_pos(struct flanterm_context *_ctx, size_t x, size_t
}
}
ctx->cursor_offset = y * VD_COLS + x * 2;
+ ctx->cursor_overflow = false;
}
static uint8_t ansi_colours[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
@@ -219,17 +220,32 @@ static void text_set_text_bg_default_bright(struct flanterm_context *_ctx) {
static void text_putchar(struct flanterm_context *_ctx, uint8_t c) {
struct textmode_context *ctx = (void *)_ctx;
- ctx->back_buffer[ctx->cursor_offset] = c;
- ctx->back_buffer[ctx->cursor_offset + 1] = ctx->text_palette;
- if (ctx->cursor_offset / VD_COLS == _ctx->scroll_bottom_margin - 1
- && ctx->cursor_offset % VD_COLS == VD_COLS - 2) {
- if (_ctx->scroll_enabled) {
- text_scroll(_ctx);
+ // Handle overflow from previous putchar
+ if (ctx->cursor_overflow) {
+ ctx->cursor_overflow = false;
+ if (_ctx->wrap_enabled
+ && (ctx->cursor_offset / VD_COLS < _ctx->scroll_bottom_margin - 1
+ || _ctx->scroll_enabled)) {
ctx->cursor_offset -= ctx->cursor_offset % VD_COLS;
+ ctx->cursor_offset += VD_COLS;
+ if (ctx->cursor_offset / VD_COLS == _ctx->scroll_bottom_margin) {
+ ctx->cursor_offset -= VD_COLS;
+ text_scroll(_ctx);
+ }
+ if (ctx->cursor_offset >= VD_ROWS * VD_COLS) {
+ ctx->cursor_offset = (VD_ROWS - 1) * VD_COLS;
+ }
+ } else {
+ ctx->cursor_offset = ctx->cursor_offset - (ctx->cursor_offset % VD_COLS) + VD_COLS - 2;
}
- } else if (ctx->cursor_offset >= (VIDEO_BOTTOM - 1)) {
- ctx->cursor_offset -= ctx->cursor_offset % VD_COLS;
- } else {
+ }
+
+ ctx->back_buffer[ctx->cursor_offset] = c;
+ ctx->back_buffer[ctx->cursor_offset + 1] = ctx->text_palette;
+ if (ctx->cursor_offset % VD_COLS == VD_COLS - 2) {
+ // At last column - flag overflow for next putchar
+ ctx->cursor_overflow = true;
+ } else if (ctx->cursor_offset < (VIDEO_BOTTOM - 1)) {
ctx->cursor_offset += 2;
}
}
@@ -285,6 +301,7 @@ void vga_textmode_init(bool managed) {
}
ctx->cursor_offset = 0;
+ ctx->cursor_overflow = false;
ctx->text_palette = 0x07;
ctx->video_mem = (volatile uint8_t *)0xb8000;
diff --git a/common/drivers/vga_textmode.h b/common/drivers/vga_textmode.h
index c7bca53b..e8b56ce3 100644
--- a/common/drivers/vga_textmode.h
+++ b/common/drivers/vga_textmode.h
@@ -22,6 +22,7 @@ struct textmode_context {
size_t cursor_offset;
size_t old_cursor_offset;
bool cursor_status;
+ bool cursor_overflow;
uint8_t text_palette;
uint8_t saved_state_text_palette;
