Added delete routine in screen and adjusted the code

This commit is contained in:
lucic71 2022-06-28 19:40:51 +03:00
parent 0344f13328
commit 7cd7c93166
5 changed files with 137 additions and 24 deletions

View File

@ -15,14 +15,14 @@
/*
* _screen_move_cursor:
* Moves the cursor of the framebuffer to a give position calculated using
* @x and @y coordinates.
* Moves the cursor of the framebuffer to a given position calculated using
* the arguments.
*
* @param x - horizontal position
* @param y - vertical position
* @param column - Vertical position
* @param row - Horizontal position
*
*/
void _screen_move_cursor(uint8_t x, uint8_t y);
void _screen_move_cursor(uint8_t column, uint8_t row);
#endif

View File

@ -17,14 +17,14 @@ size_t screen_color;
* Put character at a specified position or put character at the next position
* available in framebuffer acording to state variables.
*
* @param c - Char to be displayed
* @param color - Color attributes of @c
* @param x - Vertical position
* @param y - Horizontal position
* @param c - Char to be displayed
* @param color - Color attributes of @c
* @param column - Vertical position
* @param row - Horizontal position
*
*/
void _screen_putchar_at(char c, uint16_t color, size_t x, size_t y);
void _screen_putchar_at(char c, uint16_t color, size_t column, size_t row);
void _screen_putchar(char c);
/*
@ -35,4 +35,37 @@ void _screen_putchar(char c);
void _screen_scroll_up(void);
/*
* _screen_delete_at:
* Deletes a character at a given position.
*
* @param column - Vertical position
* @param row - Horizontal position
*
*/
void _screen_delete_at(size_t column, size_t row);
/*
* _find_last_nonwhite_column:
*
*
* @return - the column with the last nonwhite character on the previous
* line.
*/
size_t _find_last_nonwhite_column(void);
/*
* _is_whitespace:
*
* @param column - Vertical position
* @param row - Horizontal poistion
* @return - 1 if it is whitespace
* 0 else
*
*/
int _is_whitespace(size_t column, size_t row);
#endif

View File

@ -16,9 +16,9 @@
*
*/
void _screen_move_cursor(uint8_t x, uint8_t y) {
void _screen_move_cursor(uint8_t column, uint8_t row) {
uint16_t sindex = y * VGA_WIDTH + x;
uint16_t sindex = row * VGA_WIDTH + column;
outb(CURSOR_COMMAND_PORT, CURSOR_HIGH_BYTE_COMMAND);
outb(CURSOR_DATA_PORT, ((sindex >> 8)) & 0x00FF);

View File

@ -2,6 +2,7 @@
#include "framebuffer.h"
#include "screen_internals.h"
#include "cursor.h"
#include "lib/vga.h"
@ -25,14 +26,9 @@ void screen_init(void) {
fbuffer = (uint16_t *) FBUFFER_START_ADDR;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
fbuffer[index] = vga_entry(' ', screen_color);
}
}
for (size_t row = 0; row < VGA_HEIGHT; row++)
for (size_t column = 0; column < VGA_WIDTH; column++)
_screen_delete_at(column, row);
}
@ -54,3 +50,35 @@ size_t screen_write(char *buf, size_t len) {
return i;
}
/*
* screen_delete:
* --------------
*
* Deletes the current character and updates the cursor. If current position
* is (0, 0) then do nothing. If current position is at the beginning of a
* line then find the last nonwhite element on the last line and move the
* cursor there. Else just delete the current element.
*
* Side effects:
* cursor position will be affected too.
*
*/
void screen_delete(void) {
if (!screen_column && !screen_row)
return;
if (!screen_column && screen_row) {
screen_column = _find_last_nonwhite_column();
screen_row--;
} else
screen_column--;
_screen_delete_at(screen_column, screen_row);
_screen_move_cursor(screen_column, screen_row);
}

View File

@ -6,6 +6,21 @@
#include <stddef.h>
#include <stdint.h>
/*
* _screen_delete_at:
* ------------------
*
* Replaces the character at (row, column) with a whitespace.
*
*/
void _screen_delete_at(size_t column, size_t row) {
const size_t index = row * VGA_WIDTH + column;
fbuffer[index] = vga_entry(' ', screen_color);
}
/*
* _screen_putchar_at:
* ------------------
@ -15,9 +30,9 @@
*
*/
void _screen_putchar_at(char c, uint16_t color, size_t x, size_t y) {
void _screen_putchar_at(char c, uint16_t color, size_t column, size_t row) {
const size_t index = y * VGA_WIDTH + x;
const size_t index = row * VGA_WIDTH + column;
fbuffer[index] = vga_entry(c, color);
}
@ -38,7 +53,7 @@ void _screen_scroll_up(void) {
fbuffer[i] = fbuffer[i + 80];
for (i = 0; i < VGA_WIDTH; i++)
fbuffer[(VGA_HEIGHT - 1) * VGA_WIDTH + i] = vga_entry(' ', screen_color);
_screen_delete_at(i, VGA_HEIGHT - 1);
}
@ -75,7 +90,44 @@ void _screen_putchar(char c) {
}
_screen_putchar_at(c, screen_color, screen_column++, screen_row);
_screen_putchar_at(c, screen_color, screen_column, screen_row);
screen_column++;
_screen_move_cursor(screen_column, screen_row);
}
/*
* _is_whitespace:
* ---------------
*
*/
int _is_whitespace(size_t column, size_t row) {
int index = row * VGA_WIDTH + column;
return fbuffer[index] == vga_entry(' ', screen_color);
}
/*
* _find_last_nonwhite_column:
* ---------------------------
*
* Goes on the last line and returns the first column that has a nonwhite
* char. The traversal is from the end of the line to the beginning.
* It will return 0 if there is no nonwhite character.
*
*/
size_t _find_last_nonwhite_column(void) {
int row = screen_row - 1;
int y = VGA_WIDTH;
for (; y > 0; y--)
if (!_is_whitespace(y, row))
break;
return y;
}