Added debugger

This commit is contained in:
neauoire 2021-02-15 10:12:44 -08:00
parent 14cd9e03c4
commit f377bdf59c
4 changed files with 73 additions and 73 deletions

View File

@ -23,7 +23,7 @@ typedef unsigned char Uint8;
int WIDTH = 8 * HOR + 8 * PAD * 2; int WIDTH = 8 * HOR + 8 * PAD * 2;
int HEIGHT = 8 * (VER + 2) + 8 * PAD * 2; int HEIGHT = 8 * (VER + 2) + 8 * PAD * 2;
int FPS = 30, GUIDES = 1, BIGPIXEL = 0, ZOOM = 2; int FPS = 30, GUIDES = 1, REQDRAW = 0, ZOOM = 2;
Uint32 theme[] = { Uint32 theme[] = {
0x000000, 0x000000,
@ -32,6 +32,24 @@ Uint32 theme[] = {
0x666666, 0x666666,
0x222222}; 0x222222};
Uint8 icons[][8] = {
{0x00, 0x3c, 0x46, 0x4a, 0x52, 0x62, 0x3c, 0x00},
{0x00, 0x18, 0x28, 0x08, 0x08, 0x08, 0x3e, 0x00},
{0x00, 0x3c, 0x42, 0x02, 0x3c, 0x40, 0x7e, 0x00},
{0x00, 0x3c, 0x42, 0x1c, 0x02, 0x42, 0x3c, 0x00},
{0x00, 0x08, 0x18, 0x28, 0x48, 0x7e, 0x08, 0x00},
{0x00, 0x7e, 0x40, 0x7c, 0x02, 0x42, 0x3c, 0x00},
{0x00, 0x3c, 0x40, 0x7c, 0x42, 0x42, 0x3c, 0x00},
{0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00},
{0x00, 0x3c, 0x42, 0x3c, 0x42, 0x42, 0x3c, 0x00},
{0x00, 0x3c, 0x42, 0x42, 0x3e, 0x02, 0x3c, 0x00},
{0x00, 0x3c, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x00},
{0x00, 0x7c, 0x42, 0x7c, 0x42, 0x42, 0x7c, 0x00},
{0x00, 0x3c, 0x42, 0x40, 0x40, 0x42, 0x3c, 0x00},
{0x00, 0x78, 0x44, 0x42, 0x42, 0x44, 0x78, 0x00},
{0x00, 0x7e, 0x40, 0x7c, 0x40, 0x40, 0x7e, 0x00},
{0x00, 0x7e, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x00}};
SDL_Window *gWindow; SDL_Window *gWindow;
SDL_Renderer *gRenderer; SDL_Renderer *gRenderer;
SDL_Texture *gTexture; SDL_Texture *gTexture;
@ -90,12 +108,35 @@ error(char *msg, const char *err)
} }
void void
redraw(Uint32 *dst) drawdebugger(Uint32 *dst, Uxn *u)
{ {
Uint8 i;
for(i = 0; i < 0x10; ++i) { /* memory */
Uint8 x = (i % 8) * 3 + 1, y = i / 8 + 1, b = u->ram.dat[i];
drawicn(dst, x * 8, y * 8, icons[(b >> 4) & 0xf], 1, 0);
drawicn(dst, x * 8 + 8, y * 8, icons[b & 0xf], 1, 0);
}
for(i = 0; i < 0x10; ++i) { /* memory */
Uint8 x = (i % 8) * 3 + 1, y = i / 8 + 0x13, b = u->wst.dat[i];
drawicn(dst, x * 8, y * 8, icons[(b >> 4) & 0xf], 1 + (u->wst.ptr == i), 0);
drawicn(dst, x * 8 + 8, y * 8, icons[b & 0xf], 1 + (u->wst.ptr == i), 0);
}
drawicn(dst, 25 * 8, 8, icons[getflag(&u->status, FLAG_HALT) != 0], 2, 0);
drawicn(dst, 26 * 8, 8, icons[getflag(&u->status, FLAG_SHORT) != 0], 2, 0);
drawicn(dst, 27 * 8, 8, icons[getflag(&u->status, FLAG_SIGN) != 0], 2, 0);
drawicn(dst, 28 * 8, 8, icons[getflag(&u->status, FLAG_COND) != 0], 2, 0);
}
void
redraw(Uint32 *dst, Uxn *u)
{
if(GUIDES)
drawdebugger(dst, u);
SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32)); SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32));
SDL_RenderClear(gRenderer); SDL_RenderClear(gRenderer);
SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); SDL_RenderCopy(gRenderer, gTexture, NULL, NULL);
SDL_RenderPresent(gRenderer); SDL_RenderPresent(gRenderer);
REQDRAW = 0;
} }
void void
@ -132,43 +173,6 @@ init(void)
return 1; return 1;
} }
void
echos(St8 *s, Uint8 len, char *name)
{
int i;
printf("\n%s\n", name);
for(i = 0; i < len; ++i) {
if(i % 16 == 0)
printf("\n");
printf("%02x%c", s->dat[i], s->ptr == i ? '<' : ' ');
}
printf("\n\n");
}
void
echom(Memory *m, Uint8 len, char *name)
{
int i;
printf("\n%s\n", name);
for(i = 0; i < len; ++i) {
if(i % 16 == 0)
printf("\n");
printf("%02x ", m->dat[i]);
}
printf("\n\n");
}
void
echof(Uxn *c)
{
printf("ended @ %d steps | hf: %x sf: %x sf: %x cf: %x\n",
c->counter,
getflag(&c->status, FLAG_HALT) != 0,
getflag(&c->status, FLAG_SHORT) != 0,
getflag(&c->status, FLAG_SIGN) != 0,
getflag(&c->status, FLAG_COND) != 0);
}
void void
domouse(SDL_Event *event) domouse(SDL_Event *event)
{ {
@ -242,15 +246,15 @@ screenr(Device *d, Memory *m, Uint8 b)
Uint8 Uint8
screenw(Device *d, Memory *m, Uint8 b) screenw(Device *d, Memory *m, Uint8 b)
{ {
d->mem[d->len++] = b; d->mem[d->ptr++] = b;
if(d->len > 5) { if(d->ptr > 5) {
putpixel(pixels, putpixel(pixels,
(d->mem[2] << 8) + d->mem[3], (d->mem[2] << 8) + d->mem[3],
(d->mem[0] << 8) + d->mem[1], (d->mem[0] << 8) + d->mem[1],
d->mem[4]); d->mem[4]);
if(d->mem[5]) if(d->mem[5])
redraw(pixels); REQDRAW = 1;
d->len = 0; d->ptr = 0;
} }
(void)m; (void)m;
return 0; return 0;
@ -259,15 +263,15 @@ screenw(Device *d, Memory *m, Uint8 b)
Uint8 Uint8
spritew(Device *d, Memory *m, Uint8 b) spritew(Device *d, Memory *m, Uint8 b)
{ {
d->mem[d->len++] = b; d->mem[d->ptr++] = b;
if(d->len > 6) { if(d->ptr > 6) {
Uint16 x = (d->mem[2] << 8) + d->mem[3]; Uint16 x = (d->mem[2] << 8) + d->mem[3];
Uint16 y = (d->mem[0] << 8) + d->mem[1]; Uint16 y = (d->mem[0] << 8) + d->mem[1];
Uint8 *chr = &m->dat[(d->mem[4] << 8) + d->mem[5]]; Uint8 *chr = &m->dat[(d->mem[4] << 8) + d->mem[5]];
drawchr(pixels, x, y, chr); drawchr(pixels, x, y, chr);
if(d->mem[6]) if(d->mem[6])
redraw(pixels); REQDRAW = 1;
d->len = 0; d->ptr = 0;
} }
return 0; return 0;
} }
@ -279,11 +283,6 @@ start(Uxn *u)
{ {
int ticknext = 0; int ticknext = 0;
evaluxn(u, u->vreset); evaluxn(u, u->vreset);
echos(&u->wst, 0x40, "stack");
echom(&u->ram, 0x40, "ram");
echof(u);
while(1) { while(1) {
int tick = SDL_GetTicks(); int tick = SDL_GetTicks();
SDL_Event event; SDL_Event event;
@ -300,11 +299,13 @@ start(Uxn *u)
case SDL_KEYUP: doctrl(&event, 0); break; case SDL_KEYUP: doctrl(&event, 0); break;
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
if(event.window.event == SDL_WINDOWEVENT_EXPOSED) if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
redraw(pixels); redraw(pixels, u);
break; break;
} }
} }
evaluxn(u, u->vframe); evaluxn(u, u->vframe);
if(REQDRAW)
redraw(pixels, u);
} }
} }

