diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-09 21:00:38 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-09 21:00:38 -0500 |
| commit | 893694168d8b943505ff30bd4db57ac8aaef6fef (patch) | |
| tree | c5e74fade8a3183e5b6db53e45eb58cb707dff05 | |
| parent | d894f23d893ee2fa05c34f02231e5c46563dc312 (diff) | |
| download | kappa-893694168d8b943505ff30bd4db57ac8aaef6fef.zip kappa-893694168d8b943505ff30bd4db57ac8aaef6fef.tar.gz kappa-893694168d8b943505ff30bd4db57ac8aaef6fef.tar.bz2 kappa-893694168d8b943505ff30bd4db57ac8aaef6fef.tar.xz | |
optimization
| -rw-r--r-- | drivers/gfx.c | 74 | ||||
| -rw-r--r-- | drivers/gfx_font.c | 24 | ||||
| -rw-r--r-- | drivers/include/gfx.h | 10 | ||||
| -rw-r--r-- | drivers/include/tty.h | 4 | ||||
| -rw-r--r-- | drivers/tty.c | 6 | ||||
| -rw-r--r-- | kernel/include/fpu.h | 4 | ||||
| -rw-r--r-- | kernel/include/log.h | 2 | ||||
| -rw-r--r-- | kernel/log.c | 2 | ||||
| -rw-r--r-- | kernel/main.c | 58 | ||||
| -rw-r--r-- | libc/include/stdio.h | 2 | ||||
| -rw-r--r-- | libc/include/stdlib.h | 5 | ||||
| -rw-r--r-- | libc/stdio.c | 6 | ||||
| -rw-r--r-- | libc/stdlib.c | 62 |
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); } |