Fix VGA drawing functions.

This commit is contained in:
Enrico Fraccaroli (Galfurian)
2022-07-13 11:53:13 -04:00
parent cef88432a1
commit 36aa392534
4 changed files with 133 additions and 126 deletions
+20 -12
View File
@@ -26,12 +26,18 @@ int vga_height();
/// @brief Clears the screen. /// @brief Clears the screen.
void vga_clear_screen(); void vga_clear_screen();
/// @brief Draws a pixel at the given position.
/// @param x x-axis position.
/// @param y y-axis position.
/// @param color color of the character.
void vga_draw_pixel(int x, int y, unsigned char color);
/// @brief Draws a character at the given position. /// @brief Draws a character at the given position.
/// @param x x-axis position. /// @param x x-axis position.
/// @param y y-axis position. /// @param y y-axis position.
/// @param c character to draw. /// @param c character to draw.
/// @param color color of the character. /// @param color color of the character.
void vga_draw_char(unsigned int x, unsigned int y, unsigned char c, unsigned char color); void vga_draw_char(int x, int y, unsigned char c, unsigned char color);
/// @brief Draws a string at the given position. /// @brief Draws a string at the given position.
/// @param x x-axis position. /// @param x x-axis position.
@@ -46,22 +52,22 @@ void vga_draw_string(int x, int y, char *str, unsigned char color);
/// @param x1 point 2 x-axis position. /// @param x1 point 2 x-axis position.
/// @param y1 point 2 y-axis position. /// @param y1 point 2 y-axis position.
/// @param color color of the line. /// @param color color of the line.
void vga_draw_line(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned char color); void vga_draw_line(int x0, int y0, int x1, int y1, unsigned char color);
/// @brief Draws a rectangle provided the position of the starting corner and the ending corner. /// @brief Draws a rectangle provided the position of the starting corner and the ending corner.
/// @param sx starting corner x-axis position. /// @param sx top-left corner x-axis position.
/// @param sy starting corner y-axis position. /// @param sy top-left corner y-axis position.
/// @param ex ending corner x-axis position. /// @param w width.
/// @param ey ending corner y-axis position. /// @param h height.
/// @param fill color used to fill the rectangle. /// @param color color of the rectangle.
void vga_draw_rectangle(unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, unsigned char fill); void vga_draw_rectangle(int sx, int sy, int w, int h, unsigned char color);
/// @brief Draws a circle provided the position of the center and the radius. /// @brief Draws a circle provided the position of the center and the radius.
/// @param xc x-axis position. /// @param xc x-axis position.
/// @param yc y-axis position. /// @param yc y-axis position.
/// @param r radius. /// @param r radius.
/// @param fill color used to fill the circle. /// @param color used to draw the circle.
void vga_draw_circle(unsigned int xc, unsigned int yc, unsigned int r, unsigned char fill); void vga_draw_circle(int xc, int yc, int r, unsigned char color);
/// @brief Draws a triangle. /// @brief Draws a triangle.
/// @param x1 1st point x-axis position. /// @param x1 1st point x-axis position.
@@ -70,5 +76,7 @@ void vga_draw_circle(unsigned int xc, unsigned int yc, unsigned int r, unsigned
/// @param y2 2nd point y-axis position. /// @param y2 2nd point y-axis position.
/// @param x3 3rd point x-axis position. /// @param x3 3rd point x-axis position.
/// @param y3 3rd point y-axis position. /// @param y3 3rd point y-axis position.
/// @param fill color used to fill the triangle. /// @param color used to draw the triangle.
void vga_draw_triangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned char fill); void vga_draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, unsigned char color);
void vga_run_test();
-4
View File
@@ -1137,22 +1137,18 @@ int ata_initialize()
ata_device_type_t type; ata_device_type_t type;
type = ata_device_detect(&ata_primary_master); type = ata_device_detect(&ata_primary_master);
if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) { if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) {
printf(" Found %s device connected to primary master.\n", ata_get_device_type_str(type));
pr_info(" Found %s device connected to primary master.\n", ata_get_device_type_str(type)); pr_info(" Found %s device connected to primary master.\n", ata_get_device_type_str(type));
} }
type = ata_device_detect(&ata_primary_slave); type = ata_device_detect(&ata_primary_slave);
if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) { if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) {
printf(" Found %s device connected to primary slave.\n", ata_get_device_type_str(type));
pr_info(" Found %s device connected to primary slave.\n", ata_get_device_type_str(type)); pr_info(" Found %s device connected to primary slave.\n", ata_get_device_type_str(type));
} }
type = ata_device_detect(&ata_secondary_master); type = ata_device_detect(&ata_secondary_master);
if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) { if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) {
printf(" Found %s device connected to secondary master.\n", ata_get_device_type_str(type));
pr_info(" Found %s device connected to secondary master.\n", ata_get_device_type_str(type)); pr_info(" Found %s device connected to secondary master.\n", ata_get_device_type_str(type));
} }
type = ata_device_detect(&ata_secondary_slave); type = ata_device_detect(&ata_secondary_slave);
if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) { if ((type != ata_dev_type_no_device) && (type != ata_dev_type_unknown)) {
printf(" Found %s device connected to secondary slave.\n", ata_get_device_type_str(type));
pr_info(" Found %s device connected to secondary slave.\n", ata_get_device_type_str(type)); pr_info(" Found %s device connected to secondary slave.\n", ata_get_device_type_str(type));
} }
return 0; return 0;
+106 -107
View File
@@ -16,10 +16,11 @@
#include "io/vga/vga_mode.h" #include "io/vga/vga_mode.h"
#include "io/vga/vga_font.h" #include "io/vga/vga_font.h"
#include "hardware/timer.h"
#include "io/port_io.h" #include "io/port_io.h"
#include "io/debug.h"
#include "stdbool.h" #include "stdbool.h"
#include "string.h" #include "string.h"
#include "io/debug.h"
#include "math.h" #include "math.h"
/// Counts the number of elements of an array. /// Counts the number of elements of an array.
@@ -61,13 +62,13 @@
/// VGA pointers for drawing operations. /// VGA pointers for drawing operations.
typedef struct { typedef struct {
/// Writes a pixel. /// Writes a pixel.
void (*write_pixel)(unsigned int x, unsigned int y, unsigned char c); void (*write_pixel)(int x, int y, unsigned char c);
/// Reads a pixel. /// Reads a pixel.
unsigned (*read_pixel)(unsigned int x, unsigned int y); unsigned (*read_pixel)(int x, int y);
/// Draws a rectangle. /// Draws a rectangle.
void (*draw_rect)(unsigned int x, unsigned int y, unsigned int wd, unsigned int ht, unsigned char c); void (*draw_rect)(int x, int y, int wd, int ht, unsigned char c);
/// Fills a rectangle. /// Fills a rectangle.
void (*fill_rect)(unsigned int x, unsigned int y, unsigned int wd, unsigned int ht, unsigned char c); void (*fill_rect)(int x, int y, int wd, int ht, unsigned char c);
} vga_ops_t; } vga_ops_t;
/// VGA font details. /// VGA font details.
@@ -361,17 +362,42 @@ assume: chain-4 addressing already off */
outportb(GC_DATA, gc6); outportb(GC_DATA, gc6);
} }
/// @brief Reverses the bits of the given number.
/// @param num the number of which we want to reverse the bits.
/// @return reversed bits.
static inline unsigned int __reverse_bits(char num)
{
unsigned int NO_OF_BITS = sizeof(num) * 8;
unsigned int reverse_num = 0;
int i;
for (i = 0; i < NO_OF_BITS; i++) {
if ((num & (1 << i)))
reverse_num |= 1 << ((NO_OF_BITS - 1) - i);
}
return reverse_num;
}
/// @brief Sets the given font.
/// @param font the new font.
void __vga_setfont(const vga_font_t *font)
{
__font->font = font->font;
__font->width = font->width;
__font->height = font->height;
}
// ============================================================================
// = WRITE PIXEL FUNCTIONS (and support)
// ============================================================================ // ============================================================================
// == WRITE PIXEL FUNCTIONS ===================================================
/// @brief Writes a pixel. /// @brief Writes a pixel.
/// @param x x coordinates. /// @param x x coordinates.
/// @param y y coordinates. /// @param y y coordinates.
/// @param c color. /// @param c color.
static void __write_pixel_1(unsigned int x, unsigned int y, unsigned char c) static inline void __write_pixel_1(int x, int y, unsigned char c)
{ {
unsigned wd_in_bytes; int wd_in_bytes;
unsigned off, mask; int off, mask;
c = (c & 1) * 0xFF; c = (c & 1) * 0xFF;
wd_in_bytes = driver->width / 8; wd_in_bytes = driver->width / 8;
@@ -385,10 +411,10 @@ static void __write_pixel_1(unsigned int x, unsigned int y, unsigned char c)
/// @param x x coordinates. /// @param x x coordinates.
/// @param y y coordinates. /// @param y y coordinates.
/// @param c color. /// @param c color.
static void __write_pixel_2(unsigned int x, unsigned int y, unsigned char c) static inline void __write_pixel_2(int x, int y, unsigned char c)
{ {
unsigned wd_in_bytes; int wd_in_bytes;
unsigned off, mask; int off, mask;
c = (c & 3) * 0x55; c = (c & 3) * 0x55;
wd_in_bytes = driver->width / 4; wd_in_bytes = driver->width / 4;
@@ -402,7 +428,7 @@ static void __write_pixel_2(unsigned int x, unsigned int y, unsigned char c)
/// @param x x coordinates. /// @param x x coordinates.
/// @param y y coordinates. /// @param y y coordinates.
/// @param c color. /// @param c color.
static void __write_pixel_4(unsigned int x, unsigned int y, unsigned char color) static inline void __write_pixel_4(int x, int y, unsigned char color)
{ {
int rotation = 0; int rotation = 0;
int16_t t; int16_t t;
@@ -423,7 +449,7 @@ static void __write_pixel_4(unsigned int x, unsigned int y, unsigned char color)
break; break;
} }
unsigned wd_in_bytes, off, mask, p, pmask; int wd_in_bytes, off, mask, p, pmask;
wd_in_bytes = driver->width / 8; wd_in_bytes = driver->width / 8;
off = wd_in_bytes * y + x / 8; off = wd_in_bytes * y + x / 8;
@@ -444,27 +470,16 @@ static void __write_pixel_4(unsigned int x, unsigned int y, unsigned char color)
/// @param x x coordinates. /// @param x x coordinates.
/// @param y y coordinates. /// @param y y coordinates.
/// @param c color. /// @param c color.
static inline void __write_pixel_8(unsigned int x, unsigned int y, unsigned char color) static inline void __write_pixel_8(int x, int y, unsigned char color)
{ {
__set_plane(x); __set_plane(x);
__write_byte(((y * driver->width) + x) / 4, color); __write_byte(((y * driver->width) + x) / 4, color);
// (y << 6) + (y << 4) + (x >> 2) // (y << 6) + (y << 4) + (x >> 2)
} }
/// @brief Reverses the bits of the given number. // ============================================================================
/// @param num the number of which we want to reverse the bits. // = VGA PUBLIC FUNCTIONS
/// @return reversed bits. // ============================================================================
unsigned int reverseBits(char num)
{
unsigned int NO_OF_BITS = sizeof(num) * 8;
unsigned int reverse_num = 0;
int i;
for (i = 0; i < NO_OF_BITS; i++) {
if ((num & (1 << i)))
reverse_num |= 1 << ((NO_OF_BITS - 1) - i);
}
return reverse_num;
}
int vga_is_enabled() int vga_is_enabled()
{ {
@@ -485,15 +500,6 @@ int vga_height()
return 0; return 0;
} }
/// @brief Sets the given font.
/// @param font the new font.
void __vga_setfont(const vga_font_t *font)
{
__font->font = font->font;
__font->width = font->width;
__font->height = font->height;
}
void vga_clear_screen() void vga_clear_screen()
{ {
for (int p = 0; p < 4; p++) { for (int p = 0; p < 4; p++) {
@@ -502,7 +508,12 @@ void vga_clear_screen()
} }
} }
void vga_draw_char(unsigned int x, unsigned int y, unsigned char c, unsigned char color) void vga_draw_pixel(int x, int y, unsigned char color)
{
driver->ops->write_pixel(x, y, color);
}
void vga_draw_char(int x, int y, unsigned char c, unsigned char color)
{ {
static unsigned mask[] = { static unsigned mask[] = {
1u << 0u, // 1 1u << 0u, // 1
@@ -518,7 +529,7 @@ void vga_draw_char(unsigned int x, unsigned int y, unsigned char c, unsigned cha
unsigned char *glyph = __font->font + c * __font->height; unsigned char *glyph = __font->font + c * __font->height;
for (unsigned cy = 0; cy < __font->height; ++cy) { for (unsigned cy = 0; cy < __font->height; ++cy) {
for (unsigned cx = 0; cx < __font->width; ++cx) { for (unsigned cx = 0; cx < __font->width; ++cx) {
driver->ops->write_pixel(x + (__font->width - cx), y + cy, glyph[cy] & mask[cx] ? color : 0x00u); vga_draw_pixel(x + (__font->width - cx), y + cy, glyph[cy] & mask[cx] ? color : 0x00u);
} }
} }
} }
@@ -533,76 +544,56 @@ void vga_draw_string(int x, int y, char *str, unsigned char color)
} }
} }
void vga_draw_line(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned char color) void vga_draw_line(int x0, int y0, int x1, int y1, unsigned char color)
{ {
bool_t steep = abs(y1 - y0) > abs(x1 - x0); int dx = abs(x1 - x0), sx = sign(x1 - x0);
int tmp = 0; int dy = abs(y1 - y0), sy = sign(y1 - y0);
if (steep) { int err = (dx > dy ? dx : -dy) / 2;
tmp = x0; while (true) {
x0 = y0; vga_draw_pixel(x0, y0, color);
y0 = tmp; if ((x0 == x1) && (y0 == y1))
break;
tmp = x1; if (dx > dy) {
x1 = y1; x0 += sx;
y1 = tmp; err -= dy;
} if (err < 0)
if (x0 > x1) { err += dx;
tmp = x0; y0 += sy;
x0 = x1; } else {
x1 = tmp; y0 += sy;
err -= dx;
tmp = y0; if (err < 0)
y0 = y1; err += dy;
y1 = tmp; x0 += sx;
}
int deltax = x1 - x0;
int deltay = abs(y1 - y0);
int error = deltax / 2;
int ystep;
int y = y0;
if (y0 < y1)
ystep = 1;
else
ystep = -1;
for (int x = x0; x < x1; x++) {
if (steep)
driver->ops->write_pixel(y, x, color);
else
driver->ops->write_pixel(x, y, color);
error = error - deltay;
if (error < 0) {
y = y + ystep;
error = error + deltax;
} }
} }
} }
void vga_draw_rectangle(unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, unsigned char fill) void vga_draw_rectangle(int sx, int sy, int w, int h, unsigned char color)
{ {
vga_draw_line(sx, sy, ex, sy, fill); vga_draw_line(sx, sy, sx + w, sy, color);
vga_draw_line(sx, sy, sx, ey, fill); vga_draw_line(sx, sy, sx, sy + h, color);
vga_draw_line(sx, ey, ex, ey, fill); vga_draw_line(sx, sy + h, sx + w, sy + h, color);
vga_draw_line(ex, ey, ex, sy, fill); vga_draw_line(sx + w, sy, sx + w, sy + h, color);
} }
void vga_draw_circle(unsigned int xc, unsigned int yc, unsigned int r, unsigned char fill) void vga_draw_circle(int xc, int yc, int r, unsigned char color)
{ {
unsigned int x = 0; int x = 0;
unsigned int y = r; int y = r;
unsigned int p = 3 - 2 * r; int p = 3 - 2 * r;
if (!r) if (!r)
return; return;
while (y >= x) // only formulate 1/8 of circle while (y >= x) // only formulate 1/8 of circle
{ {
driver->ops->write_pixel(xc - x, yc - y, fill); //upper left left vga_draw_pixel(xc - x, yc - y, color); //upper left left
driver->ops->write_pixel(xc - y, yc - x, fill); //upper upper left vga_draw_pixel(xc - y, yc - x, color); //upper upper left
driver->ops->write_pixel(xc + y, yc - x, fill); //upper upper right vga_draw_pixel(xc + y, yc - x, color); //upper upper right
driver->ops->write_pixel(xc + x, yc - y, fill); //upper right right vga_draw_pixel(xc + x, yc - y, color); //upper right right
driver->ops->write_pixel(xc - x, yc + y, fill); //lower left left vga_draw_pixel(xc - x, yc + y, color); //lower left left
driver->ops->write_pixel(xc - y, yc + x, fill); //lower lower left vga_draw_pixel(xc - y, yc + x, color); //lower lower left
driver->ops->write_pixel(xc + y, yc + x, fill); //lower lower right vga_draw_pixel(xc + y, yc + x, color); //lower lower right
driver->ops->write_pixel(xc + x, yc + y, fill); //lower right right vga_draw_pixel(xc + x, yc + y, color); //lower right right
if (p < 0) if (p < 0)
p += 4 * x++ + 6; p += 4 * x++ + 6;
else else
@@ -610,21 +601,29 @@ void vga_draw_circle(unsigned int xc, unsigned int yc, unsigned int r, unsigned
} }
} }
void vga_draw_triangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned char fill) void vga_draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, unsigned char color)
{ {
vga_draw_line(x1, y1, x2, y2, fill); vga_draw_line(x1, y1, x2, y2, color);
vga_draw_line(x2, y2, x3, y3, fill); vga_draw_line(x2, y2, x3, y3, color);
vga_draw_line(x3, y3, x1, y1, fill); vga_draw_line(x3, y3, x1, y1, color);
} }
static void __test_vga(void) void vga_run_test(void)
{ {
vga_clear_screen(); vga_clear_screen();
vga_draw_rectangle(1, 1, driver->width - 1, driver->height - 1, 3); int w2h = (vga_width() / 2);
for (unsigned i = 1; i < driver->height - 1; i++) { int h2h = (vga_height() / 2);
driver->ops->write_pixel((driver->width - driver->height) / 2 + i, i, 1);
driver->ops->write_pixel((driver->height + driver->width) / 2 - i, i, 1); for (unsigned r = 0; r <= min(vga_width() / 2, vga_height() / 2); r += 4)
} vga_draw_circle(vga_width() / 2, vga_height() / 2, r, 2);
for (unsigned y = 0; y < vga_height(); y += 2)
vga_draw_line(0, y, vga_width(), y, 3);
for (unsigned dim = 0; dim < min(vga_width(), vga_height()); dim += 4)
vga_draw_rectangle(w2h - (dim / 2), h2h - (dim / 2), dim, dim, 4);
vga_draw_triangle(0, 50, 50, 0, 100, 50, 2);
} }
// == MODEs and DRIVERs ======================================================= // == MODEs and DRIVERs =======================================================
+7 -3
View File
@@ -229,27 +229,30 @@ int kmain(boot_info_t *boot_informations)
//========================================================================== //==========================================================================
// Scan for ata devices. // Scan for ata devices.
pr_notice("Initialize ATA devices...\n"); pr_notice("Initialize ATA devices...\n");
printf("Initialize ATA devices...\n"); printf("Initialize ATA devices...");
if (ata_initialize()) { if (ata_initialize()) {
pr_emerg("Failed to initialize ATA devices!\n"); pr_emerg("Failed to initialize ATA devices!\n");
return 1; return 1;
} }
print_ok();
//========================================================================== //==========================================================================
pr_notice("Initialize EXT2 filesystem...\n"); pr_notice("Initialize EXT2 filesystem...\n");
printf("Initialize EXT2 filesystem...\n"); printf("Initialize EXT2 filesystem...");
if (ext2_initialize()) { if (ext2_initialize()) {
pr_emerg("Failed to initialize EXT2 filesystem!\n"); pr_emerg("Failed to initialize EXT2 filesystem!\n");
return 1; return 1;
} }
print_ok();
//========================================================================== //==========================================================================
pr_notice("Mount EXT2 filesystem...\n"); pr_notice("Mount EXT2 filesystem...\n");
printf("Mount EXT2 filesystem...\n"); printf("Mount EXT2 filesystem...");
if (do_mount("ext2", "/", "/dev/hda")) { if (do_mount("ext2", "/", "/dev/hda")) {
pr_emerg("Failed to mount EXT2 filesystem...\n"); pr_emerg("Failed to mount EXT2 filesystem...\n");
return 1; return 1;
} }
print_ok();
//========================================================================== //==========================================================================
pr_notice(" Initialize 'procfs'...\n"); pr_notice(" Initialize 'procfs'...\n");
@@ -268,6 +271,7 @@ int kmain(boot_info_t *boot_informations)
pr_emerg("Failed to mount procfs at `/proc`!\n"); pr_emerg("Failed to mount procfs at `/proc`!\n");
return 1; return 1;
} }
print_ok();
//========================================================================== //==========================================================================
pr_notice("Initialize video procfs file...\n"); pr_notice("Initialize video procfs file...\n");