X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=dcpu16.c;h=23ef53a41747da7aadb9a51baec085033d5e1bab;hb=4185a67f55fb99f34f013b939a8ef9e13454c1e5;hp=5b4825852cc8e6c53720d1f609ee88deb87006e2;hpb=662d752f2adae37efcfa62354b2107c0d0de2d6d;p=dcpu16 diff --git a/dcpu16.c b/dcpu16.c index 5b48258..23ef53a 100644 --- a/dcpu16.c +++ b/dcpu16.c @@ -26,6 +26,8 @@ * TODO * change api to print into buffers rather than stdio * refactor opcode functiontables into switch statements + * let callbacks determine whether to override events, or just observe + * sort init callbacks by base addr, to call in-order */ static const char * const src_id_ = "$Id$"; @@ -87,13 +89,13 @@ void dcpu16_trace_cb_set(void (*fn)(char *fmt, ...)) { * invokes callbacks for specified event */ static inline -void acct_event_(struct dcpu16 *vm, dcpu16_acct_event_ ev, DCPU16_WORD addr) { +void acct_event_(struct dcpu16 *vm, dcpu16_acct_event ev, DCPU16_WORD addr) { struct dcpu16_acct_cb *cb = vm->cb_table_; size_t i; for (i = 0; i < vm->cb_table_entries_; i++) { if ( (cb[i].mask & ev) ) - cb[i].fn(vm, ev, addr); + cb[i].fn(vm, ev, addr, cb[i].data); } } @@ -691,6 +693,8 @@ void dcpu16_step(struct dcpu16 *d) { if (!d) return; + acct_event_(d, DCPU16_ACCT_EV_CYCLE, d->pc); + /* PC is advanced while decoding the operands by the opcode functions. Things like this could be organized a little better.. @@ -763,11 +767,12 @@ void dcpu16_dump_ram(struct dcpu16 *d, DCPU16_WORD start, DCPU16_WORD end) { * Register callback fn to be triggered whenever event matching any events * in bitwise mask occur. */ -int dcpu16_acct_add(struct dcpu16 *vm, dcpu16_acct_event_ mask, void (*fn)(struct dcpu16 *, dcpu16_acct_event_, DCPU16_WORD)) { +int dcpu16_acct_add(struct dcpu16 *vm, dcpu16_acct_event mask, dcpu16_ev_cb_t *fn, void *data) { struct dcpu16_acct_cb cb; cb.mask = mask; cb.fn = fn; + cb.data = data; if (vm->cb_table_entries_ == vm->cb_table_allocated_) { size_t new_entries = vm->cb_table_allocated_ + 32; @@ -787,12 +792,20 @@ int dcpu16_acct_add(struct dcpu16 *vm, dcpu16_acct_event_ mask, void (*fn)(struc } /* dcpu16_reset - * resets a dcpu16 instance to initial state + * signals cpu to reset, clearing runstate and ram, then reload any init callbacks */ void dcpu16_reset(struct dcpu16 *d) { if (!d) return; - memset(d, 0, sizeof *d); + d->cycle = 0; + memset(d->reg, 0, sizeof d->reg); + d->pc = 0; + d->sp = 0; + d->o = 0; + d->skip_ = 0; + memset(d->ram, 0, sizeof d->ram); + + acct_event_(d, DCPU16_ACCT_EV_RESET, 0); } /* dcpu16_new