END_TEST START_TEST (test_cpu_stack) { uint16_t old_sp = ctx.cpu.SP; cpu_push(&ctx, 0x1234); fail_unless(ctx.cpu.SP == old_sp - 2); fail_unless(cpu_pop(&ctx) == 0x1234); }
int calculator(FILE* strin, FILE* strout, cpu* my_cpu) { VERIFY(my_cpu != NULL); const char MAXLINE = 10; char word[MAXLINE] = {}; const char PUSH_MAXLINE = 50; char push_word[PUSH_MAXLINE] = {}; int c = 0; double temp = 0; int cond = 0; fprintf(stdout, "# This is prototype of processor unit which calculates expressions\n" "# written in inverted Polish way (or something like that)\n" "# There are commands available:\n" "\n push {number}\n" " pop\n" " add\n" " sub\n" " mul\n" " div\n" " sin\n" " cos\n" " tan\n" " sqrt\n" " pow\n" " end\n" "PLEASE, USE [.] TO DIVIDE FLOAT PART\n" "Here you go\n"); while (true) { cond = cpu_check(my_cpu); VERIFY(cond == CPU_CHECK_OK); fscanf(strin,"%s", &word); c = CHECK_COMMAND(word, PUSH) CHECK_COMMAND(word, POP) CHECK_COMMAND(word, ADD) CHECK_COMMAND(word, SUB) CHECK_COMMAND(word, MUL) CHECK_COMMAND(word, DIV) CHECK_COMMAND(word, SIN) CHECK_COMMAND(word, COS) CHECK_COMMAND(word, TAN) CHECK_COMMAND(word, SQRT) CHECK_COMMAND(word, POW) CHECK_COMMAND(word, END) CHECK_COMMAND(word, DUMP) CMD_NONE; switch (c) { case CMD_PUSH: cond = fscanf(strin, "%s", push_word); VERIFY(cond); cond = cpu_catch_error(strout, my_cpu, cpu_push(my_cpu, push_word)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); if (cond == CPU_ERROR_PUSH_BAD_TOKEN) { fprintf(strout, "\nPUSH BAD TOKEN [%s]\n", push_word); break; } break; case CMD_POP: cond = cpu_catch_error(strout, my_cpu, cpu_pop(strout, my_cpu, &temp)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_ADD: cond = cpu_catch_error(strout, my_cpu, cpu_add(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_SUB: cond = cpu_catch_error(strout, my_cpu, cpu_sub(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_MUL: cond = cpu_catch_error(strout, my_cpu, cpu_mul(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_DIV: cond = cpu_catch_error(strout, my_cpu, cpu_div(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_SIN: cond = cpu_catch_error(strout, my_cpu, cpu_sin(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_COS: cond = cpu_catch_error(strout, my_cpu, cpu_cos(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_TAN: cond = cpu_catch_error(strout, my_cpu, cpu_tan(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_SQRT: cond = cpu_catch_error(strout, my_cpu, cpu_sqrt(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_POW: cond = cpu_catch_error(strout, my_cpu, cpu_pow(my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_DUMP: cond = cpu_catch_error(strout, my_cpu, cpu_dump(strout, my_cpu)); //if (cond == CPU_ERROR_CATCHER_BAD) VERIFY(!"ERROR HAS BEEN CAUGHT"); break; case CMD_END: return 0; default: fprintf(strout, "WRONG TOKEN [%s]\n", word); break; } cond = cpu_check(my_cpu); VERIFY(cond == CPU_CHECK_OK); } }
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; }