// The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #include "arch.h" #ifdef _NEED_DISASM #define _except __except static inline void _except(ctx_t *ctx, int x, char *fmt, ...) { va_list ap; log("Disassembly error: "); va_start(ap, fmt); vlog(fmt, ap); va_end(ap); log("\n"); if (ctx->disf) fclose(ctx->disf); exit(-1); } #endif static void scan_param(ctx_t *ctx, acc_t *p) { ushort c; reg_t *r; c = ctx->get(ctx); if (c == A_MEM) { p->mem = 1; p->off = 0; c = ctx->get(ctx); } else if (c == A_OFF) { p->mem = 1; p->off = (short)ctx->get(ctx); c = ctx->get(ctx); } if (c >= A_IMM16) { // Check for double access code if (p->type != A_REG) _except(ctx, E_ILL, "Bad access code"); p->type = c; c = ctx->get(ctx); } p->val = c; if (p->type == A_IMM32) { p->val = (p->val << 16) | ctx->get(ctx); } else if (p->type == A_IMM64) { p->val = (p->val << 16) | ctx->get(ctx); p->val = (p->val << 16) | ctx->get(ctx); p->val = (p->val << 16) | ctx->get(ctx); } else if (p->type == A_REG) { if (p->val > NREGS) { _except(ctx, E_ILL, "Inexistent REG"); } r = &ctx->r[p->val]; if (r->flags & (RES | CTL)) { _except(ctx, E_ACC, "Reserved REG"); } } } #ifndef _NEED_DISASM void decode(ctx_t *ctx) #else void disasm(ctx_t *ctx) #endif { instr_t *i; acc_t p1 = { 0 }, p2 = { 0 }; ulong rip = ctx->r[RIP].val; ushort c = ctx->get(ctx); if (ISPREF(c)) { // nothing for now } else if (!ISINSTR(c)) { _except(ctx, E_ILL, "Bad opcode: 0x%4hX", c); } i = &ctx->i[c]; // Scan for parameters if (i->prm1 != NOPRM) { scan_param(ctx, &p1); if (i->prm2 != NOPRM) { scan_param(ctx, &p2); } } dumpinstr(ctx, rip, c, &p1, &p2); #ifndef _NEED_DISASM i->func(ctx, &p1, &p2); #endif }