void tdb_shell(tvm_t* vm) { int run = 1, i; char* tokens[MAX_TOKENS]; char str[MAX_INPUT_LENGTH]; int num_breakpoints = 0; tdb_breakpoint_t* breakpoints = NULL; for(i = 0; i < MAX_TOKENS; i++) tokens[i] = malloc(TOKEN_LENGTH); vm->pMemory->registers[0x8].i32 = vm->pProgram->start; while(run) { int retcode = 0; printf(": "); for(i = 0; i < MAX_TOKENS; i++) memset(tokens[i], 0, TOKEN_LENGTH); fgets(str, MAX_INPUT_LENGTH, stdin); tokenize(str, (char**)tokens); switch(cmd_to_idx(tokens[0])) { case -0x1: printf("\nWARNING: \"%s\" is not a valid command.\n", tokens[0]); break; case 0x0: run = 0; break; case 0x1: retcode = tdb_run(vm, breakpoints, num_breakpoints); break; case 0x2: breakpoints = realloc(breakpoints, sizeof(tdb_breakpoint_t) * ++num_breakpoints); breakpoints[num_breakpoints - 1].address = tvm_parse_value(tokens[1]); break; case 0x3: tvm_step(vm, &vm->pMemory->registers[0x8].i32); vm->pMemory->registers[0x8].i32++; printf("Advancing instruction pointer to %i\n", vm->pMemory->registers[0x8].i32); break; }; if(retcode == 1) printf("Breakpoint hit at address: %i\n", vm->pMemory->registers[0x8].i32); printf("\n"); } free(breakpoints); for(i = 0; i < MAX_TOKENS; i++) free(tokens[i]); }
int parse_instructions(tvm_program_t *p, const char ***tokens, tvm_memory_t *pMemory) { int line_idx; for(line_idx = 0; tokens[line_idx]; line_idx++) { p->instr = (int *)realloc(p->instr, sizeof(int) * (line_idx + 2)); p->instr[line_idx] = 0; p->args = (int ***)realloc(p->args, sizeof(int **) * (line_idx + 2)); p->args[line_idx] = (int **)calloc(MAX_ARGS, sizeof(int *)); int token_idx; for(token_idx = 0; token_idx < MAX_TOKENS; token_idx++) { int opcode = 0; /* Skip empty tokens */ if(!tokens[line_idx][token_idx]) continue; opcode = instr_to_opcode(tokens[line_idx][token_idx]); /* If it *isn't* an opcode, skip trying to parse arguments */ if(opcode == -1) continue; int i, instr_idx = 0, num_instr = p->num_instructions; p->instr[p->num_instructions++] = opcode; for(i = ++token_idx; i < (token_idx + 2); ++i) { if(!tokens[line_idx][i] || strlen(tokens[line_idx][i]) <= 0) continue; char *newline = strchr(tokens[line_idx][i], '\n'); if(newline) *newline = 0; /* Check to see if the token specifies a register */ int *pRegister = token_to_register(tokens[line_idx][i], pMemory); if(pRegister) { p->args[num_instr][i - token_idx] = pRegister; continue; } /* Check to see whether the token specifies an address */ if(tokens[line_idx][i][0] == '[') { char *end_symbol = strchr(tokens[line_idx][i], ']'); if(end_symbol) { *end_symbol = 0; p->args[num_instr][i - token_idx] = &((int *)pMemory->mem_space)[tvm_parse_value(tokens[line_idx][i] + 1)]; continue; } } /* Check if the argument is a label */ instr_idx = htab_find(p->label_htab, tokens[line_idx][i]); if(instr_idx >= 0) { p->args[num_instr][i - token_idx] = tvm_add_value(p, instr_idx); continue; } /* F**k it, parse it as a value */ p->args[num_instr][i - token_idx] = tvm_add_value(p, tvm_parse_value(tokens[line_idx][i])); } } } p->args[line_idx] = NULL; p->instr[line_idx] = -0x1; return 0; }
void parse_instruction(tvm_program_t* p, const char** tokens, tvm_memory_t* pMemory) { int token_idx; for(token_idx = 0; token_idx < MAX_TOKENS; token_idx++) { int opcode = 0; /* Skip empty tokens */ if(!tokens[token_idx]) continue; opcode = instr_to_opcode(tokens[token_idx]); /* If it *is* an opcode, parse the arguments */ if(opcode != -1) { int i, instr_idx = 0, num_instr = p->num_instructions; p->instr[p->num_instructions++] = opcode; for(i = ++token_idx; i < (token_idx + 2); ++i) { char* newline; if(!tokens[i] || strlen(tokens[i]) <= 0) continue; newline = strchr(tokens[i], '\n'); if(newline) *newline = 0; /* Check to see if the token specifies a register */ int* pRegister = token_to_register(tokens[i], pMemory); if(pRegister) { p->args[num_instr][i - token_idx] = pRegister; continue; } /* Check to see whether the token specifies an address */ if(tokens[i][0] == '[') { char* end_symbol = strchr(tokens[i], ']'); if(end_symbol) { *end_symbol = 0; p->args[num_instr][i - token_idx] = &((int*)pMemory->mem_space)[tvm_parse_value(tokens[i] + 1)]; continue; } } /* Check if the argument is a label */ instr_idx = htab_find(p->label_htab, tokens[i]); if(instr_idx >= 0) { p->args[num_instr][i - token_idx] = tvm_add_value(p, instr_idx); continue; } /* F**k it, parse it as a value */ p->args[num_instr][i - token_idx] = tvm_add_value(p, tvm_parse_value(tokens[i])); } } } }