From e22bdfa072479f7ea72081808c0b1fa3602e726c Mon Sep 17 00:00:00 2001 From: Justin Wind Date: Sun, 13 May 2012 09:40:54 -0700 Subject: [PATCH] starting to add timing to vm driver not quite there yet, but starting to get it running at 'real time' speed, rather than as fast as possible --- as-dcpu16.c | 5 ++--- common.c | 22 +++++++++++++++++++ common.h | 2 ++ hw_lem1802.c | 3 ++- tests/{test.s => test.dasm} | 0 tests/test_lem1802.dasm | 32 ++++++++++++++++++---------- vm-dcpu16.c | 42 +++++++++++++++++++++++++++++++++++++ 7 files changed, 91 insertions(+), 15 deletions(-) rename tests/{test.s => test.dasm} (100%) diff --git a/as-dcpu16.c b/as-dcpu16.c index 73b2fa3..37954aa 100644 --- a/as-dcpu16.c +++ b/as-dcpu16.c @@ -538,8 +538,7 @@ int value_bits_(struct dynamic_array *labels, const char *operand_orig, DCPU16_W *nextwordused += 1; return 0x1e; } else if (errno) { - DEBUG_PRINTFQ("is out of range\n"); - fprintf(stderr, "trouble with operand '%s': %s\n", operand_orig, strerror(errno)); + /* if number wasn't parsable, just fall through and assume it's a label */ } /* not a number? try a label */ @@ -1065,7 +1064,7 @@ int assemble_check_(struct dynamic_array *instructionps, struct dynamic_array *l return retval; } if (! (*instrp)->ready) { - fprintf(stderr, "instruction not resolvable\n"); + fprintf(stderr, "instruction not resolvable at line %lu\n", (*instrp)->src_line); return -1; } } diff --git a/common.c b/common.c index ce1b6c0..5887c22 100644 --- a/common.c +++ b/common.c @@ -204,3 +204,25 @@ char *strqtok_r(char *str, const char *sep, int esc, const char *quote, char **l return tok; } + +int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) { + /* Perform the carry for the later subtraction by updating y. */ + if (x->tv_usec < y->tv_usec) { + int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; + y->tv_usec -= 1000000 * nsec; + y->tv_sec += nsec; + } + if (x->tv_usec - y->tv_usec > 1000000) { + int nsec = (x->tv_usec - y->tv_usec) / 1000000; + y->tv_usec += 1000000 * nsec; + y->tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_usec is certainly positive. */ + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_usec = x->tv_usec - y->tv_usec; + + /* Return 1 if result is negative. */ + return x->tv_sec < y->tv_sec; +} diff --git a/common.h b/common.h index 80ed333..02db4d7 100644 --- a/common.h +++ b/common.h @@ -21,4 +21,6 @@ int str_to_word(char *s); char *strqtok_r(char *str, const char *sep, int esc, const char *quote, char **lastq, char **lasts); +int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y); + #endif /* COMMON_H_QPRCB1BH */ diff --git a/hw_lem1802.c b/hw_lem1802.c index ae0c9dd..92e5149 100644 --- a/hw_lem1802.c +++ b/hw_lem1802.c @@ -17,6 +17,7 @@ #include "chargen-4x8.h" #include "hw_lem1802.h" +#undef DEBUG #ifdef DEBUG #define TRACE(...) do { printf("[debug] "); printf(__VA_ARGS__); printf("\n"); } while (0) #else /* DEBUG */ @@ -526,7 +527,7 @@ struct dcpu16_hw *lem1802_new(struct dcpu16 *vm) { } ((struct lem1802_ *)(hw->data))->refresh_rate = 1666; - ((struct lem1802_ *)(hw->data))->blink_rate = 75000; + ((struct lem1802_ *)(hw->data))->blink_rate = 100000; return hw; } diff --git a/tests/test.s b/tests/test.dasm similarity index 100% rename from tests/test.s rename to tests/test.dasm diff --git a/tests/test_lem1802.dasm b/tests/test_lem1802.dasm index 898808b..c25858f 100644 --- a/tests/test_lem1802.dasm +++ b/tests/test_lem1802.dasm @@ -15,23 +15,33 @@ HWN [num] HWI [num] ; set border - SET B, 0x0003 + SET B, 0x0002 SET A, 3 HWI [num] ; show some text - SET I, string + SET I, string1 SET J, 0x8000 - ; color SET Z, 0x1e00 -:print - BOR [i], Z - STI [j], [i] - IFN [I], 0 - SET PC, print + JSR print + + SET I, string2 + SET Z, 0x1e80 + JSR print -:wait - SET PC, wait +:done + SET PC, done + +; prints string at I to vram at J in color Z +:print XOR [I], Z + SET [J], [I] + XOR [I], Z + ADD I, 1 + ADD J, 1 + IFE [I], 0 + SET PC, POP + SET PC, print :num dat 0x0000 -:string dat "yerf!", 0 \ No newline at end of file +:string1 dat "yerf!", 0 +:string2 dat "ortort?", 0 \ No newline at end of file diff --git a/vm-dcpu16.c b/vm-dcpu16.c index 6324717..367cdbc 100644 --- a/vm-dcpu16.c +++ b/vm-dcpu16.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include @@ -371,11 +373,20 @@ COMMAND_HELP(set) { fprintf(f, "Sets addr to value."); } +#define MICROSECONDS_PER_CYCLE 10 COMMAND_IMPL(run) { struct sigaction act; + struct timeval run_start_tv, run_stop_tv; + long long run_cycle_start; + struct timeval start_tv, now_tv, diff_tv; + long long cycle_start, cycles_to_wait; + struct timespec sleep_time; + (void)arg_count, (void)arg_vector; running_ = 1; + gettimeofday(&run_start_tv, NULL); + run_cycle_start = vm->cycle; memset(&act, 0, sizeof act); act.sa_handler = sigint_handler_; @@ -387,6 +398,9 @@ COMMAND_IMPL(run) { } while(running_) { + gettimeofday(&start_tv, NULL); + cycle_start = vm->cycle; + dcpu16_step(vm); if (opt_.verbose > 1) dcpu16_state_print(vm); @@ -394,8 +408,36 @@ COMMAND_IMPL(run) { dcpu16_disassemble_print(vm, vm->reg[DCPU16_REG_PC]); printf("\n"); } + + /* how many cycles did this instr use? */ + cycles_to_wait = vm->cycle - cycle_start; + + if (cycles_to_wait == 0) + continue; + + /* each cycle wants 10 microseconds */ + + + /* how much of that did we spend already */ + gettimeofday(&now_tv, NULL); + timeval_subtract(&diff_tv, &now_tv, &start_tv); + /* do we have time to kill? */ + if (cycles_to_wait * MICROSECONDS_PER_CYCLE > diff_tv.tv_usec) { + sleep_time.tv_sec = diff_tv.tv_sec; + sleep_time.tv_nsec = 1000 * ( (cycles_to_wait * MICROSECONDS_PER_CYCLE) - diff_tv.tv_usec); + sleep_time.tv_nsec = diff_tv.tv_usec * 1000; + + nanosleep(&sleep_time, NULL); + } } + gettimeofday(&run_stop_tv, NULL); + timeval_subtract(&diff_tv, &run_stop_tv, &run_start_tv); + fprintf(stderr, "ran %llu cycles in %lds %dus\n", + vm->cycle - run_cycle_start, + diff_tv.tv_sec, + diff_tv.tv_usec); + printf("interrupted...\n"); return 0; -- 2.43.2