diff --git a/Makefile b/Makefile index e37556e..3a7ba4c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -CC=tcc CFLAGS= -Wall -g -Wextra -g all: gb diff --git a/cpu.c b/cpu.c index 0d44d93..3fad857 100644 --- a/cpu.c +++ b/cpu.c @@ -1,5 +1,5 @@ #include "gb.h" -#include +#include "print.h" #define BC() ((u16)r[rB] << 8 | r[rC]) #define DE() ((u16)r[rD] << 8 | r[rE]) @@ -36,7 +36,7 @@ Var cpuvars[] = {ARR(r), VAR(ime), VAR(pc), VAR(curpc), VAR(sp), VAR(halt), void state(void) { - printf("A:%02X F:%02X B:%02X C:%02X D:%02X E:%02X H:%02X L:%02X SP:%04X " + print("A:%02X F:%02X B:%02X C:%02X D:%02X E:%02X H:%02X L:%02X SP:%04X " "PC:%04X PCMEM:%02X,%02X,%02X,%02X\n", r[rA], r[rF], diff --git a/error.c b/error.c index b23855d..335bbd2 100644 --- a/error.c +++ b/error.c @@ -1,30 +1,29 @@ #include "gb.h" -#include -#include +#include "print.h" #include #include void -panic(const char* fmt, ...) +panic(char* fmt, ...) { va_list ap; va_start(ap, fmt); - fprintf(stderr, "panic:"); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); + fprint(2, "panic:"); + vfprint(2, fmt, ap); + fprint(2, "\n"); exit(1); } void -error(const char* fmt, ...) +error(char* fmt, ...) { va_list ap; va_start(ap, fmt); - fprintf(stderr, "panic:"); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); + fprint(2, "panic:"); + vfprint(2, fmt, ap); + fprint(2, "\n"); } void* diff --git a/gb.c b/gb.c index 7770552..6dc4148 100644 --- a/gb.c +++ b/gb.c @@ -1,5 +1,4 @@ #include "gb.h" -#include #include #include #include @@ -66,31 +65,31 @@ loadsave(const char *file) static void loadrom(const char* file) { - int feat; - FILE* f; + int rc; + int feat; + int fd; long sz; static u8 mbctab[31] = { 0, 1, 1, 1, -1, 2, 2, -1, 0, 0, -1, 6, 6, 6, -1, 3, 3, 3, 3, 3, -1, 4, 4, 4, -1, 5, 5, 5, 5, 5, 5 }; - static u8 feattab[31] = { - 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, 0, - FEATRAM, FEATRAM|FEATBAT, 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATTIM|FEATBAT, - FEATTIM|FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, 0, 0, FEATRAM, FEATRAM|FEATBAT, - 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, - }; + static u8 feattab[31] = { + 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, 0, + FEATRAM, FEATRAM|FEATBAT, 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATTIM|FEATBAT, + FEATTIM|FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, 0, 0, FEATRAM, FEATRAM|FEATBAT, + 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, + }; - f = fopen(file, "r"); - if (f == nil) + fd = open(file, O_RDONLY); + if (fd == nil) panic("can't open %s", file); - fseek(f, 0, SEEK_END); - sz = ftell(f); - if (sz < 0 || sz > 32 * 1024 * 1024) - panic("bad size %d", sz); - fseek(f, 0, SEEK_SET); + sz = lseek(fd, 0, SEEK_END); + if(sz <= 0 || sz > 32*1024*1024) + panic("invalid file size %d", sz); + lseek(fd, 0, SEEK_SET); nrom = sz; rom = xalloc(nrom); - if (fread(rom, 1, nrom, f) != nrom) - panic("siz is different %z", nrom); - fclose(f); + if((rc = read(fd, rom, nrom)) != nrom) + panic("rom size is not matched %d\n", rc); + close(fd); if (rom[0x147] > 0x1F) panic("bad cartidge type %d\n", rom[0x147]); mbc = mbctab[rom[0x147]]; diff --git a/gb.h b/gb.h index 973b9be..a97616a 100644 --- a/gb.h +++ b/gb.h @@ -245,8 +245,8 @@ writeback(void); /* error */ void -error(const char*, ...); +error(char*, ...); void -panic(const char*, ...); +panic(char*, ...); void* xalloc(long); diff --git a/print.c b/print.c new file mode 100644 index 0000000..6a76a19 --- /dev/null +++ b/print.c @@ -0,0 +1,222 @@ +#include "print.h" +#include +#include +#include +#include +#include + +enum +{ + FlagLong = 1<<0, + FlagLongLong = 1<<1, + FlagUnsigned = 1<<2, +}; + +static char* +printstr(char *dst, char *edst, char *s, int sz) +{ + int l, n, isneg; + + isneg = 0; + if(sz < 0){ + sz = -sz; + isneg = 1; + } + if(dst >= edst) + return dst; + n = l = strlen(s); + if(n < sz) + n = sz; + if(n >= edst - dst) + n = (edst - dst) - 1; + if(l > n) + l = n; + if(isneg){ + memmove(dst, s, l); + if(n - l) + memset(dst + l, ' ', n - l); + }else{ + if(n - l) + memset(dst, ' ', n - l); + memmove(dst + n - l, s, l); + } + return dst + n; +} + +char* +vseprint(char *dst, char *edst, char *fmt, va_list arg) +{ + int fl, sz, sign, base; + char *p, *w; + char cbuf[2]; + + w = dst; + for(p = fmt; *p && w < edst - 1; p++){ + switch(*p){ + default: + *w++ = *p; + break; + case '%': + sign = 1; + fl = sz = 0; + for(p++; *p; p++){ + switch(*p){ + case '-': sign = -1; break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + sz = sz * 10 + *p - '0'; + break; + case 'l': if(fl & FlagLong)fl |= FlagLongLong;break; + case 'u': fl |= FlagUnsigned; break; + case 'i': case 'd': + base = 10; goto num; + case 'o': base = 8; goto num; + case 'p': case 'x': case 'X': + base = 16; + goto num; + num: + { + static char digits[] = "0123456789abcdef"; + char buf[30], *p; + int neg, zero; + unsigned long long luv; + + if(fl & FlagLongLong){ + if(fl & FlagUnsigned) + luv = va_arg(arg, unsigned long long); + else + luv = va_arg(arg, long long); + }else{ + if(fl & FlagLong){ + if(fl & FlagUnsigned) + luv = va_arg(arg, unsigned long); + else + luv = va_arg(arg, long); + }else{ + if(fl & FlagUnsigned) + luv = va_arg(arg, unsigned int); + else + luv = va_arg(arg, int); + } + } + p = buf + sizeof(buf); + neg = zero = 0; + if((fl & FlagUnsigned) == 0 && (long long)luv < 0){ + neg = 1; + luv = -luv; + } + if(luv == 0) + zero = 1; + *--p = 0; + while(luv){ + *--p = digits[luv % base]; + luv /= base; + } + if(base == 16){ + *--p = 'x'; + *--p = '0'; + } + if(base == 8 || zero) + *--p = '0'; + w = printstr(w, edst,p, sz * sign); + goto break2; + } + case 'c': + cbuf[0] = va_arg(arg, int); + cbuf[1] = 0; + w = printstr(w, edst, cbuf, sz * sign); + goto break2; + case 's': + w = printstr(w, edst, va_arg(arg, char*), sz*sign); + goto break2; + case 'r': + w = printstr(w, edst, strerror(errno), sz*sign); + goto break2; + default: + p = "error"; + goto break2; + } + } + break2: + break; + } + } + assert(w < edst); + *w = 0; + return dst; +} + +char* +vsnprint(char *dst, unsigned int n, char *fmt, va_list arg) +{ + return vseprint(dst, dst + n, fmt, arg); +} + +char* +snprint(char *dst, unsigned int n, char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + vsnprint(dst, n, fmt, arg); + va_end(arg); + return dst; +} + +char* +seprint(char* dst, char* edst, char* fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + vseprint(dst, edst, fmt, arg); + va_end(arg); + return dst; +} + +int +vfprint(int fd, char *fmt, va_list arg) +{ + char buf[1024]; + + vseprint(buf, buf + sizeof buf, fmt, arg); + return write(fd, buf, strlen(buf)); +} + + +int +vprint(char *fmt, va_list arg) +{ + return vfprint(1, fmt, arg); +} + +int +fprint(int fd, char *fmt, ...) +{ + int n; + va_list arg; + + va_start(arg, fmt); + n = vfprint(fd, fmt, arg); + va_end(arg); + return n; +} + +int +print(char *fmt, ...) +{ + int n; + va_list arg; + + va_start(arg, fmt); + n = vprint(fmt, arg); + va_end(arg); + return n; +} + +char* +strecpy(char *dst, char *edst, char *src) +{ + *printstr(dst, edst, src, 0) = 0; + return dst; +} diff --git a/print.h b/print.h new file mode 100644 index 0000000..b3e0635 --- /dev/null +++ b/print.h @@ -0,0 +1,11 @@ +#include + +char* vseprint(char *dst, char *edst, char *fmt, va_list arg); +char* vsnprint(char *dst, unsigned int n, char *fmt, va_list arg); +char* snprint(char *dst, unsigned int n, char *fmt, ...); +char* seprint(char* dst, char* edst, char* fmt, ...); +int vfprint(int fd, char *fmt, va_list arg); +int vprint(char *fmt, va_list arg); +int fprint(int fd, char *fmt, ...); +int print(char *fmt, ...); +char* strecpy(char *dst, char *edst, char *src); diff --git a/save.c b/save.c index 293f23d..eac1325 100644 --- a/save.c +++ b/save.c @@ -88,7 +88,7 @@ getvars(Var *v) n = v->n; q = v->a; while(n--){ - l |= fgetc(fp); + l = fgetc(fp); l |= fgetc(fp) << 8; l |= fgetc(fp) << 16; l |= fgetc(fp) << 24;