actually commit minor cleanups
authorJustin Wind <justin.wind@gmail.com>
Tue, 10 Apr 2012 19:08:32 +0000 (12:08 -0700)
committerJustin Wind <justin.wind@gmail.com>
Tue, 10 Apr 2012 19:08:32 +0000 (12:08 -0700)
hah, still acclimating to git

Makefile
as-dcpu16.h
dcpu16.c

index f3324efabc61a143f42e044148b85957ad7dd30b..78f7941e97ac6c8879efcc87610d227e54ef14c5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 #!make
 #
-PROGRAMS = dcpu16
+PROGRAMS = dcpu16 as-dcpu16
 
 CFLAGS = -g -Wall -Wextra -pedantic -std=c99
 LDFLAGS = 
index 68bf54ebd36977ef5863381d68a12a5639509e7f..3b11d85445f54f460dad101a774094dd097139b4 100644 (file)
@@ -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_))
index d0d3b40dbff499c2265750c26b710016bc445416..26c594e02b60e524f596afcda0490d8e697456e2 100644 (file)
--- a/dcpu16.c
+++ b/dcpu16.c
  *  Justin Wind <justin.wind@gmail.com>
  *    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);