From 42d738b5fa1986a59ddb9aba1cc6f21eeddb6275 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Wed, 1 Feb 2017 13:56:56 +0100 Subject: [PATCH] Disassembler implemented. --- debug.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- main.cpp | 3 +- 2 files changed, 111 insertions(+), 5 deletions(-) diff --git a/debug.cpp b/debug.cpp index 58e1c72..7b2af6e 100644 --- a/debug.cpp +++ b/debug.cpp @@ -135,17 +135,21 @@ static void debug_print_callstack(byte offset) { static void debug_print_basic(byte offset) { debug_draw_space(1, 2, 70, 35, "CODE:"); debug_set_ink(255, 255, 255); + if (*pc >= 0x8000) { + debug_print(17, 17, "No source code for this memory region"); + return; + } int line = offset; int row = 0; char* prog = program; - if (lines[*pc] == line) { debug_set_ink(128, 128, 0); debug_fill_rect(1, 2 + line, 70, 1); debug_set_ink(255, 255, 0); } + if (lines[*pc] == line) { debug_set_ink(0, 0, 0); debug_fill_rect(1, 2 + line, 70, 1); debug_set_ink(255, 255, 0); } else debug_set_ink(255, 255, 255); while (line < 35 && *prog != 0) { if (*prog == '\t') { row += 4; } else if (*prog == '\n') { row = 0; line++; - if (lines[*pc] == line) { debug_set_ink(128, 128, 0); debug_fill_rect(1, 2 + line, 70, 1); debug_set_ink(255, 255, 0); } + if (lines[*pc] == line) { debug_set_ink(0, 0, 0); debug_fill_rect(1, 2 + line, 70, 1); debug_set_ink(255, 255, 0); } else debug_set_ink(255, 255, 255); } else if (*prog == 13) { // row++; @@ -171,6 +175,106 @@ static void debug_print_registers() { debug_print(72, 27, cadena); debug_print_ex(74, 27, &debug_mem[0xFFFD], 1); } +char asm_line[255]; +static void get_op1(word& offset, const char* op) { sprintf(asm_line, "%.4X: %.2X %s", offset, debug_mem[offset++], op); } +static void get_op2(word& offset, const char* op) { sprintf(asm_line, "%.4X: %.2X%.2X %s %.2X", offset, debug_mem[offset], debug_mem[offset + 1], op, debug_mem[offset + 1]); offset += 2; } +static void get_op3(word& offset, const char* op) { sprintf(asm_line, "%.4X: %.2X%.2X%.2X %s %.4X", offset, debug_mem[offset], debug_mem[offset + 1], debug_mem[offset + 2], op, debug_mem[offset + 1] + (debug_mem[offset + 2] << 8));; offset += 3; } +static char* get_asm_line(word& offset) { + + //sprintf(asm_line, "%.4X ", offset); + switch (debug_mem[offset]) { + case OP_NOP: get_op1(offset, "NOP"); break; + case OP_PUSH: get_op2(offset, "PUSH"); break; + case OP_POP: get_op1(offset, "POP"); break; + case OP_DUP: get_op1(offset, "DUP"); break; + case OP_SWAP: get_op1(offset, "SWAP"); break; + + case OP_LOAD: get_op3(offset, "LOAD"); break; + case OP_LOADI: get_op3(offset, "LOADI"); break; + case OP_STORE: get_op3(offset, "STORE"); break; + case OP_STOREI: get_op3(offset, "STOREI"); break; + + case OP_LOADXY: get_op1(offset, "LOADXY"); break; + case OP_STOREXY: get_op1(offset, "STOREXY"); break; + case OP_SETX: get_op3(offset, "SETX"); break; + case OP_SETY: get_op1(offset, "SETY"); break; + case OP_SETZ: get_op1(offset, "SETZ"); break; + case OP_GETY: get_op1(offset, "GETY"); break; + case OP_GETZ: get_op1(offset, "GETZ"); break; + case OP_INCX: get_op1(offset, "INCX"); break; + case OP_DECX: get_op1(offset, "DECX"); break; + case OP_INCY: get_op1(offset, "INCY"); break; + case OP_DECY: get_op1(offset, "DECY"); break; + case OP_INCZ: get_op1(offset, "INCZ"); break; + case OP_DECZ: get_op1(offset, "DECZ"); break; + + case OP_JMP: get_op3(offset, "JMP"); break; + case OP_JNT: get_op3(offset, "JNT"); break; + case OP_JTR: get_op3(offset, "JTR"); break; + case OP_JSR: get_op3(offset, "JSR"); break; + case OP_RET: get_op1(offset, "RET"); break; + case OP_CALL: get_op1(offset, "CALL"); break; + + case OP_RJ: get_op2(offset, "RJ"); break; + case OP_RB: get_op2(offset, "RB"); break; + case OP_RJZ: get_op2(offset, "RJZ"); break; + case OP_RJN: get_op2(offset, "RJN"); break; + case OP_RBZ: get_op2(offset, "RBZ"); break; + case OP_RBN: get_op2(offset, "RBN"); break; + + case OP_RJYZ: get_op2(offset, "RJYZ"); break; + case OP_RJYN: get_op2(offset, "RJYN"); break; + case OP_RBYZ: get_op2(offset, "RBYZ"); break; + case OP_RBYN: get_op2(offset, "RBYN"); break; + case OP_RJZZ: get_op2(offset, "RJZZ"); break; + case OP_RJZN: get_op2(offset, "RJZN"); break; + case OP_RBZZ: get_op2(offset, "RBZZ"); break; + case OP_RBZN: get_op2(offset, "RBZN"); break; + + case OP_ADD: get_op1(offset, "ADD"); break; + case OP_SUB: get_op1(offset, "SUB"); break; + case OP_MUL: get_op1(offset, "MUL"); break; + case OP_DIV: get_op1(offset, "DIV"); break; + case OP_MOD: get_op1(offset, "MOD"); break; + case OP_AND: get_op1(offset, "AND"); break; + case OP_OR: get_op1(offset, "OR"); break; + case OP_NOT: get_op1(offset, "NOT"); break; + case OP_NEG: get_op1(offset, "NEG"); break; + case OP_INC: get_op1(offset, "INC"); break; + case OP_DEC: get_op1(offset, "DEC"); break; + case OP_CONCAT: get_op1(offset, "CONCAT"); break; + + case OP_EQ: get_op1(offset, "EQ"); break; + case OP_NEQ: get_op1(offset, "NEQ"); break; + case OP_LT: get_op1(offset, "LT"); break; + case OP_GT: get_op1(offset, "GT"); break; + case OP_LEQ: get_op1(offset, "LEQ"); break; + case OP_GEQ: get_op1(offset, "GEQ"); break; + + case OP_IN: get_op2(offset, "IN"); break; + case OP_OUT: get_op2(offset, "OUT"); break; + case OP_SLEEP: get_op1(offset, "SLEEP"); break; + default: sprintf(asm_line, "%.4X: ERROR: Unknown opcode: %.2X", offset, debug_mem[offset-1]); break; + } + return asm_line; +} + +void debug_print_asm(byte offset) { + word pointer = *pc + offset; if (pointer >= 10) pointer -= 10; + debug_draw_space(39, 39, 40, 20, "ASM:"); + debug_set_ink(255, 255, 255); + char cadena[255]; + for (int i = 0; i < 20; i++) { + if (*pc == pointer) { debug_set_ink(0, 0, 0); debug_fill_rect(39, 39 + i, 40, 1); debug_set_ink(255, 255, 0); } + else debug_set_ink(255, 255, 255); + debug_print(39, 39+i, get_asm_line(pointer)); + //sprintf(cadena, "%.4X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X", offset, debug_mem[offset], debug_mem[offset + 1], debug_mem[offset + 2], debug_mem[offset + 3], debug_mem[offset + 4], debug_mem[offset + 5], debug_mem[offset + 6], debug_mem[offset + 7]); + //debug_print(1, 39 + i, cadena); debug_print_ex(30, 39 + i, &debug_mem[offset], 8); + //offset += 8; + } + +} + void debug_init(unsigned char* mem) { debug_mem = mem; lines = parser_get_lines(); @@ -210,14 +314,15 @@ void debug_update() { debug_set_paper(128, 128, 128); debug_clear(); - debug_set_ink(64, 64, 64); +/* debug_set_ink(64, 64, 64); debug_fill_rect(39, 39, 40, 20); debug_draw_inset(39, 39, 40, 20); debug_set_ink(0, 0, 0); - debug_print(39, 38, "DISASSEMBLY:"); + debug_print(39, 38, "DISASSEMBLY:");*/ debug_print_memory(0); + debug_print_asm(0); debug_print_datastack(0); debug_print_callstack(0); debug_print_registers(); diff --git a/main.cpp b/main.cpp index fe4bd0d..89cc66d 100644 --- a/main.cpp +++ b/main.cpp @@ -60,7 +60,8 @@ int main(int argc, char** argv) { anykey = true; just_pressed = sdlEvent.key.keysym.scancode; if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { should_quit = true; } - if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_RETURN) { vm_big_step(); debug_update(); } + if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_F10) { vm_big_step(); debug_update(); } + if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_F11) { vm_step(); debug_update(); } } } //vm_step();