From 37ceff93572bba6defd916884999c496108220ee Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Mon, 20 Oct 2014 20:51:01 +0200 Subject: started porting simple brainfuck interpreter --- kernel/kernel.c | 4 ++ kernel/vesa.c | 6 +++ userspace/Makefile | 4 +- userspace/brainfuck.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ userspace/syscalls.c | 85 ++++++++++++++++++++++++++++++++ userspace/test.c | 81 +----------------------------- 6 files changed, 231 insertions(+), 82 deletions(-) create mode 100644 userspace/brainfuck.c create mode 100644 userspace/syscalls.c diff --git a/kernel/kernel.c b/kernel/kernel.c index 3372b75..34f3d69 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -202,6 +202,10 @@ void kernel_main(uint32_t initial_stack, int mp) // // //vesa_init_doublebuff(); + + // autorun "user-space" prog + asm("push $0x80800"); + asm("ret"); while(1) { } diff --git a/kernel/vesa.c b/kernel/vesa.c index 7001e02..b0e9885 100644 --- a/kernel/vesa.c +++ b/kernel/vesa.c @@ -172,9 +172,15 @@ void PutString(char *str, int x,int y, int color, va_list va) void PutConsoleChar(char c, int color) { + if(c=='\n') + { + PutConsoleNL(); + return; + } PutFont(c, console_x*10,console_y*12, color); console_x++; + #ifdef FOOLOS_CONSOLE_AUTOBREAK if(console_x>console_cols)PutConsoleNL(); #endif diff --git a/userspace/Makefile b/userspace/Makefile index 2a286da..bd1e6ec 100644 --- a/userspace/Makefile +++ b/userspace/Makefile @@ -8,7 +8,7 @@ LDFLAGS=-L/home/miguel/temp/fool-os-stuff/newlib-build-clean/i686-elf/newlib/ \ -L/home/miguel/temp/fool-os-stuff/newlib-build-clean/i686-elf/libgloss/libnosys/ \ -lnosys -all: test.o crt0.o - ${CC} -T linker.ld ${LDFLAGS} test.o -Wl,--oformat,binary -o userprog +all: brainfuck.o crt0.o + ${CC} -T linker.ld ${LDFLAGS} brainfuck.o -Wl,--oformat,binary -o userprog clean: -rm *.o *.out userprog diff --git a/userspace/brainfuck.c b/userspace/brainfuck.c new file mode 100644 index 0000000..03ce4f5 --- /dev/null +++ b/userspace/brainfuck.c @@ -0,0 +1,133 @@ +// taken from: http://it-ride.blogspot.com/2009/11/brainfuck-interpreter.html + +/* comment + * TODO + * You have a bug. You don't check for EOF while looking for square brackets. + */ + +/* + + A brainfuck intepreter written in C, complete with error checking so you + don't hurt yourself while, uh, brainfucking. Nothing really special about + the implementation and it is probably very poor performance-wise. + + Author: Felix Oghină + License: (brain)fuck licenses! + +*/ + +// ADDED BY FOOLOS : foolos syscalls! +#include "syscalls.c" + +#include +#include +#include + +// by brainfuck standards (doesn't that sound funny?), the data pointer has +// 30,000 bytes at its disposal, but I hate hard-coding such stuff. +#define DATA_SIZE 30000 + +void usage() { + puts( + "Usage: brainfuck FILE\n" + "If FILE is ommited or is '-', standard input is read" + ); +} + +int main(int argc, char **argv) { + + // ADDED BY FOOLOS: we will show usage anyway + usage(); + + // used by the bf program + unsigned char *dataptr = malloc(sizeof(char) * DATA_SIZE); + // position of the data pointer + unsigned int datapos = 0; + // input file + FILE *input; + // level - deepness of brackets + // i - uh, you need explanation for this one? + unsigned int level, i; + // we will read chars from the input into r + unsigned char r; + + // determine input + if (argc == 2) { + if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) { + usage(); + return EXIT_SUCCESS; + } + else { + input = fopen(argv[1], "r"); + if (input == NULL) { + puts("Error opening input file"); + return EXIT_FAILURE; + } + } + } + else { + usage(); + return EXIT_FAILURE; + } + + // zero the data pointer + for (i=0; i < DATA_SIZE; i++) { + dataptr[i] = 0; + } + + // start interpreting + rewind(input); + while (!feof(input)) { + r = (unsigned char) fgetc(input); + switch(r) { + case '>': + if (datapos < DATA_SIZE - 1) datapos++; + else { + puts("brainfuck error: pointer overflow"); + return EXIT_FAILURE; + } + break; + case '<': + if (datapos > 0) datapos--; + else { + puts("brainfuck error: pointer underflow"); + return EXIT_FAILURE; + } + break; + case '+': + dataptr[datapos]++; + break; + case '-': + dataptr[datapos]--; + break; + case '.': + putchar(dataptr[datapos]); + break; + case ',': + dataptr[datapos] = getchar(); + break; + case '[': + if (dataptr[datapos] == 0) { + level = 1; + while (level != 0) { + r = (unsigned char) fgetc(input); + if (r == '[') level ++; + else if (r == ']') level --; + } + } + break; + case ']': + if (dataptr[datapos] != 0) { + level = 1; + while (level != 0) { + fseek(input, -2, SEEK_CUR); + r = (unsigned char) fgetc(input); + if (r == ']') level ++; + else if (r == '[') level --; + } + } + break; + } + } + return EXIT_SUCCESS; +} diff --git a/userspace/syscalls.c b/userspace/syscalls.c new file mode 100644 index 0000000..6547879 --- /dev/null +++ b/userspace/syscalls.c @@ -0,0 +1,85 @@ + +//printf needs following syscalls: sbrk write close fstat isatty lseek read +// + +#include + +int close(int file) +{ + return -1; +} + +int fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +int isatty(int file) { + return 1; +} + +int lseek(int file, int ptr, int dir) { + return 0; +} + +int read(int file, char *ptr, int len) { + return 0; +} + int open(const char *name, int flags, int mode) { + return -1; + } + + +int write(int file, char *ptr, int len) +{ + + int todo; + for (todo = 0; todo < len; todo++) + { + + char byte=(*ptr++); + int byt=byte; + + int ebx; // will hold return value; + // system call + asm("pusha"); + asm("mov $61,%eax"); // select syscall) + + asm("mov %0,%%edx"::"m"(byt)); + //asm("mov $88,%edx"); + + asm("int $0x80"); // actual syscall ! interrupt + asm("mov %%ebx, %0": "=b" (ebx)); + asm("popa"); + // + + } + return len; +} + +caddr_t sbrk(int incr) +{ + +// extern char _end; /* Defined by the linker */ + char _end; + static char *heap_end; + char *prev_heap_end; + + if (heap_end == 0) { + heap_end = &_end; + } + prev_heap_end = heap_end; + /* + if (heap_end + incr > stack_ptr) { + write (1, "Heap and stack collision\n", 25); + abort (); + } + */ + + heap_end += incr; + return (caddr_t) prev_heap_end; +} + +// + diff --git a/userspace/test.c b/userspace/test.c index bdc6da0..12226d3 100644 --- a/userspace/test.c +++ b/userspace/test.c @@ -1,86 +1,7 @@ #include #include - -//printf needs following syscalls: sbrk write close fstat isatty lseek read -// - -#include - -int close(int file) -{ - return -1; -} - -int fstat(int file, struct stat *st) -{ - st->st_mode = S_IFCHR; - return 0; -} - -int isatty(int file) { - return 1; -} - -int lseek(int file, int ptr, int dir) { - return 0; -} - -int read(int file, char *ptr, int len) { - return 0; -} - -int write(int file, char *ptr, int len) -{ - - int todo; - for (todo = 0; todo < len; todo++) - { - - char byte=(*ptr++); - int byt=byte; - - int ebx; // will hold return value; - // system call - asm("pusha"); - asm("mov $61,%eax"); // select syscall) - - asm("mov %0,%%edx"::"m"(byt)); - //asm("mov $88,%edx"); - - asm("int $0x80"); // actual syscall ! interrupt - asm("mov %%ebx, %0": "=b" (ebx)); - asm("popa"); - // - - } - return len; -} - -caddr_t sbrk(int incr) -{ - -// extern char _end; /* Defined by the linker */ - char _end; - static char *heap_end; - char *prev_heap_end; - - if (heap_end == 0) { - heap_end = &_end; - } - prev_heap_end = heap_end; - /* - if (heap_end + incr > stack_ptr) { - write (1, "Heap and stack collision\n", 25); - abort (); - } - */ - - heap_end += incr; - return (caddr_t) prev_heap_end; -} - -// +#include "syscalls.h> int main() { -- cgit v1.2.3