// // Created by imanol on 12/26/16. // #include #include #include "debug.h" //uint32_t cycle_count = 0; uint8_t breakpoint = 1; uint16_t breakpoints[0xFF]; uint16_t nbpoints = 0; char lastchoice = 0; void load_state(char *filename) { FILE *state = fopen(filename,"r"); uint16_t regsdump[NUM_REGISTERS+1]; uint16_t memdump[MEMSIZE]; uint16_t *stackdump; uint32_t stacksize, stackpos; fread(regsdump,sizeof(uint16_t),NUM_REGISTERS+1,state); fread(memdump,sizeof(uint16_t),MEMSIZE,state); stackpos = ftell(state); fseek(state,0,SEEK_END); stacksize = (ftell(state) - stackpos)/sizeof(uint16_t); stackdump = calloc(stacksize,sizeof(uint16_t)); fseek(state,stackpos,SEEK_SET); fread(stackdump,sizeof(uint16_t),stacksize,state); fclose(state); load_regs(regsdump); load_memory(memdump); stack_load(stackdump,stacksize); free(stackdump); } void save_state(char *filename) { FILE *state = fopen(filename,"w"); uint16_t regsdump[NUM_REGISTERS+1]; uint16_t memdump[MEMSIZE]; uint16_t *stackdump; uint32_t stacksize; dump_regs(regsdump); dump_memory(memdump); stacksize = stack_dump(&stackdump); fwrite(regsdump,sizeof(uint16_t),NUM_REGISTERS+1,state); fwrite(memdump,sizeof(uint16_t),MEMSIZE,state); fwrite(stackdump,sizeof(uint16_t),stacksize,state); fclose(state); free(stackdump); } void query() { //TODO discard stdin uint8_t end = 0; uint16_t bpoint; uint16_t mempos; char input[100] = {0}; char filename[32]; uint8_t reg; uint8_t value; while(!end) { printf("\n> "); char command = 0; fgets(input,100,stdin); command = input[0]; if (command != '\n') { lastchoice = command; } else { command = lastchoice; } switch (command) { case 'b': sscanf(input,"b %d\n",&bpoint); fprintf(stderr,"Set breakpoint %d to %d",nbpoints,bpoint); breakpoints[nbpoints] = bpoint; nbpoints = nbpoints + 1 % 0xFF; break; case 'd': sscanf(input,"d %d\n",&bpoint); fprintf(stderr,"Deleted breakpoint %d",bpoint); breakpoints[bpoint] = 0; break; case 'c': breakpoint = 0; end = 1; break; case 'n': end = 1; break; case 'r': print_regs(); break; case 'm': sscanf(input,"m %d\n",&mempos); fprintf(stderr,"%d: %02x\n",mempos,mem[mempos]); break; case 's': sscanf(input,"s %s\n",filename); save_state(filename); fprintf(stderr,"Saved state as %s",filename); break; case 'l': sscanf(input,"l %s\n",filename); load_state(filename); fprintf(stderr,"Loaded state as %s",filename); break; case 'w': sscanf(input,"w %d %d\n",®,&value); fprintf(stderr,"Setting register %d to %d",reg,value); regs[reg] = value; break; default: break; } } } uint8_t in_breakpoint(uint16_t pc) { uint8_t i; for(i = 0; i < nbpoints; i++) { if(breakpoints[i] == pc) { return 1; } } return 0; } uint16_t fetch_debug() { uint16_t value = mem[pc++]; /*if(breakpoint) { fprintf(stderr,"0x%2x (0x%2x): %d", pc, pc * sizeof(uint16_t),value); fprintf(stderr," cycle: %d\n", cycle_count++); }*/ return value; } void print_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3) { switch(opcode) { case HALT: printf("HALT\n"); break; case MOV: printf("MOV %d %d\n",arg1,arg2); break; case PUSH: printf("PUSH %d\n",arg1); break; case POP: printf("POP %d\n",arg1); break; case TEQ: printf("TEQ %d %d %d\n",arg1,arg2,arg3); break; case TGT: printf("TGT %d %d %d\n",arg1,arg2,arg3); break; case JMP: printf("JMP %d\n",arg1); break; case JNZ: printf("JNZ %d %d\n",arg1,arg2); break; case JZ: printf("JZ %d %d\n",arg1,arg2); break; case ADD: printf("ADD %d %d %d\n",arg1,arg2,arg3); break; case MUL: printf("MUL %d %d %d\n",arg1,arg2,arg3); break; case MOD: printf("MOD %d %d %d\n",arg1,arg2,arg3); break; case AND: printf("AND %d %d %d\n",arg1,arg2,arg3); break; case OR: printf("OR %d %d %d\n",arg1,arg2,arg3); break; case NOT: printf("NOT %d %d\n",arg1,arg2); break; case LOAD: printf("LOAD %d %d\n",arg1,arg2); break; case STOR: printf("STOR %d %d\n",arg1,arg2); break; case CALL: printf("CALL %d\n",arg1); break; case RET: printf("RET\n"); break; case OUT: printf("OUT %d\n",arg1); break; case IN: printf("IN %d\n",arg1); break; case NOP: printf("NOP\n"); break; default: printf("UNK %d\n", opcode); break; } } void debug_program() { memset(breakpoints,0x00,0xFF); uint16_t arg1; uint16_t arg2; uint16_t arg3; for(;;) { if(in_breakpoint(pc) || breakpoint) { breakpoint = 1; fprintf(stderr, "%d: ", pc); print_instruction(mem[pc], mem[pc+1], mem[pc+2], mem[pc+3]); query(); } uint16_t opcode = fetch_debug(); decode_instruction(opcode, &arg1, &arg2, &arg3); if (execute_instruction(opcode, arg1, arg2, arg3)) { return; } } }