From: Justin Wind Date: Tue, 10 Apr 2012 19:08:32 +0000 (-0700) Subject: actually commit minor cleanups X-Git-Url: https://git.squeep.com/?a=commitdiff_plain;h=95ed7334e5fb35010f287765161fcff1efa69758;p=dcpu16 actually commit minor cleanups hah, still acclimating to git --- diff --git a/Makefile b/Makefile index f3324ef..78f7941 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ #!make # -PROGRAMS = dcpu16 +PROGRAMS = dcpu16 as-dcpu16 CFLAGS = -g -Wall -Wextra -pedantic -std=c99 LDFLAGS = diff --git a/as-dcpu16.h b/as-dcpu16.h index 68bf54e..3b11d85 100644 --- a/as-dcpu16.h +++ b/as-dcpu16.h @@ -7,26 +7,15 @@ struct instruction_ { char *label; /* set if a label points here */ char *opcode; /* tokenized instruction text */ struct operand_ *operands; /* list of operands */ - unsigned int length; /* words */ unsigned int ready : 1; /* bytecode computed? */ + unsigned int length; /* number of words of bytecode */ DCPU16_WORD instr_words[]; }; -enum operand_types_{ - OT_DIRECT, /* these operands simply render their contents into bytecode */ - OT_NEXT, /* these operands increase instruction length */ - OT_LABEL /* labels need to be computed then converted to other types */ -}; - struct operand_ { struct operand_ *next; char *operand; /* tokenized operand text */ - enum operand_types_ type; - union { - DCPU16_WORD word_value; - struct instruction_ *label_destination; - } value; }; @@ -39,10 +28,12 @@ struct instruction_list_ { }; -/* note label table holds its own structs, not pointers */ +/* note label table holds its own structs, not pointers like instruction list */ struct label_ { char *label; /* name of label */ - struct instruction_ *instr; + struct instruction_ **instr; /* pointer into instruction list table */ + unsigned int ready : 1; /* do we know where this label is yet? */ + DCPU16_WORD addr; }; #define LL_SIZE(entries) (((entries) * sizeof(struct label_ *)) + sizeof(struct label_list_)) diff --git a/dcpu16.c b/dcpu16.c index d0d3b40..26c594e 100644 --- a/dcpu16.c +++ b/dcpu16.c @@ -17,9 +17,12 @@ * Justin Wind * 2012 04 05 - implementation started * 2012 04 06 - first functionality achieved + * 2012 04 09 - minor cleanups * * TODO * move cli driver to separate module + * drop checks for assigning to literals -- it won't affect anything anyhow + * debug short literal decoding */ static const char * const src_id_ = "$Id$"; @@ -37,16 +40,17 @@ struct dcpu16 { WORD pc; /* program counter */ WORD sp; /* stack pointer */ WORD o; /* overflow */ - unsigned int skip_ : 1; /* */ + unsigned int skip_ : 1; /* skip execution of next instruction */ WORD ram[RAM_SIZE]; /* memory */ }; -static unsigned int trace_mode_ = 0; /* turn on for overly verbose internals */ +static unsigned int trace_mode_ = 0; /* spew overly verbose internals */ -#define WARN(...) warn(__VA_ARGS__) -static inline void warn(char *fmt, ...) __attribute__((format(printf, 1, 2))); -static inline void warn(char *fmt, ...) { +#define WARN(...) do { if (warn_cb_) warn_cb_(__VA_ARGS__); } while (0) +static inline void warn_(char *fmt, ...) __attribute__((format(printf, 1, 2))); +static inline +void warn_(char *fmt, ...) { va_list ap; fprintf(stderr, "!!! "); @@ -56,12 +60,15 @@ static inline void warn(char *fmt, ...) { fprintf(stderr, "\n"); fflush(stderr); } +static void (*warn_cb_)(char *fmt, ...) = warn_; +void dcpu16_warn_cb_set(void (*fn)(char *fmt, ...)) { + warn_cb_ = fn; +} - -#define TRACE(...) do { if (trace_mode_) trace(__VA_ARGS__); } while (0) -static inline void trace(char *fmt, ...) __attribute__((format(printf, 1, 2))); +#define TRACE(...) do { if (trace_cb_ && trace_mode_) trace_cb_(__VA_ARGS__); } while (0) +static inline void trace_(char *fmt, ...) __attribute__((format(printf, 1, 2))); static inline -void trace(char *fmt, ...) { +void trace_(char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -70,6 +77,11 @@ void trace(char *fmt, ...) { fprintf(stdout, "\n"); fflush(stdout); } +static void (*trace_cb_)(char *fmt, ...) = trace_; +void dcpu16_trace_cb_set(void (*fn)(char *fmt, ...)) { + trace_cb_ = fn; +} + /* sets *v to be the destination of the value */ @@ -79,7 +91,7 @@ static unsigned int value_decode(struct dcpu16 *d, WORD value, WORD *work_v, WOR WORD nextword; unsigned int retval = 0; - assert(value >= 0x00 && value <= 0x3f); + assert(value <= 0x3f); /* does this value indicate a literal */ if (value >= 0x1f) @@ -200,12 +212,11 @@ struct opcode_entry { #define OP_IMPL(x) static void op_##x(struct dcpu16 *d, WORD val_a, WORD val_b) -#define OP_NBI_ (void)val_b +#define OP_NBI_ (void)val_b, (void)b #define OP_BASIC_ (void)value_decode(d, val_b, &d->reg_work_[0], &b) #define OP_TYPE(op_type) WORD *a, *b;\ unsigned int lit_a;\ do {\ - assert(d != NULL);\ lit_a = value_decode(d, val_a, &d->reg_work_[0], &a);\ op_type;\ if (d->skip_) {\ @@ -214,33 +225,8 @@ struct opcode_entry { return;\ }\ } while (0) - - -#define OP_BASIC(x) WORD *a, *b;\ - unsigned int lit_a;\ - do {\ - assert(d != NULL);\ - lit_a = value_decode(d, val_a, &d->reg_work_[0], &a);\ - value_decode(d, val_b, &d->reg_work_[1], &b);\ - if (d->skip_) {\ - TRACE("++ SKIPPED");\ - d->skip_ = 0;\ - return;\ - }\ - } while(0) - -#define OP_NBI(x) WORD *a;\ - unsigned int lit_a;\ - do {\ - assert(d != NULL);\ - lit_a = value_decode(d, val_a, &d->reg_work_[0], &a);\ - (void)val_b;\ - if (d->skip_) {\ - TRACE("++ SKIPPED");\ - d->skip_ = 0;\ - return;\ - }\ - } while(0) +#define OP_BASIC(x) OP_TYPE(OP_BASIC_) +#define OP_NBI(x) OP_TYPE(OP_NBI_) /* extended opcodes */ @@ -293,7 +279,6 @@ static const struct opcode_entry opcode_nbi_entries[] = { instructions only have one operand. */ OP_IMPL(_nbi_) { - assert(d != NULL); /* non-basic instruction */ /* don't do normal value decoding here */ @@ -563,11 +548,11 @@ void dump_instruction(struct dcpu16 *d, WORD addr) { a = (d->ram[addr] >> (OPCODE_BASIC_SHIFT + OPCODE_BASIC_BITS)) & ((1 << 6) - 1); b = (d->ram[addr] >> (OPCODE_BASIC_SHIFT + OPCODE_BASIC_BITS + 6)) & ((1 << 6) - 1); - assert(opcode < 0x0f); - assert(a < 0x3f); - assert(b < 0x3f); + assert(opcode <= 0x0f); + assert(a <= 0x3f); + assert(b <= 0x3f); - printf("next instr 0x%04x: %04x", addr, d->ram[addr]); + printf(" next instr 0x%04x: %04x", addr, d->ram[addr]); if (opcode != 0) { @@ -585,7 +570,11 @@ void dump_instruction(struct dcpu16 *d, WORD addr) { e = opcode_basic_entries + opcode; else e = opcode_nbi_entries + ( (a < OPCODE_NBI_MAX) ? a : (OPCODE_NBI_MAX - 1) ); - printf("\n\t%s", e->name); + + printf("%s%s ; %s", + instr_len < 3 ? " " : "", + instr_len < 2 ? " " : "", + e->name); if (opcode != 0) { dump_value(a, d->ram[addr + 1]); if (a == 0x1e || a == 0x1f) @@ -603,11 +592,7 @@ void dcpu16_execute_next_instruction(struct dcpu16 *d) { WORD val_a, val_b; const struct opcode_entry *e; - /* fetch next instruction */ - if (d->pc > RAM_SIZE) { /* currently impossible */ - WARN("%s beyond %u", "PC", RAM_SIZE); - /* d->pc %= RAM_SIZE; */ - } + /* decode opcode and invoke */ opcode = (d->ram[ d->pc ] >> OPCODE_BASIC_SHIFT) & ((1 << OPCODE_BASIC_BITS) - 1); val_a = (d->ram[d->pc] >> (OPCODE_BASIC_SHIFT + OPCODE_BASIC_BITS)) & ((1 << 6) - 1); @@ -640,7 +625,9 @@ static void usage(char *prog, unsigned int full) { if (full) { fprintf(f, "\nOptions:\n" - "\t-h -- this screen\n"); + "\t-h -- this screen\n" + "\t-t -- test mode, load demo program\n" + "\t-v -- verbose execution tracing\n"); fprintf(f, "\n%78s\n", src_id_); } @@ -690,7 +677,7 @@ static void dump_cpu_state(struct dcpu16 *d) { unsigned int i; - printf("[--- cycle:0x%08llx %2s:0x%04x %2s:0x%04x %2s:0x%04x\n", + printf("---- cycle:0x%08llx %2s:0x%04x %2s:0x%04x %2s:0x%04x\n", d->cycle, "PC", d->pc, "SP", d->sp, @@ -726,12 +713,15 @@ int main(int argc, char **argv) { exit(EX_OSERR); } - while ( (c = getopt(argc, argv, "ht")) != EOF ) + while ( (c = getopt(argc, argv, "htv")) != EOF ) { switch (c) { - case 't': + case 'v': trace_mode_ = 1; + break; + + case 't': dump_ram(m, 0, 0x001f); testprog_load(m); dump_ram(m, 0, 0x001f); @@ -754,11 +744,11 @@ int main(int argc, char **argv) { } dump_cpu_state(m); + dump_instruction(m, m->pc); while (fgets(buf, sizeof buf, stdin)) { dcpu16_execute_next_instruction(m); dump_cpu_state(m); - if (trace_mode_) - dump_instruction(m, m->pc); + dump_instruction(m, m->pc); } free(m);