View File

@ -8,7 +8,6 @@
|0100 @RESET |0100 @RESET
#12 #34 WSR2 #12 #34 WSR2
RSW2
,test JSR ,test JSR
BRK BRK

30
uxn.c
View File

@ -18,21 +18,19 @@ WITH REGARD TO THIS SOFTWARE.
/* clang-format off */ /* clang-format off */
void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); } void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); }
int getflag(Uint8 *a, char flag) { return *a & flag; } int getflag(Uint8 *a, char flag) { return *a & flag; }
void warn(char *s, Uint8 b) { printf("Warning: %s(%d)\n", s, b);}
void mempoke8(Memory *m, Uint16 a, Uint8 b) { m->dat[a] = b; } void mempoke8(Memory *m, Uint16 a, Uint8 b) { m->dat[a] = b; }
Uint8 mempeek8(Memory *m, Uint16 a) { return m->dat[a]; } Uint8 mempeek8(Memory *m, Uint16 a) { return m->dat[a]; }
void mempoke16(Memory *m, Uint16 a, Uint16 b) { mempoke8(m, a, b >> 8); mempoke8(m, a + 1, b); } void mempoke16(Memory *m, Uint16 a, Uint16 b) { mempoke8(m, a, b >> 8); mempoke8(m, a + 1, b); }
Uint16 mempeek16(Memory *m, Uint16 a) { return (mempeek8(m, a) << 8) + mempeek8(m, a + 1); } Uint16 mempeek16(Memory *m, Uint16 a) { return (mempeek8(m, a) << 8) + mempeek8(m, a + 1); }
void push8(St8 *s, Uint8 a) { s->dat[s->ptr++] = a; } void push8(Stack *s, Uint8 a) { s->dat[s->ptr++] = a; }
Uint8 pop8(St8 *s) { return s->dat[--s->ptr]; } Uint8 pop8(Stack *s) { return s->dat[--s->ptr]; }
Uint8 peek8(St8 *s, Uint8 a) { return s->dat[s->ptr - a - 1]; } Uint8 peek8(Stack *s, Uint8 a) { return s->dat[s->ptr - a - 1]; }
void push16(St8 *s, Uint16 a) { push8(s, a >> 8); push8(s, a); } void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); } Uint16 pop16(Stack *s) { return pop8(s) + (pop8(s) << 8); }
Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); } Uint16 peek16(Stack *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
/* I/O */ /* I/O */
void op_brk(Uxn *u) { setflag(&u->status, FLAG_HALT, 1); } void op_brk(Uxn *u) { setflag(&u->status, FLAG_HALT, 1); }
void op_lit(Uxn *u) { u->literal += 1; } void op_lit(Uxn *u) { u->literal += 1; }
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
void op_nop(Uxn *u) { printf("0x%02x \n", pop8(&u->wst)); fflush(stdout); } void op_nop(Uxn *u) { printf("0x%02x \n", pop8(&u->wst)); fflush(stdout); }
void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, &u->ram, pop8(&u->wst))); } void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, &u->ram, pop8(&u->wst))); }
void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, &u->ram, a); } void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, &u->ram, a); }
@ -40,8 +38,8 @@ void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram
void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); } void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); }
/* Logic */ /* Logic */
void op_jmp(Uxn *u) { u->ram.ptr = pop16(&u->wst); } void op_jmp(Uxn *u) { u->ram.ptr = pop16(&u->wst); }
void op_jsr(Uxn *u) { if(u->balance > 0){ warn("Stack unbalance", u->balance); } push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst); } void op_jsr(Uxn *u) { push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst); }
void op_rts(Uxn *u) { if(u->balance > 0){ warn("Stack unbalance", u->balance); } u->ram.ptr = pop16(&u->rst); } void op_rts(Uxn *u) { u->ram.ptr = pop16(&u->rst); }
void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); } void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); }
void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); } void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); }
void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); } void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); }
@ -93,12 +91,12 @@ void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u-
void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint16)b < (Sint16)a : b < a); } void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint16)b < (Sint16)a : b < a); }
void (*ops[])(Uxn *u) = { void (*ops[])(Uxn *u) = {
op_brk, op_nop, op_lit, op_lix, op_ior, op_iow, op_ldr, op_str, op_brk, op_nop, op_lit, op_nop, op_ior, op_iow, op_ldr, op_str,
op_jmp, op_jsr, op_nop, op_rts, op_and, op_ora, op_rol, op_ror, op_jmp, op_jsr, op_nop, op_rts, op_and, op_ora, op_rol, op_ror,
op_pop, op_dup, op_swp, op_ovr, op_rot, op_wsr, op_rsw, op_nop, op_pop, op_dup, op_swp, op_ovr, op_rot, op_wsr, op_rsw, op_nop,
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth,
/* 16-bit */ /* 16-bit */
op_brk, op_nop16, op_lit16, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, op_brk, op_nop16, op_lit16, op_nop, op_ior16, op_iow16, op_ldr16, op_str16,
op_jmp, op_jsr, op_nop, op_rts, op_and16, op_ora16, op_rol16, op_ror16, op_jmp, op_jsr, op_nop, op_rts, op_and16, op_ora16, op_rol16, op_ror16,
op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_wsr16, op_rsw16, op_nop, op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_wsr16, op_rsw16, op_nop,
op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16 op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16
@ -121,7 +119,7 @@ Uint8 opr[][2] = {
int int
haltuxn(Uxn *u, char *name, int id) haltuxn(Uxn *u, char *name, int id)
{ {
printf("Error: %s#%04x, at 0x%04x\n", name, id, u->counter); printf("Halted: %s#%04x, at 0x%04x\n", name, id, u->counter);
return 0; return 0;
} }
@ -142,6 +140,8 @@ opcuxn(Uxn *u, Uint8 instr)
setflag(&u->status, FLAG_SHORT, (instr >> 5) & 1); setflag(&u->status, FLAG_SHORT, (instr >> 5) & 1);
setflag(&u->status, FLAG_SIGN, (instr >> 6) & 1); setflag(&u->status, FLAG_SIGN, (instr >> 6) & 1);
setflag(&u->status, FLAG_COND, (instr >> 7) & 1); setflag(&u->status, FLAG_COND, (instr >> 7) & 1);
if((op == 0x09 || op == 0x0b) && u->balance)
return haltuxn(u, "Stack unbalance", op);
if(getflag(&u->status, FLAG_SHORT)) if(getflag(&u->status, FLAG_SHORT))
op += 32; op += 32;
if(u->wst.ptr < opr[op][0]) if(u->wst.ptr < opr[op][0])
@ -192,7 +192,7 @@ loaduxn(Uxn *u, char *filepath)
{ {
FILE *f; FILE *f;
if(!(f = fopen(filepath, "rb"))) if(!(f = fopen(filepath, "rb")))
return haltuxn(u, "Missing input.", 0); return haltuxn(u, "Missing input rom.", 0);
fread(u->ram.dat, sizeof(u->ram.dat), 1, f); fread(u->ram.dat, sizeof(u->ram.dat), 1, f);
u->devr = 0xfff8; u->devr = 0xfff8;
u->devw = 0xfff9; u->devw = 0xfff9;
@ -213,7 +213,7 @@ portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn
Device *d = &u->dev[u->devices++]; Device *d = &u->dev[u->devices++];
d->read = rfn; d->read = rfn;
d->write = wfn; d->write = wfn;
d->len = 0; d->ptr = 0;
printf("Device #%d: %s \n", u->devices - 1, name); printf("Device #%d: %s \n", u->devices - 1, name);
return d; return d;
} }

6
uxn.h
View File

@ -24,7 +24,7 @@ typedef signed short Sint16;
typedef struct { typedef struct {
Uint8 ptr; Uint8 ptr;
Uint8 dat[256]; Uint8 dat[256];
} St8; } Stack;
typedef struct { typedef struct {
Uint16 ptr; Uint16 ptr;
@ -32,7 +32,7 @@ typedef struct {
} Memory; } Memory;
typedef struct Device { typedef struct Device {
Uint8 len, mem[8]; Uint8 ptr, mem[8];
Uint8 (*read)(struct Device *, Memory *, Uint8); Uint8 (*read)(struct Device *, Memory *, Uint8);
Uint8 (*write)(struct Device *, Memory *, Uint8); Uint8 (*write)(struct Device *, Memory *, Uint8);
} Device; } Device;
@ -40,7 +40,7 @@ typedef struct Device {
typedef struct { typedef struct {
Uint8 literal, status, balance, devices; Uint8 literal, status, balance, devices;
Uint16 counter, devr, devw, vreset, vframe, verror; Uint16 counter, devr, devw, vreset, vframe, verror;
St8 wst, rst; Stack wst, rst;
Memory ram; Memory ram;
Device dev[256]; Device dev[256];
} Uxn; } Uxn;