From c0df0ee6437aa2786b1a92bc6af1284958d104c7 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 7 Feb 2015 11:03:48 -0500 Subject: new rng, some rework of I/O --- boot/head.S | 6 +++--- drivers/include/vga.h | 10 ++++++++-- drivers/vga.c | 28 +++++++++++++++++++++++++--- kernel/include/log.h | 4 ++-- kernel/include/timer.h | 9 +++++++-- kernel/log.c | 6 ++---- kernel/main.c | 11 ++++++++--- kernel/timer.c | 24 +++++++++++++++++++++--- libc/include/stdlib.h | 3 +++ libc/stdlib.c | 23 +++++++++++++++++++++++ 10 files changed, 102 insertions(+), 22 deletions(-) diff --git a/boot/head.S b/boot/head.S index 4d17f73..6149665 100644 --- a/boot/head.S +++ b/boot/head.S @@ -17,9 +17,9 @@ multiboot_header: .long 0 .long 0 .long 0 - .long 320 - .long 200 - .long 32 + .long 0 # screen height (don't care) + .long 0 # screen width (don't care) + .long 32 # screen BPP: MUST be 32 .section .stack stack_bottom: # Stack grows up in addresses, so bottom is diff --git a/drivers/include/vga.h b/drivers/include/vga.h index b83ec95..8ea478b 100644 --- a/drivers/include/vga.h +++ b/drivers/include/vga.h @@ -33,6 +33,12 @@ enum vga_color_t { #define VGA_MAKE_ENTRY(ch, col) (((uint16_t)ch)|((uint16_t)col<<8)) #define VGA_RGBPACK(r, g, b) ((r << 16)|(g << 8)|(b << 0)) -void vga_init(); +struct vbe_info_t; -void vga_drawpixel(int x, int y, uint32_t pix); +void vga_init(struct vbe_info_t *vbe_mode_info); + +void vga_drawpixel(int x, int y, uint32_t color); + +void vga_clear(uint32_t color); + +extern const uint16_t *vga_width, *vga_height; diff --git a/drivers/vga.c b/drivers/vga.c index cfcd287..ccf0949 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -1,20 +1,42 @@ #include #include +#include "log.h" #include "multiboot.h" +#include "panic.h" #include "vga.h" static uint8_t *framebuffer = NULL; static uint16_t fb_width; static uint16_t fb_height; +/* this is BYTES per pixel */ +static uint8_t fb_bpp; -void vga_drawpixel(int x, int y, uint32_t pixel) +const uint16_t *vga_width = &fb_width; +const uint16_t *vga_height = &fb_height; + +void vga_drawpixel(int x, int y, uint32_t col) +{ + ((uint32_t*)framebuffer)[y * fb_width + x] = col; +} + +void vga_clear(uint32_t col) { - ((uint32_t*)framebuffer)[y * fb_width + x] = pixel; + uint8_t *p = framebuffer; + uint8_t *stop = framebuffer + fb_width * fb_height * fb_bpp; + while(p < stop) + { + *(uint32_t*)p = col; + p += fb_bpp; + } } void vga_init(struct vbe_info_t *vbe_mode_info) { - framebuffer = vbe_mode_info->physbase; + framebuffer = (uint8_t*)vbe_mode_info->physbase; fb_width = vbe_mode_info->Xres; fb_height = vbe_mode_info->Yres; + fb_bpp = vbe_mode_info->bpp / 8; + if(fb_bpp != 4) + panic("BPP *MUST* be 32!!!\n"); + vga_clear(VGA_RGBPACK(0, 0, 0)); } diff --git a/kernel/include/log.h b/kernel/include/log.h index fb29dd3..6953bee 100644 --- a/kernel/include/log.h +++ b/kernel/include/log.h @@ -1,3 +1,3 @@ -int log_putchar(char); -int log_puts(const char*); +void log_putchar(char); +void log_puts(const char*); void log(const char*, ...); diff --git a/kernel/include/timer.h b/kernel/include/timer.h index a7459a6..bf2eddd 100644 --- a/kernel/include/timer.h +++ b/kernel/include/timer.h @@ -1,7 +1,12 @@ #include -extern const uint64_t *current_tick; +#define HZ 100 +#define PIT_FREQ 1193182 + +extern volatile const uint64_t *current_tick; struct regs_t; -void timer_init(void); +void timer_init(uint32_t freq); + +void timer_delay(uint64_t ticks); diff --git a/kernel/log.c b/kernel/log.c index 3f509c5..efc945d 100644 --- a/kernel/log.c +++ b/kernel/log.c @@ -5,17 +5,15 @@ #define BOCHS_PUTCHAR(ch) (outb(0xe9, ch)) -int log_putchar(int ch) +void log_putchar(int ch) { BOCHS_PUTCHAR(ch); - return 0; } -int log_puts(const char* str) +void log_puts(const char* str) { while(*str) log_putchar(*str++); - return 0; } static char hex_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', diff --git a/kernel/main.c b/kernel/main.c index 9082859..d791da1 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,11 +1,13 @@ #include #include +#include #include "gdt.h" #include "idt.h" #include "isr.h" #include "irq.h" #include "log.h" #include "multiboot.h" +#include "panic.h" #include "pcspkr.h" #include "ps2.h" #include "timer.h" @@ -36,15 +38,18 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) irq_init(); /* initialize other drivers */ - timer_init(); + timer_init(HZ); ps2_init(); asm("sti"); printf("Boot finished.\n"); - for(int i=0;i<50;++i) - vga_drawpixel(i, i, VGA_RGBPACK(255, 0, 0)); + printf("Testing RNG...\n"); + srand(*current_tick); + + for(int i=0;i>=0;++i) + vga_drawpixel(rand() % *vga_width, rand() % *vga_height, rand() % 0xFFFFFF); printf("Testing keyboard LED's...\n"); diff --git a/kernel/timer.c b/kernel/timer.c index 571fcbe..2fbd8eb 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1,10 +1,11 @@ #include +#include "io.h" #include "isr.h" #include "timer.h" -uint64_t current_tick_data = 0; +volatile uint64_t current_tick_data = 0; -const uint64_t *current_tick = ¤t_tick_data; +volatile const uint64_t *current_tick = ¤t_tick_data; static void timer_callback(struct regs_t regs) { @@ -12,7 +13,24 @@ static void timer_callback(struct regs_t regs) ++current_tick_data; } -void timer_init(void) +void timer_init(uint32_t freq) { set_interrupt_handler(IRQ(0), timer_callback); + + current_tick_data = 0; + + uint32_t divisor = PIT_FREQ / freq; + + uint8_t hi = (divisor >> 8) & 0xFF; + uint8_t lo = (divisor >> 0) & 0xFF; + + outb(0x43, 0x36); + outb(0x40, lo); + outb(0x40, hi); +} + +void timer_delay(uint64_t ticks) +{ + uint64_t end = *current_tick + ticks; + while(*current_tick <= end); } diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 146b4b8..0a3d559 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -2,3 +2,6 @@ /* NOT reentrant! */ char* itoa(int val, int base); + +int rand(void); +void srand(unsigned int); diff --git a/libc/stdlib.c b/libc/stdlib.c index 356fc33..49f61f1 100644 --- a/libc/stdlib.c +++ b/libc/stdlib.c @@ -13,3 +13,26 @@ char* itoa(int val, int base) return &buf[i+1]; } + +static int rand_state = 42; + +/* some constants for the RNG */ +#define A 48271 +#define M 2147483647 +#define Q (M/A) +#define R (M%A) + +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; +} + +void srand(unsigned int seed) +{ + rand_state = seed; +} -- cgit v1.1