int cpu_start(Cpu *cpu){ cpu->run = 1; int ret_val = 0; while ((NPC < cpu->prog_len) && cpu->run){ switch (cpu->firmware[NPC]){ case push_num: cpu_push_num(cpu, cpu->firmware[NPC + 1]); NPC_INC(2); break; case pop: cpu_pop(cpu, cpu->firmware[NPC + 1]); if (p_errno){ break; } NPC_INC(2); break; case push_reg: cpu_push_reg(cpu, cpu->firmware[NPC + 1]); NPC_INC(2); break; case add: cpu_add(cpu); if (p_errno){ break; } NPC_INC(1); break; case mul: cpu_mul(cpu); if (p_errno){ break; } NPC_INC(1); break; case sub: cpu_sub(cpu); if (p_errno){ break; } NPC_INC(1); break; case divide: cpu_div(cpu); if (p_errno){ break; } NPC_INC(1); break; case tr: cpu_tr(cpu, cpu->firmware[NPC + 1]); break; case trip: cpu_trip(cpu, cpu->firmware[NPC + 1]); break; case trin: cpu_trin(cpu, cpu->firmware[NPC + 1]); break; case triz: cpu_triz(cpu, cpu->firmware[NPC + 1]); break; case gsp: cpu_gsp(cpu, cpu->firmware[NPC + 1]); NPC_INC(2); break; case ssp: cpu_ssp(cpu, cpu->firmware[NPC + 1]); NPC_INC(2); break; case syscall: cpu_syscall(cpu, &ret_val); NPC_INC(1); break; case out: cpu_out(cpu); NPC_INC(1); break; default: NPC_INC(1); } if (p_errno){ printf("\nError at %d", NPC); return 1; } } cpu->run = 0; return ret_val; }
/** This function exec byte code of instructions @param code array of byte code @return number of error(0 if no error) */ int cpu_run(char* addr_code) { assert(addr_code); cpu_t* cpu = NULL; cpu_ctor(&cpu, CPU_STACK_MAX, addr_code); char* current_byte = addr_code; start_logging("logs.txt"); while(FOREVER) { int cmd = *current_byte; current_byte++; //printf("%d \n",cmd); switch(cmd) { case PUSH: if(cpu_push(cpu, ¤t_byte)) printf("CPU CRASHED! PUSH HAVEN'T FULFILLED"); break; case POP: if(cpu_pop(cpu, ¤t_byte)) printf("CPU CRASHED! POP HAVEN'T FULFILLED"); break; case OK: if(cpu_ok(cpu)) printf("CPU CRASHED! CPU ISN'T OK"); break; case DUMP: if(cpu_dump(cpu)) printf("CPU CRASHED! DUMP HAVEN'T FULFILLED"); break; case ADD: if(cpu_add(cpu)) printf("CPU CRASHED! ADD HAVEN'T FULFILLED"); break; case SUB: if(cpu_sub(cpu)) printf("CPU CRASHED! SUB HAVEN'T FULFILLED"); break; case MUL: if(cpu_mul(cpu)) printf("CPU CRASHED! MUL HAVEN'T FULFILLED"); break; case DIR: if(cpu_dir(cpu)) printf("CPU CRASHED! DIR HAVEN'T FULFILLED"); break; case SIN: if(cpu_sin(cpu)) printf("CPU CRASHED! SIN HAVEN'T FULFILLED"); break; case COS: if(cpu_cos(cpu)) printf("CPU CRASHED! COS HAVEN'T FULFILLED"); break; case SQRT: if(cpu_sqrt(cpu)) printf("CPU CRASHED! SQRT HAVEN'T FULFILLED"); break; case JA: if(cpu_ja(cpu, ¤t_byte)) printf("CPU CRASHED! JA HAVEN'T FULFILLED"); break; case JAE: if(cpu_jae(cpu, ¤t_byte)) printf("CPU CRASHED! JAE HAVEN'T FULFILLED"); break; case JB: if(cpu_jb(cpu, ¤t_byte)) printf("CPU CRASHED! JB HAVEN'T FULFILLED"); break; case JBE: if(cpu_jbe(cpu, ¤t_byte)) printf("CPU CRASHED! JBE HAVEN'T FULFILLED"); break; case JE: if(cpu_je(cpu, ¤t_byte)) printf("CPU CRASHED! JE HAVEN'T FULFILLED"); break; case JNE: if(cpu_jne(cpu, ¤t_byte)) printf("CPU CRASHED! JNE HAVEN'T FULFILLED"); break; case JMP: if(cpu_jmp(cpu, ¤t_byte)) printf("CPU CRASHED! JMP HAVEN'T FULFILLED"); break; case OUT: if(cpu_out(cpu)) printf("CPU CRASHED! OUT HAVEN'T FULFILLED"); break; case MOV: if(cpu_mov(cpu, ¤t_byte)) printf("CPU CRASHED! MOV HAVEN'T FULFILLED"); break; case INC: if(cpu_inc(cpu, ¤t_byte)) printf("CPU CRASHED! INC HAVEN'T FULFILLED"); break; case DEC: if(cpu_dec(cpu, ¤t_byte)) printf("CPU CRASHED! DEC HAVEN'T FULFILLED"); break; case CALL: if(cpu_call(cpu, ¤t_byte)) printf("CPU CRASHED! CALL HAVEN'T FULFILLED"); break; case RET: if(cpu_ret(cpu, ¤t_byte)) printf("CPU CRASHED! RET HAVEN'T FULFILLED"); break; case END: return 0; break; default: { fprintf(stderr, "ERROR! Unknown command at address %o. \n", (int)current_byte); return 1; } } } return 0; }