From b29631c48410d1e6035275d7f98afb8df44671b1 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Wed, 5 Jun 2019 22:59:32 +0200 Subject: [PATCH] itoa, step --- ka/fmt/itoa.k | 21 +++++++++++++++------ ka/main.k | 7 +++---- ka/str/strrev.k | 39 +++++++++++++++++++++++++++++++++++++++ vm/in/INSTRS | 2 ++ vm/in/debug.c | 8 +++++++- vm/in/instrs.h | 16 ++++++++++++++++ vm/in/mov.c | 2 +- vm/pc/arch.h | 3 +++ vm/pc/except.c | 13 +++++++++++++ vm/pc/main.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 10 files changed, 142 insertions(+), 15 deletions(-) diff --git a/ka/fmt/itoa.k b/ka/fmt/itoa.k index 18e366e..1004772 100644 --- a/ka/fmt/itoa.k +++ b/ka/fmt/itoa.k @@ -31,7 +31,7 @@ _itoa: cmp ax2, 10 ; base 10 cjmpnz .conv - cmp ax2, -9223372036854775808 ; LONG_MIN + cmp ax1, -9223372036854775808 ; LONG_MIN cjmpz .min sgn rdx, ax1 ; extract ax1 sign @@ -49,23 +49,32 @@ _itoa: mod rsx, ax2 ; ax1 % base cmp rsx, 9 ; rsx > 9 ? - caddz rsx, 48 ; '0' - cjmpz .next + cjmpa .nondec + add rsx, 48 ; '0' + jmp .next + +.nondec: add rsx, 87 ; 'a' - 10 - mov ax1, rsx .next: mov b[ax0], rsx inc ax0 div ax1, ax2 - break jmp .conv - ; null-terminate and reverse + ; add minus flag, null-terminate and reverse .fini: + cmp rdx, -1 + cmovz b[ax0], 45 ; '-' + cincz ax0 + mov b[ax0], 0 + + mov ax0, rax + call strrev2 + ret ; diff --git a/ka/main.k b/ka/main.k index dfdfc64..a29639e 100644 --- a/ka/main.k +++ b/ka/main.k @@ -8,17 +8,16 @@ main: enter mov ax0, .buf - mov ax1, 65 + mov ax1, -9223372036854775807 mov ax2, 10 call itoa mov ax0, rax call print - ; prn 10 - + prn 10 mov ax0, .buf - mov ax1, 0xffffffffffffffff + mov ax1, 0xfff85ffffffffff4 mov ax2, 16 call itoa diff --git a/ka/str/strrev.k b/ka/str/strrev.k index 48c24db..ec4d0b0 100644 --- a/ka/str/strrev.k +++ b/ka/str/strrev.k @@ -4,6 +4,8 @@ ; ; void strrev(char *buf, const char *str) ; +; buf and src must NOT overlap +; strrev: test b[ax1], b[ax1] cmovz b[ax0], 0 @@ -32,3 +34,40 @@ strrev: dec ax1 jmp .2 + +; +; void strrev2(char *str) +; +; Inverses str +; +strrev2: + test b[ax0], b[ax0] + cretz + + mov ax1, ax0 + + ; go to str's end, just before + ; the null terminator +.1: + test b[ax1+1], b[ax1+1] + cincnz ax1 + cjmpnz .1 + + ; increase ax0 while decreasing ax1, performing exchanges +.2: + cmp ax0, ax1 + cjmpae .3 + + xchg b[ax0], b[ax1] + + inc ax0 + dec ax1 + jmp .2 + +.3: + ret + + + + + diff --git a/vm/in/INSTRS b/vm/in/INSTRS index 38df33e..09c1a50 100644 --- a/vm/in/INSTRS +++ b/vm/in/INSTRS @@ -210,3 +210,5 @@ break cbreakz cbreaknz +step rim + diff --git a/vm/in/debug.c b/vm/in/debug.c index a65891d..8cff4f2 100644 --- a/vm/in/debug.c +++ b/vm/in/debug.c @@ -10,7 +10,13 @@ IMPL_START_0(break) log("\nExecuting BREAK INSTR\n"); dumpregs(ctx); - while ((getchar() != '\n')); + getchar(); log("Resuming execution\n"); } IMPL_END; + +IMPL_START_1(step) +{ + ctx->step = !!v1; +} +IMPL_END; diff --git a/vm/in/instrs.h b/vm/in/instrs.h index 5182f1b..25a5f6b 100644 --- a/vm/in/instrs.h +++ b/vm/in/instrs.h @@ -37,6 +37,22 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ else R(p1->val) = v1; \ } +#define IMPL_OUT_2 \ + assert(p1->type == A_REG || p1->mem); \ + if (p1->mem) { \ + ulong addr = p1->type == A_REG ? R(p1->val) : p1->val; \ + writemem(ctx, v1, addr + p1->off, p1->mlen); \ + } \ + else R(p1->val) = v1; \ + \ + assert(p2->type == A_REG || p2->mem); \ + if (p2->mem) { \ + ulong addr = p2->type == A_REG ? R(p2->val) : p2->val; \ + writemem(ctx, v2, addr + p2->off, p2->mlen); \ + } \ + else R(p2->val) = v2; \ +} + #define IMPL_END \ } diff --git a/vm/in/mov.c b/vm/in/mov.c index 18a99ee..cf58310 100644 --- a/vm/in/mov.c +++ b/vm/in/mov.c @@ -63,7 +63,7 @@ IMPL_START_2(xchg) v1 = v2; v2 = t; } -IMPL_OUT; +IMPL_OUT_2; IMPL_START_1(lea) { diff --git a/vm/pc/arch.h b/vm/pc/arch.h index 288a759..1645fd4 100644 --- a/vm/pc/arch.h +++ b/vm/pc/arch.h @@ -109,6 +109,9 @@ struct ctx_t // For disassembly FILE *disf; + // Step by step + int step; + // Devices list head dev_t *dh; }; diff --git a/vm/pc/except.c b/vm/pc/except.c index 0cae9f2..556b4f6 100644 --- a/vm/pc/except.c +++ b/vm/pc/except.c @@ -2,11 +2,21 @@ // See the LICENSE file in the project root for more information. #include +#include void _except(ctx_t *ctx, int code, char *fmt, ...) { va_list ap; + // + // Restore stdin echoing + // + struct termios t; + tcgetattr(0, &t); + t.c_lflag |= ECHO; + tcsetattr(0, TCSANOW, &t); + + log("\nException %d - ", code); va_start(ap, fmt); @@ -23,6 +33,9 @@ void _except(ctx_t *ctx, int code, char *fmt, ...) if (ctx->mp) free(ctx->mp); + // + // Shut down devices + // if (devfiniall(ctx) < 0) { log("Couldn't deinitialize devices\n"); exit(-100 - code); diff --git a/vm/pc/main.c b/vm/pc/main.c index 2a2fe4a..6b143a5 100644 --- a/vm/pc/main.c +++ b/vm/pc/main.c @@ -3,6 +3,7 @@ #include #include +#include #define FWPROGSIZE (1024 * 1024 * 1024) static ssize_t fwsize; @@ -43,17 +44,53 @@ ushort dget(ctx_t *ctx) ctx_t main_ctx; +void sigint(int _) +{ + // + // Enable stdin echoing + // + struct termios t; + tcgetattr(0, &t); + t.c_lflag |= ECHO; + tcsetattr(0, TCSANOW, &t); + + // + // Shut down devices + // + devfiniall(&main_ctx); + + exit(0); +} + int main(int argc, char **argv) { FILE *fwfile; - struct timeval time; + main_ctx.r = arch_r; + main_ctx.i = arch_i; + // + // srand + // + struct timeval time; gettimeofday(&time, NULL); srandom((time.tv_sec * 1000) + (time.tv_usec / 1000)); - main_ctx.r = arch_r; - main_ctx.i = arch_i; + // + // Disable stdin echoing + // + struct termios t; + tcgetattr(0, &t); + t.c_lflag &= ~ECHO; + tcsetattr(0, TCSANOW, &t); + + // + // Signal handling + // + + // + // Load program + // if (argc < 2) { log("Not enough arguments\n"); @@ -106,6 +143,9 @@ int main(int argc, char **argv) while (1) { decode(&main_ctx); + + if (main_ctx.step) + getchar(); } }