add print
This commit is contained in:
parent
d82b0a8ccd
commit
db41ae86e3
1
Makefile
1
Makefile
@ -1,4 +1,3 @@
|
|||||||
CC=tcc
|
|
||||||
CFLAGS= -Wall -g -Wextra -g
|
CFLAGS= -Wall -g -Wextra -g
|
||||||
|
|
||||||
all: gb
|
all: gb
|
||||||
|
|||||||
4
cpu.c
4
cpu.c
@ -1,5 +1,5 @@
|
|||||||
#include "gb.h"
|
#include "gb.h"
|
||||||
#include <stdio.h>
|
#include "print.h"
|
||||||
|
|
||||||
#define BC() ((u16)r[rB] << 8 | r[rC])
|
#define BC() ((u16)r[rB] << 8 | r[rC])
|
||||||
#define DE() ((u16)r[rD] << 8 | r[rE])
|
#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
|
void
|
||||||
state(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",
|
"PC:%04X PCMEM:%02X,%02X,%02X,%02X\n",
|
||||||
r[rA],
|
r[rA],
|
||||||
r[rF],
|
r[rF],
|
||||||
|
|||||||
19
error.c
19
error.c
@ -1,30 +1,29 @@
|
|||||||
#include "gb.h"
|
#include "gb.h"
|
||||||
#include <stdarg.h>
|
#include "print.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
panic(const char* fmt, ...)
|
panic(char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
fprintf(stderr, "panic:");
|
fprint(2, "panic:");
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprint(2, fmt, ap);
|
||||||
fprintf(stderr, "\n");
|
fprint(2, "\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
error(const char* fmt, ...)
|
error(char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
fprintf(stderr, "panic:");
|
fprint(2, "panic:");
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprint(2, fmt, ap);
|
||||||
fprintf(stderr, "\n");
|
fprint(2, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
|
|||||||
23
gb.c
23
gb.c
@ -1,5 +1,4 @@
|
|||||||
#include "gb.h"
|
#include "gb.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -66,8 +65,9 @@ loadsave(const char *file)
|
|||||||
static void
|
static void
|
||||||
loadrom(const char* file)
|
loadrom(const char* file)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
int feat;
|
int feat;
|
||||||
FILE* f;
|
int fd;
|
||||||
long sz;
|
long sz;
|
||||||
static u8 mbctab[31] = { 0, 1, 1, 1, -1, 2, 2, -1, 0, 0, -1, 6, 6, 6, -1, 3,
|
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 };
|
3, 3, 3, 3, -1, 4, 4, 4, -1, 5, 5, 5, 5, 5, 5 };
|
||||||
@ -78,19 +78,18 @@ loadrom(const char* file)
|
|||||||
0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT,
|
0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT,
|
||||||
};
|
};
|
||||||
|
|
||||||
f = fopen(file, "r");
|
fd = open(file, O_RDONLY);
|
||||||
if (f == nil)
|
if (fd == nil)
|
||||||
panic("can't open %s", file);
|
panic("can't open %s", file);
|
||||||
fseek(f, 0, SEEK_END);
|
sz = lseek(fd, 0, SEEK_END);
|
||||||
sz = ftell(f);
|
if(sz <= 0 || sz > 32*1024*1024)
|
||||||
if (sz < 0 || sz > 32 * 1024 * 1024)
|
panic("invalid file size %d", sz);
|
||||||
panic("bad size %d", sz);
|
lseek(fd, 0, SEEK_SET);
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
nrom = sz;
|
nrom = sz;
|
||||||
rom = xalloc(nrom);
|
rom = xalloc(nrom);
|
||||||
if (fread(rom, 1, nrom, f) != nrom)
|
if((rc = read(fd, rom, nrom)) != nrom)
|
||||||
panic("siz is different %z", nrom);
|
panic("rom size is not matched %d\n", rc);
|
||||||
fclose(f);
|
close(fd);
|
||||||
if (rom[0x147] > 0x1F)
|
if (rom[0x147] > 0x1F)
|
||||||
panic("bad cartidge type %d\n", rom[0x147]);
|
panic("bad cartidge type %d\n", rom[0x147]);
|
||||||
mbc = mbctab[rom[0x147]];
|
mbc = mbctab[rom[0x147]];
|
||||||
|
|||||||
4
gb.h
4
gb.h
@ -245,8 +245,8 @@ writeback(void);
|
|||||||
|
|
||||||
/* error */
|
/* error */
|
||||||
void
|
void
|
||||||
error(const char*, ...);
|
error(char*, ...);
|
||||||
void
|
void
|
||||||
panic(const char*, ...);
|
panic(char*, ...);
|
||||||
void*
|
void*
|
||||||
xalloc(long);
|
xalloc(long);
|
||||||
|
|||||||
222
print.c
Normal file
222
print.c
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
#include "print.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
11
print.h
Normal file
11
print.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
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);
|
||||||
Loading…
Reference in New Issue
Block a user