aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gfx-as.S11
-rw-r--r--drivers/gfx.c218
-rw-r--r--drivers/gfx_font.c10
-rw-r--r--drivers/include/gfx.h26
-rw-r--r--drivers/ps2.c3
5 files changed, 235 insertions, 33 deletions
diff --git a/drivers/gfx-as.S b/drivers/gfx-as.S
index 675a6d5..a58fa12 100644
--- a/drivers/gfx-as.S
+++ b/drivers/gfx-as.S
@@ -25,8 +25,10 @@ gfx_clear_packed:
popl %ebx
ret
- .global gfx_hline
-gfx_hline:
+ .global gfx_hline_fast
+
+gfx_hline_fast:
+ int $0x80
pushl %ebx
movl 8(%esp), %eax
movl 12(%esp), %ecx
@@ -54,8 +56,9 @@ gfx_hline:
popl %ebx
ret
- .global gfx_vline
-gfx_vline:
+ .global gfx_vline_fast
+
+gfx_vline_fast:
pushl %esi
pushl %ebx
movl 12(%esp), %eax
diff --git a/drivers/gfx.c b/drivers/gfx.c
index 7c56800..028a5e5 100644
--- a/drivers/gfx.c
+++ b/drivers/gfx.c
@@ -9,7 +9,10 @@
#include "panic.h"
#include "gfx.h"
+uint8_t *real_framebuffer = NULL;
+uint8_t *temp_framebuffer = NULL;
uint8_t *framebuffer = NULL;
+bool double_buffer = false;
uint16_t fb_width;
uint16_t fb_height;
@@ -28,6 +31,8 @@ uint32_t _gfx_fgcol, _gfx_bgcol;
void (*gfx_clear)(void);
void (*gfx_drawpixel)(int x, int y);
+void (*gfx_hline)(int x1, int x2, int y);
+void (*gfx_vline)(int y1, int y2, int x);
void gfx_set_background(uint32_t col)
{
@@ -58,6 +63,7 @@ void gfx_drawpixel_32bpp_checked(int x, int y)
else
panic("pixel OOB!\n");
}
+
/* implemented in assembly now */
/*
void gfx_clear(uint32_t col)
@@ -195,8 +201,7 @@ void gfx_puts(const char* str)
}
/* implemented in assembly now */
-#if 0
-void gfx_hline(int x1, int x2, int y)
+void gfx_hline_checked(int x1, int x2, int y)
{
/* make sure x1 is to the left of x2 */
if(x2 < x1)
@@ -206,19 +211,26 @@ void gfx_hline(int x1, int x2, int y)
x2 = temp;
}
- uint8_t *base = framebuffer + y * fb_stride;
+ x1 = MAX(0, x1);
+ x2 = MIN(x2, fb_width);
- uint8_t *dest = base + x1 * fb_bpp;
- uint8_t *stop = base + x2 * fb_bpp;
- const uint32_t col = _gfx_fgcol;
- while(dest < stop)
+ if(0 <= y && y < fb_height)
{
- *(uint32_t*)dest = col;
- dest += fb_bpp;
+
+ uint8_t *base = framebuffer + y * fb_stride;
+
+ uint8_t *dest = base + x1 * fb_bpp;
+ uint8_t *stop = base + x2 * fb_bpp;
+ const uint32_t col = _gfx_fgcol;
+ while(dest < stop)
+ {
+ *(uint32_t*)dest = col;
+ dest += fb_bpp;
+ }
}
}
-void gfx_vline(int y1, int y2, int x)
+void gfx_vline_checked(int y1, int y2, int x)
{
/* make sure y1 is above y2 */
if(y2 < y1)
@@ -228,17 +240,22 @@ void gfx_vline(int y1, int y2, int x)
y2 = temp;
}
- uint8_t *dest = framebuffer + y1 * fb_stride + x * fb_bpp;
- uint8_t *stop = framebuffer + y2 * fb_stride + x * fb_bpp;
- const uint32_t col = _gfx_fgcol;
- const uint16_t stride = fb_stride;
- while(dest < stop)
+ y1 = MAX(0, y1);
+ y2 = MIN(y2, fb_height);
+
+ if(0 <= x && x < fb_width)
{
- *(uint32_t*)dest = col;
- dest += stride;
+ uint8_t *dest = framebuffer + y1 * fb_stride + x * fb_bpp;
+ uint8_t *stop = framebuffer + y2 * fb_stride + x * fb_bpp;
+ const uint32_t col = _gfx_fgcol;
+ const uint16_t stride = fb_stride;
+ while(dest < stop)
+ {
+ *(uint32_t*)dest = col;
+ dest += stride;
+ }
}
}
-#endif
void gfx_fillrect(int x, int y, int w, int h)
{
@@ -328,15 +345,172 @@ void gfx_fillcircle(int cx, int cy, int r)
}
}
+/* these next two functions were taken directly from the Rockbox project's XLCD
+ * library.
+ * Copyright (C) 2005 Jens Arnold */
+
+/* sort the given coordinates by increasing x value */
+static void sort_points_by_increasing_y(int* y1, int* x1,
+ int* y2, int* x2,
+ int* y3, int* x3)
+{
+ int x, y;
+ if (*x1 > *x3)
+ {
+ if (*x2 < *x3) /* x2 < x3 < x1 */
+ {
+ x = *x1; *x1 = *x2; *x2 = *x3; *x3 = x;
+ y = *y1; *y1 = *y2; *y2 = *y3; *y3 = y;
+ }
+ else if (*x2 > *x1) /* x3 < x1 < x2 */
+ {
+ x = *x1; *x1 = *x3; *x3 = *x2; *x2 = x;
+ y = *y1; *y1 = *y3; *y3 = *y2; *y2 = y;
+ }
+ else /* x3 <= x2 <= x1 */
+ {
+ x = *x1; *x1 = *x3; *x3 = x;
+ y = *y1; *y1 = *y3; *y3 = y;
+ }
+ }
+ else
+ {
+ if (*x2 < *x1) /* x2 < x1 <= x3 */
+ {
+ x = *x1; *x1 = *x2; *x2 = x;
+ y = *y1; *y1 = *y2; *y2 = y;
+ }
+ else if (*x2 > *x3) /* x1 <= x3 < x2 */
+ {
+ x = *x2; *x2 = *x3; *x3 = x;
+ y = *y2; *y2 = *y3; *y3 = y;
+ }
+ /* else already sorted */
+ }
+}
+
+/* draw a filled triangle, using horizontal lines for speed */
+void gfx_filltriangle(int x1, int y1,
+ int x2, int y2,
+ int x3, int y3)
+{
+ long fp_x1, fp_x2, fp_dx1, fp_dx2;
+ int y;
+ sort_points_by_increasing_y(&x1, &y1, &x2, &y2, &x3, &y3);
+
+ if (y1 < y3) /* draw */
+ {
+ fp_dx1 = ((x3 - x1) << 16) / (y3 - y1);
+ fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1);
+
+ if (y1 < y2) /* first part */
+ {
+ fp_dx2 = ((x2 - x1) << 16) / (y2 - y1);
+ fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1);
+ for (y = y1; y < y2; y++)
+ {
+ gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y);
+ fp_x1 += fp_dx1;
+ fp_x2 += fp_dx2;
+ }
+ }
+ if (y2 < y3) /* second part */
+ {
+ fp_dx2 = ((x3 - x2) << 16) / (y3 - y2);
+ fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1);
+ for (y = y2; y < y3; y++)
+ {
+ gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y);
+ fp_x1 += fp_dx1;
+ fp_x2 += fp_dx2;
+ }
+ }
+ }
+}
+
+static void gfx_bitmap32(int x, int y, const struct bitmap_t *bmp)
+{
+ /* SLOOW */
+ uint8_t *data = bmp->data;
+ for(unsigned int i = y; i < y + bmp->h && i < fb_height; ++i)
+ {
+ for(unsigned int j = x; j < x + bmp->w && j < fb_width; ++j)
+ {
+ uint8_t r = *data++;
+ uint8_t g = *data++;
+ uint8_t b = *data++;
+ gfx_set_foreground(VGA_RGBPACK(r, g, b));
+ gfx_drawpixel(j, i);
+ }
+ }
+}
+
+void gfx_bitmap(int x, int y, const struct bitmap_t *bmp)
+{
+ gfx_bitmap32(x, y, bmp);
+}
+
+void gfx_drawrect(int x, int y, int w, int h)
+{
+ gfx_hline(MAX(0, x), MIN(x + w, fb_width), MAX(0, y));
+ gfx_hline(MAX(0, x), MIN(x + w, fb_width), MIN(y + h, fb_height));
+ gfx_vline(MAX(0, y), MIN(y + h, fb_height),MAX(0, x));
+ gfx_vline(MAX(0, y), MIN(y + h, fb_height),MIN(x + w, fb_width));
+}
+
+void gfx_update(void)
+{
+ memcpy(real_framebuffer, framebuffer, fb_height * fb_stride);
+}
+
+void gfx_set_doublebuffer(bool yesno)
+{
+ if(yesno)
+ framebuffer = temp_framebuffer;
+ else
+ framebuffer = real_framebuffer;
+}
+
+bool gfx_get_doublebuffer(void)
+{
+ if(framebuffer == temp_framebuffer)
+ return true;
+ else
+ return false;
+}
+
+void gfx_putsxy(int x, int y, const char* str)
+{
+ while(*str)
+ {
+ gfx_drawchar(x, y, *str);
+ x += FONT_WIDTH;
+ str++;
+ }
+}
+
+void gfx_putsxy_bg(int x, int y, const char* str)
+{
+ while(*str)
+ {
+ gfx_drawchar_bg(x, y, *str);
+ x += FONT_WIDTH;
+ str++;
+ }
+}
bool gfx_init(struct vbe_info_t *vbe_mode_info)
{
- framebuffer = (uint8_t*)vbe_mode_info->physbase;
+ real_framebuffer = (uint8_t*)vbe_mode_info->physbase;
+ gfx_set_doublebuffer(false);
fb_width = vbe_mode_info->Xres;
fb_height = vbe_mode_info->Yres;
fb_bpp = vbe_mode_info->bpp / 8;
fb_stride = vbe_mode_info->pitch;
- fb_stride32 = fb_stride / 4;
+ fb_stride32 = fb_stride / sizeof(uint32_t);
+ gfx_hline = gfx_hline_checked;
+ gfx_vline = gfx_vline_checked;
+ temp_framebuffer = malloc(fb_height * fb_stride);
if(fb_bpp != 4)
{
printf("WARNING: BPP != 32, falling back to text mode...\n");
@@ -344,8 +518,8 @@ bool gfx_init(struct vbe_info_t *vbe_mode_info)
}
else
{
- //extern void gfx_drawpixel_32bpp(int, int);
- gfx_drawpixel = &gfx_drawpixel_32bpp_checked;
+ extern void gfx_drawpixel_32bpp(int, int);
+ gfx_drawpixel = &gfx_drawpixel_32bpp;
}
set_putchar(gfx_putchar);
diff --git a/drivers/gfx_font.c b/drivers/gfx_font.c
index 4515b31..6669931 100644
--- a/drivers/gfx_font.c
+++ b/drivers/gfx_font.c
@@ -1719,10 +1719,10 @@ const uint8_t gfx_font[][12] = {
b(11111000),
b(11111100),
b(11111110),
- b(11111111), /* 8 */
- b(11111000),
- b(11011000),
- b(10001100),
- b(00000110) /* 12 */
+ b(11100000), /* 8 */
+ b(11000000),
+ b(10000000),
+ b(00000000),
+ b(00000000) /* 12 */
},
};
diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h
index 2abc172..5e97100 100644
--- a/drivers/include/gfx.h
+++ b/drivers/include/gfx.h
@@ -62,9 +62,9 @@ void gfx_set_background(uint32_t);
uint32_t gfx_get_background(void);
-void gfx_hline(int x1, int x2, int y);
+void (*gfx_hline)(int x1, int x2, int y);
-void gfx_vline(int y1, int y2, int x);
+void (*gfx_vline)(int y1, int y2, int x);
void gfx_fillrect(int x1, int y1, int w, int h);
@@ -75,9 +75,31 @@ void gfx_drawcircle(int cx, int cy, int rad);
void gfx_fillcircle(int cx, int cy, int rad);
+void gfx_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3);
+
extern const uint16_t *gfx_width, *gfx_height;
/* this is _BYTES_ per pixel, NOT BITS per pixel! */
extern const uint8_t *gfx_bpp;
+struct bitmap_t {
+ unsigned int w, h;
+ unsigned int bpp;
+ uint8_t *data;
+};
+
+void gfx_bitmap(int x, int y, const struct bitmap_t*);
+
+void gfx_drawrect(int x, int y, int w, int h);
+
+void gfx_set_doublebuffer(bool);
+
+bool gfx_get_doublebuffer(void);
+
+/* don't call this wo/ double buffering! */
+void gfx_update(void);
+
+void gfx_putsxy(int, int, const char*);
+
+void gfx_putsxy_bg(int, int, const char*);
#endif
diff --git a/drivers/ps2.c b/drivers/ps2.c
index c9ff30e..9da026d 100644
--- a/drivers/ps2.c
+++ b/drivers/ps2.c
@@ -4,6 +4,7 @@
#include "io.h"
#include "isr.h"
#include "ps2.h"
+#include "ps2_keymaps.h"
static void ps2_wait(void)
{
@@ -19,6 +20,8 @@ void ps2_set_leds(uint8_t status)
outb(0x60, status);
}
+static uint8_t keyboard_state[16];
+
static void key_handler(struct regs_t *regs)
{
(void) regs;