/* 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].data);
+ vm->hw_table_[i].cycle(vm, &vm->hw_table_[i]);
}
}
}
dcpu16_cycle_inc(vm, 4);
if (vm->hw_table_[*a].hwi)
- vm->hw_table_[*a].hwi(vm, vm->hw_table_[*a].data);
+ vm->hw_table_[*a].hwi(vm, &vm->hw_table_[*a]);
else
WARN("hardware 0x%04x has no interrupt handler", *a);
}
}
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;
}
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;
}
}
-/* 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_add(struct dcpu16 *vm, struct dcpu16_hw *hw) {
+int dcpu16_hw_attach(struct dcpu16 *vm, struct dcpu16_hw *hw) {
if (!vm || !hw)
return -1;
/* 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].data);
+ vm->hw_table_[i].reset(vm, &vm->hw_table_[i]);
}
memset(vm->reg, 0, sizeof vm->reg);