uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit f377bdf59c5f03452b165204623cb1bb67c2a18b
parent 14cd9e03c44fa3e1d736f1d2d1c5fa9b97222218
Author: neauoire <aliceffekt@gmail.com>
Date:   Mon, 15 Feb 2021 10:12:44 -0800

Added debugger

Diffstat:
Memulator.c | 107++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mexamples/test.usm | 1-
Muxn.c | 32++++++++++++++++----------------
Muxn.h | 6+++---
4 files changed, 73 insertions(+), 73 deletions(-)

diff --git a/emulator.c b/emulator.c @@ -23,7 +23,7 @@ typedef unsigned char Uint8; int WIDTH = 8 * HOR + 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[] = { 0x000000, @@ -32,6 +32,24 @@ Uint32 theme[] = { 0x666666, 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_Renderer *gRenderer; SDL_Texture *gTexture; @@ -90,12 +108,35 @@ error(char *msg, const char *err) } 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_RenderClear(gRenderer); SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); SDL_RenderPresent(gRenderer); + REQDRAW = 0; } void @@ -133,43 +174,6 @@ init(void) } 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 domouse(SDL_Event *event) { int x = event->motion.x / ZOOM; @@ -242,15 +246,15 @@ screenr(Device *d, Memory *m, Uint8 b) Uint8 screenw(Device *d, Memory *m, Uint8 b) { - d->mem[d->len++] = b; - if(d->len > 5) { + d->mem[d->ptr++] = b; + if(d->ptr > 5) { putpixel(pixels, (d->mem[2] << 8) + d->mem[3], (d->mem[0] << 8) + d->mem[1], d->mem[4]); if(d->mem[5]) - redraw(pixels); - d->len = 0; + REQDRAW = 1; + d->ptr = 0; } (void)m; return 0; @@ -259,15 +263,15 @@ screenw(Device *d, Memory *m, Uint8 b) Uint8 spritew(Device *d, Memory *m, Uint8 b) { - d->mem[d->len++] = b; - if(d->len > 6) { + d->mem[d->ptr++] = b; + if(d->ptr > 6) { Uint16 x = (d->mem[2] << 8) + d->mem[3]; Uint16 y = (d->mem[0] << 8) + d->mem[1]; Uint8 *chr = &m->dat[(d->mem[4] << 8) + d->mem[5]]; drawchr(pixels, x, y, chr); if(d->mem[6]) - redraw(pixels); - d->len = 0; + REQDRAW = 1; + d->ptr = 0; } return 0; } @@ -279,11 +283,6 @@ start(Uxn *u) { int ticknext = 0; evaluxn(u, u->vreset); - - echos(&u->wst, 0x40, "stack"); - echom(&u->ram, 0x40, "ram"); - echof(u); - while(1) { int tick = SDL_GetTicks(); SDL_Event event; @@ -300,11 +299,13 @@ start(Uxn *u) case SDL_KEYUP: doctrl(&event, 0); break; case SDL_WINDOWEVENT: if(event.window.event == SDL_WINDOWEVENT_EXPOSED) - redraw(pixels); + redraw(pixels, u); break; } } evaluxn(u, u->vframe); + if(REQDRAW) + redraw(pixels, u); } } diff --git a/examples/test.usm b/examples/test.usm @@ -8,7 +8,6 @@ |0100 @RESET #12 #34 WSR2 - RSW2 ,test JSR BRK diff --git a/uxn.c b/uxn.c @@ -18,21 +18,19 @@ WITH REGARD TO THIS SOFTWARE. /* clang-format off */ void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *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; } 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); } 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; } -Uint8 pop8(St8 *s) { return s->dat[--s->ptr]; } -Uint8 peek8(St8 *s, Uint8 a) { return s->dat[s->ptr - a - 1]; } -void push16(St8 *s, Uint16 a) { push8(s, a >> 8); push8(s, a); } -Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); } -Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); } +void push8(Stack *s, Uint8 a) { s->dat[s->ptr++] = a; } +Uint8 pop8(Stack *s) { return s->dat[--s->ptr]; } +Uint8 peek8(Stack *s, Uint8 a) { return s->dat[s->ptr - a - 1]; } +void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); } +Uint16 pop16(Stack *s) { return pop8(s) + (pop8(s) << 8); } +Uint16 peek16(Stack *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); } /* I/O */ void op_brk(Uxn *u) { setflag(&u->status, FLAG_HALT, 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_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); } @@ -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); } /* Logic */ 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_rts(Uxn *u) { if(u->balance > 0){ warn("Stack unbalance", u->balance); } u->ram.ptr = pop16(&u->rst); } +void op_jsr(Uxn *u) { push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst); } +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_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); } @@ -93,13 +91,13 @@ 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 (*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_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, /* 16-bit */ - op_brk, op_nop16, op_lit16, op_lix, 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_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_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 }; @@ -121,7 +119,7 @@ Uint8 opr[][2] = { int 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; } @@ -142,6 +140,8 @@ opcuxn(Uxn *u, Uint8 instr) setflag(&u->status, FLAG_SHORT, (instr >> 5) & 1); setflag(&u->status, FLAG_SIGN, (instr >> 6) & 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)) op += 32; if(u->wst.ptr < opr[op][0]) @@ -192,7 +192,7 @@ loaduxn(Uxn *u, char *filepath) { FILE *f; 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); u->devr = 0xfff8; 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++]; d->read = rfn; d->write = wfn; - d->len = 0; + d->ptr = 0; printf("Device #%d: %s \n", u->devices - 1, name); return d; } diff --git a/uxn.h b/uxn.h @@ -24,7 +24,7 @@ typedef signed short Sint16; typedef struct { Uint8 ptr; Uint8 dat[256]; -} St8; +} Stack; typedef struct { Uint16 ptr; @@ -32,7 +32,7 @@ typedef struct { } Memory; typedef struct Device { - Uint8 len, mem[8]; + Uint8 ptr, mem[8]; Uint8 (*read)(struct Device *, Memory *, Uint8); Uint8 (*write)(struct Device *, Memory *, Uint8); } Device; @@ -40,7 +40,7 @@ typedef struct Device { typedef struct { Uint8 literal, status, balance, devices; Uint16 counter, devr, devw, vreset, vframe, verror; - St8 wst, rst; + Stack wst, rst; Memory ram; Device dev[256]; } Uxn;