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
*/
};
typedef void (dcpu16_hw_signal_t)(struct dcpu16 *, void *);
+typedef void (dcpu16_hw_data_free_t)(struct dcpu16_hw *);
/* these are used to define hardware attached to the system */
struct dcpu16_hw {
struct dcpu16 *vm; /* which system do I belong to */
dcpu16_hw_signal_t *hwi;
dcpu16_hw_signal_t *cycle;
dcpu16_hw_signal_t *reset;
+
+ dcpu16_hw_data_free_t *data_free;
void *data;
};
+typedef int (dcpu16_hw_data_init_t)(struct dcpu16_hw *, void *);
+struct dcpu16_hw_module {
+ struct dcpu16_hw *template;
+ dcpu16_hw_data_init_t *data_init;
+ dcpu16_hw_data_free_t *data_free;
+};
+
/* instantiate a new core */
struct dcpu16 *dcpu16_new(void);
static dcpu16_hw_signal_t spc2000_cycle_;
static dcpu16_hw_signal_t spc2000_hwi_;
static struct dcpu16_hw hw_ = {
+ .vm = NULL,
.name_ = "SPC2000 - Suspension Chamber 2000",
.id_l = 0x1d9d,
.id_h = 0x40e4,
.data = (struct spc2000_ *)NULL
};
+static dcpu16_hw_data_init_t spc2000_data_init_;
+static dcpu16_hw_data_free_t spc2000_data_free_;
+struct dcpu16_hw_module dcpu16_hw_module_spc2000 = {
+ .template = &hw_,
+ .data_init = spc2000_data_init_,
+ .data_free = spc2000_data_free_,
+};
+
struct spc2000_ {
DCPU16_WORD skip_unit;
long long skip;
};
+static
+int spc2000_data_init_(struct dcpu16_hw *hw, void *extra) {
+ (void)extra;
+
+ hw->data = calloc(1, sizeof(struct spc2000_));
+ if (hw->data == NULL) {
+ hw->vm->warn_cb_("%s():%s", "calloc", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+static
+void spc2000_data_free_(struct dcpu16_hw *hw) {
+ if (hw) {
+ if (hw->data) {
+ free(hw->data);
+ hw->data = NULL;
+ }
+ }
+}
+
static
void spc2000_reset_(struct dcpu16 *vm, void *data) {
struct spc2000_ *spc2000 = (struct spc2000_ *)data;
#ifndef SPC2000_H_IE4EG0MO
#define SPC2000_H_IE4EG0MO
-struct dcpu16_hw *spc2000_new(struct dcpu16 *);
-void spc2000_del(struct dcpu16_hw **);
+extern struct dcpu16_hw_module dcpu16_hw_module_spc2000;
#endif /* SPC2000_H_IE4EG0MO */