further reorg of module abstraction and control interface
[dcpu16] / dcpu16.c
index a0e1ad0ca3864ee2be54535b1f5030c79713a9a2..2b39bafd35507092237027462fdf3d1b419502f0 100644 (file)
--- a/dcpu16.c
+++ b/dcpu16.c
@@ -1369,13 +1369,13 @@ struct dcpu16_hw *dcpu16_hw_new(struct dcpu16 *vm, struct dcpu16_hw_module *mod,
     }
     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;
     }
-    hw->data_free = mod->data_free;
 
     return hw;
 }
@@ -1384,8 +1384,8 @@ struct dcpu16_hw *dcpu16_hw_new(struct dcpu16 *vm, struct dcpu16_hw_module *mod,
 void dcpu16_hw_del(struct dcpu16_hw **hw) {
     if (hw) {
         if (*hw) {
-            if ((*hw)->data_free) {
-                (*hw)->data_free(*hw);
+            if ((*hw)->mod->data_free) {
+                (*hw)->mod->data_free(*hw);
             }
             free(*hw);
             *hw = NULL;
@@ -1393,7 +1393,24 @@ void dcpu16_hw_del(struct dcpu16_hw **hw) {
     }
 }
 
-/*  dcpu16_hw_add
+/*  dcpu16_hw_ctl
+ *  invokes per-module controls for hw device
+ */
+int dcpu16_hw_ctl(struct dcpu16_hw *hw, const char *cmd, void *data_in, void *data_out) {
+    if (hw) {
+        if (hw->mod) {
+            if (hw->mod->ctl) {
+                if (cmd) {
+                    return hw->mod->ctl(hw, cmd, data_in, data_out);
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+
+/*  dcpu16_hw_attach
  *  registers new 'hardware' device with system
  */
 int dcpu16_hw_attach(struct dcpu16 *vm, struct dcpu16_hw *hw) {