:: commit 0e6ad967dee01b224a0526d77ac74058ae324bd1

mintsuki <mintsuki@protonmail.com> — 2021-07-07 01:37

parents: 4d1a02b0b5

textmode: Fix various cursor-related issues

diff --git a/stage23/drivers/vga_textmode.s2.c b/stage23/drivers/vga_textmode.s2.c
index e002d4b4..a0fa694d 100644
--- a/stage23/drivers/vga_textmode.s2.c
+++ b/stage23/drivers/vga_textmode.s2.c
@@ -26,27 +26,33 @@ static uint8_t text_palette;
 static uint8_t cursor_palette;
 
 static void clear_cursor(void) {
-    current_buffer[cursor_offset + 1] = text_palette;
-    return;
+    if (cursor_status) {
+        video_mem[cursor_offset + 1] = current_buffer[cursor_offset + 1];
+    }
 }
 
 static void draw_cursor(void) {
     if (cursor_status) {
-        current_buffer[cursor_offset + 1] = cursor_palette;
+        video_mem[cursor_offset + 1] = cursor_palette;
     }
-    return;
 }
 
 static void scroll(void) {
     // move the text up by one row
-    for (size_t i = 0; i <= VIDEO_BOTTOM - VD_COLS; i++)
+    for (size_t i = 0; i <= VIDEO_BOTTOM - VD_COLS; i++) {
         current_buffer[i] = current_buffer[i + VD_COLS];
+        if (current_buffer == front_buffer)
+            video_mem[i] = current_buffer[i + VD_COLS];
+    }
     // clear the last line of the screen
     for (size_t i = VIDEO_BOTTOM; i > VIDEO_BOTTOM - VD_COLS; i -= 2) {
         current_buffer[i] = text_palette;
         current_buffer[i - 1] = ' ';
+        if (current_buffer == front_buffer) {
+            video_mem[i] = text_palette;
+            video_mem[i - 1] = ' ';
+        }
     }
-    return;
 }
 
 void text_clear(bool move) {
@@ -54,6 +60,10 @@ void text_clear(bool move) {
     for (size_t i = 0; i < VIDEO_BOTTOM; i += 2) {
         current_buffer[i] = ' ';
         current_buffer[i + 1] = text_palette;
+        if (current_buffer == front_buffer) {
+            video_mem[i] = ' ';
+            video_mem[i + 1] = text_palette;
+        }
     }
     if (move)
         cursor_offset = 0;
@@ -69,8 +79,8 @@ void text_enable_cursor(void) {
 
 bool text_disable_cursor(void) {
     bool ret = cursor_status != 0;
-    cursor_status = 0;
     clear_cursor();
+    cursor_status = 0;
     return ret;
 }
 
@@ -83,6 +93,8 @@ void init_vga_textmode(int *_rows, int *_cols, bool managed) {
         current_video_mode = -1;
     }
 
+    back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
+    front_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
 
     cursor_offset = 0;
     cursor_status = 1;
@@ -117,10 +129,6 @@ void init_vga_textmode(int *_rows, int *_cols, bool managed) {
 
 void text_double_buffer(bool state) {
     if (state) {
-        if (back_buffer == NULL)
-            back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
-        if (front_buffer == NULL)
-            front_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
         memset(video_mem, 0, VD_ROWS * VD_COLS);
         memset(back_buffer, 0, VD_ROWS * VD_COLS);
         memset(front_buffer, 0, VD_ROWS * VD_COLS);
@@ -128,7 +136,7 @@ void text_double_buffer(bool state) {
         text_clear(true);
         text_double_buffer_flush();
     } else {
-        current_buffer = video_mem;
+        current_buffer = front_buffer;
         text_clear(true);
     }
 }
@@ -141,6 +149,8 @@ void text_double_buffer_flush(void) {
         front_buffer[i] = back_buffer[i];
         video_mem[i]    = back_buffer[i];
     }
+
+    draw_cursor();
 }
 
 static int text_get_cursor_pos_y(void) {
@@ -192,11 +202,17 @@ void text_putchar(uint8_t c) {
         default:
             clear_cursor();
             current_buffer[cursor_offset] = c;
+            current_buffer[cursor_offset+1] = text_palette;
+            if (current_buffer == front_buffer) {
+                video_mem[cursor_offset] = c;
+                video_mem[cursor_offset+1] = text_palette;
+            }
             if (cursor_offset >= (VIDEO_BOTTOM - 1)) {
                 scroll();
                 cursor_offset = VIDEO_BOTTOM - (VD_COLS - 1);
-            } else
+            } else {
                 cursor_offset += 2;
+            }
             draw_cursor();
     }
 }
diff --git a/test/limine.cfg b/test/limine.cfg
index b4bf521f..3f42f8b1 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -1,6 +1,6 @@
 DEFAULT_ENTRY=1
 TIMEOUT=3
-#GRAPHICS=yes
+GRAPHICS=yes
 MENU_FONT=boot:///boot/font.bin
 VERBOSE=yes
 
tab: 248 wrap: offon