X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=sidebyside;f=dcpu16.c;h=a0e1ad0ca3864ee2be54535b1f5030c79713a9a2;hb=8b552fe61db48874f043bccfb589e5444509444c;hp=ac052d59887a148f62f5195db9ac8c2c08557063;hpb=ce296c260b229bb5c2e866db7842f3a46ea8c4b7;p=dcpu16 diff --git a/dcpu16.c b/dcpu16.c index ac052d5..a0e1ad0 100644 --- a/dcpu16.c +++ b/dcpu16.c @@ -172,7 +172,7 @@ 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].data); + vm->hw_table_[i].cycle(vm, &vm->hw_table_[i]); } } } @@ -533,7 +533,7 @@ 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].data); + vm->hw_table_[*a].hwi(vm, &vm->hw_table_[*a]); else WARN("hardware 0x%04x has no interrupt handler", *a); } @@ -1358,10 +1358,45 @@ void dcpu16_dump_ram(struct dcpu16 *vm, DCPU16_WORD start, DCPU16_WORD end) { 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); + if (hw == NULL) { + vm->warn_cb_("%s():%s", "calloc", strerror(errno)); + return NULL; + } + memcpy(hw, mod->template, sizeof *hw); + hw->vm = vm; + + 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; +} + +/* destroy a 'hardware' device */ +void dcpu16_hw_del(struct dcpu16_hw **hw) { + if (hw) { + if (*hw) { + if ((*hw)->data_free) { + (*hw)->data_free(*hw); + } + free(*hw); + *hw = NULL; + } + } +} + /* dcpu16_hw_add * 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; @@ -1450,7 +1485,7 @@ 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].data); + vm->hw_table_[i].reset(vm, &vm->hw_table_[i]); } memset(vm->reg, 0, sizeof vm->reg);