Scrolling screen when necessary
This commit is contained in:
		
							parent
							
								
									4f00d428bf
								
							
						
					
					
						commit
						055c41adb3
					
				| @ -2,17 +2,22 @@ | ||||
| #include <memory.h> | ||||
| 
 | ||||
| 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(); | ||||
| } | ||||
|  | ||||
| @ -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'); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user