From ce296c260b229bb5c2e866db7842f3a46ea8c4b7 Mon Sep 17 00:00:00 2001 From: Justin Wind Date: Thu, 17 May 2012 14:11:41 -0700 Subject: [PATCH] cycles now correctly accounted for Previously, hardware &c was only signaled for a cycle once per instruction step, rather than for the full count of cycles the instruction took. --- dcpu16.c | 141 +++++++++++++++++++++++++++++---------------------- dcpu16.h | 3 +- hw_lem1802.c | 102 ++++++++++++++++++++++++++++--------- vm-dcpu16.c | 8 +-- 4 files changed, 164 insertions(+), 90 deletions(-) diff --git a/dcpu16.c b/dcpu16.c index 616237d..ac052d5 100644 --- a/dcpu16.c +++ b/dcpu16.c @@ -11,6 +11,7 @@ /* * emulates the DCPU16 system from http://0x10c.com/doc/dcpu-16.txt + * currently emulates '1.7' spec from http://pastebin.com/Q4JvQvnM * * I couldn't remember ever implementing an emulator before, so this * happened. As such, consider this a toy in progress. @@ -26,7 +27,6 @@ * !! v1.7 hardware interface needs to be finished * !! v1.7 interrupts need to be finished * 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 * make all callbacks register addr range of interest @@ -157,6 +157,26 @@ DCPU16_WORD interrupt_dequeue_(struct dcpu16 *vm) { return message; } +inline +void dcpu16_cycle_inc(struct dcpu16 *vm, unsigned int n) { + size_t i; + + while (n--) { + /* new cycle */ + vm->cycle_ += 1; + TRACE("%s>> starting cycle %llu", vm->cycle_); + + /* signal interested cycle hooks */ + acct_event_(vm, DCPU16_ACCT_EV_CYCLE, vm->reg[DCPU16_REG_PC]); + + /* 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); + } + } +} + /* value_decode_ * sets *v to be the address of the represented value * value_is_a is 0 for b, 1 for a, alters behavior of some operands @@ -336,7 +356,7 @@ struct opcode_entry { &vm->reg_work_[1], &a, &ev_a_addr,\ &pc_adjust, &sp_adjust, &cycle_adjust);\ vm->reg[DCPU16_REG_SP] += sp_adjust;\ - vm->cycle += cycle_adjust;\ + dcpu16_cycle_inc(vm, cycle_adjust);\ } while (0) #define OP_NBI_ (void)val_b, (void)b, (void)ev_b_addr, (void)val_b_data #define OP_BASIC_ value_decode_(vm, val_b, 0, val_b_data,\ @@ -384,7 +404,7 @@ OP_IMPL(nbi_jsr) { vm->ram[ --vm->reg[DCPU16_REG_SP] ] = vm->reg[DCPU16_REG_PC]; vm->reg[DCPU16_REG_PC] = *a; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(vm->reg[DCPU16_REG_SP] + 1); } @@ -419,7 +439,7 @@ OP_IMPL(nbi_int) { vm->reg[0] = *a; } - vm->cycle += 4; + dcpu16_cycle_inc(vm, 4); } OP_IMPL(nbi_iag) { @@ -427,6 +447,8 @@ OP_IMPL(nbi_iag) { *a = vm->reg[DCPU16_REG_IA]; + dcpu16_cycle_inc(vm, 1); + ACCT_W(ev_a_addr); } @@ -435,6 +457,8 @@ OP_IMPL(nbi_ias) { vm->reg[DCPU16_REG_IA] = *a; + dcpu16_cycle_inc(vm, 1); + ACCT_R(ev_a_addr); } @@ -445,6 +469,8 @@ OP_IMPL(nbi_rfi) { vm->interrupts_deferred_ = 0; vm->reg[DCPU16_REG_A] = vm->ram[vm->reg[DCPU16_REG_SP]++]; vm->reg[DCPU16_REG_PC] = vm->ram[vm->reg[DCPU16_REG_SP]++]; + + dcpu16_cycle_inc(vm, 3); } OP_IMPL(nbi_iaq) { @@ -456,6 +482,8 @@ OP_IMPL(nbi_iaq) { vm->interrupts_deferred_ = 0; } + dcpu16_cycle_inc(vm, 2); + ACCT_R(ev_a_addr); } @@ -466,7 +494,7 @@ OP_IMPL(nbi_hwn) { *a = vm->hw_table_entries_; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(nbi_hwq) { @@ -490,7 +518,7 @@ OP_IMPL(nbi_hwq) { vm->reg[DCPU16_REG_X] = vm->hw_table_[*a].mfg_l; vm->reg[DCPU16_REG_Y] = vm->hw_table_[*a].mfg_h; - vm->cycle += 4; + dcpu16_cycle_inc(vm, 4); } OP_IMPL(nbi_hwi) { @@ -503,7 +531,7 @@ OP_IMPL(nbi_hwi) { return; } - vm->cycle += 4; + dcpu16_cycle_inc(vm, 4); if (vm->hw_table_[*a].hwi) vm->hw_table_[*a].hwi(vm, vm->hw_table_[*a].data); else @@ -518,7 +546,7 @@ OP_IMPL(nbi_hcf) { vm->on_fire_ = 1; WARN("system on fire"); - vm->cycle += 9; + dcpu16_cycle_inc(vm, 9); } static const struct opcode_entry opcode_nbi_entries[] = { @@ -583,7 +611,7 @@ OP_IMPL(set) { */ *b = *a; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); ACCT_W(ev_b_addr); } @@ -599,7 +627,7 @@ OP_IMPL(add) { *b = acc; vm->reg[DCPU16_REG_EX] = (acc > 0xffff); - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -615,7 +643,7 @@ OP_IMPL(sub) { *b = acc; vm->reg[DCPU16_REG_EX] = (acc > 0xffff); - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -631,7 +659,7 @@ OP_IMPL(mul) { *b = acc; vm->reg[DCPU16_REG_EX] = acc >> 16; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -647,7 +675,7 @@ OP_IMPL(mli) { *b = acc; vm->reg[DCPU16_REG_EX] = acc >> 16; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -667,7 +695,7 @@ OP_IMPL(div) { vm->reg[DCPU16_REG_EX] = (*b << 16) / *a; } - vm->cycle += 3; + dcpu16_cycle_inc(vm, 3); ACCT_W(ev_b_addr); } @@ -687,7 +715,7 @@ OP_IMPL(dvi) { vm->reg[DCPU16_REG_EX] = (short)(*b << 16) / (short)*a; } - vm->cycle += 3; + dcpu16_cycle_inc(vm, 3); ACCT_W(ev_b_addr); } @@ -705,7 +733,7 @@ OP_IMPL(mod) { *b = *b % *a; } - vm->cycle += 3; + dcpu16_cycle_inc(vm, 3); ACCT_W(ev_a_addr); } @@ -723,7 +751,7 @@ OP_IMPL(mdi) { *b = (short)*b % (short)*a; } - vm->cycle += 3; + dcpu16_cycle_inc(vm, 3); ACCT_W(ev_b_addr); } @@ -737,7 +765,7 @@ OP_IMPL(and) { *b = *b & *a; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); ACCT_W(ev_b_addr); } @@ -751,7 +779,7 @@ OP_IMPL(bor) { *b = *b | *a; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); ACCT_W(ev_b_addr); } @@ -765,7 +793,7 @@ OP_IMPL(xor) { *b = *b ^ *a; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); ACCT_W(ev_b_addr); } @@ -781,7 +809,7 @@ OP_IMPL(shr) { *b = acc & 0xffff; vm->reg[DCPU16_REG_EX] = (*b << 16) >> *a; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); WARN("IMPLEMENT"); @@ -799,7 +827,7 @@ OP_IMPL(asr) { *b = acc & 0xffff; vm->reg[DCPU16_REG_EX] = (*b << 16) >> *a; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); WARN("IMPLEMENT"); @@ -818,7 +846,7 @@ OP_IMPL(shl) { vm->reg[DCPU16_REG_EX] = acc >> 16; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -834,10 +862,10 @@ OP_IMPL(ifb) { /* */ } else { vm->skip_ = 1; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ifc) { @@ -851,10 +879,10 @@ OP_IMPL(ifc) { /* */ } else { vm->skip_ = 1; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ife) { @@ -868,10 +896,10 @@ OP_IMPL(ife) { /* */ } else { vm->skip_ = 1; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ifn) { @@ -885,10 +913,10 @@ OP_IMPL(ifn) { /* */ } else { vm->skip_ = 1; - vm->cycle++; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ifg) { @@ -902,10 +930,10 @@ OP_IMPL(ifg) { /* */ } else { vm->skip_ = 1; - vm->cycle++; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ifa) { @@ -919,10 +947,10 @@ OP_IMPL(ifa) { /* */ } else { vm->skip_ = 1; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ifl) { @@ -936,10 +964,10 @@ OP_IMPL(ifl) { /* */ } else { vm->skip_ = 1; - vm->cycle++; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(ifu) { @@ -953,10 +981,10 @@ OP_IMPL(ifu) { /* */ } else { vm->skip_ = 1; - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); } - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); } OP_IMPL(adx) { @@ -974,7 +1002,7 @@ OP_IMPL(adx) { else vm->reg[DCPU16_REG_EX] = 0x0000; - vm->cycle += 3; + dcpu16_cycle_inc(vm, 3); ACCT_W(ev_b_addr); } @@ -994,7 +1022,7 @@ OP_IMPL(sbx) { else vm->reg[DCPU16_REG_EX] = 0; - vm->cycle += 3; + dcpu16_cycle_inc(vm, 3); ACCT_W(ev_b_addr); } @@ -1010,7 +1038,7 @@ OP_IMPL(sti) { vm->reg[DCPU16_REG_I] += 1; vm->reg[DCPU16_REG_J] += 1; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -1026,7 +1054,7 @@ OP_IMPL(std) { vm->reg[DCPU16_REG_I] -= 1; vm->reg[DCPU16_REG_J] -= 1; - vm->cycle += 2; + dcpu16_cycle_inc(vm, 2); ACCT_W(ev_b_addr); } @@ -1229,24 +1257,11 @@ int dcpu16_interrupt(struct dcpu16 *vm, DCPU16_WORD message) { /* execute the next instruction */ void dcpu16_step(struct dcpu16 *vm) { DCPU16_WORD opcode, b, a, instr_len, *b_data, *a_data; - size_t i; const struct opcode_entry *e; if (!vm) return; - /* signal interested parties that a new cycle has ticked */ - TRACE("%s>> sending global cycle event", __func__); - acct_event_(vm, DCPU16_ACCT_EV_CYCLE, vm->reg[DCPU16_REG_PC]); - - /* signal attached hardware */ - for (i = 0; i < vm->hw_table_entries_; i++) { - if (vm->hw_table_[i].cycle) { - TRACE("%s>> sending cycle to %s", __func__, vm->hw_table_[i].name_); - vm->hw_table_[i].cycle(vm, vm->hw_table_[i].data); - } - } - instruction_decode_(vm->ram, vm->reg[DCPU16_REG_PC], &opcode, &b, &b_data, &a, &a_data, &instr_len); /* consume what we decoded */ @@ -1269,7 +1284,7 @@ void dcpu16_step(struct dcpu16 *vm) { TRACE("++ SKIPPED %x words", instr_len); if (opcode >= 0x10 && opcode <= 0x17) { /* skipping a branch instruction? skip branch's skippable instruction as well */ - vm->cycle += 1; + dcpu16_cycle_inc(vm, 1); } else { vm->skip_ = 0; } @@ -1282,16 +1297,18 @@ void dcpu16_step(struct dcpu16 *vm) { DCPU16_WORD message; message = interrupt_dequeue_(vm); + TRACE("%s>> %s interrupt IA:0x%04x message:0x%04x", + __func__, + vm->reg[DCPU16_REG_IA] ? "servicing" : "ignoring", + vm->reg[DCPU16_REG_IA], + message); if (vm->reg[DCPU16_REG_IA]) { - TRACE("%s>> servicing interrupt IA:0x%04x message:0x%04x \n", __func__, vm->reg[DCPU16_REG_IA], message); /* then service the next interrupt */ vm->interrupts_deferred_ = 1; vm->ram[--vm->reg[DCPU16_REG_SP]] = vm->reg[DCPU16_REG_PC]; vm->ram[--vm->reg[DCPU16_REG_SP]] = vm->reg[DCPU16_REG_A]; vm->reg[DCPU16_REG_PC] = vm->reg[DCPU16_REG_IA]; vm->reg[DCPU16_REG_A] = message; - } else { - TRACE("%s>> ignoring interrupt IA:0", __func__); } } } @@ -1312,7 +1329,7 @@ void dcpu16_state_print(struct dcpu16 *vm) { printf("\n"); printf("(0x%08llx) %2s:0x%04x %2s:0x%04x %2s:0x%04x %2s:0x%04x [%2s]:", - vm->cycle, + 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], @@ -1438,7 +1455,7 @@ void dcpu16_reset(struct dcpu16 *vm) { memset(vm->reg, 0, sizeof vm->reg); memset(vm->ram, 0, sizeof vm->ram); - vm->cycle = 0; + vm->cycle_ = 0; acct_event_(vm, DCPU16_ACCT_EV_RESET, 0); } diff --git a/dcpu16.h b/dcpu16.h index f2bf787..38203ed 100644 --- a/dcpu16.h +++ b/dcpu16.h @@ -40,6 +40,7 @@ struct dcpu16 { size_t hw_table_entries_; /* hardware list maintenance */ size_t hw_table_allocated_; /* hardware list maintenance */ + unsigned long long cycle_; /* number of cycles this core has executed */ unsigned int skip_ : 1; /* skip execution of next instruction */ unsigned int interrupts_deferred_ : 1; /* queue software interrupts */ unsigned int on_fire_ : 1; /* cpu is on fire */ @@ -48,7 +49,6 @@ struct dcpu16 { size_t interrupts_head_; /* interrupt queue maintenance */ size_t interrupts_tail_; /* interrupt queue maintenance */ - unsigned long long cycle; /* number of cycles this core has executed */ DCPU16_WORD reg[DCPU16_REG__NUM]; /* system registers, a b c x y z i j */ DCPU16_WORD ram[DCPU16_RAM]; /* memory */ }; @@ -116,6 +116,7 @@ void dcpu16_step(struct dcpu16 *); void dcpu16_delete(struct dcpu16 **); int dcpu16_interrupt(struct dcpu16 *, DCPU16_WORD); +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 */ void dcpu16_warn_cb_set(void (*)(char *, ...)); diff --git a/hw_lem1802.c b/hw_lem1802.c index 1be1810..e7e6183 100644 --- a/hw_lem1802.c +++ b/hw_lem1802.c @@ -2,6 +2,7 @@ #include #include #include +#include #ifdef HAVE_LIBPNG #include @@ -39,6 +40,8 @@ static struct dcpu16_hw hw_ = { .data = (struct lem1802_ *)NULL }; +#define LEM1802_POWER_ON_CYCLES 100000 /* this should vary by, let us say, 10% */ + #define PIX_X 160 /* pixels in display */ #define PIX_Y 128 /* pixels in display */ #define PIX_BORDER 16 /* border pixels from edge to first tile */ @@ -75,7 +78,8 @@ struct pixel_ { }; struct lem1802_ { - long long cycle_activated; /* for tracking 'turn on delay' */ + long long cycle_activated; /* running since */ + long long cycles_until_active_; /* for tracking power-up delay */ DCPU16_WORD video_base; DCPU16_WORD font_base; @@ -90,10 +94,32 @@ struct lem1802_ { unsigned int blink_tally_; /* tick */ unsigned int blink_state; + enum cycle_state_ { + CYCLE_IDLE, + CYCLE_COPY_TO_RAM, + } cycle_state_; + const DCPU16_WORD *cycle_state_copy_src_ptr_; + DCPU16_WORD cycle_state_copy_dst_addr_; + size_t cycle_state_copy_words_; + int (*render)(void *, struct pixel_ *, size_t, size_t); void *renderer_data; }; +static +long long power_on_cycles_(void) { + struct tv; + long long r = 0; + +#if WANT_DELAY_START + gettimeofday(&tv, NULL); + r += LEM1802_POWER_ON_CYCLES - (LEM1802_POWER_ON_CYCLES / 10); + r += tv.tv_usec % (LEM1802_POWER_ON_CYCLES / 5); +#endif + + return r; +} + static inline void pixel_color_(struct pixel_ *pix, DCPU16_WORD color) { unsigned char x; @@ -206,8 +232,14 @@ void lem1802_pixbuf_refresh_full_(struct lem1802_ *display, DCPU16_WORD *mem) { TRACE("%s>> video_base:0x%04x", __func__, display->video_base); #endif + if (display->cycles_until_active_) { + /* show cute power-up sequence.. */ + memset(display->pixbuf, 0, PIX_X * PIX_Y * sizeof *display->pixbuf); + return; + } + if (display->video_base == 0) { - /* disconnected, blank display. static might be fun, too */ + /* disconnected, blank display */ memset(display->pixbuf, 0, PIX_X * PIX_Y * sizeof *display->pixbuf); return; } @@ -332,7 +364,8 @@ int pixbuf_render_vnc_(void *data, struct pixel_ *pixbuf, size_t x, size_t y) { (void)pixbuf; /* derp */ - rfbMarkRectAsModified(s, 0, 0, x, y); + if (s) + rfbMarkRectAsModified(s, 0, 0, x, y); TRACE("%s>>", __func__); @@ -359,6 +392,8 @@ void lem1802_reset_(struct dcpu16 *vm, void *data) { display->blink_tally_ = 0; display->blink_state = 0; + display->cycle_state_ = 0; + #if DEBUG vm->trace_cb_("%s>>", __func__); #endif /* DEBUG */ @@ -370,10 +405,8 @@ void lem1802_cycle_(struct dcpu16 *vm, void *data) { (void)vm; /* - maybe just step through video memory (if set) - one word per clock..? could just cheat and - use accounting callbacks.. - + for more cycle-accuracy, could step through video memory, if set, + one word per clock.. for now just count cycles and issue a full refresh/render every so often */ @@ -393,6 +426,33 @@ void lem1802_cycle_(struct dcpu16 *vm, void *data) { lem1802_pixbuf_refresh_full_(display, vm->ram); display->render(display->renderer_data, display->pixbuf, PIX_X, PIX_Y); } + + switch (display->cycle_state_) { + case CYCLE_IDLE: + break; + + case CYCLE_COPY_TO_RAM: + TRACE("%s>> copy_to_ram words:%zu src:%p dst_addr:0x%04x", + __func__, + display->cycle_state_copy_words_, + display->cycle_state_copy_src_ptr_, + display->cycle_state_copy_dst_addr_); + vm->ram[display->cycle_state_copy_dst_addr_] = *display->cycle_state_copy_src_ptr_; + display->cycle_state_copy_dst_addr_++; + display->cycle_state_copy_src_ptr_++; + display->cycle_state_copy_words_--; + if (display->cycle_state_copy_words_ == 0) { + display->cycle_state_ = CYCLE_IDLE; + } + break; + } + + if (display->cycles_until_active_) { + display->cycles_until_active_--; + if (display->cycles_until_active_ == 0) { + TRACE("%s>> display now active", __func__); + } + } } static @@ -400,14 +460,14 @@ void lem1802_hwi_(struct dcpu16 *vm, void *data) { struct lem1802_ *display = (struct lem1802_ *)data; DCPU16_WORD reg_a = vm->reg[DCPU16_REG_A]; DCPU16_WORD reg_b = vm->reg[DCPU16_REG_B]; - size_t i; TRACE("%s>> A:0x%04x B:0x%04x", __func__, reg_a, reg_b); switch (reg_a) { case 0: /* MEM_MAP_SCREEN */ if (display->cycle_activated == 0 && reg_b) { - display->cycle_activated = vm->cycle; + display->cycle_activated = vm->cycle_; + display->cycles_until_active_ = power_on_cycles_(); } display->video_base = reg_b; if (reg_b == 0) @@ -427,23 +487,19 @@ void lem1802_hwi_(struct dcpu16 *vm, void *data) { break; case 4: /* MEM_DUMP_FONT */ - for (i = 0; i < 128 ; i++) { - vm->ram[reg_b] = chargen_4x8_glyphs[reg_b][0] << 8; - vm->ram[reg_b] |= chargen_4x8_glyphs[reg_b][1]; - reg_b += 1; - vm->ram[reg_b] = chargen_4x8_glyphs[reg_b][2] << 8; - vm->ram[reg_b] |= chargen_4x8_glyphs[reg_b][3]; - reg_b += 1; - } - vm->cycle += 256; + display->cycle_state_copy_src_ptr_ = (DCPU16_WORD *)chargen_4x8_glyphs; + display->cycle_state_copy_dst_addr_ = reg_b; + display->cycle_state_copy_words_ = 256; + display->cycle_state_ = CYCLE_COPY_TO_RAM; + dcpu16_cycle_inc(vm, 256); break; case 5: /* MEM_DUMP_PALETTE */ - for (i = 0; i < 16; i++) { - vm->ram[reg_b] = palette_default_[i]; - reg_b += 1; - } - vm->cycle += 16; + display->cycle_state_copy_src_ptr_ = palette_default_; + display->cycle_state_copy_dst_addr_ = reg_b; + display->cycle_state_copy_words_ = 16; + display->cycle_state_ = CYCLE_COPY_TO_RAM; + dcpu16_cycle_inc(vm, 16); break; } } diff --git a/vm-dcpu16.c b/vm-dcpu16.c index a463f7a..5accf2f 100644 --- a/vm-dcpu16.c +++ b/vm-dcpu16.c @@ -447,7 +447,7 @@ COMMAND_IMPL(run) { running_ = 1; gettimeofday(&run_start_tv, NULL); - run_cycle_start = vm->cycle; + run_cycle_start = vm->cycle_; memset(&act, 0, sizeof act); act.sa_handler = sigint_handler_; @@ -460,7 +460,7 @@ COMMAND_IMPL(run) { while (running_) { gettimeofday(&start_tv, NULL); - cycle_start = vm->cycle; + cycle_start = vm->cycle_; dcpu16_step(vm); if (opt_.verbose > 1) @@ -471,7 +471,7 @@ COMMAND_IMPL(run) { } /* how many cycles did this instr use? */ - cycles_to_wait = vm->cycle - cycle_start; + cycles_to_wait = vm->cycle_ - cycle_start; if (cycles_to_wait == 0) continue; @@ -500,7 +500,7 @@ COMMAND_IMPL(run) { run_usec = diff_tv.tv_sec * 1000000; run_usec += diff_tv.tv_usec; fprintf(stderr, "ran %llu cycles in %lds %dus (%lldus)\n", - vm->cycle - run_cycle_start, + vm->cycle_ - run_cycle_start, diff_tv.tv_sec, diff_tv.tv_usec, run_usec); -- 2.45.2