Mercurial > sos > sos
changeset 45:9cec88f4c98b
Merged changes in
author | Jonathan Pevarnek <pevarnj@gmail.com> |
---|---|
date | Fri, 08 Apr 2011 09:56:20 -0400 |
parents | 03c6618b2c24 (diff) 3d69c66b2610 (current diff) |
children | a6be89bc4b04 |
files | .hgignore Makefile arch/io.c include/system.h src/dynamic.c src/fs.c src/init.c src/sarpn.c |
diffstat | 20 files changed, 932 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Fri Apr 08 09:44:57 2011 -0400 +++ b/.hgignore Fri Apr 08 09:56:20 2011 -0400 @@ -3,6 +3,8 @@ \.rto$ ^ipl/ipl_ccws\.S$ ^sarpn$ +^dynamic$ +^fs$ ^loader\.bin$ ^cscope\.out$ \.swp$
--- a/Makefile Fri Apr 08 09:44:57 2011 -0400 +++ b/Makefile Fri Apr 08 09:56:20 2011 -0400 @@ -11,9 +11,11 @@ CXXFLAGS=$(CFLAGS) LDFLAGS=-m elf64_s390 -BINS=sarpn +BINS=sarpn dynamic fs -sarpn_OBJS=src/init.o arch/arch.a +sarpn_OBJS=src/sarpn.o arch/arch.a src/std.o src/stack.o src/operations.o src/math.o +dynamic_OBJS=src/dynamic.o arch/arch.a src/std.o src/stack.o +fs_OBJS=src/fs.o arch/arch.a src/std.o ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o @@ -25,15 +27,22 @@ clean: rm -f $(sarpn_OBJS) + rm -f $(dynamic_OBJS) + rm -f $(fs_OBJS) rm -f $(ARCH_OBJS) rm -f $(BINS) rm -f loader.bin ipl/*.o ipl/*.rto ipl/ipl_ccws.S cscope.out tags: cscope -R -b + ctags -R sarpn: $(sarpn_OBJS) $(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^ +dynamic: $(dynamic_OBJS) + $(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^ +fs: $(fs_OBJS) + $(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^ arch/arch.a: $(ARCH_OBJS) $(AR) rc $@ $^ @@ -78,3 +87,17 @@ ipl/%.o: ipl/%.S $(AS) -m64 -o $@ $< + +depend: + makedepend -I include src/*.c + +# DO NOT DELETE + +src/date.o: include/tod.h include/std.h +src/dynamic.o: include/std.h include/operations.h include/stack.h +src/fs.o: include/std.h +src/operations.o: include/operations.h include/std.h include/stack.h +src/operations.o: include/math.h +src/sarpn.o: include/std.h include/operations.h include/stack.h +src/stack.o: include/stack.h include/std.h +src/std.o: include/std.h
--- a/arch/io.c Fri Apr 08 09:44:57 2011 -0400 +++ b/arch/io.c Fri Apr 08 09:56:20 2011 -0400 @@ -1,3 +1,4 @@ + #include "channel.h" #include <die.h>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hercules/dynamic.cnf Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,20 @@ +CPUSERIAL 314359 # CPU serial number +CPUMODEL 2097 # CPU model number +MAINSIZE 128 # Main storage size in megabytes +XPNDSIZE 0 # Expanded storage size in megabytes +CNSLPORT 3270 # TCP port number to which consoles connect +NUMCPU 1 # Number of CPUs +#OSTAILOR QUIET # OS tailoring +OSTAILOR NULL # OS tailoring +PANRATE SLOW # Panel refresh rate + +# .-----------------------Device number +# | .-----------------Device type +# | | .---------File name and parameters +# | | | +# V V V +#--- ---- -------------------- +0009 3215 +000C 3505 ../loader.bin ../dynamic ebcdic multifile eof + +0100 9336 disk.img
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hercules/fs.cnf Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,20 @@ +CPUSERIAL 314359 # CPU serial number +CPUMODEL 2097 # CPU model number +MAINSIZE 128 # Main storage size in megabytes +XPNDSIZE 0 # Expanded storage size in megabytes +CNSLPORT 3270 # TCP port number to which consoles connect +NUMCPU 1 # Number of CPUs +#OSTAILOR QUIET # OS tailoring +OSTAILOR NULL # OS tailoring +PANRATE SLOW # Panel refresh rate + +# .-----------------------Device number +# | .-----------------Device type +# | | .---------File name and parameters +# | | | +# V V V +#--- ---- -------------------- +0009 3215 +000C 3505 ../loader.bin ../fs ebcdic multifile eof + +0100 9336 disk.img
--- a/hercules/herc.cnf Fri Apr 08 09:44:57 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -CPUSERIAL 314359 # CPU serial number -CPUMODEL 2097 # CPU model number -MAINSIZE 128 # Main storage size in megabytes -XPNDSIZE 0 # Expanded storage size in megabytes -CNSLPORT 3270 # TCP port number to which consoles connect -NUMCPU 1 # Number of CPUs -#OSTAILOR QUIET # OS tailoring -OSTAILOR NULL # OS tailoring -PANRATE SLOW # Panel refresh rate - -# .-----------------------Device number -# | .-----------------Device type -# | | .---------File name and parameters -# | | | -# V V V -#--- ---- -------------------- -0009 3215 -000C 3505 ../loader.bin ../sarpn ebcdic multifile eof - -0100 9336 disk.img
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hercules/sarpn.cnf Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,20 @@ +CPUSERIAL 314359 # CPU serial number +CPUMODEL 2097 # CPU model number +MAINSIZE 128 # Main storage size in megabytes +XPNDSIZE 0 # Expanded storage size in megabytes +CNSLPORT 3270 # TCP port number to which consoles connect +NUMCPU 1 # Number of CPUs +#OSTAILOR QUIET # OS tailoring +OSTAILOR NULL # OS tailoring +PANRATE SLOW # Panel refresh rate + +# .-----------------------Device number +# | .-----------------Device type +# | | .---------File name and parameters +# | | | +# V V V +#--- ---- -------------------- +0009 3215 +000C 3505 ../loader.bin ../sarpn ebcdic multifile eof + +0100 9336 disk.img
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/math.h Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,14 @@ +#ifndef __MATH_H +#define __MATH_H + +double iPow(double base, int exponent); +double exp(double exp); +double log(double num); +double pow(double base, double exponent); + +double math_add(double first, double sec); +double math_sub(double first, double sec); +double math_mult(double first, double sec); +double math_div(double first, double sec); + +#endif //__MATH_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/operations.h Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,26 @@ +#ifndef __OPERATIONS_H +#define __OPERATIONS_H + +#include <std.h> +#include <stack.h> + +enum Operation {PRINT, ADD, SUB, MULT, DIV, POW, DUP, DROP, LOG, EXP, SWAP, MAXOP}; +extern const char operationNames[MAXOP][10]; +extern void (*operation[MAXOP])(Stack*); + +void op_math1(Stack *stack, eltType (*mathop)(eltType)); +void op_math2(Stack *stack, eltType (*mathop)(eltType, eltType)); + +void op_print(Stack *stack); +void op_add(Stack *stack); +void op_sub(Stack *stack); +void op_mult(Stack *stack); +void op_div(Stack *stack); +void op_pow(Stack *stack); +void op_dup(Stack *stack); +void op_drop(Stack *stack); +void op_log(Stack *stack); +void op_exp(Stack *stack); +void op_swap(Stack *stack); + +#endif //__OPERATIONS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/stack.h Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,25 @@ +#ifndef __STACK_H +#define __STACK_H + +typedef double eltType; + +struct STACKELT { + eltType elt; + struct STACKELT *next; +}; +typedef struct STACKELT StackElt; + +struct STACK { + StackElt* top; + unsigned int size; +}; +typedef struct STACK Stack; + +short pop(Stack *stack, eltType *value); +//pop returns 0 on success and -1 on failure. If the function call is +//successful, *value will be the value removed from the stack +void push(Stack *stack, eltType val); +Stack* stack_init(); +void stack_destroy(Stack *stack); + +#endif //__STACK_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/std.h Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,37 @@ +#ifndef __STD_H +#define __STD_H + +double abs(double num); + +char* ftoa(double x, char *a, unsigned int prec); +char* itoa(long long n, char *a, unsigned short base); +s64 atoi(char *a); +double atof(char *a); + +void sPrint(char *a); +char* sGet(char *a, unsigned int n); + +void strcpy(char *dest, const char *src); +int strcmp(const char *a, const char *b); + +int arrayLookup(char *text, const char array[][10], int last); + +char* append(char *dest, char *src); + +//MALLOC CODE + +struct header{ + struct header *next; + size_t size; +}; +typedef struct header Header; + +typedef Header blockUnit; + +void malloc_init(size_t memSize); +void* malloc(size_t size); +void free(void *ptr); +void printHeader(Header* head); +void printMem(); + +#endif
--- a/include/system.h Fri Apr 08 09:44:57 2011 -0400 +++ b/include/system.h Fri Apr 08 09:56:20 2011 -0400 @@ -5,6 +5,14 @@ #define CON_DEV 0x0009 #define NULL ((void*) 0) +#define CON_LEN 132 +#define HEAP_START 0x200000 + +#define INF __builtin_inff() +#define NAN __builtin_nanf("") + +typedef unsigned long long size_t; +typedef unsigned long long intptr_t; typedef unsigned long long u64; typedef signed long long s64;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dynamic.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,76 @@ +/* + * This is where everything starts + */ + +#include <std.h> +#include <operations.h> +#include <stack.h> + +void dumpBuffer(char *a, int b) +{ + int i; + for(i = 0; i < b; i++) { + int foo = (int) a[i]; + char c[10]; + itoa(foo, c, 16); + sPrint(c); + sPrint(" "); + if(!((i + 1)%20)) sPrint("\n"); + } +} + +void start(u64 __memsize) +{ + init_io_int(); + init_console(); + malloc_init(__memsize - HEAP_START); + size_t n; + char *buffer; + char input[30]; + + while(0) { + sPrint("How long do you want the string? "); + n = atoi(sGet(input, 30)); + buffer = (char*) malloc(n); + if (!buffer) { //allocation failed, too large + sPrint("ERROR\n"); + break; + } +// size_t i; +// for (i = 0; i < n - 1; i++) +// buffer[i]='a'; //I need to make rand... +// buffer[n - 1]='\0'; +// sPrint(buffer), sPrint("\n"); +// dumpBuffer(buffer, n); + sPrint(append(itoa((unsigned long)buffer, input, 16), "\n")); + free(buffer); + } + + printMem(); + + Stack *stack = stack_init(); + + for(n = 0; n < 1000; n++) { + push(stack, n); + } + stack_destroy(stack); + + + printMem(); + void *a = malloc(1223); + void *b = malloc(352); + void *c = malloc(3539); + void *d = malloc(325); + printMem(); + free(b); + printMem(); + b = malloc(400); + printMem(); + sPrint("DONE\n"); + free(a); + free(c); + free(d); + + for(;;) + sGet(input, 0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fs.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,150 @@ +#include <std.h> + +struct SUPERBLOCK { + u32 magic; // == 0x42420374 + u32 root_inode; // the disk block containing the root inode + u32 nblocks; // number of block on the disk + u32 _pad[253]; // unused (should be '\0' filled) +}; +typedef struct SUPERBLOCK Superblock; + +struct INODE { + u32 size; // file length in bytes + u32 _pad0; // unused (should be 0) + u64 ctime; // creation time stamp + u64 mtime; // last modification time stamp + u16 nblocks; // number of data blocks in this file + u16 _pad1; // unused (should be 0) + u32 _pad2; // unused (should be 0) + u32 blocks[248]; // file block ptrs +}; +typedef struct INODE Inode; + +struct DIRENTRY { //32 bytes + char fname[28]; + u32 inode; +}; +typedef struct DIRENTRY Direntry; + +//REQUIRES: fsBlock points to an object with size at least 1024 +//EFFECTS: Sets fsBlock to be equal +int readFSBlock(u32 dev, u32 blkno, void *fsBlock) +{ + if(fba_read_blk(dev, blkno*2, fsBlock)) return 1; + if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1; + return 0; +} + +void printFname(char *name) +{ + putline(name, 28); +} + +//Sets name to contain a filename entered by the user +//REQUIRES: name is 28 characters long +void getFname(char *fname) +{ + int chars = getline(fname, 28); + for(;chars < 28; chars++) { + fname[chars] = ' '; + } +} + +//Checks whether two file names are equal +int fnameCmp(const char *a, const char *b) +{ + int i; + for(i = 0; i < 28; i++, a++, b++) { + if(*a - *b) return *a - *b; + } + return 0; +} + +//Finds the item within an array of filenames with the same name as fname +int fnameLookup(char *fname, const Direntry array[], int last) +{ + int i; + for(i = 0; i < last; i++) + if(!fnameCmp(fname, array[i].fname)) return i; + return last; +} + +void dumpText(char *text, int size) +{ + do { + putline(text, (size > CON_LEN)?CON_LEN:size); + size -= CON_LEN; + text += CON_LEN; + } while(size > 0); +} + +void start(u64 __memsize) +{ + init_io_int(); + init_console(); + char buffer[256]; + int i; + + u32 dev = find_dev(0x100); + Superblock sb; + if(readFSBlock(dev, 1, &sb)) { //get the super block + sPrint("ERROR\n"); + goto END; + } + Inode root; + if(readFSBlock(dev, sb.root_inode, &root)) { //get the root inode + sPrint("ERROR\n"); + goto END; + } + int nFiles = root.size/sizeof(Direntry); + //calculate how many files (assume less than 32 for the moment) + //TODO get rid of assumption + Direntry direntries[32]; + if(readFSBlock(dev, root.blocks[0], direntries)) { //get the "first 32" files + sPrint("ERROR\n"); + goto END; + } + + while(1) { + + //Prints off the name of each file + Direntry *dp; + for(dp = direntries; dp - direntries < nFiles; dp++) { + printFname(dp->fname), sPrint("\n"); + } + char fname[28]; + sPrint("Please enter the file to read: "); + getFname(fname); + int file = fnameLookup(fname, direntries, nFiles); + + u32 fileLoc = direntries[file].inode; + if(fileLoc == nFiles) continue; + + Inode fileToRead; + if(readFSBlock(dev, fileLoc, &fileToRead)) { + sPrint("ERROR\n"); + goto END; + } + + u32 fileSize = fileToRead.size; + + for(i = 0; i < fileToRead.nblocks; i++) { + char text[1024]; + if(readFSBlock(dev, fileToRead.blocks[i], text)) { + sPrint("ERROR\n"); + goto END; + } + dumpText(text, (fileSize > 1024)?1024:fileSize); + fileSize -= 1024; + } + } + + +END: + sPrint("DONE\n"); + for(;;) { + char buffer[1]; + sGet(buffer, 0); + } +} +
--- a/src/init.c Fri Apr 08 09:44:57 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -/* - * This is where everything starts - */ -void start(u64 __memsize) -{ - init_io_int(); - init_console(); - - putline("Hello\n", 6); - - for(;;) - ; -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/math.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,84 @@ +double iPow(double base, int exponent) +{ + double ans = 1; + short isNeg = 0; + if(exponent < 0) { + isNeg = 1; + exponent *= -1; + } + while(exponent > 0) { + if(exponent%2) { + exponent -= 1; + ans *= base; + } else { + exponent /= 2; + base *= base; + } + } + return isNeg ? 1/ans : ans; +} + +double exp(double exp) +{ + unsigned int i; //a counter for the loop + double ans = 1; + double prev = -1; + double term = 1; + short isNeg = 0; + if(exp < 0) { + isNeg = 1; + exp *= -1; + } + for(i = 1; ans - prev; i++) { + prev = ans; + term *= exp/i; + ans += term; + } + return isNeg ? 1/ans : ans; +} + +double log(double num) +{ + unsigned int denom = 1; + double euler = 2.71828182845904; + double ans = 0; + double prev = -1; + double term = -1; + while(num <= -1 || num >= 1) { + num /= euler; + ans += 1; + } + for(; ans - prev; denom++) { + prev = ans; + term *= (-1*(num - 1)); + ans += term/denom; + } + return ans; +} + +double pow(double base, double exponent) +{ + if(exponent == (int) exponent) + return iPow(base, (int) exponent); + return exp(exponent*log(base)); +} + +double math_add(double first, double sec) +{ + return first + sec; +} + +double math_sub(double first, double sec) +{ + return first - sec; +} + +double math_mult(double first, double sec) +{ + return first*sec; +} + +double math_div(double first, double sec) +{ + return first/sec; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/operations.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,113 @@ +#include <operations.h> +#include <std.h> +#include <stack.h> +#include <math.h> + +const char operationNames[MAXOP][10] = {".", "+", "-", "*", "/", "**", "dup", "drop", "log", "exp", "swap"}; +void (*operation[MAXOP])(Stack*) = {op_print, op_add, op_sub, op_mult, + op_div, op_pow, op_dup, op_drop, op_log, op_exp, op_swap}; + +static void error_unk() +{ + sPrint("ERROR: CAUSE UNKNOWN\n"); +} + +static void error_small() +{ + sPrint("ERROR: STACK TOO SMALL\n"); +} + +void op_math1(Stack *stack, eltType (*mathop)(eltType)) +{ + if(stack->size >= 1) { + eltType val; + if(pop(stack, &val)) error_unk(); + else push(stack, mathop(val)); + } else error_small(); +} + +void op_math2(Stack *stack, eltType (*mathop)(eltType, eltType)) +{ + if(stack->size >= 2) { + eltType val1, val2; + if(pop(stack, &val2) || pop(stack, &val1)) error_unk(); + else push(stack, mathop(val1, val2)); + } else error_small(); +} + +void op_print(Stack *stack) +{ + if(stack->size >= 1) { + char output[30]; + eltType val; + if(pop(stack, &val)) error_unk(); + else sPrint(append(ftoa(val, output, 10), "\n")); + } else error_small(); +} + +void op_add(Stack *stack) +{ + op_math2(stack, math_add); +} + +void op_sub(Stack *stack) +{ + op_math2(stack, math_sub); +} + +void op_mult(Stack *stack) +{ + op_math2(stack, math_mult); +} + +void op_div(Stack *stack) +{ + op_math2(stack, math_div); +} + +void op_pow(Stack *stack) +{ + op_math2(stack, pow); +} + +void op_dup(Stack *stack) +{ + if(stack->size >= 1) { + eltType val; + if(pop(stack, &val)) error_unk(); + else { + push(stack, val); + push(stack, val); + } + } else error_small(); +} + +void op_drop(Stack *stack) +{ + if(stack->size >= 1) { + eltType val; + pop(stack, &val); + } else error_small(); +} + +void op_log(Stack *stack) +{ + op_math1(stack, log); +} + +void op_exp(Stack *stack) +{ + op_math1(stack, exp); +} + +void op_swap(Stack *stack) +{ + if(stack->size >= 2) { + eltType val1, val2; + if(pop(stack, &val2) || pop(stack, &val1)) error_unk(); + else { + push(stack, val2); + push(stack, val1); + } + } else error_small(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sarpn.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,31 @@ +/* + * This is where everything starts + */ + +#include <std.h> +#include <operations.h> +#include <stack.h> + +void start(u64 __memsize) +{ + init_io_int(); + init_console(); + malloc_init(__memsize - HEAP_START); + + Stack *stack = stack_init(); + while(1) { + int opVal; + char input[30]; + sPrint("Please enter an operation or value: "); + opVal = arrayLookup(sGet(input, 30), operationNames, MAXOP); + if(opVal != MAXOP) { + (*operation[opVal]) (stack); //call the function array + } else { + push(stack, atof(input)); + } + } + stack_destroy(stack); + + for(;;) + ; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/stack.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,40 @@ +#include <stack.h> +#include <std.h> + +short pop(Stack *stack, eltType *value) +{ + if(stack->top == NULL) { + return -1; //failure + } else { + StackElt *tip = stack->top; + *value = tip->elt; + stack->top = tip->next; + free(tip); + stack->size--; + return 0; //success + } +} + +void push(Stack *stack, eltType val) +{ + StackElt *new = malloc(sizeof(StackElt)); + new->elt = val; + new->next = stack->top; + stack->top = new; + stack->size++; +} + +Stack* stack_init() +{ + Stack *new = malloc(sizeof(Stack)); + new->top = NULL; + return new; +} + +void stack_destroy(Stack *stack) +{ + eltType *val = malloc(sizeof(eltType)); + while(stack->top) pop(stack, val); + free(stack); + free(val); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/std.c Fri Apr 08 09:56:20 2011 -0400 @@ -0,0 +1,240 @@ +#include <std.h> + +double abs(double num) +{ + if(num < 0) return num*-1; + else return num; +} + +char* itoa(s64 n, char *a, unsigned short base) +{ + char *ret = a; + if(n < 0) { + *a++ = '-'; + n *= -1; + } + char *b = a; + if(!n) *b++ = '0'; + for(; n; b++) { + int temp = n%base; + if(temp < 10) *b = '0' + temp; + else *b = 'a' + temp - 10; + n = n/base; + } + *b-- = '\0'; + for(; a < b; a++, b--) { //reverse + char temp = *b; + *b = *a; + *a = temp; + } + return ret; +} + +char* ftoa(double x, char *a, unsigned int prec) +{ + char *ret = a; + if(x == INF || x == -INF) { + strcpy(a, "INF"); + } else if(x != x) { //NAN != NAN + strcpy(a, "NAN"); + } else { + s64 n = (s64) x; //integer part + double d = abs(x - (double) n); //fractional part; + itoa(n, a, 10); + if(prec) { //only do the decimal part if decimal parts were asked for + while(*a && *++a); //get to the null character from itoa + int i; //counter variable for the for loop + *a++ = '.'; //put the decimal in place + for(i = 0; i < prec; i++) { + d *= 10; //the integer part is the decimal digit + *a++ = ((int) d) + '0'; //add the integer part of d to the string + d -= (int) d; //chop off the integer part + } a--; //move back to the last digit + while(*a != '.') { + if(*a == '0') { + a--; + continue; + } else if(*a > '0' && *a <= '9') { + a++; + break; + } else { + sPrint("ERROR: SOMETHING IS VERY WRONG\n"); + break; + } + } + *a = '\0'; + } + } + return ret; +} + +s64 atoi(char *a) +{ + short neg = 0; + s64 n = 0; + if(*a == '-') { + neg = 1; + a++; + } else if(*a == '+') a++; + while(*a >= '0' && *a <= '9') + n = n*10 + (*a++ - '0'); + if(neg) n *= -1; + return n; +} + +double atof(char *a) +{ + s64 n = atoi(a); + double x = 0; + double dec = .1; + short neg = 0; + if(*a == '-') { + neg = 1; + a++; + } + while(*a != '.') { + if(!(*a >= '0' && *a <= '9') && *a != '-') return n; + a++; + } a++; //a will be immediately after the decimal point + while(*a >= '0' && *a <= '9') { //goes through the decimal part + x += (*a - '0')*dec; + dec *= .1; + a++; + } + if(neg) x*=-1; + return n + x; +} + +void sPrint(char *a) +{ + char *b = a; + while(*b && *++b); + do { + putline(a, (b - a > CON_LEN)?CON_LEN:(b - a)); + a += CON_LEN; + } while(a < b); +} + +void strcpy(char *dest, const char *src) +{ + while((*dest++ = *src++)); +} + +int strcmp(const char *a, const char *b) +{ + while(1) { + if(*a - *b) return *a - *b; + if(*a == '\0') return 0; + a++; + b++; + } + return -1; +} + +char* sGet(char *a, unsigned int n) +{ + int length = getline(a, n); + a[(length < n)?length:n - 1] = '\0'; + return a; +} + +int arrayLookup(char *text, const char array[][10], int last) +{ + int i; + for(i = 0; i < last; i++) + if(!strcmp(array[i], text)) return i; + return last; +} + +char* append(char *dest, char *src) +{ + char *ret = dest; + while(*dest&& *++dest); //get to null in first string + while((*dest++ = *src++)); + return ret; +} + +static Header base; +static Header *allocp = NULL; //the location of the last known free block + +void malloc_init(size_t memSize) +{ + allocp = &base; + allocp->size = 0; + allocp->next = (void*)HEAP_START; + allocp->next->next = &base; + allocp->next->size = memSize/sizeof(blockUnit); + if((sizeof(blockUnit)%sizeof(u64))) { + sPrint("WARNING: MEMORY NOT 8-BYTE ALIGNED\n"); + char foo[40]; + sPrint(append("MEMORY BLOCK SIZE IS: ", append(itoa(sizeof(Header), foo, 10), "\n"))); + } +} + +void* malloc(size_t size) +{ + if(allocp == NULL) return NULL; + size_t nUnits = ((size + sizeof(Header)) + sizeof(blockUnit) - 1)/sizeof(blockUnit); + Header *prev = allocp; + Header *cur, *temp; + for(cur = prev->next;; prev = cur, cur = cur->next) { + if(cur->size >= nUnits) { + if(cur->size == nUnits) { + prev->next = cur->next; + } else { + temp = cur + nUnits; //This requires sizeof(blockUnit) == sizeof(Header). TODO fix + temp->size = cur->size - nUnits; + temp->next = cur->next; + prev->next = temp; + cur->size = nUnits; + } + allocp = prev; + return (void*)(cur + 1); + } else if(cur == allocp) { //We went back to the start... + return NULL; + } + } +} + +void free(void *ptr) +{ + Header *toFree = (Header *)ptr - 1; + Header *scan; + for(scan = allocp; !(toFree > scan && toFree < scan->next); scan = scan->next) + if(scan->next < scan && (toFree > scan || toFree < scan->next)) break; + toFree->next = scan->next; + scan->next = toFree; + if(scan + scan->size == toFree) { + scan->size += toFree->size; + scan->next = toFree->next; + toFree = scan; + } + if(toFree + toFree->size == toFree->next) { + toFree->size += toFree->next->size; + toFree->next = toFree->next->next; + } +} + +void printHeader(Header* head) +{ + char buffer[20]; + sPrint("Memory address is: "); + sPrint(itoa((intptr_t)head, buffer, 16)); + sPrint("\n"); + sPrint("The size of the block is: "); + sPrint(itoa(head->size, buffer, 10)); + sPrint("\n"); + sPrint("Next memory address is: "); + sPrint(itoa((intptr_t)head->next, buffer, 16)); + sPrint("\n\n"); +} + +void printMem() +{ + Header *cur = allocp; + do { + printHeader(cur); + cur = cur->next; + } while(cur != allocp); + sPrint("PRINTOUT DONE\n\n"); +}