From f953c1d4335dfc861d05b2287f228c9ac21f07f8 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 8 May 2012 20:37:03 +0000 Subject: reduce number of global vars --- dcpu16.h | 26 ++++----- emu.c | 192 +++++++++++++++++++++++++++++++-------------------------------- gramar.y | 13 ++--- gui.c | 16 +++--- main.c | 21 +++---- tui.c | 83 +++++++++++++++------------ 6 files changed, 176 insertions(+), 175 deletions(-) diff --git a/dcpu16.h b/dcpu16.h index 4f3522a..084ca22 100644 --- a/dcpu16.h +++ b/dcpu16.h @@ -44,14 +44,6 @@ enum { NOP, JSR, BRK, #define KEYB 0x9000 #define KEYP 0x9010 -struct device { - unsigned int id; - unsigned int version; - unsigned int manufacturer; - void (*cb)(unsigned short *); - struct device *next; -}; - struct context { unsigned short mem[MEMSZ]; unsigned short reg[nReg]; @@ -59,12 +51,20 @@ struct context { int ndev; }; +struct device { + unsigned int id; + unsigned int version; + unsigned int manufacturer; + void (*cb)(struct context *); + struct device *next; +}; + /* display: 32x12 (128x96) + 16 pixel boarder, font 8x4 */ -unsigned short *compile(FILE *, size_t); -int step(unsigned short *, unsigned short *); -void tuiemu(unsigned short *, unsigned short *); -void guiemu(unsigned short *, unsigned short *); -void dumpcode(unsigned short *, unsigned short *); +int compile(FILE *, unsigned short *, size_t); +int step(struct context *); +void tuiemu(struct context *); +void guiemu(struct context *); +void dumpcode(struct context *); #endif diff --git a/emu.c b/emu.c index 5c6d1b9..1f1df17 100644 --- a/emu.c +++ b/emu.c @@ -20,101 +20,98 @@ #include #include "dcpu16.h" -static unsigned short *mem; -static unsigned short *reg; - static unsigned short skip = 0; static unsigned short run = 1; static unsigned short cycle = 0; static int errors = 0; void -nop(unsigned short *a) +nop(struct context *c, unsigned short *a) { cycle += 1; } void -jsr(unsigned short *a) +jsr(struct context *c, unsigned short *a) { - mem[--reg[SP]] = reg[PC]; - reg[PC] = *a; + c->mem[--c->reg[SP]] = c->reg[PC]; + c->reg[PC] = *a; cycle += 3; } void -stop(unsigned short *a) +stop(struct context *c, unsigned short *a) { run = 0; cycle += 1; } void -hcf(unsigned short *a) +hcf(struct context *c, unsigned short *a) { /* TODO: halt catch fire */ cycle += 9; } void -intr(unsigned short *a) +intr(struct context *c, unsigned short *a) { /* TODO */ cycle += 4; } void -iag(unsigned short *a) +iag(struct context *c, unsigned short *a) { - *a = reg[IA]; + *a = c->reg[IA]; cycle += 1; } void -ias(unsigned short *a) +ias(struct context *c, unsigned short *a) { - reg[IA] = *a; + c->reg[IA] = *a; cycle += 1; } void -rfi(unsigned short *a) +rfi(struct context *c, unsigned short *a) { /* TODO */ - *a = mem[reg[SP]++]; - reg[PC] = mem[reg[SP]++]; + *a = c->mem[c->reg[SP]++]; + c->reg[PC] = c->mem[c->reg[SP]++]; cycle += 3; } void -iaq(unsigned short *a) +iaq(struct context *c, unsigned short *a) { /* TODO */ cycle += 2; } void -hwn(unsigned short *a) +hwn(struct context *c, unsigned short *a) { /* TODO */ cycle += 2; } void -hwq(unsigned short *a) +hwq(struct context *c, unsigned short *a) { /* TODO */ cycle += 4; } void -hwi(unsigned short *a) +hwi(struct context *c, unsigned short *a) { /* TODO */ cycle += 4; } -void (*extop[nExt])(unsigned short *) = { +void (*extop[nExt])(struct context *, unsigned short *) = { [NOP] = nop, [JSR] = jsr, [BRK] = stop, @@ -130,10 +127,10 @@ void (*extop[nExt])(unsigned short *) = { }; void -ext(unsigned short *b, unsigned short *a) +ext(struct context *c, unsigned short *b, unsigned short *a) { if (extop[*b]) - extop[*b](a); + extop[*b](c, a); else { warnx("wrong extended opcode 0x%x (0x%x)", *b, *a); ++errors; @@ -141,85 +138,85 @@ ext(unsigned short *b, unsigned short *a) } void -set(unsigned short *b, unsigned short *a) +set(struct context *c, unsigned short *b, unsigned short *a) { *b = *a; cycle += 1; } void -add(unsigned short *b, unsigned short *a) +add(struct context *c, unsigned short *b, unsigned short *a) { int tmp = *b + *a; - reg[EX] = tmp >> 16; + c->reg[EX] = tmp >> 16; *b = tmp; cycle += 2; } void -sub(unsigned short *b, unsigned short *a) +sub(struct context *c, unsigned short *b, unsigned short *a) { int tmp = *b - *a; - reg[EX] = tmp >> 16; + c->reg[EX] = tmp >> 16; *b = tmp; cycle += 2; } void -mul(unsigned short *b, unsigned short *a) +mul(struct context *c, unsigned short *b, unsigned short *a) { int tmp = *b * *a; - reg[EX] = tmp >> 16; + c->reg[EX] = tmp >> 16; *b = tmp; cycle += 2; } void -mli(unsigned short *b, unsigned short *a) +mli(struct context *c, unsigned short *b, unsigned short *a) { int tmp = (signed short)*b * (signed short)*b; - reg[EX] = tmp >> 16; + c->reg[EX] = tmp >> 16; *b = tmp; cycle += 2; } void -div(unsigned short *b, unsigned short *a) +div(struct context *c, unsigned short *b, unsigned short *a) { int tmp; if (*a == 0) { - reg[EX] = 0; + c->reg[EX] = 0; *b = 0; } else { tmp = ((unsigned int)*b << 16) / *a; - reg[EX] = tmp; + c->reg[EX] = tmp; *b = tmp >> 16; } cycle += 3; } void -dvi(unsigned short *b, unsigned short *a) +dvi(struct context *c, unsigned short *b, unsigned short *a) { int tmp; if (*a == 0) { - reg[EX] = 0; + c->reg[EX] = 0; *b = 0; } else { tmp = ((signed int)*b << 16) / (signed short)*a; - reg[EX] = tmp; + c->reg[EX] = tmp; *b = tmp >> 16; } cycle += 3; } void -mod(unsigned short *b, unsigned short *a) +mod(struct context *c, unsigned short *b, unsigned short *a) { if (*a == 0) *b = 0; @@ -229,7 +226,7 @@ mod(unsigned short *b, unsigned short *a) } void -mdi(unsigned short *b, unsigned short *a) +mdi(struct context *c, unsigned short *b, unsigned short *a) { /* TODO */ if (*a == 0) @@ -240,146 +237,145 @@ mdi(unsigned short *b, unsigned short *a) } void -and(unsigned short *b, unsigned short *a) +and(struct context *c, unsigned short *b, unsigned short *a) { *b &= *a; cycle += 1; } void -bor(unsigned short *b, unsigned short *a) +bor(struct context *c, unsigned short *b, unsigned short *a) { *b |= *a; cycle += 1; } void -xor(unsigned short *b, unsigned short *a) +xor(struct context *c, unsigned short *b, unsigned short *a) { *b ^= *a; cycle += 1; } void -shr(unsigned short *b, unsigned short *a) +shr(struct context *c, unsigned short *b, unsigned short *a) { - reg[EX] = (((unsigned int)*b << 16) >> *a); + c->reg[EX] = (((unsigned int)*b << 16) >> *a); *b >>= *a; cycle += 1; } void -asr(unsigned short *b, unsigned short *a) +asr(struct context *c, unsigned short *b, unsigned short *a) { - reg[EX] = (((unsigned int)*b << 16) >> *a); + c->reg[EX] = (((unsigned int)*b << 16) >> *a); *b = (signed short)*b >> *a; cycle += 1; } void -shl(unsigned short *b, unsigned short *a) +shl(struct context *c, unsigned short *b, unsigned short *a) { - reg[EX] = (((unsigned int)*b << *a) >> 16); + c->reg[EX] = (((unsigned int)*b << *a) >> 16); *b <<= *a; cycle += 1; } void -ifb(unsigned short *b, unsigned short *a) +ifb(struct context *c, unsigned short *b, unsigned short *a) { skip = !(*b & *a); cycle += 2 + skip; } void -ifc(unsigned short *b, unsigned short *a) +ifc(struct context *c, unsigned short *b, unsigned short *a) { skip = (*b & *a); cycle += 2 + skip; } void -ife(unsigned short *b, unsigned short *a) +ife(struct context *c, unsigned short *b, unsigned short *a) { skip = !(*b == *a); cycle += 2 + skip; } void -ifn(unsigned short *b, unsigned short *a) +ifn(struct context *c, unsigned short *b, unsigned short *a) { skip = (*b == *a); cycle += 2 + skip; } void -ifg(unsigned short *b, unsigned short *a) +ifg(struct context *c, unsigned short *b, unsigned short *a) { skip = !(*b > *a); cycle += 2 + skip; } void -ifa(unsigned short *b, unsigned short *a) +ifa(struct context *c, unsigned short *b, unsigned short *a) { skip = !((signed short)*b > (signed short)*a); cycle += 2 + skip; } void -ifl(unsigned short *b, unsigned short *a) +ifl(struct context *c, unsigned short *b, unsigned short *a) { skip = !(*b < *a); cycle += 2 + skip; } void -ifu(unsigned short *b, unsigned short *a) +ifu(struct context *c, unsigned short *b, unsigned short *a) { skip = !((signed short)*b < (signed short)*a); cycle += 2 + skip; } void -adx(unsigned short *b, unsigned short *a) +adx(struct context *c, unsigned short *b, unsigned short *a) { - int tmp = *b + *a + reg[EX]; + int tmp = *b + *a + c->reg[EX]; - reg[EX] = tmp > 16; + c->reg[EX] = tmp > 16; *b = tmp; cycle += 3; } void -sbx(unsigned short *b, unsigned short *a) +sbx(struct context *c, unsigned short *b, unsigned short *a) { - int tmp = *b - *a + reg[EX]; + int tmp = *b - *a + c->reg[EX]; - reg[EX] = tmp >> 16; + c->reg[EX] = tmp >> 16; *b = tmp; cycle += 3; } - void -sti(unsigned short *b, unsigned short *a) +sti(struct context *c, unsigned short *b, unsigned short *a) { *b = *a; - ++reg[I]; - ++reg[J]; + ++c->reg[I]; + ++c->reg[J]; cycle += 2; } void -std(unsigned short *b, unsigned short *a) +std(struct context *c, unsigned short *b, unsigned short *a) { *b = *a; - --reg[I]; - --reg[J]; + --c->reg[I]; + --c->reg[J]; cycle += 2; } -void (*op[nOpt])(unsigned short *, unsigned short *) = { +void (*op[nOpt])(struct context *, unsigned short *, unsigned short *) = { [EXT] = ext, [SET] = set, [ADD] = add, @@ -412,7 +408,7 @@ void (*op[nOpt])(unsigned short *, unsigned short *) = { }; unsigned short * -fetcharg(int a, int barg) +fetcharg(struct context *c, int a, int barg) { switch (a) { case 0x00: @@ -424,7 +420,7 @@ fetcharg(int a, int barg) case 0x06: case 0x07: /* register */ - return ®[a]; + return &c->reg[a]; case 0x08: case 0x09: case 0x0a: @@ -434,7 +430,7 @@ fetcharg(int a, int barg) case 0x0e: case 0x0f: /* [register] */ - return &mem[reg[a - 0x08]]; + return &c->mem[c->reg[a - 0x08]]; case 0x10: case 0x11: case 0x12: @@ -445,69 +441,67 @@ fetcharg(int a, int barg) case 0x17: /* [next word + register] */ cycle += 1; - return &mem[mem[reg[PC]++] + reg[a - 0x10]]; + return &c->mem[c->mem[c->reg[PC]++] + c->reg[a - 0x10]]; case 0x18: /* TODO push or pop */ if (barg) - return &mem[--reg[SP]]; /* push */ + return &c->mem[--c->reg[SP]]; /* push */ else - return &mem[reg[SP]++]; /* pop */ + return &c->mem[c->reg[SP]++]; /* pop */ case 0x19: /* peek */ - return &mem[reg[SP]]; + return &c->mem[c->reg[SP]]; case 0x1a: /* pick */ - return &mem[reg[SP] + reg[PC]++]; + return &c->mem[c->reg[SP] + c->reg[PC]++]; case 0x1b: /* SP */ - return ®[SP]; + return &c->reg[SP]; case 0x1c: /* PC */ - return ®[PC]; + return &c->reg[PC]; case 0x1d: /* EX */ - return ®[EX]; + return &c->reg[EX]; case 0x1e: /* [next word] */ cycle += 1; - return &mem[mem[reg[PC]++]]; + return &c->mem[c->mem[c->reg[PC]++]]; case 0x1f: /* next word */ cycle += 1; - return &mem[reg[PC]++]; + return &c->mem[c->reg[PC]++]; default: /* literal */ - reg[Aux] = a - 0x20 - 1; - return ®[Aux]; + c->reg[Aux] = a - 0x20 - 1; + return &c->reg[Aux]; } } int -step(unsigned short *m, unsigned short *r) +step(struct context *c) { - unsigned short c, o, *a, *b, s, tmp; + unsigned short ch, o, *a, *b, s, tmp; if (!run || errors > 3) return -1; - mem = m; - reg = r; cycle = 0; - c = mem[reg[PC]++]; - s = reg[SP]; /* store SP */ + ch = c->mem[c->reg[PC]++]; + s = c->reg[SP]; /* store SP */ - o = c & 0x1f; - a = fetcharg((c >> 10) & 0x3f, 0); - tmp = (c >> 5) & 0x1f; - b = o ? fetcharg(tmp, 1) : &tmp; + o = ch & 0x1f; + a = fetcharg(c, (ch >> 10) & 0x3f, 0); + tmp = (ch >> 5) & 0x1f; + b = o ? fetcharg(c, tmp, 1) : &tmp; if (skip) { skip = 0; - reg[SP] = s; /* restore SP on skipped opcode */ + c->reg[SP] = s; /* restore SP on skipped opcode */ } else { if (op[o]) - op[o](b, a); + op[o](c, b, a); else { warnx("wrong opcode 0x%x (0x%x, 0x%x)", o, *b, *a); ++errors; diff --git a/gramar.y b/gramar.y index e4ac0ea..853d486 100644 --- a/gramar.y +++ b/gramar.y @@ -344,10 +344,10 @@ restorerefs(void) buffer[i] = findref(&label[i]); } -unsigned short * -compile(FILE *fd, size_t sz) +int +compile(FILE *fd, unsigned short *mem, size_t sz) { - buffer = calloc(sz, sizeof(unsigned short)); + buffer = mem; label = calloc(sz, sizeof(struct label)); stack = calloc(sz, sizeof(struct pair)); ref = calloc(sz, sizeof(struct pair)); @@ -364,10 +364,5 @@ compile(FILE *fd, size_t sz) free(stack); free(label); - if (haserrors) { - free(buffer); - buffer = NULL; - } - - return buffer; + return haserrors; } diff --git a/gui.c b/gui.c index 4879581..8e6be46 100644 --- a/gui.c +++ b/gui.c @@ -172,9 +172,9 @@ loadfont(unsigned short *m, char *font) } void -guiemu(unsigned short *m, unsigned short *r) +guiemu(struct context *c) { - int x, y, c, n = 0; + int x, y, cnt, n = 0; screen = SDL_SetVideoMode(real.w, real.h, 8, SDL_HWSURFACE|SDL_HWPALETTE); SDL_SetColors(screen, color, 0, 16); @@ -184,10 +184,10 @@ guiemu(unsigned short *m, unsigned short *r) atexit(SDL_Quit); - loadfont(m, "font.xpm"); + loadfont(c->mem, "font.xpm"); - while ((c = step(m, r)) != -1) { - if ((n += c) < 100) + while ((cnt = step(c)) != -1) { + if ((n += cnt) < 100) continue; n = 0; @@ -195,11 +195,11 @@ guiemu(unsigned short *m, unsigned short *r) if (SDL_MUSTLOCK(screen) && SDL_LockSurface(screen)) continue; - SDL_FillRect(scratch, &scr, m[BORDER] & 0x0f); + SDL_FillRect(scratch, &scr, c->mem[BORDER] & 0x0f); for (x = 0; x < 32; x++) for (y = 0; y < 12; y++) - drawglyph(scratch, x, y, m); + drawglyph(scratch, x, y, c->mem); SDL_SoftStretch(scratch, &scr, screen, &real); @@ -208,7 +208,7 @@ guiemu(unsigned short *m, unsigned short *r) if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); - if (keyboard(m) == -1) + if (keyboard(c->mem) == -1) break; } diff --git a/main.c b/main.c index 7f43556..af1538b 100644 --- a/main.c +++ b/main.c @@ -18,25 +18,26 @@ #include #include #include +#include #include #include "dcpu16.h" -void (*emu)(unsigned short *, unsigned short *); +void (*emu)(struct context *); void -dumpcode(unsigned short *m, unsigned short *r) +dumpcode(struct context *c) { int i, k, sum; for (i = 0; i < MEMSZ; i += 8) { sum = 0; for (k = 0; k < 8; k++) - sum += m[i + k]; + sum += c->mem[i + k]; if (!sum) continue; printf("%4.4x:", i); for (k = 0; k < 8; k++) - printf("%5.4x", m[i + k]); + printf("%5.4x", c->mem[i + k]); printf("\n"); } } @@ -53,8 +54,7 @@ usage(void) int main(int argc, char **argv) { - unsigned short *m; - unsigned short r[nReg] = { 0 }; + struct context c; FILE *fd; int ch; @@ -83,12 +83,13 @@ main(int argc, char **argv) if (!fd) err(1, "cannot open file"); - m = compile(fd, MEMSZ); - fclose(fd); - if (!m) + bzero(&c, sizeof(c)); + if (compile(fd, c.mem, MEMSZ)) errx(1, "compilation errors"); - emu(m, r); + fclose(fd); + + emu(&c); return 0; } diff --git a/tui.c b/tui.c index 6e487d7..39b2b83 100644 --- a/tui.c +++ b/tui.c @@ -26,7 +26,7 @@ WINDOW *outbox, *out, *regbox, *regs, *code; void -dumpmem(unsigned short *m) +dumpmem(struct context *c) { int i, k, sum, lines = 0; @@ -34,14 +34,14 @@ dumpmem(unsigned short *m) for (lines = 0, i = 0; i < MEMSZ; i += 8) { for (sum = 0, k = 0; k < 8; k++) - sum |= m[i + k]; + sum |= c->mem[i + k]; if (!sum) continue; if (++lines > 24) break; wprintw(code, "%4.4x:", i); for (k = 0; k < 8; k++) - wprintw(code, "%5.4x", m[i + k]); + wprintw(code, "%5.4x", c->mem[i + k]); wprintw(code, "\n"); } @@ -49,33 +49,33 @@ dumpmem(unsigned short *m) } void -dumpdisp(unsigned short *m) +dumpdisp(struct context *c) { int i; - char c, b, hbg, bg, hfg, fg, col; + char ch, b, hbg, bg, hfg, fg, col; wmove(out, 0, 0); for (i = DISP; i < DISPEND; i++) { - c = m[i] & 0x7f; + ch = c->mem[i] & 0x7f; - b = (m[i] >> 7) & 0x01; - bg = (m[i] >> 8) & 0x07; - hbg = (m[i] >> 11) & 0x01; - fg = (m[i] >> 12) & 0x07; - hfg = (m[i] >> 15) & 0x01; + b = (c->mem[i] >> 7) & 0x01; + bg = (c->mem[i] >> 8) & 0x07; + hbg = (c->mem[i] >> 11) & 0x01; + fg = (c->mem[i] >> 12) & 0x07; + hfg = (c->mem[i] >> 15) & 0x01; col = (fg << 3) | bg; - if (!(isascii(c) && isprint(c))) - c = ' '; + if (!(isascii(ch) && isprint(ch))) + ch = ' '; if (b) wattron(out, A_BLINK); if (hfg) wattron(out, A_BOLD); wattron(out, COLOR_PAIR(col)); - waddch(out, c); + waddch(out, ch); wattroff(out, COLOR_PAIR(col)); if (hfg) wattroff(out, A_BOLD); @@ -87,24 +87,35 @@ dumpdisp(unsigned short *m) } void -dumpreg(unsigned short *mem, unsigned short *reg) +dumpreg(struct context *c) { wmove(regs, 0, 0); - mvwprintw(regs, 0, 0, " A: %4.4x [%4.4x]", reg[A], mem[reg[A]]); - mvwprintw(regs, 1, 0, " B: %4.4x [%4.4x]", reg[B], mem[reg[B]]); - mvwprintw(regs, 2, 0, " C: %4.4x [%4.4x]", reg[C], mem[reg[C]]); + mvwprintw(regs, 0, 0, " A: %4.4x [%4.4x]", + c->reg[A], c->mem[c->reg[A]]); + mvwprintw(regs, 1, 0, " B: %4.4x [%4.4x]", + c->reg[B], c->mem[c->reg[B]]); + mvwprintw(regs, 2, 0, " C: %4.4x [%4.4x]", + c->reg[C], c->mem[c->reg[C]]); - mvwprintw(regs, 3, 0, " X: %4.4x [%4.4x]", reg[X], mem[reg[X]]); - mvwprintw(regs, 4, 0, " Y: %4.4x [%4.4x]", reg[Y], mem[reg[Y]]); - mvwprintw(regs, 5, 0, " Z: %4.4x [%4.4x]", reg[Z], mem[reg[Z]]); - - mvwprintw(regs, 6, 0, " I: %4.4x [%4.4x]", reg[I], mem[reg[I]]); - mvwprintw(regs, 7, 0, " J: %4.4x [%4.4x]", reg[J], mem[reg[J]]); - - mvwprintw(regs, 0, 16, "PC: %4.4x [%4.4x]", reg[PC], mem[reg[PC]]); - mvwprintw(regs, 1, 16, "SP: %4.4x [%4.4x]", reg[SP], mem[reg[SP]]); - mvwprintw(regs, 2, 16, "EX: %4.4x [%4.4x]", reg[EX], mem[reg[EX]]); + mvwprintw(regs, 3, 0, " X: %4.4x [%4.4x]", + c->reg[X], c->mem[c->reg[X]]); + mvwprintw(regs, 4, 0, " Y: %4.4x [%4.4x]", + c->reg[Y], c->mem[c->reg[Y]]); + mvwprintw(regs, 5, 0, " Z: %4.4x [%4.4x]", + c->reg[Z], c->mem[c->reg[Z]]); + + mvwprintw(regs, 6, 0, " I: %4.4x [%4.4x]", + c->reg[I], c->mem[c->reg[I]]); + mvwprintw(regs, 7, 0, " J: %4.4x [%4.4x]", + c->reg[J], c->mem[c->reg[J]]); + + mvwprintw(regs, 0, 16, "PC: %4.4x [%4.4x]", + c->reg[PC], c->mem[c->reg[PC]]); + mvwprintw(regs, 1, 16, "SP: %4.4x [%4.4x]", + c->reg[SP], c->mem[c->reg[SP]]); + mvwprintw(regs, 2, 16, "EX: %4.4x [%4.4x]", + c->reg[EX], c->mem[c->reg[EX]]); wnoutrefresh(regs); } @@ -125,7 +136,7 @@ init_colors() } void -tuiemu(unsigned short *m, unsigned short *r) +tuiemu(struct context *c) { int ch; @@ -149,16 +160,16 @@ tuiemu(unsigned short *m, unsigned short *r) code = derwin(stdscr, 24, 46, 0, 0); - m[KEYP] = KEYB; + c->mem[KEYP] = KEYB; - while (step(m, r) != -1) { - dumpmem(m); - dumpdisp(m); - dumpreg(m, r); + while (step(c) != -1) { + dumpmem(c); + dumpdisp(c); + dumpreg(c); if ((ch = wgetch(stdscr)) != ERR) { - m[m[KEYP]] = ch; - m[KEYP] = KEYB + (m[KEYP] + 1) % 0x10; + c->mem[c->mem[KEYP]] = ch; + c->mem[KEYP] = KEYB + (c->mem[KEYP] + 1) % 0x10; } doupdate(); -- cgit v1.2.3