aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gfx.c74
-rw-r--r--drivers/gfx_font.c24
-rw-r--r--drivers/include/gfx.h10
-rw-r--r--drivers/include/tty.h4
-rw-r--r--drivers/tty.c6
-rw-r--r--kernel/include/fpu.h4
-rw-r--r--kernel/include/log.h2
-rw-r--r--kernel/log.c2
-rw-r--r--kernel/main.c58
-rw-r--r--libc/include/stdio.h2
-rw-r--r--libc/include/stdlib.h5
-rw-r--r--libc/stdio.c6
-rw-r--r--libc/stdlib.c62
13 files changed, 190 insertions, 69 deletions
diff --git a/drivers/gfx.c b/drivers/gfx.c
index e0c5f17..87b2962 100644
--- a/drivers/gfx.c
+++ b/drivers/gfx.c
@@ -46,7 +46,14 @@ uint32_t gfx_get_foreground(void)
void gfx_drawpixel(int x, int y)
{
- ((uint32_t*)framebuffer)[y * fb_width + x] = _gfx_fgcol;
+ if(0 <= y && y < fb_height && 0 <= x && x < fb_width)
+ ((uint32_t*)framebuffer)[y * fb_width + x] = _gfx_fgcol;
+ else
+ {
+ printf("x: %d, y: %d\n", x, y);
+ printf("max_x: %d\nmax_y: %d\n", fb_width, fb_height);
+ panic("OOB");
+ }
}
/* implemented in assembly now */
@@ -72,11 +79,32 @@ void gfx_reset(void)
cursor_x = 0;
}
-void gfx_drawchar(int x, int y, char c)
+void gfx_drawchar(int x, int y, int c)
+{
+ uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride);
+ const uint32_t fg = _gfx_fgcol;
+ const uint16_t stride = fb_stride;
+ if(c < 0 || c > 132)
+ return;
+ for(int i = 0; i < FONT_HEIGHT; ++i)
+ {
+ uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1};
+ for(int j = 0; j < 8; ++j)
+ {
+ if(gfx_font[c][i] & mask_table[j])
+ ((uint32_t*)line_addr)[j] = fg;
+ }
+ line_addr += stride;
+ }
+}
+
+void gfx_drawchar_bg(int x, int y, int c)
{
uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride);
- const uint32_t bg = _gfx_bgcol;
const uint32_t fg = _gfx_fgcol;
+ const uint16_t stride = fb_stride;
+ if(c < 0 || c > 132)
+ return;
for(int i = 0; i < FONT_HEIGHT; ++i)
{
uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1};
@@ -84,12 +112,14 @@ void gfx_drawchar(int x, int y, char c)
{
if(gfx_font[c][i] & mask_table[j])
((uint32_t*)line_addr)[j] = fg;
+ else
+ ((uint32_t*)line_addr)[j] = _gfx_bgcol;
}
- line_addr += fb_stride;
+ line_addr += stride;
}
}
-void gfx_putchar(char ch)
+void gfx_putchar(int ch)
{
if(ch != '\n')
{
@@ -126,7 +156,7 @@ void gfx_puts(const char* str)
}
}
-/* implemented in assembly */
+/* implemented in assembly now */
#if 0
void gfx_hline(int x1, int x2, int y)
{
@@ -163,15 +193,15 @@ void gfx_vline(int y1, int y2, int x)
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 += fb_stride;
+ dest += stride;
}
}
#endif
-#define SWAP(x, y, tmp) (tmp=x;x=y;y=tmp;)
void gfx_fillrect(int x, int y, int w, int h)
{
for(int i = 0; i < h; ++i)
@@ -180,6 +210,34 @@ void gfx_fillrect(int x, int y, int w, int h)
}
}
+void gfx_drawline(int x1, int y1, int x2, int y2)
+{
+ int dx = abs(x2 - x1);
+ int sx = x1 < x2 ? 1 : -1;
+ int dy = -abs(y2 - y1);
+ int sy = y1 < y2 ? 1 : -1;
+ int err = dx + dy;
+ int e2; /* error value e_xy */
+
+ while(1)
+ {
+ gfx_drawpixel(x1, y1);
+ if (x1 == x2 && y1 == y2)
+ break;
+ e2 = err << 1;
+ if (e2 >= dy)
+ {
+ err += dy;
+ x1 += sx;
+ }
+ if (e2 <= dx)
+ {
+ err += dx;
+ y1 += sy;
+ }
+ }
+}
+
bool gfx_init(struct vbe_info_t *vbe_mode_info)
{
framebuffer = (uint8_t*)vbe_mode_info->physbase;
diff --git a/drivers/gfx_font.c b/drivers/gfx_font.c
index 311e86d..4515b31 100644
--- a/drivers/gfx_font.c
+++ b/drivers/gfx_font.c
@@ -1712,17 +1712,17 @@ const uint8_t gfx_font[][12] = {
b(00000000),
b(00000000) /* 12 */
},
- { b(00000000),
- b(01100110),
- b(01100110),
- b(01100110), /* 4 */
- b(01100110),
- b(00000000),
- b(00000000),
- b(00111100), /* 8 */
- b(01100110),
- b(11000011),
- b(00000000),
- b(00000000) /* 12 */
+ { b(10000000),
+ b(11000000),
+ b(11100000),
+ b(11110000), /* 4 */
+ b(11111000),
+ b(11111100),
+ b(11111110),
+ b(11111111), /* 8 */
+ b(11111000),
+ b(11011000),
+ b(10001100),
+ b(00000110) /* 12 */
},
};
diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h
index 561eb3e..50b84dc 100644
--- a/drivers/include/gfx.h
+++ b/drivers/include/gfx.h
@@ -36,9 +36,13 @@ bool gfx_init(struct vbe_info_t *vbe_mode_info);
void gfx_drawpixel(int x, int y);
-void gfx_drawchar(int x, int y, char ch);
+/* transparent background */
+void gfx_drawchar(int x, int y, int ch);
-void gfx_putchar(char ch);
+/* fills the background with bgcolor */
+void gfx_drawchar_bg(int x, int y, int ch);
+
+void gfx_putchar(int ch);
void gfx_puts(const char* str);
@@ -60,6 +64,8 @@ void gfx_vline(int y1, int y2, int x);
void gfx_fillrect(int x1, int y1, int w, int h);
+void gfx_drawline(int x1, int y1, int x2, int y2);
+
extern const uint16_t *gfx_width, *gfx_height;
/* this is _BYTES_ per pixel, NOT BITS per pixel! */
diff --git a/drivers/include/tty.h b/drivers/include/tty.h
index 0e142c6..4748d81 100644
--- a/drivers/include/tty.h
+++ b/drivers/include/tty.h
@@ -4,6 +4,6 @@ void tty_init(void);
void tty_clear(void);
void tty_set_color(uint8_t);
uint8_t tty_get_color(void);
-void tty_putchar_at(char ch, uint8_t color, int x, int y);
-void tty_putchar(char ch);
+void tty_putchar_at(int ch, uint8_t color, int x, int y);
+void tty_putchar(int ch);
void tty_puts(const char*);
diff --git a/drivers/tty.c b/drivers/tty.c
index ae15778..e39722b 100644
--- a/drivers/tty.c
+++ b/drivers/tty.c
@@ -75,12 +75,12 @@ uint8_t tty_get_color(void)
return term_col;
}
-void tty_putchar_at(char ch, uint8_t col, int x, int y)
+void tty_putchar_at(int ch, uint8_t col, int x, int y)
{
- term_buf[y * VGA_WIDTH + x] = VGA_MAKE_ENTRY(ch, col);
+ term_buf[y * VGA_WIDTH + x] = VGA_MAKE_ENTRY((char)ch, col);
}
-void tty_putchar(char ch)
+void tty_putchar(int ch)
{
if(ch != '\n')
{
diff --git a/kernel/include/fpu.h b/kernel/include/fpu.h
index da2b48a..0eb448a 100644
--- a/kernel/include/fpu.h
+++ b/kernel/include/fpu.h
@@ -1,2 +1,2 @@
-void enable_fpu(void);
-void disable_fpu(void);
+void fpu_enable(void);
+void fpu_disable(void);
diff --git a/kernel/include/log.h b/kernel/include/log.h
index 6953bee..1a28c0d 100644
--- a/kernel/include/log.h
+++ b/kernel/include/log.h
@@ -1,3 +1,3 @@
-void log_putchar(char);
+void log_putchar(int);
void log_puts(const char*);
void log(const char*, ...);
diff --git a/kernel/log.c b/kernel/log.c
index efc945d..311af54 100644
--- a/kernel/log.c
+++ b/kernel/log.c
@@ -7,7 +7,7 @@
void log_putchar(int ch)
{
- BOCHS_PUTCHAR(ch);
+ BOCHS_PUTCHAR((char)ch);
}
void log_puts(const char* str)
diff --git a/kernel/main.c b/kernel/main.c
index 787a471..fd263db 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -1,8 +1,10 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include "fpu.h"
#include "gdt.h"
#include "gfx.h"
+#include "gfx_font.h"
#include "idt.h"
#include "isr.h"
#include "irq.h"
@@ -17,10 +19,11 @@
void gpf(struct regs_t regs)
{
+ gfx_reset();
printf("General protection fault!\n");
printf("EIP before fault: 0x%x\n", regs.eip);
printf("Error code: 0x%x\n", regs.err_code);
- panic("GPF");
+ panic("GPF!");
}
void main(struct multiboot_info_t *hdr, uint32_t magic)
@@ -63,22 +66,30 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
printf("Boot finished.\n");
- printf("Testing RNG...\n");
- srand(*current_tick);
+ printf("Running graphics benchmark...\n");
+ srand(42);
+
if(gfx_status)
{
+ const int width = *gfx_width;
+ const int height = *gfx_height;
+
+ gfx_clear();
+
int startpix = *current_tick;
for(int i=0;i<1000000;++i)
{
- int rx = rand() % *gfx_width;
- int ry = rand() % *gfx_height;
+ int rx = rand() % width;
+ int ry = rand() % height;
gfx_set_foreground(rand() % 0x1000000);
gfx_drawpixel(rx, ry);
}
int endpix = *current_tick;
+ gfx_clear();
+
int startfill = *current_tick;
for(int i=0;i<1000;++i)
{
@@ -87,14 +98,13 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
}
int endfill = *current_tick;
- gfx_set_background(0);
- gfx_set_foreground(0xFFFFFF);
gfx_clear();
int starttext = *current_tick;
for(int i=0;i<1000000;++i)
{
- int rx = rand() % *gfx_width;
- int ry = rand() % *gfx_height;
+ int rx = rand() % width;
+ int ry = rand() % height;
+ gfx_set_foreground(rand() % 0x1000000);
gfx_drawchar(rx, ry, rand()%127+1);
}
int endtext = *current_tick;
@@ -103,7 +113,8 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
int starthline = *current_tick;
for(int i=0;i<1000000;++i)
{
- gfx_hline(rand() % *gfx_width, rand() % *gfx_width, rand() % *gfx_height);
+ gfx_set_foreground(rand() % 0x1000000);
+ gfx_hline(rand() % width, rand() % width, rand() % height);
}
int endhline = *current_tick;
@@ -112,7 +123,8 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
int startvline = *current_tick;
for(int i=0;i<1000000;++i)
{
- gfx_vline(rand() % *gfx_height, rand() % *gfx_height, rand() % *gfx_width);
+ gfx_set_foreground(rand() % 0x1000000);
+ gfx_vline(rand() % height, rand() % height, rand() % width);
}
int endvline = *current_tick;
@@ -121,14 +133,29 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
int startrect = *current_tick;
for(int i=0;i<10000;++i)
{
- int x = rand() % *gfx_width;
- int y = rand() % *gfx_height;
- int w = rand() % (*gfx_width - x);
- int h = rand() % (*gfx_height - y);
+ int x = rand() % width;
+ int y = rand() % height;
+ int w = rand() % (width - x);
+ int h = rand() % (height - y);
+ gfx_set_foreground(rand() % 0x1000000);
gfx_fillrect(x, y, w, h);
}
int endrect = *current_tick;
+ gfx_clear();
+
+ int startline = *current_tick;
+ for(int i=0;i<1000000;++i)
+ {
+ int x1= rand() % width;
+ int x2= rand() % width;
+ int y1= rand() % height;
+ int y2= rand() % height;
+ gfx_set_foreground(rand() % 0x1000000);
+ gfx_drawline(x1, y1, x2, y2);
+ }
+ int endline = *current_tick;
+
gfx_reset();
printf("--- Graphics benchmark results ---\n");
printf("Ticks for 1,000,000 random pixels: %d\n", endpix-startpix);
@@ -137,6 +164,7 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
printf("Ticks for 1,000,000 random hlines: %d\n", endhline-starthline);
printf("Ticks for 1,000,000 random vlines: %d\n", endvline-startvline);
printf("Ticks for 10,000 random rects: %d\n", endrect-startrect);
+ printf("Ticks for 1,000,000 random lines: %d\n", endline-startline);
printf("Ticks per second: %d\n", HZ);
printf("Resolution: %dx%dx%d\n", *gfx_width, *gfx_height, *gfx_bpp * 8);
}
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 92442ac..49966cf 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -3,5 +3,5 @@ int puts(const char*);
int putchar(int);
/* sets the I/O functions, allows easy switching between text mode and VBE */
-void set_putchar(void (*func)(char));
+void set_putchar(void (*func)(int));
void set_puts(void (*func)(const char*));
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 0a3d559..91f16f3 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -3,5 +3,8 @@
/* NOT reentrant! */
char* itoa(int val, int base);
-int rand(void);
+#define RAND_MAX ((1U << 31) - 1)
+
+unsigned int rand(void);
void srand(unsigned int);
+int abs(int);
diff --git a/libc/stdio.c b/libc/stdio.c
index 0ef8b0c..8219d11 100644
--- a/libc/stdio.c
+++ b/libc/stdio.c
@@ -3,12 +3,12 @@
#include <stdio.h>
#include <stdlib.h>
-static void (*putchar_ptr)(char) = log_putchar;
+static void (*putchar_ptr)(int) = log_putchar;
static void (*puts_ptr)(const char*) = log_puts;
int putchar(int ch)
{
- putchar_ptr((char)ch);
+ putchar_ptr(ch);
return 0;
}
@@ -18,7 +18,7 @@ int puts(const char* str)
return 0;
}
-void set_putchar(void (*func)(char))
+void set_putchar(void (*func)(int))
{
putchar_ptr = func;
}
diff --git a/libc/stdlib.c b/libc/stdlib.c
index ca890b4..bea3b65 100644
--- a/libc/stdlib.c
+++ b/libc/stdlib.c
@@ -5,35 +5,61 @@ char* itoa(int val, int base)
{
static char buf[32] = {0};
- int i = 30;
+ int neg = 0;
+
+ if(val < 0)
+ {
+ val = -val;
+ neg = 1;
+ }
- for(; val && i ; --i, val /= base)
+ int i = 30;
+ do
+ {
buf[i] = "0123456789abcdef"[val % base];
+ --i;
+ val /= base;
+ }
+ while(val && i);
+
+ if(neg)
+ {
+ buf[i] = '-';
+ }
- return &buf[i+1];
+ return &buf[i+(neg?0:1)];
}
-static int rand_state = 42;
+static unsigned long rand_s1 = 18, rand_s2 = 5, rand_s3 = 43;
-/* some constants for the RNG */
-#define A 48271
-#define M 2147483647
-#define Q (M/A)
-#define R (M%A)
+#define M 1103515245UL
+#define A 12345UL
-int rand(void)
+/* this is a very fast tausworthe RNG */
+
+unsigned int rand(void)
{
- int tmp = A * (rand_state % Q) - R * (rand_state / Q);
- if(tmp >= 0)
- rand_state = tmp;
- else
- rand_state = tmp + M;
- return rand_state;
+ rand_s1 = (((rand_s1&4294967294)<<12)^(((rand_s1<<13)^rand_s1)>>19));
+ rand_s2 = (((rand_s2&4294967288)<< 4)^(((rand_s2<< 2)^rand_s2)>>25));
+ rand_s3 = (((rand_s3&4294967280)<<17)^(((rand_s3<< 3)^rand_s3)>>11));
+ return (rand_s1 ^ rand_s2 ^ rand_s3);
}
void srand(unsigned int seed)
{
- /* prevent a zero seed */
- rand_state = (!seed?42:seed);
+ if(!seed)
+ seed = 42;
+ rand_s1 = seed++;
+ rand_s2 = seed++;
+ rand_s3 = seed++;
+ /* "warm it up" */
+ rand();
+ rand();
+ rand();
+}
+
+int abs(int val)
+{
+ return (val<0?-val:val);
}