aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2015-02-08 17:32:23 -0500
committerFranklin Wei <frankhwei536@gmail.com>2015-02-08 17:32:23 -0500
commit52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1 (patch)
treea092e2e798139456d5f1b2f6b320a6c60a705205
parent0d7cde7c4d735ebebd39b988440f50f5889bd29f (diff)
downloadkappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.zip
kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.tar.gz
kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.tar.bz2
kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.tar.xz
lots of optimization, new features
-rw-r--r--Makefile14
-rw-r--r--drivers/gfx-as.S66
-rw-r--r--drivers/gfx.c73
-rw-r--r--drivers/include/gfx.h6
-rw-r--r--kernel/irq-as.S64
-rw-r--r--kernel/isr-as.S116
-rw-r--r--kernel/main.c36
7 files changed, 268 insertions, 107 deletions
diff --git a/Makefile b/Makefile
index 476b8f7..00c3bcf 100644
--- a/Makefile
+++ b/Makefile
@@ -3,8 +3,8 @@ CC = gcc
LD = ld
INCLUDES = -Idrivers/include -Ikernel/include -Ilibc/include -Iapps/
-CFLAGS := -std=gnu99 -ffreestanding -fno-stack-protector -nostdlib -Wall -Wextra -m32 $(INCLUDES) -g -O1 -mtune=generic -msse
-CFLAGS += -fexpensive-optimizations -ftree-loop-vectorize -finline-functions -fomit-frame-pointer -ftree-vectorize
+CFLAGS = -std=gnu99 -ffreestanding -fno-stack-protector -nostdlib -Wall -Wextra -m32 $(INCLUDES) -g
+OPTFLAGS = -fexpensive-optimizations -ftree-loop-vectorize -finline-functions -fomit-frame-pointer -ftree-vectorize -O1 -mtune=generic
QEMU = qemu-system-i386
BOCHS = bochs
@@ -37,13 +37,19 @@ iso: kappa.bin
kappa.bin: $(OBJ) $(SOURCES) Makefile
@$(LD) -T kernel/linker.ld -o kappa.bin -melf_i386 $(OBJ)
@echo "LD $@"
+
+drivers/gfx.o: drivers/gfx.c Makefile
+ @echo "CC $<"
+ @$(CC) $(CFLAGS) -O3 -msse -c $< -o $@
+
%.o: %.c Makefile
- @$(CC) $(CFLAGS) -c $< -o $@
@echo "CC $<"
+ @$(CC) $(CFLAGS) $(OPTFLAGS) -c $< -o $@
+
%.o: %.S Makefile
- @$(AS) $(ASFLAGS) -c $< -o $@
@echo "AS $<"
+ @$(AS) $(ASFLAGS) -c $< -o $@
clean:
@echo "Cleaning build directory..."
@rm -f $(OBJ) kappa.iso kappa.bin
diff --git a/drivers/gfx-as.S b/drivers/gfx-as.S
index 70009c1..51c1db8 100644
--- a/drivers/gfx-as.S
+++ b/drivers/gfx-as.S
@@ -17,11 +17,73 @@ gfx_clear:
addl %eax, %edx
cmpl %edx, %eax
jnb .L2
-.L6:
+.L1:
movl %ebx, (%eax)
addl %ecx, %eax
cmpl %eax, %edx
- ja .L6
+ ja .L1
.L2:
popl %ebx
ret
+
+ .global gfx_hline
+gfx_hline:
+ pushl %ebx
+ movl 8(%esp), %eax
+ movl 12(%esp), %ecx
+ cmpl %eax, %ecx
+ jge .L3
+ xchgl %eax, %ecx
+.L3:
+ movzwl fb_stride, %edx
+ movzbl fb_bpp, %ebx
+ imull 16(%esp), %edx
+ addl framebuffer, %edx
+ imull %ebx, %ecx
+ imull %ebx, %eax
+ addl %edx, %eax
+ addl %ecx, %edx
+ movl _gfx_fgcol, %ecx
+ cmpl %edx, %eax
+ jnb .L5
+.L4:
+ movl %ecx, (%eax)
+ addl %ebx, %eax
+ cmpl %eax, %edx
+ ja .L4
+.L5:
+ popl %ebx
+ ret
+
+ .global gfx_vline
+gfx_vline:
+ pushl %esi
+ pushl %ebx
+ movl 12(%esp), %eax
+ movl 16(%esp), %edx
+ cmpl %eax, %edx
+ jge .L6
+ xchgl %eax, %edx
+.L6:
+ movzwl fb_stride, %ebx
+ movzbl fb_bpp, %ecx
+ imull 20(%esp), %ecx
+ movl framebuffer, %esi
+ imull %ebx, %edx
+ imull %ebx, %eax
+ addl %ecx, %eax
+ addl %edx, %ecx
+ leal (%esi,%ecx), %edx
+ addl %esi, %eax
+ movl _gfx_fgcol, %ecx
+ cmpl %edx, %eax
+ jnb .L8
+.L7:
+ movl %ecx, (%eax)
+ addl %ebx, %eax
+ cmpl %eax, %edx
+ ja .L7
+.L8:
+ popl %ebx
+ popl %esi
+ ret
diff --git a/drivers/gfx.c b/drivers/gfx.c
index 8dc9d74..e0c5f17 100644
--- a/drivers/gfx.c
+++ b/drivers/gfx.c
@@ -15,6 +15,7 @@ uint16_t fb_height;
/* this is BYTES per pixel */
uint8_t fb_bpp;
+uint16_t fb_stride;
const uint8_t *gfx_bpp = &fb_bpp;
const uint16_t *gfx_width = &fb_width;
@@ -73,19 +74,18 @@ void gfx_reset(void)
void gfx_drawchar(int x, int y, char c)
{
- int stride = fb_bpp * fb_width;
- uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * stride);
+ uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride);
+ const uint32_t bg = _gfx_bgcol;
+ const uint32_t fg = _gfx_fgcol;
for(int i = 0; i < FONT_HEIGHT; ++i)
{
- uint32_t line_buf[8] = {_gfx_bgcol};
- uint8_t mask = 0x80;
- for(int j = 0; j < 8; ++j, mask >>= 1)
+ uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1};
+ for(int j = 0; j < 8; ++j)
{
- if(gfx_font[(int)c][i] & mask)
- line_buf[j] = _gfx_fgcol;
+ if(gfx_font[c][i] & mask_table[j])
+ ((uint32_t*)line_addr)[j] = fg;
}
- memcpy(line_addr, line_buf, sizeof(line_buf));
- line_addr += stride;
+ line_addr += fb_stride;
}
}
@@ -126,12 +126,67 @@ void gfx_puts(const char* str)
}
}
+/* implemented in assembly */
+#if 0
+void gfx_hline(int x1, int x2, int y)
+{
+ /* make sure x1 is to the left of x2 */
+ if(x2 < x1)
+ {
+ int temp = x1;
+ x1 = x2;
+ x2 = temp;
+ }
+
+ uint8_t *base = framebuffer + y * fb_stride;
+
+ uint8_t *dest = base + x1 * fb_bpp;
+ uint8_t *stop = base + x2 * fb_bpp;
+ const uint32_t col = _gfx_fgcol;
+ while(dest < stop)
+ {
+ *(uint32_t*)dest = col;
+ dest += fb_bpp;
+ }
+}
+
+void gfx_vline(int y1, int y2, int x)
+{
+ /* make sure y1 is above y2 */
+ if(y2 < y1)
+ {
+ int temp = y1;
+ y1 = y2;
+ y2 = temp;
+ }
+
+ 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;
+ while(dest < stop)
+ {
+ *(uint32_t*)dest = col;
+ dest += fb_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)
+ {
+ gfx_hline(x, x + w, y + i);
+ }
+}
+
bool gfx_init(struct vbe_info_t *vbe_mode_info)
{
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;
+ fb_stride = fb_bpp * fb_width;
if(fb_bpp != 4)
{
printf("WARNING: BPP != 32, falling back to text mode...\n");
diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h
index 42ada32..561eb3e 100644
--- a/drivers/include/gfx.h
+++ b/drivers/include/gfx.h
@@ -54,6 +54,12 @@ void gfx_set_background(uint32_t);
uint32_t gfx_get_background(void);
+void gfx_hline(int x1, int x2, int y);
+
+void gfx_vline(int y1, int y2, int x);
+
+void gfx_fillrect(int x1, int y1, int w, int h);
+
extern const uint16_t *gfx_width, *gfx_height;
/* this is _BYTES_ per pixel, NOT BITS per pixel! */
diff --git a/kernel/irq-as.S b/kernel/irq-as.S
index 12de4b6..8840299 100644
--- a/kernel/irq-as.S
+++ b/kernel/irq-as.S
@@ -44,96 +44,96 @@ irq_stub:
_irq0:
cli
- push $0
- push $32
+ pushl $0
+ pushl $32
jmp irq_stub
_irq1:
cli
- push $0
- push $33
+ pushl $0
+ pushl $33
jmp irq_stub
_irq2:
cli
- push $0
- push $34
+ pushl $0
+ pushl $34
jmp irq_stub
_irq3:
cli
- push $0
- push $35
+ pushl $0
+ pushl $35
jmp irq_stub
_irq4:
cli
- push $0
- push $36
+ pushl $0
+ pushl $36
jmp irq_stub
_irq5:
cli
- push $0
- push $37
+ pushl $0
+ pushl $37
jmp irq_stub
_irq6:
cli
- push $0
- push $38
+ pushl $0
+ pushl $38
jmp irq_stub
_irq7:
cli
- push $0
- push $39
+ pushl $0
+ pushl $39
jmp irq_stub
_irq8:
cli
- push $0
- push $40
+ pushl $0
+ pushl $40
jmp irq_stub
_irq9:
cli
- push $0
- push $41
+ pushl $0
+ pushl $41
jmp irq_stub
_irq10:
cli
- push $0
- push $42
+ pushl $0
+ pushl $42
jmp irq_stub
_irq11:
cli
- push $0
- push $43
+ pushl $0
+ pushl $43
jmp irq_stub
_irq12:
cli
- push $0
- push $44
+ pushl $0
+ pushl $44
jmp irq_stub
_irq13:
cli
- push $0
- push $45
+ pushl $0
+ pushl $45
jmp irq_stub
_irq14:
cli
- push $0
- push $46
+ pushl $0
+ pushl $46
jmp irq_stub
_irq15:
cli
- push $0
- push $47
+ pushl $0
+ pushl $47
jmp irq_stub
diff --git a/kernel/isr-as.S b/kernel/isr-as.S
index 464ec5b..858ce47 100644
--- a/kernel/isr-as.S
+++ b/kernel/isr-as.S
@@ -60,155 +60,155 @@ isr_stub:
_isr0:
cli
- push $0
- push $0
+ pushl $0
+ pushl $0
jmp isr_stub
_isr1:
cli
- push $0
- push $1
+ pushl $0
+ pushl $1
jmp isr_stub
_isr2:
cli
- push $0
- push $2
+ pushl $0
+ pushl $2
jmp isr_stub
_isr3:
cli
- push $0
- push $3
+ pushl $0
+ pushl $3
jmp isr_stub
_isr4:
cli
- push $0
- push $4
+ pushl $0
+ pushl $4
jmp isr_stub
_isr5:
cli
- push $0
- push $5
+ pushl $0
+ pushl $5
jmp isr_stub
_isr6:
cli
- push $0
- push $6
+ pushl $0
+ pushl $6
jmp isr_stub
_isr7:
cli
- push $0
- push $7
+ pushl $0
+ pushl $7
jmp isr_stub
_isr8:
cli
- push $8
+ pushl $8
jmp isr_stub
_isr9:
cli
- push $0
- push $9
+ pushl $0
+ pushl $9
jmp isr_stub
_isr10:
cli
- push $10
+ pushl $10
jmp isr_stub
_isr11:
cli
- push $11
+ pushl $11
jmp isr_stub
_isr12:
cli
- push $12
+ pushl $12
jmp isr_stub
_isr13:
cli
- push $13
+ pushl $13
jmp isr_stub
_isr14:
cli
- push $14
+ pushl $14
jmp isr_stub
_isr15:
cli
- push $0
- push $15
+ pushl $0
+ pushl $15
jmp isr_stub
_isr16:
cli
- push $0
- push $16
+ pushl $0
+ pushl $16
jmp isr_stub
_isr17:
cli
- push $0
- push $17
+ pushl $0
+ pushl $17
jmp isr_stub
_isr18:
cli
- push $0
- push $18
+ pushl $0
+ pushl $18
jmp isr_stub
_isr19:
cli
- push $0
- push $19
+ pushl $0
+ pushl $19
jmp isr_stub
_isr20:
cli
- push $0
- push $20
+ pushl $0
+ pushl $20
jmp isr_stub
_isr21:
cli
- push $0
- push $21
+ pushl $0
+ pushl $21
jmp isr_stub
_isr22:
cli
- push $0
- push $22
+ pushl $0
+ pushl $22
jmp isr_stub
_isr23:
cli
- push $0
- push $23
+ pushl $0
+ pushl $23
jmp isr_stub
_isr24:
cli
- push $0
- push $24
+ pushl $0
+ pushl $24
jmp isr_stub
_isr25:
cli
- push $0
- push $25
+ pushl $0
+ pushl $25
jmp isr_stub
_isr26:
cli
- push $0
- push $26
+ pushl $0
+ pushl $26
jmp isr_stub
_isr27:
cli
- push $0
- push $27
+ pushl $0
+ pushl $27
jmp isr_stub
_isr28:
cli
- push $0
- push $28
+ pushl $0
+ pushl $28
jmp isr_stub
_isr29:
cli
- push $0
- push $29
+ pushl $0
+ pushl $29
jmp isr_stub
_isr30:
cli
- push $0
- push $30
+ pushl $0
+ pushl $30
jmp isr_stub
_isr31:
cli
- push $0
- push $31
+ pushl $0
+ pushl $31
jmp isr_stub
diff --git a/kernel/main.c b/kernel/main.c
index 927a497..211be18 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -19,7 +19,7 @@ void gpf(struct regs_t regs)
{
printf("General protection fault!\n");
printf("EIP before fault: 0x%x\n", regs.eip);
- printf("Error code: %d\n", regs.err_code);
+ printf("Error code: 0x%x\n", regs.err_code);
panic("GPF");
}
@@ -78,6 +78,7 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
gfx_drawpixel(rx, ry);
}
int endpix = *current_tick;
+
int startfill = *current_tick;
for(int i=0;i<1000;++i)
{
@@ -97,11 +98,43 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
gfx_drawchar(rx, ry, rand()%127+1);
}
int endtext = *current_tick;
+ gfx_clear();
+
+ int starthline = *current_tick;
+ for(int i=0;i<1000000;++i)
+ {
+ gfx_hline(rand() % *gfx_width, rand() % *gfx_width, rand() % *gfx_height);
+ }
+ int endhline = *current_tick;
+
+ gfx_clear();
+
+ int startvline = *current_tick;
+ for(int i=0;i<1000000;++i)
+ {
+ gfx_vline(rand() % *gfx_height, rand() % *gfx_height, rand() % *gfx_width);
+ }
+ int endvline = *current_tick;
+
+ int startrect = *current_tick;
+ for(int i=0;i<1000;++i)
+ {
+ int x = rand() % *gfx_width;
+ int y = rand() % *gfx_height;
+ int w = rand() % (*gfx_width - x);
+ int h = rand() % (*gfx_height - y);
+ gfx_fillrect(x, y, w, h);
+ }
+ int endrect = *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 1,000 random rects: %d\n", endrect-startrect);
printf("Ticks per second: %d\n", HZ);
printf("Resolution: %dx%dx%d\n", *gfx_width, *gfx_height, *gfx_bpp * 8);
}
@@ -119,5 +152,4 @@ void main(struct multiboot_info_t *hdr, uint32_t magic)
ps2_set_leds(PS2_CAPS_LOCK);
timer_delay(HZ/4);
}
- while(1);
}