diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | drivers/gfx-as.S | 2 | ||||
| -rw-r--r-- | drivers/gfx.c | 68 | ||||
| -rw-r--r-- | drivers/include/gfx.h | 10 | ||||
| -rw-r--r-- | kernel/include/irq.h | 1 | ||||
| -rw-r--r-- | kernel/include/timer.h | 1 | ||||
| -rw-r--r-- | kernel/irq-as.S | 7 | ||||
| -rw-r--r-- | kernel/irq.c | 2 | ||||
| -rw-r--r-- | kernel/main.c | 25 | ||||
| -rw-r--r-- | kernel/timer.c | 3 | ||||
| -rw-r--r-- | libc/include/stdlib.h | 6 |
11 files changed, 119 insertions, 10 deletions
@@ -20,11 +20,11 @@ test: kappa.iso @echo "EMULATOR kappa.iso" @$(QEMU) kappa.iso -test-bochs: iso +test-bochs: kappa.iso @echo "BOCHS bochs.cfg" @$(BOCHS) -f bochs.cfg -q -iso: kappa.bin +kappa.iso: kappa.bin @echo "Building ISO under $(ISODIR)/..." @mkdir -p $(ISODIR) @mkdir -p $(ISODIR)/boot diff --git a/drivers/gfx-as.S b/drivers/gfx-as.S index 9daf53a..675a6d5 100644 --- a/drivers/gfx-as.S +++ b/drivers/gfx-as.S @@ -89,7 +89,7 @@ gfx_vline: .global gfx_drawpixel_32bpp gfx_drawpixel_32bpp: - movzwl fb_stride, %eax + movzwl fb_stride32, %eax movl framebuffer, %edx imull 8(%esp), %eax movl _gfx_fgcol, %ecx diff --git a/drivers/gfx.c b/drivers/gfx.c index b781adc..7c56800 100644 --- a/drivers/gfx.c +++ b/drivers/gfx.c @@ -16,6 +16,8 @@ uint16_t fb_height; /* this is BYTES per pixel */ uint8_t fb_bpp; uint16_t fb_stride; +/* fb_stride / 4 */ +uint16_t fb_stride32; const uint8_t *gfx_bpp = &fb_bpp; const uint16_t *gfx_width = &fb_width; @@ -48,9 +50,13 @@ uint32_t gfx_get_foreground(void) } /* assembly */ -void gfx_drawpixel_test(int x, int y) +void gfx_drawpixel_32bpp_checked(int x, int y) { - ((uint32_t*)framebuffer)[y * fb_stride + x] = _gfx_fgcol; + if(0 <= x && x < fb_width && + 0 <= y && y < fb_height) + ((uint32_t*)framebuffer)[y * fb_stride32 + x] = _gfx_fgcol; + else + panic("pixel OOB!\n"); } /* implemented in assembly now */ /* @@ -270,6 +276,59 @@ void gfx_drawline(int x1, int y1, int x2, int y2) } } +void gfx_drawcircle(int cx, int cy, int r) +{ + int d = 3 - (r * 2); + int x = 0; + int y = r; + while(x <= y) + { + gfx_drawpixel(cx + x, cy + y); + gfx_drawpixel(cx - x, cy + y); + gfx_drawpixel(cx + x, cy - y); + gfx_drawpixel(cx - x, cy - y); + gfx_drawpixel(cx + y, cy + x); + gfx_drawpixel(cx - y, cy + x); + gfx_drawpixel(cx + y, cy - x); + gfx_drawpixel(cx - y, cy - x); + if(d < 0) + { + d += (x * 4) + 6; + } + else + { + d += ((x - y) * 4) + 10; + --y; + } + ++x; + } +} + +void gfx_fillcircle(int cx, int cy, int r) +{ + int d = 3 - (r * 2); + int x = 0; + int y = r; + while(x <= y) + { + gfx_hline(cx - x, cx + x, cy + y); + gfx_hline(cx - x, cx + x, cy - y); + gfx_hline(cx - y, cx + y, cy + x); + gfx_hline(cx - y, cx + y, cy - x); + if(d < 0) + { + d += (x * 4) + 6; + } + else + { + d += ((x - y) * 4) + 10; + --y; + } + ++x; + } +} + + bool gfx_init(struct vbe_info_t *vbe_mode_info) { framebuffer = (uint8_t*)vbe_mode_info->physbase; @@ -277,6 +336,7 @@ bool gfx_init(struct vbe_info_t *vbe_mode_info) fb_height = vbe_mode_info->Yres; fb_bpp = vbe_mode_info->bpp / 8; fb_stride = vbe_mode_info->pitch; + fb_stride32 = fb_stride / 4; if(fb_bpp != 4) { printf("WARNING: BPP != 32, falling back to text mode...\n"); @@ -284,8 +344,8 @@ bool gfx_init(struct vbe_info_t *vbe_mode_info) } else { - extern void gfx_drawpixel_32bpp(int, int); - gfx_drawpixel = &gfx_drawpixel_32bpp; + //extern void gfx_drawpixel_32bpp(int, int); + gfx_drawpixel = &gfx_drawpixel_32bpp_checked; } set_putchar(gfx_putchar); diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h index 6f0f171..2abc172 100644 --- a/drivers/include/gfx.h +++ b/drivers/include/gfx.h @@ -1,3 +1,6 @@ +#ifndef _GFX_H_ +#define _GFX_H_ + #include <stdbool.h> #include <stdint.h> @@ -67,7 +70,14 @@ void gfx_fillrect(int x1, int y1, int w, int h); void gfx_drawline(int x1, int y1, int x2, int y2); +/* these circle algorithms are very fast */ +void gfx_drawcircle(int cx, int cy, int rad); + +void gfx_fillcircle(int cx, int cy, int rad); + extern const uint16_t *gfx_width, *gfx_height; /* this is _BYTES_ per pixel, NOT BITS per pixel! */ extern const uint8_t *gfx_bpp; + +#endif diff --git a/kernel/include/irq.h b/kernel/include/irq.h index de1d545..13461e9 100644 --- a/kernel/include/irq.h +++ b/kernel/include/irq.h @@ -14,5 +14,6 @@ extern void _irq12(void); extern void _irq13(void); extern void _irq14(void); extern void _irq15(void); +extern void _int0x80(void); void irq_init(void); diff --git a/kernel/include/timer.h b/kernel/include/timer.h index bf2eddd..7a15949 100644 --- a/kernel/include/timer.h +++ b/kernel/include/timer.h @@ -9,4 +9,5 @@ struct regs_t; void timer_init(uint32_t freq); +/* NOTE: enables interrupts by default */ void timer_delay(uint64_t ticks); diff --git a/kernel/irq-as.S b/kernel/irq-as.S index b2c0004..1d16392 100644 --- a/kernel/irq-as.S +++ b/kernel/irq-as.S @@ -41,6 +41,7 @@ irq_stub: .global _irq13 .global _irq14 .global _irq15 + .global _int0x80 _irq0: cli @@ -137,3 +138,9 @@ _irq15: pushl $0 pushl $47 jmp irq_stub + +_int0x80: + cli + pushl $0 + pushl $0x80 + jmp irq_stub diff --git a/kernel/irq.c b/kernel/irq.c index c6652e9..c6dbf4c 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -43,6 +43,7 @@ void irq_init(void) idt_set_gate(45, (uint32_t)_irq13, 0x08, 0x8E); idt_set_gate(46, (uint32_t)_irq14, 0x08, 0x8E); idt_set_gate(47, (uint32_t)_irq15, 0x08, 0x8E); + idt_set_gate(128,(uint32_t)_int0x80, 0x08, 0x8E); } void irq_handler(struct regs_t *regs) @@ -57,7 +58,6 @@ void irq_handler(struct regs_t *regs) } else { - printf("WARNING: Unhandled IRQ: 0x%x!\n", regs->int_no); } /* If the IDT entry that was invoked was greater than 40 diff --git a/kernel/main.c b/kernel/main.c index 0ec03f0..dc0926d 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -27,12 +27,23 @@ void gpf(struct regs_t *regs) panic("GPF!"); } +void int80(struct regs_t *regs) +{ + switch(regs->eax) + { + case 0: + panic((const char*)regs->ebx); + break; + case 1: + puts((const char*)regs->ebx); + break; + } +} + void main(struct multiboot_info_t *hdr, uint32_t magic) { fpu_enable(); - asm("movq %xmm0, %xmm0"); - /* this should go to port e9, which is the Bochs debug port */ printf("Testing early I/O\n"); @@ -64,6 +75,7 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) ps2_init(); set_interrupt_handler(0xd, gpf); + set_interrupt_handler(0x80, int80); asm("sti"); @@ -71,9 +83,18 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) printf("Kernel version %s: \"%s\"\n", KAPPA_KERNEL_VERSION, KAPPA_KERNEL_CODENAME); + //printf("Starting linked-in application XRacer...\n"); printf("Running graphics benchmark...\n"); srand(42); + gfx_drawcircle(100, 100, 100); + + gfx_fillcircle(50, 30, 20); + + while(1); + + //xracer_main(); + if(gfx_status) { const int width = *gfx_width; diff --git a/kernel/timer.c b/kernel/timer.c index e1f248b..2c05167 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -34,5 +34,8 @@ void timer_delay(uint64_t ticks) { uint64_t end = *current_tick + ticks; while(*current_tick <= end) + { + asm("sti"); asm("hlt"); + } } diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 990d77a..a6e27f2 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -1,3 +1,6 @@ +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + /* this is by no means standards-compliant... but who cares? :P */ /* NOT reentrant! */ @@ -6,7 +9,10 @@ char* itoa(int val, int base); #define RAND_MAX ((1U << 31) - 1) #define MIN(x,y) ((x<y)?x:y) +#define MAX(x,y) ((x>y)?x:y) unsigned int rand(void); void srand(unsigned int); int abs(int); + +#endif |