From 33efa05d43acf927c97daab10c00d1cbc2a7b9f6 Mon Sep 17 00:00:00 2001 From: Justin Wind Date: Sun, 20 May 2012 19:03:13 -0700 Subject: [PATCH] moved module/hw fields around --- dcpu16.c | 91 +++++++++++++++------------------------------------ dcpu16.h | 43 +++++++++++------------- hw_clock.c | 10 +++--- hw_keyboard.c | 9 ++--- hw_lem1802.c | 7 ++-- hw_spc2000.c | 8 ++--- vm-dcpu16.c | 57 +++++++++++++++++++++++++++++--- 7 files changed, 109 insertions(+), 116 deletions(-) diff --git a/dcpu16.c b/dcpu16.c index 2b39baf..817cfb0 100644 --- 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); diff --git a/dcpu16.h b/dcpu16.h index f70372a..d0b366a 100644 --- 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 */ diff --git a/hw_clock.c b/hw_clock.c index 83eaa80..a6c87b1 100644 --- a/hw_clock.c +++ b/hw_clock.c @@ -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, diff --git a/hw_keyboard.c b/hw_keyboard.c index 7192efd..aaf2f2c 100644 --- a/hw_keyboard.c +++ b/hw_keyboard.c @@ -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_, diff --git a/hw_lem1802.c b/hw_lem1802.c index 0c70754..0b95d11 100644 --- a/hw_lem1802.c +++ b/hw_lem1802.c @@ -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_, diff --git a/hw_spc2000.c b/hw_spc2000.c index c967822..1e20f59 100644 --- a/hw_spc2000.c +++ b/hw_spc2000.c @@ -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, diff --git a/vm-dcpu16.c b/vm-dcpu16.c index 86f773a..b479883 100644 --- a/vm-dcpu16.c +++ b/vm-dcpu16.c @@ -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; -- 2.45.2