moved module/hw fields around
authorJustin Wind <justin.wind@gmail.com>
Mon, 21 May 2012 02:03:13 +0000 (19:03 -0700)
committerJustin Wind <justin.wind@gmail.com>
Mon, 21 May 2012 02:03:13 +0000 (19:03 -0700)
dcpu16.c
dcpu16.h
hw_clock.c
hw_keyboard.c
hw_lem1802.c
hw_spc2000.c
vm-dcpu16.c

index 2b39bafd35507092237027462fdf3d1b419502f0..817cfb0da6c54d6490f4d32fda344526d152ed1f 100644 (file)
--- a/dcpu16.c
+++ b/dcpu16.c
@@ -171,8 +171,9 @@ void dcpu16_cycle_inc(struct dcpu16 *vm, unsigned int n) {
 
         /* signal attached hardware */
         for (i = 0; i < vm->hw_table_entries_; i++) {
-            TRACE("%s>> notifying %s", __func__, vm->hw_table_[i].name_);
-            vm->hw_table_[i].cycle(vm, &vm->hw_table_[i]);
+            TRACE("%s>> notifying %s", __func__, vm->hw_table_[i].mod->name_);
+            if (vm->hw_table_[i].mod->cycle)
+                vm->hw_table_[i].mod->cycle(vm, &vm->hw_table_[i]);
         }
     }
 }
@@ -512,11 +513,11 @@ OP_IMPL(nbi_hwq) {
         return;
     }
 
-    vm->reg[DCPU16_REG_A] = vm->hw_table_[*a].id_l;
-    vm->reg[DCPU16_REG_B] = vm->hw_table_[*a].id_h;
-    vm->reg[DCPU16_REG_C] = vm->hw_table_[*a].ver;
-    vm->reg[DCPU16_REG_X] = vm->hw_table_[*a].mfg_l;
-    vm->reg[DCPU16_REG_Y] = vm->hw_table_[*a].mfg_h;
+    vm->reg[DCPU16_REG_A] = vm->hw_table_[*a].mod->id_l;
+    vm->reg[DCPU16_REG_B] = vm->hw_table_[*a].mod->id_h;
+    vm->reg[DCPU16_REG_C] = vm->hw_table_[*a].mod->ver;
+    vm->reg[DCPU16_REG_X] = vm->hw_table_[*a].mod->mfg_l;
+    vm->reg[DCPU16_REG_Y] = vm->hw_table_[*a].mod->mfg_h;
 
     dcpu16_cycle_inc(vm, 4);
 }
@@ -532,8 +533,8 @@ OP_IMPL(nbi_hwi) {
     }
 
     dcpu16_cycle_inc(vm, 4);
-    if (vm->hw_table_[*a].hwi)
-        vm->hw_table_[*a].hwi(vm, &vm->hw_table_[*a]);
+    if (vm->hw_table_[*a].mod->hwi)
+        vm->hw_table_[*a].mod->hwi(vm, &vm->hw_table_[*a]);
     else
         WARN("hardware 0x%04x has no interrupt handler", *a);
 }
@@ -1314,67 +1315,27 @@ void dcpu16_step(struct dcpu16 *vm) {
     }
 }
 
