diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-28 20:46:37 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-28 20:46:37 -0500 |
| commit | e81f651b15be15624d7184e1823bf5b623f11604 (patch) | |
| tree | fda3d16b0245dd83f367f523042f02a0e1b14db0 | |
| parent | 2dc45e8cac33313e847f6097cbe2ba3bb3ceab2a (diff) | |
| download | kappa-e81f651b15be15624d7184e1823bf5b623f11604.zip kappa-e81f651b15be15624d7184e1823bf5b623f11604.tar.gz kappa-e81f651b15be15624d7184e1823bf5b623f11604.tar.bz2 kappa-e81f651b15be15624d7184e1823bf5b623f11604.tar.xz | |
stuff
| -rw-r--r-- | OBJ | 8 | ||||
| -rw-r--r-- | apps/plugin.h | 3 | ||||
| -rw-r--r-- | apps/xracer/util.c | 1 | ||||
| -rw-r--r-- | boot/head.S | 2 | ||||
| -rw-r--r-- | drivers/include/ps2_keymaps.h | 39 | ||||
| -rw-r--r-- | drivers/include/ps2kbd.h | 33 | ||||
| -rw-r--r-- | drivers/ps2_keymaps.c | 99 | ||||
| -rw-r--r-- | drivers/ps2kbd.c | 113 | ||||
| -rw-r--r-- | kernel/main.c | 326 | ||||
| -rw-r--r-- | libc/include/stdlib.h | 4 | ||||
| -rw-r--r-- | libc/stdlib.c | 49 |
11 files changed, 482 insertions, 195 deletions
@@ -1,19 +1,19 @@ apps/fixedpoint.o apps/plugin.o -apps/xracer/graphics.o apps/xracer/generator.o +apps/xracer/graphics.o +apps/xracer/main.o apps/xracer/map.o apps/xracer/maps.o apps/xracer/sprite.o -apps/xracer/main.o apps/xracer/util.o boot/head.o -drivers/gfx.o drivers/gfx-as.o +drivers/gfx.o drivers/gfx_font.o drivers/pcspkr.o -drivers/ps2kbd.o drivers/ps2_keymaps.o +drivers/ps2kbd.o drivers/tty.o kernel/fpu.o kernel/gdt-as.o diff --git a/apps/plugin.h b/apps/plugin.h index e9c790c..4eb7066 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -2,6 +2,7 @@ #define _PLUGIN_H_ #include <stddef.h> +#include <stdint.h> #include <stdlib.h> #include <stdio.h> #include "gfx.h" @@ -41,7 +42,7 @@ struct plugin_api { void (*lcd_set_background)(unsigned foreground); unsigned (*lcd_get_background)(void); - void (*srand)(unsigned int seed); + void (*srand)(uint64_t seed); unsigned int (*rand)(void); void (*lcd_filltriangle)(int, int, int, int, int, int); diff --git a/apps/xracer/util.c b/apps/xracer/util.c index 8f09d67..7403c33 100644 --- a/apps/xracer/util.c +++ b/apps/xracer/util.c @@ -88,7 +88,6 @@ int camera_calc_depth(int fov) } void error_real(const char *msg, ...) { - char buf[256]; LOGF("ERROR: %s!", msg); } diff --git a/boot/head.S b/boot/head.S index 896cdb3..8e607e0 100644 --- a/boot/head.S +++ b/boot/head.S @@ -24,7 +24,7 @@ multiboot_header: .section .stack stack_bottom: # Stack grows up in addresses, so bottom is # lower in memory than the top - .skip 65536 # 32KB stack + .skip 32768 # 32KB stack stack_top: .section .text diff --git a/drivers/include/ps2_keymaps.h b/drivers/include/ps2_keymaps.h index 91688c8..0e8ae26 100644 --- a/drivers/include/ps2_keymaps.h +++ b/drivers/include/ps2_keymaps.h @@ -1,8 +1,39 @@ #include <stdint.h> -#define ERROR_KEY 0x00 -#define PRINTING_KEY 0x01 -#define SPECIAL_KEY 0x02 +#define EXTENDED_SCANCODE 0xE0 -extern uint8_t ps2_scancodes_set1[128]; +#define ERROR_KEY 0 +#define PRINTING_KEY 1 +#define SPECIAL_KEY 2 + +#define SPECIAL_NONE 0 +#define SPECIAL_SHIFT 1 +#define SPECIAL_CTRL 2 +#define SPECIAL_BKSP 3 +#define SPECIAL_ALT 4 +#define SPECIAL_GUI 5 +#define SPECIAL_NUMLOCK 6 +#define SPECIAL_CAPLOCK 7 +#define SPECIAL_SCRLLOCK 8 +#define SPECIAL_UPARROW 9 +#define SPECIAL_DNARROW 10 +#define SPECIAL_LFTARROW 11 +#define SPECIAL_RTARROW 12 +#define SPECIAL_ESC 13 +#define SPECIAL_F1 21 +#define SPECIAL_F2 22 +#define SPECIAL_F3 23 +#define SPECIAL_F4 24 +#define SPECIAL_F5 25 +#define SPECIAL_F6 26 +#define SPECIAL_F7 27 +#define SPECIAL_F8 28 +#define SPECIAL_F9 29 +#define SPECIAL_F10 30 +#define SPECIAL_F11 31 +#define SPECIAL_F12 32 + +extern uint8_t ps2_set1_scancodes[128]; extern char ps2_set1_ascii[128]; +extern char ps2_set1_shift[128]; +extern uint8_t ps2_set1_special[128]; diff --git a/drivers/include/ps2kbd.h b/drivers/include/ps2kbd.h index dcde1d8..bf4871d 100644 --- a/drivers/include/ps2kbd.h +++ b/drivers/include/ps2kbd.h @@ -1,5 +1,8 @@ /* this is both a PS/2 keyboard AND a PS/2 MOUSE driver */ +#ifndef _PS2KBD_H_ +#define _PS2KBD_H_ +#include <stdbool.h> #include <stdint.h> #define PS2_SCROLL_LOCK (1 << 0) @@ -16,6 +19,34 @@ #define MODIFIER_CTRL (1 << 1) #define MODIFIER_ALT (1 << 2) +struct ps2_specialkeys_t { + int shift :1; + int ctrl :1; + int bksp :1; + int alt :1; + int gui :1; + int numlock :1; + int capslock :1; + int scrllock :1; + int uparrow :1; + int downarrow :1; + int leftarrow :1; + int rightarrow :1; + int esc :1; + int f1 :1; + int f2 :1; + int f3 :1; + int f4 :1; + int f5 :1; + int f6 :1; + int f7 :1; + int f8 :1; + int f9 :1; + int f10 :1; + int f11 :1; + int f12 :1; +}; + /* returns which arrow keys are down */ uint8_t ps2kbd_button_get(void); @@ -24,3 +55,5 @@ uint8_t ps2kbd_modifier_get(void); void ps2kbd_set_leds(uint8_t status); void ps2kbd_init(void); + +#endif diff --git a/drivers/ps2_keymaps.c b/drivers/ps2_keymaps.c index cd7fd08..1e685c0 100644 --- a/drivers/ps2_keymaps.c +++ b/drivers/ps2_keymaps.c @@ -1,7 +1,7 @@ #include <stdint.h> #include "ps2_keymaps.h" -uint8_t ps2_scancodes_set1[128] = { +uint8_t ps2_set1_scancodes[128] = { ERROR_KEY, /* error */ SPECIAL_KEY, /* esc */ PRINTING_KEY, /* 1 */ @@ -192,6 +192,7 @@ char ps2_set1_ascii[128] = { '\0', '\0', }; + char ps2_set1_shift[128] = { '\0', '\0', @@ -287,3 +288,99 @@ char ps2_set1_shift[128] = { '\0', '\0', }; + +uint8_t ps2_set1_special[128] = { + 0, /* error */ + SPECIAL_ESC, /* esc */ + 0, /* 1 */ + 0, /* 2 */ + 0, /* 3 */ + 0, /* 4 */ + 0, /* 5 */ + 0, /* 6 */ + 0, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 0, /* 0 */ + 0, /* - */ + 0, /* = */ + SPECIAL_BKSP, /* backspace */ + 0, /* tab */ + 0, /* Q */ + 0, /* W */ + 0, /* E */ + 0, /* R */ + 0, /* T */ + 0, /* Y */ + 0, /* U */ + 0, /* I */ + 0, /* O */ + 0, /* P */ + 0, /* [ */ + 0, /* ] */ + 0, /* enter */ + SPECIAL_CTRL, /* left ctrl */ + 0, /* A */ + 0, /* S */ + 0, /* D */ + 0, /* F */ + 0, /* G */ + 0, /* H */ + 0, /* J */ + 0, /* K */ + 0, /* L */ + 0, /* ; */ + 0, /* ' */ + 0, /* ` */ + SPECIAL_SHIFT, /* left shift */ + 0, /* \ (backslash) */ + 0, /* Z */ + 0, /* X */ + 0, /* C */ + 0, /* V */ + 0, /* B */ + 0, /* N */ + 0, /* M */ + 0, /* , */ + 0, /* . */ + 0, /* / */ + SPECIAL_SHIFT, /* right shift */ + 0, /* keypad * */ + SPECIAL_ALT, /* right alt */ + 0, /* space */ + SPECIAL_CAPLOCK, /* caps lock */ + SPECIAL_F1, /* F1 */ + SPECIAL_F2, /* F2 */ + SPECIAL_F3, /* F3 */ + SPECIAL_F4, /* F4 */ + SPECIAL_F5, /* F5 */ + SPECIAL_F6, /* F6 */ + SPECIAL_F7, /* F7 */ + SPECIAL_F8, /* F8 */ + SPECIAL_F9, /* F9 */ + SPECIAL_F10, /* F10 */ + SPECIAL_NUMLOCK, /* num lock */ + SPECIAL_SCRLLOCK, /* scroll lock */ + 0, /* keypad 7 */ + 0, /* keypad 8 */ + 0, /* keypad 9 */ + 0, /* keypad - */ + 0, /* keypad 4 */ + 0, /* keypad 5 */ + 0, /* keypad 6 */ + 0, /* keypad + */ + 0, /* keypad 1 */ + 0, /* keypad 2 */ + 0, /* keypad 3 */ + 0, /* keypad 0 */ + 0, /* keypad . */ + 0, /* 0x54 */ + 0, /* 0x55 */ + 0, /* 0x56 */ + SPECIAL_F11, /* F11 */ + SPECIAL_F12, /* F12 */ + 0, + 0, + 0, + 0 +}; diff --git a/drivers/ps2kbd.c b/drivers/ps2kbd.c index 73b75d1..40b06ac 100644 --- a/drivers/ps2kbd.c +++ b/drivers/ps2kbd.c @@ -1,6 +1,7 @@ -/* this is both a PS/2 keyboard driver */ +/* this is a PS/2 keyboard driver */ #include <stdint.h> #include <stdio.h> +#include <string.h> #include "io.h" #include "isr.h" #include "ps2kbd.h" @@ -57,23 +58,122 @@ uint8_t ps2kbd_modifier_get(void) return ret; } +static struct ps2_specialkeys_t special_keys; + +static void handle_special_key(uint8_t scancode, int release) +{ + int press = ~release; + switch(ps2_set1_special[scancode]) + { + case SPECIAL_SHIFT: + special_keys.shift = press; + break; + case SPECIAL_CTRL: + special_keys.ctrl = press; + break; + case SPECIAL_BKSP: + special_keys.bksp = press; + break; + case SPECIAL_ALT: + special_keys.alt = press; + break; + case SPECIAL_NUMLOCK: + special_keys.numlock = ~special_keys.numlock; + ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); + break; + case SPECIAL_CAPLOCK: + special_keys.capslock = ~special_keys.capslock; + ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); + break; + case SPECIAL_SCRLLOCK: + special_keys.scrllock = ~special_keys.scrllock; + ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); + break; + case SPECIAL_ESC: + special_keys.esc = press; + break; + case SPECIAL_F1: + special_keys.f1 = press; + break; + case SPECIAL_F2: + special_keys.f2 = press; + break; + case SPECIAL_F3: + special_keys.f3 = press; + break; + case SPECIAL_F4: + special_keys.f4 = press; + break; + case SPECIAL_F5: + special_keys.f5 = press; + break; + case SPECIAL_F6: + special_keys.f6 = press; + break; + case SPECIAL_F7: + special_keys.f7 = press; + break; + case SPECIAL_F8: + special_keys.f8 = press; + break; + case SPECIAL_F9: + special_keys.f9 = press; + break; + case SPECIAL_F10: + special_keys.f10 = press; + break; + case SPECIAL_F11: + special_keys.f11 = press; + break; + case SPECIAL_F12: + special_keys.f12 = press; + break; + } +} + +static void handle_extended_scancode(void) +{ + uint8_t temp = inb(0x60); + //printf("Extended scancode: 0x%x\n", temp); +} + static void key_handler(struct regs_t *regs) { (void) regs; uint8_t scancode = inb(0x60); - if(scancode == 0xE0) - /* extended, forget it! */ + //printf("INTR SCAN: 0x%x\n", scancode); + if(scancode == EXTENDED_SCANCODE) + { + handle_extended_scancode(); return; + } + /* AND by 0x7F to get in the range of [0,128) */ - int type = ps2_scancodes_set1[scancode & 0x7F]; - int release = (scancode & 0x80) >> 7; + + int type = ps2_set1_scancodes[scancode & 0x7F]; + int release = (scancode & (1<<7)) >> 7; switch(type) { case PRINTING_KEY: + { if(!release) - putchar(ps2_set1_ascii[scancode]); + { + int capitals = special_keys.capslock; + if(special_keys.shift) + capitals = ~capitals; + if(capitals) + putchar(ps2_set1_shift[scancode]); + else + putchar(ps2_set1_ascii[scancode]); + } + break; + } + case SPECIAL_KEY: + handle_special_key(scancode & 0x7F, release); break; } + if(special_keys.bksp) + putchar('\b'); } static void ps2_set_scancode_set(uint8_t set) @@ -87,6 +187,7 @@ static void keyboard_init(void) { set_interrupt_handler(IRQ(1), key_handler); ps2_set_scancode_set(1); + memset(&special_keys, 0, sizeof(special_keys)); } void ps2kbd_init(void) diff --git a/kernel/main.c b/kernel/main.c index 005ac1d..cdab037 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -52,7 +52,55 @@ void nothin(struct regs_t* regs) (void) regs; } -void main(struct multiboot_info_t *hdr, uint32_t magic) +void flash_leds(void) +{ + printf("Testing keyboard LED's"); + + int n = 0; + int s = 1; + + while(1) + { + ps2kbd_set_leds(PS2_NUM_LOCK); + timer_delay(HZ/4); + if(s < 0) + putchar('\b'); + else + putchar('.'); + n+=s; + if(n<=0 || n>=3) + s=-s; + ps2kbd_set_leds(PS2_CAPS_LOCK); + timer_delay(HZ/4); + if(s < 0) + putchar('\b'); + else + putchar('.'); + n+=s; + if(n<=0 || n>=3) + s=-s; + ps2kbd_set_leds(PS2_SCROLL_LOCK); + timer_delay(HZ/4); + if(s < 0) + putchar('\b'); + else + putchar('.'); + n+=s; + if(n<=0 || n>=3) + s=-s; + ps2kbd_set_leds(PS2_CAPS_LOCK); + timer_delay(HZ/4); + if(s < 0) + putchar('\b'); + else + putchar('.'); + n+=s; + if(n<=0 || n>=3) + s=-s; + } +} + +bool boot(struct multiboot_info_t *hdr, uint32_t magic) { fpu_enable(); @@ -103,179 +151,139 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) printf("Kernel version %s: \"%s\"\n", KAPPA_KERNEL_VERSION, KAPPA_KERNEL_CODENAME); - while(1) - asm("hlt"); + return gfx_status; +} - printf("Starting linked-in application XRacer...\n"); - //printf("Running graphics benchmark...\n"); - srand(42); +void run_gfx_benchmark(void) +{ + const int width = *gfx_width; + const int height = *gfx_height; gfx_reset(); - enum plugin_status; - struct plugin_api; - extern enum plugin_status xracer_main(const struct plugin_api*); - extern void plugin_load(enum plugin_status (*func)(const struct plugin_api*)); + int startpix = *current_tick; + for(int i=0;i<1000000;++i) + { + int rx = rand() % width; + int ry = rand() % height; - plugin_load(xracer_main); + gfx_set_foreground(rand() % 0x1000000); + gfx_drawpixel(rx, ry); + } + int endpix = *current_tick; - gfx_filltriangle(100, 100, 100, 100, 100, 100); + gfx_reset(); - for(int i=0;i<200;) + int startfill = *current_tick; + for(int i=0;i<1000;++i) { - gfx_putsxy_bg(i, 0, " "); - gfx_drawchar_bg(++i, 0, 131); - timer_delay(1); + gfx_set_background(rand() % 0x1000000); + gfx_clear(); } - while(1); + int endfill = *current_tick; - if(gfx_status) + gfx_reset(); + + int starttext = *current_tick; + for(int i=0;i<1000000;++i) { - const int width = *gfx_width; - const int height = *gfx_height; - - gfx_reset(); - - int startpix = *current_tick; - for(int i=0;i<1000000;++i) - { - int rx = rand() % width; - int ry = rand() % height; - - gfx_set_foreground(rand() % 0x1000000); - gfx_drawpixel(rx, ry); - } - int endpix = *current_tick; - - gfx_reset(); - - int startfill = *current_tick; - for(int i=0;i<1000;++i) - { - gfx_set_background(rand() % 0x1000000); - gfx_clear(); - } - int endfill = *current_tick; - - gfx_reset(); - - int starttext = *current_tick; - for(int i=0;i<1000000;++i) - { - int rx = rand() % width; - int ry = rand() % height; - gfx_set_foreground(rand() % 0x1000000); - gfx_drawchar(rx, ry, rand()%127+1); - } - int endtext = *current_tick; - - gfx_reset(); - - int starthline = *current_tick; - for(int i=0;i<1000000;++i) - { - gfx_set_foreground(rand() % 0x1000000); - gfx_hline(rand() % width, rand() % width, rand() % height); - } - int endhline = *current_tick; - - gfx_reset(); - - int startvline = *current_tick; - for(int i=0;i<1000000;++i) - { - gfx_set_foreground(rand() % 0x1000000); - gfx_vline(rand() % height, rand() % height, rand() % width); - } - int endvline = *current_tick; - - gfx_reset(); - - int startrect = *current_tick; - for(int i=0;i<10000;++i) - { - 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_reset(); - - 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); - char buf[32]; - snprintf(buf, 32, "Line %d", i); - gfx_putsxy(0, 0, buf); - } - int endline = *current_tick; - - gfx_reset(); - - printf("--- Graphics benchmark results ---\n"); - printf("Ticks for 1,000,000 random pixels: %d\n", endpix-startpix); - printf("Ticks for 1,000 random fills: %d\n", endfill-startfill); - printf("Ticks for 1,000,000 random chars: %d\n", endtext-starttext); - 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); + int rx = rand() % width; + int ry = rand() % height; + gfx_set_foreground(rand() % 0x1000000); + gfx_drawchar(rx, ry, rand()%127+1); } + int endtext = *current_tick; - printf("Testing keyboard LED's"); + gfx_reset(); - int n = 0; - int s = 1; + int starthline = *current_tick; + for(int i=0;i<1000000;++i) + { + gfx_set_foreground(rand() % 0x1000000); + gfx_hline(rand() % width, rand() % width, rand() % height); + } + int endhline = *current_tick; - while(1) + gfx_reset(); + + int startvline = *current_tick; + for(int i=0;i<1000000;++i) { - ps2kbd_set_leds(PS2_NUM_LOCK); - timer_delay(HZ/4); - if(s < 0) - putchar('\b'); - else - putchar('.'); - n+=s; - if(n<=0 || n>=3) - s=-s; - ps2kbd_set_leds(PS2_CAPS_LOCK); - timer_delay(HZ/4); - if(s < 0) - putchar('\b'); - else - putchar('.'); - n+=s; - if(n<=0 || n>=3) - s=-s; - ps2kbd_set_leds(PS2_SCROLL_LOCK); - timer_delay(HZ/4); - if(s < 0) - putchar('\b'); - else - putchar('.'); - n+=s; - if(n<=0 || n>=3) - s=-s; - ps2kbd_set_leds(PS2_CAPS_LOCK); - timer_delay(HZ/4); - if(s < 0) - putchar('\b'); - else - putchar('.'); - n+=s; - if(n<=0 || n>=3) - s=-s; + gfx_set_foreground(rand() % 0x1000000); + gfx_vline(rand() % height, rand() % height, rand() % width); + } + int endvline = *current_tick; + + gfx_reset(); + + int startrect = *current_tick; + for(int i=0;i<10000;++i) + { + 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_reset(); + + 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); + printf("Ticks for 1,000 random fills: %d\n", endfill-startfill); + printf("Ticks for 1,000,000 random chars: %d\n", endtext-starttext); + 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); +} + +void main(struct multiboot_info_t *hdr, uint32_t magic) +{ + bool gfx_status = boot(hdr, magic); + gfx_set_foreground(0x80FF80); + printf("Hello, world!\n"); + gfx_set_foreground(GFX_WHITE); + + while(1)asm("hlt"); + + //char *ptr = 0xA00000; + //putchar(*ptr); + + printf("Starting linked-in application XRacer...\n"); + //printf("Running graphics benchmark...\n"); + srand(42); + + gfx_reset(); + + enum plugin_status; + struct plugin_api; + extern enum plugin_status xracer_main(const struct plugin_api*); + extern void plugin_load(enum plugin_status (*func)(const struct plugin_api*)); + + //plugin_load(xracer_main); + + if(gfx_status) + { + run_gfx_benchmark(); } + flash_leds(); } diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index ffe9073..95c7915 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -3,6 +3,7 @@ #include <stddef.h> #include <stdio.h> +#include <stdint.h> /* this is by no means standards-compliant... but who cares? :P */ @@ -14,8 +15,9 @@ char* itoa(int val, int base); #define MIN(x,y) ((x<y)?x:y) #define MAX(x,y) ((x>y)?x:y) +uint64_t rand64(void); unsigned int rand(void); -void srand(unsigned int); +void srand(uint64_t); int abs(int); void *malloc(size_t); int snprintf(char*, int, const char*, ...); diff --git a/libc/stdlib.c b/libc/stdlib.c index bb30039..57b370c 100644 --- a/libc/stdlib.c +++ b/libc/stdlib.c @@ -35,31 +35,45 @@ char* itoa(int val, int base) return &buf[i+(neg?0:1)]; } -static unsigned long rand_s1 = 18, rand_s2 = 5, rand_s3 = 43; +#define RAND_A1 12 +#define RAND_A2 25 +#define RAND_A3 27 -#define M 1103515245UL -#define A 12345UL +#define RAND_C1 4101842887655102017LL +#define RAND_C2 2685821657736338717LL -/* this is a very fast tausworthe RNG */ +static uint64_t rand_state = RAND_C1; + +uint64_t rand64(void) +{ + /* Marsaglia's Xorshift generator combined with a LCRNG */ + rand_state ^= rand_state >> RAND_A1; + rand_state ^= rand_state << RAND_A2; + rand_state ^= rand_state >> RAND_A3; + return rand_state * RAND_C2; +} + +static uint64_t rand_temp; +static int bytes_left = 0; unsigned int rand(void) { - 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); + if(bytes_left < 4) + { + rand_temp = rand64(); + bytes_left = 8; + } + unsigned int ret = rand_temp & 0xFFFFFFFF; + rand_temp >>= 32; + bytes_left -= 4; + return ret; } -void srand(unsigned int seed) +void srand(uint64_t seed) { - if(!seed) - seed = 42; - rand_s1 = seed++; - rand_s2 = seed++; - rand_s3 = seed++; - /* "warm it up" */ - for(int i=0;i<10;++i) - rand(); + if(seed == RAND_C1) + seed = RAND_C1 + 1; + rand_state = RAND_C1 ^ seed; } int abs(int val) @@ -69,6 +83,7 @@ int abs(int val) void *malloc(size_t sz) { + return kmalloc(sz); static uint8_t mallocbuf[1024*1024*16]; static uint8_t *next_ptr = mallocbuf; static int bytes_left = sizeof(mallocbuf); |