From 055c41adb342599cdffbb002b6f285f60f817320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Mon, 4 Dec 2017 01:30:18 +0100 Subject: [PATCH] Scrolling screen when necessary --- src/kernel/drivers/vga.c | 31 +++++++++++++++++++++------ src/kernel/drivers/vga.tt | 44 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/kernel/drivers/vga.c b/src/kernel/drivers/vga.c index c1c3924..c28e7ef 100644 --- a/src/kernel/drivers/vga.c +++ b/src/kernel/drivers/vga.c @@ -2,17 +2,22 @@ #include void *vidmem; -struct { - uint8_t character; - uint8_t format; -}__attribute__((packed)) buffer[VGA_SIZE]; +struct vga_cell{ + uint8_t c; + uint8_t f; +}__attribute__((packed)); + +struct vga_cell buffer[VGA_SIZE]; uint64_t cursor; +uint8_t format; void vga_init() { vidmem = VGA_MEMORY; memset(vidmem, 0, VGA_SIZE*2); + + format = 0x7; } void flush() @@ -20,6 +25,20 @@ void flush() memcpy(vidmem, buffer, sizeof(buffer)); } +void scroll() +{ + while(cursor >= VGA_SIZE) + { + for(int i = 0; i < VGA_ROWS-1; i++) + for(int j = 0; j < VGA_COLS; j++) + buffer[VGA_POS(i, j)] = buffer[VGA_POS(i+1, j)]; + for(int i = 0; i < VGA_COLS; i++) + buffer[VGA_POS(VGA_ROWS-1, i)] = (struct vga_cell){.c='\0', .f=format}; + cursor -= VGA_COLS; + } + +} + void vga_write(char c) { switch(c) @@ -29,9 +48,9 @@ void vga_write(char c) cursor -= VGA_COL(cursor); break; default: - buffer[cursor].character = c; - buffer[cursor].format = 0x7; + buffer[cursor] = (struct vga_cell){.c = c, .f=format}; cursor++; } + scroll(); flush(); } diff --git a/src/kernel/drivers/vga.tt b/src/kernel/drivers/vga.tt index 3e0971e..dab92f8 100644 --- a/src/kernel/drivers/vga.tt +++ b/src/kernel/drivers/vga.tt @@ -52,10 +52,10 @@ TEST(vga_write_adds_multiple_characters_to_vidmem) TEST(vga_writes_entire_screen_full) { - for(int i = 0; i < VGA_COLS*VGA_ROWS; i++) + for(int i = 0; i < (VGA_COLS*VGA_ROWS-1); i++) vga_write('x'); - VGA_ASSERT_EQ(VGA_POS(VGA_ROWS-1, VGA_COLS-1), 'x'); + VGA_ASSERT_EQ(VGA_POS(VGA_ROWS-1, VGA_COLS-2), 'x'); } TEST(vga_does_not_overflow_memory_area) { @@ -77,3 +77,43 @@ TEST(newline_moves_to_beginning_of_line) vga_write('b'); VGA_ASSERT_EQ(VGA_POS(1,0), 'b'); } + +void vga_write_str(char *str) +{ + while(*str) vga_write(*str++); +} + +TEST(writing_past_end_of_screen_scrolls_screen_one_line) +{ + vga_write_str("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"); + vga_write_str("11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n"); + vga_write_str("21\n22\n23\n24\n"); + + vga_write_str("abcde"); + VGA_ASSERT_EQ(0, '2'); +} +TEST(screen_does_not_scroll_until_write) +{ + vga_write_str("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"); + vga_write_str("11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n"); + vga_write_str("21\n22\n23\n24"); + vga_write_str("34567890123456789012345678901234567890123456789012345678901234567890123456789"); + + VGA_ASSERT_EQ(0, '1'); +} +TEST(writing_past_end_of_screen_clears_last_line) +{ + vga_write_str("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"); + vga_write_str("11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n"); + vga_write_str("21\n22\n23\n24\n"); + vga_write('a'); + VGA_ASSERT_EQ(VGA_POS(VGA_ROWS-1, 1), '\0'); +} +TEST(first_character_of_new_line_is_not_cleared) +{ + vga_write_str("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"); + vga_write_str("11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n"); + vga_write_str("21\n22\n23\n24\n"); + vga_write('a'); + VGA_ASSERT_EQ(VGA_POS(VGA_ROWS-1, 0), 'a'); +}