-/*
-    print the current state of the machine
-    shows current cycle count, registers, and next instruction
-*/
-void dcpu16_state_print(struct dcpu16 *vm) {
-    unsigned int i;
-
-    if (!vm) return;
-
-    printf("  ");
-    for (i = 0; i < 8; i++)
-        printf("  %s:0x%04x", dcpu16_reg_names[i], vm->reg[i]);
-    printf("\n");
-
-    printf("(0x%08llx) %2s:0x%04x %2s:0x%04x %2s:0x%04x %2s:0x%04x [%2s]:",
-           vm->cycle_,
-           dcpu16_reg_names[DCPU16_REG_EX], vm->reg[DCPU16_REG_EX],
-           dcpu16_reg_names[DCPU16_REG_SP], vm->reg[DCPU16_REG_SP],
-           dcpu16_reg_names[DCPU16_REG_PC], vm->reg[DCPU16_REG_PC],
-           dcpu16_reg_names[DCPU16_REG_IA], vm->reg[DCPU16_REG_IA],
-           "PC");
-
-    dcpu16_disassemble_print(vm, vm->reg[DCPU16_REG_PC]);
-    printf("\n");
-}
-
-/*  dcpu16_dump_ram
- *  print raw ram contents from start to stop
- */
-void dcpu16_dump_ram(struct dcpu16 *vm, DCPU16_WORD start, DCPU16_WORD end) {
-    unsigned int i, j;
-    const unsigned int n = 8; /* words per line */
-
-    if (!vm) return;
-
-    for (i = start, j = 0; i <= end; i++, j++) {
-        if (j % n == 0)
-            printf("0x%04x:\t", i);
-        printf(" %04x%s", vm->ram[i], (j % n) == (n - 1) ? "\n" : "");
-    }
-    if ((j % n) != (n - 1))
-        printf("\n");
-}
 
 /* instantiate a new 'hardware' device */
 struct dcpu16_hw *dcpu16_hw_new(struct dcpu16 *vm, struct dcpu16_hw_module *mod, void *data) {
     struct dcpu16_hw *hw;
 
-    hw = calloc(1, sizeof *hw);
+    hw = malloc(sizeof *hw);
     if (hw == NULL) {
-        vm->warn_cb_("%s():%s", "calloc", strerror(errno));
+        vm->warn_cb_("%s():%s", "malloc", strerror(errno));
         return NULL;
     }
-    memcpy(hw, mod->template, sizeof *hw);
     hw->vm = vm;
     hw->mod = mod;
 
-    if (mod->data_init(hw, data)) {
-        vm->warn_cb_("failed to init hw module data");
-        free(hw);
-        return NULL;
+    if (mod->data_init) {
+        if (mod->data_init(hw, data)) {
+            vm->warn_cb_("failed to init hw module data");
+            free(hw);
+            return NULL;
+        }
+    } else {
+        hw->data = NULL;
     }
 
     return hw;
@@ -1419,10 +1380,10 @@ int dcpu16_hw_attach(struct dcpu16 *vm, struct dcpu16_hw *hw) {
 
     TRACE("%s>> name:%s ID:0x%04x%04x MFG:0x%04x%04x VER:0x%04x",
           __func__,
-          hw->name_,
-          hw->id_h, hw->id_l,
-          hw->mfg_l, hw->mfg_h,
-          hw->ver);
+          hw->mod->name_,
+          hw->mod->id_h, hw->mod->id_l,
+          hw->mod->mfg_l, hw->mod->mfg_h,
+          hw->mod->ver);
 
     if (vm->hw_table_entries_ == 0xffff) {
         WARN("maximum hardware entries reached");
@@ -1501,8 +1462,8 @@ void dcpu16_reset(struct dcpu16 *vm) {
 
     /* signal attached hardware */
     for (i = 0; i < vm->hw_table_entries_; i++) {
-        if (vm->hw_table_[i].reset) 
-            vm->hw_table_[i].reset(vm, &vm->hw_table_[i]);
+        if (vm->hw_table_[i].mod->reset) 
+            vm->hw_table_[i].mod->reset(vm, &vm->hw_table_[i]);
     }
 
     memset(vm->reg, 0, sizeof vm->reg);
index f70372a0d11655034ff279e038aeb0930c54b9d4..d0b366ac6d1a7e223eb357d7da6acf4012e4ff83 100644 (file)
--- a/dcpu16.h
+++ b/dcpu16.h
@@ -68,23 +68,11 @@ struct dcpu16_acct_cb {
 };
 
 typedef void (dcpu16_hw_signal_t)(struct dcpu16 *, struct dcpu16_hw *);
-/* these are used to define hardware attached to the system */
+/* this structure defines a specific instance of this type of 'hardware' */
 struct dcpu16_hw {
-    struct dcpu16 *vm;  /* which system do I belong to */
+    struct dcpu16 *vm;              /* which system do I belong to */
     struct dcpu16_hw_module *mod;   /* whence I came */
-    char *name_;
-
-    DCPU16_WORD id_l;
-    DCPU16_WORD id_h;
-    DCPU16_WORD ver;
-    DCPU16_WORD mfg_l;
-    DCPU16_WORD mfg_h;
-
-    dcpu16_hw_signal_t *hwi;
-    dcpu16_hw_signal_t *cycle;
-    dcpu16_hw_signal_t *reset;
-
-    void *data;
+    void *data;                     /* per-instance data */
 };
 
 /* human-readable text describing hw module control operations, for convenience's sake */
@@ -94,12 +82,24 @@ struct dcpu16_hw_ctl_cmd {
     char *data_out_type;
     char *description;
 };
+
 typedef int (dcpu16_hw_data_init_t)(struct dcpu16_hw *, void *);
 typedef void (dcpu16_hw_data_free_t)(struct dcpu16_hw *);
 typedef int (dcpu16_hw_ctl_t)(struct dcpu16_hw *, const char *, void *, void *);
 struct dcpu16_hw_module {
-    struct dcpu16_hw *template;
-    dcpu16_hw_data_init_t *data_init;
+    char *name_;                /* dymo label on front panel */
+
+    DCPU16_WORD id_l;
+    DCPU16_WORD id_h;
+    DCPU16_WORD ver;
+    DCPU16_WORD mfg_l;
+    DCPU16_WORD mfg_h;
+
+    dcpu16_hw_signal_t *hwi;    /* hardware interrupt handler */
+    dcpu16_hw_signal_t *cycle;  /* cycle tick handler */
+    dcpu16_hw_signal_t *reset;  /* reset handler */
+
+    dcpu16_hw_data_init_t *data_init;   /* how to allocate a dcpu16_hw instance's data */
     dcpu16_hw_data_free_t *data_free;
     dcpu16_hw_ctl_t *ctl;
     struct dcpu16_hw_ctl_cmd *ctl_cmd;
@@ -111,12 +111,6 @@ struct dcpu16 *dcpu16_new(void);
 /* reset a core to initial state */
 void dcpu16_reset(struct dcpu16 *);
 
-/* print the current state of a core */
-void dcpu16_state_print(struct dcpu16 *);
-
-/* print the contents of ram from second to third argument */
-void dcpu16_dump_ram(struct dcpu16 *, DCPU16_WORD, DCPU16_WORD);
-
 /* print words in buf as asm */
 DCPU16_WORD dcpu16_mnemonify_buf(DCPU16_WORD *);
 
@@ -142,7 +136,10 @@ void dcpu16_step(struct dcpu16 *);
 /* release a core */
 void dcpu16_delete(struct dcpu16 **);
 
+/* signal hardware interrupt */
 int dcpu16_interrupt(struct dcpu16 *, DCPU16_WORD);
+
+/* consume a cycle */
 void dcpu16_cycle_inc(struct dcpu16 *, unsigned int);
 
 /* register callbacks to handle warning and debug messages, default is writing to stderr, may be set to null */
index 83eaa8090598866838ed90df00dc88da81e1d0c1..a6c87b11b08bac58cfe0a7c0f23349c2512279ae 100644 (file)
@@ -39,7 +39,7 @@ void clock_cycle_(struct dcpu16 *vm, struct dcpu16_hw *hw) {
 
         if (clock->interrupt_message) {
             if (dcpu16_interrupt(vm, clock->interrupt_message))
-                vm->warn_cb_("%s: could not send interrupt", hw->name_);
+                vm->warn_cb_("%s: could not send interrupt", hw->mod->name_);
         }
     }
 }
@@ -87,8 +87,10 @@ void clock_data_free_(struct dcpu16_hw *hw) {
     }
 }
 
-static struct dcpu16_hw hw_ = {
+
+struct dcpu16_hw_module dcpu16_hw_module_clock = {
     .name_  = "Generic Clock (compatible)",
+
     .id_l   = 0xb402,
     .id_h   = 0x12d0,
     .ver    = 0x0001,
@@ -97,11 +99,7 @@ static struct dcpu16_hw hw_ = {
     .hwi    = clock_hwi_,
     .cycle  = clock_cycle_,
     .reset  = clock_reset_,
-    .data   = (struct clock_ *)NULL
-};
 
-struct dcpu16_hw_module dcpu16_hw_module_clock = {
-    .template = &hw_,
     .data_init = clock_data_init_,
     .data_free = clock_data_free_,
     .ctl = NULL,
index 7192efd91f5fe48e042ded1293a452c72e837ffc..aaf2f2c88f5a24cd5139517343bd15348d165205 100644 (file)
@@ -232,9 +232,10 @@ int keyboard_data_ctl_(struct dcpu16_hw *hw, const char *cmd, void *data_in, voi
     return -EINVAL;
 }
 
-static struct dcpu16_hw hw_ = {
-    .vm     = NULL,
+
+struct dcpu16_hw_module dcpu16_hw_module_keyboard = {
     .name_  = "Generic Keyboard (compatible)",
+
     .id_l   = 0x7406,
     .id_h   = 0x30cf,
     .ver    = 0x0001,
@@ -243,11 +244,7 @@ static struct dcpu16_hw hw_ = {
     .hwi    = keyboard_hwi_,
     .cycle  = keyboard_cycle_,
     .reset  = keyboard_reset_,
-    .data   = (struct keyboard_ *)NULL
-};
 
-struct dcpu16_hw_module dcpu16_hw_module_keyboard = {
-    .template = &hw_,
     .data_init = keyboard_data_init_,
     .data_free = keyboard_data_free_,
     .ctl = keyboard_data_ctl_,
index 0c70754e4ecbf45877c8a2e2a7d1c46ab3c09ca6..0b95d1180530d885e533a05b48a8d960d5d8ac0d 100644 (file)
@@ -690,8 +690,9 @@ int lem1802_data_ctl_(struct dcpu16_hw *hw, const char *cmd, void *data_in, void
 }
 
 
-static struct dcpu16_hw hw_ = {
+struct dcpu16_hw_module dcpu16_hw_module_lem1802 = {
     .name_  = "LEM1802 - Low Energy Monitor",
+
     .id_l   = 0xf615,
     .id_h   = 0x7349,
     .ver    = 0x1802,
@@ -700,11 +701,7 @@ static struct dcpu16_hw hw_ = {
     .hwi    = lem1802_hwi_,
     .cycle  = lem1802_cycle_,
     .reset  = lem1802_reset_,
-    .data   = (struct lem1802_ *)NULL
-};
 
-struct dcpu16_hw_module dcpu16_hw_module_lem1802 = {
-    .template = &hw_,
     .data_init = lem1802_data_init_,
     .data_free = lem1802_data_free_,
     .ctl = lem1802_data_ctl_,
index c967822279768111ec770cb7dbb42a3fcd39c325..1e20f59c4ce8803aa9ed6dd706b0e8426e9629b2 100644 (file)
@@ -85,9 +85,9 @@ void spc2000_hwi_(struct dcpu16 *vm, struct dcpu16_hw *hw) {
     }
 }
 
-static struct dcpu16_hw hw_ = {
-    .vm     = NULL,
+struct dcpu16_hw_module dcpu16_hw_module_spc2000 = {
     .name_  = "SPC2000 - Suspension Chamber 2000",
+
     .id_l   = 0x1d9d,
     .id_h   = 0x40e4,
     .ver    = 0x005e,
@@ -96,11 +96,7 @@ static struct dcpu16_hw hw_ = {
     .hwi    = spc2000_hwi_,
     .cycle  = spc2000_cycle_,
     .reset  = spc2000_reset_,
-    .data   = (struct spc2000_ *)NULL
-};
 
-struct dcpu16_hw_module dcpu16_hw_module_spc2000 = {
-    .template = &hw_,
     .data_init = spc2000_data_init_,
     .data_free = spc2000_data_free_,
     .ctl = NULL,
index 86f773aac4cfa691921da0488ddddaceaa9243e9..b4798838328aeae8e7d9698c9af64c25b79014a3 100644 (file)
@@ -148,6 +148,53 @@ int file_load_(struct dcpu16 *vm, char *filename, DCPU16_WORD addr) {
     return 0;
 }
 
+/*  dump_ram_
+ *  print raw ram contents from start to stop
+ */
+static
+void dump_ram_(struct dcpu16 *vm, DCPU16_WORD start, DCPU16_WORD end) {
+    unsigned int i, j;
+    const unsigned int n = 8; /* words per line */
+
+    if (!vm) return;
+
+    for (i = start, j = 0; i <= end; i++, j++) {
+        if (j % n == 0)
+            printf("0x%04x:\t", i);
+        printf(" %04x%s", vm->ram[i], (j % n) == (n - 1) ? "\n" : "");
+    }
+    if ((j % n) != (n - 1))
+        printf("\n");
+}
+
+
+/*
+    print the current state of the machine
+    shows current cycle count, registers, and next instruction
+*/
+static
+void state_print_(struct dcpu16 *vm) {
+    unsigned int i;
+
+    if (!vm) return;
+
+    printf("  ");
+    for (i = 0; i < 8; i++)
+        printf("  %s:0x%04x", dcpu16_reg_names[i], vm->reg[i]);
+    printf("\n");
+
+    printf("(0x%08llx) %2s:0x%04x %2s:0x%04x %2s:0x%04x %2s:0x%04x [%2s]:",
+           vm->cycle_,
+           dcpu16_reg_names[DCPU16_REG_EX], vm->reg[DCPU16_REG_EX],
+           dcpu16_reg_names[DCPU16_REG_SP], vm->reg[DCPU16_REG_SP],
+           dcpu16_reg_names[DCPU16_REG_PC], vm->reg[DCPU16_REG_PC],
+           dcpu16_reg_names[DCPU16_REG_IA], vm->reg[DCPU16_REG_IA],
+           "PC");
+
+    dcpu16_disassemble_print(vm, vm->reg[DCPU16_REG_PC]);
+    printf("\n");
+}
+
 
 #ifdef HAVE_LIBVNCSERVER
 static struct dynamic_array rfbScreens_;
@@ -324,7 +371,7 @@ COMMAND_IMPL(dump) {
         return 0;
     }
 
-    dcpu16_dump_ram(vm, addr[0], addr[1]);
+    dump_ram_(vm, addr[0], addr[1]);
 
     return 0;
 }
@@ -396,7 +443,7 @@ COMMAND_IMPL(step) {
         dcpu16_step(vm);
 
         if (count > 1 && opt_.verbose)
-            dcpu16_state_print(vm);
+            state_print_(vm);
     }
 
     return 0;
@@ -480,7 +527,7 @@ COMMAND_IMPL(run) {
 
         dcpu16_step(vm);
         if (opt_.verbose > 1)
-            dcpu16_state_print(vm);
+            state_print_(vm);
         else if (opt_.verbose) {
             dcpu16_disassemble_print(vm, vm->reg[DCPU16_REG_PC]);
             printf("\n");
@@ -782,13 +829,13 @@ int main(int argc, char **argv) {
          tok_v = tok_v_prev = NULL,
          tok_c = tok_c_prev= 0,
          snprintf(prompt, sizeof prompt, prompt_fmt, vm->reg[DCPU16_REG_PC]),
-         dcpu16_state_print(vm);
+         state_print_(vm);
 
          (line = readline(prompt));
 
          printf("\n"),
          snprintf(prompt, sizeof prompt, prompt_fmt, vm->reg[DCPU16_REG_PC]),
-         dcpu16_state_print(vm)) {
+         state_print_(vm)) {
         const char whitespace[] = " \t";
         char *line_start;
         struct command_ *c;