/** * Runs the instruction at the program counters position in memory. */ void vm_exec() { cycles++; Instruction* op = mem_load_instr(pcounter); print_instr(op); switch(op->op) { case OP_NAP: break; case OP_ADD: op_add(op); break; case OP_SUB: op_sub(op); break; case OP_EXP: op_exp(op); break; case OP_SIN: op_sin(op); break; case OP_COS: op_cos(op); break; case OP_TAN: op_tan(op); break; case OP_LW: op_lw(op); break; case OP_SW: op_sw(op); break; case OP_SB: op_sb(op); break; case OP_J: op_j(op); return; // Jump case OP_JR: op_jr(op); return; case OP_JAL: op_jal(op); return; case OP_JZ: op_jz(op); return; case OP_JNZ: op_jnz(op); return; case OP_JEQ: op_jeq(op); return; case OP_JNQ: op_jnq(op); return; case OP_PUSH: op_push(op); break; case OP_POP: op_pop(op); break; case OP_PRTI: op_prti(op); break; case OP_EXIT: vm_exit(op->k); return; /* Unsupported operation */ default: printf("Error: Invalid operation at %d\n", pcounter); print_instr(op); vm_exit(-1); return; } pcounter = pcounter + 8; }
void opcode_jump (void) { error = E_UNKNOWN_OPCODE; //fda group if (strcmp( (char *)token,"addwf")==0) error = op_addwf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"addwfc")==0) error = op_addwfc((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"andwf")==0) error = op_andwf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"comf")==0) error = op_comf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"decf")==0) error = op_decf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"decfsz")==0) error = op_decfsz((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"dcfsnz")==0) error = op_dcfsnz((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"incf")==0) error = op_incf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"incfsz")==0) error = op_incfsz((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"infsnz")==0) error = op_infsnz((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"iorwf")==0) error = op_iorwf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"movf")==0) error = op_movf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"rlcf")==0) error = op_rlcf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"rlncf")==0) error = op_rlncf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"rrcf")==0) error = op_rrcf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"rrncf")==0) error = op_rrncf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"subfwb")==0) error = op_subfwb((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"subwf")==0) error = op_subwf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"subwfb")==0) error = op_subwfb((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"swapf")==0) error = op_swapf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"xorwf")==0) error = op_xorwf((unsigned char *) file_line,token_len); //fa group if (strcmp( (char *)token,"clrf")==0) error = op_clrf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"cpfseq")==0) error = op_cpfseq((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"cpfsgt")==0) error = op_cpfsgt((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"cpfslt")==0) error = op_cpfslt((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"movwf")==0) error = op_movwf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"mulwf")==0) error = op_mulwf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"negf")==0) error = op_negf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"setf")==0) error = op_setf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tstfsz")==0) error = op_tstfsz((unsigned char *) file_line,token_len); //movff if (strcmp( (char *)token,"movff")==0) error = op_movff((unsigned char *) file_line,token_len); //fba group if (strcmp( (char *)token,"bcf")==0) error = op_bcf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"bsf")==0) error = op_bsf((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"btfsc")==0) error = op_btfsc((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"btfss")==0) error = op_btfss((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"btg")==0) error = op_btg((unsigned char *) file_line,token_len); //one byte (literal, control) group - decide if relative / absolute if (strcmp( (char *)token,"bc")==0) error = op_bc((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bn")==0) error = op_bn((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bnc")==0) error = op_bnc((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bnn")==0) error = op_bnn((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bnov")==0) error = op_bnov((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bnz")==0) error = op_bnz((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bov")==0) error = op_bov((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bz")==0) error = op_bz((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"rcall")==0) error = op_rcall((unsigned char *) file_line,token_len,addr,replaced); if (strcmp( (char *)token,"bra")==0) error = op_bra((unsigned char *) file_line,token_len,addr,replaced); //no decision if (strcmp( (char *)token,"retlw")==0) error = op_retlw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"addlw")==0) error = op_addlw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"andlw")==0) error = op_andlw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"iorlw")==0) error = op_iorlw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"movlb")==0) error = op_movlb((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"movlw")==0) error = op_movlw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"mullw")==0) error = op_mullw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"sublw")==0) error = op_sublw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"xorlw")==0) error = op_xorlw((unsigned char *) file_line,token_len); //goto/call - 2 byte with 16 bit variable if (strcmp( (char *)token,"call")==0) error = op_call((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"goto")==0) error = op_goto((unsigned char *) file_line,token_len); //lfsr if (strcmp( (char *)token,"lfsr")==0) error = op_lfsr((unsigned char *) file_line,token_len); //no suffix after opcode if (strcmp( (char *)token,"clrwdt")==0) error = op_clrwdt((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"daw")==0) error = op_daw((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"nop")==0) error = op_nop((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"pop")==0) error = op_pop((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"push")==0) error = op_push((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"reset")==0) error = op_reset((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"retfie")==0) error = op_retfie((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"return")==0) error = op_return((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"sleep")==0) error = op_sleep((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblrd*")==0) error = op_tblrd((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblrd*+")==0) error = op_tblrdpi((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblrd*-")==0) error = op_tblrdpd((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblrd+*")==0) error = op_tblrdip((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblwt*")==0) error = op_tblwt((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblwt*+")==0) error = op_tblwtpi((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblwt*-")==0) error = op_tblwtpd((unsigned char *) file_line,token_len); if (strcmp( (char *)token,"tblwt+*")==0) error = op_tblwtip((unsigned char *) file_line,token_len); }
int op_tne() { return alu_tne(op_pop() , op_pop()); }
int op_tgt() { return alu_tgt(op_pop() , op_pop()); }
int op_teq() { return alu_teq(op_pop() , op_pop()); }
void op_div() { element_var_t var; alu_div(op_pop(),op_pop(),&var); op_push(var); }
void op_mul() { element_var_t var; alu_mul(op_pop(),op_pop(),&var); op_push(var); }
void op_sub() { element_var_t var; alu_sub(op_pop(),op_pop(),&var); op_push(var); }
void op_add() { element_var_t var; alu_add(op_pop(),op_pop(),&var); op_push(var); }
void Step() { Opcodes OP = (Opcodes)Fetch8(); //printf("%08X:%08X\n", Registers[sp], Registers[pc]); switch (OP) { case O_NOP: op_nop(); break; case O_MOV: op_mov(); break; case O_ADD: op_add(); break; case O_SUB: op_sub(); break; case O_MUL: op_mul(); break; case O_DIV: op_div(); break; case O_LI: op_li(); break; case O_MOVF: op_movf(); break; case O_ADDF: op_addf(); break; case O_SUBF: op_subf(); break; case O_MULF: op_mulf(); break; case O_DIVF: op_divf(); break; case O_LIF: op_lif(); break; case O_XOR: op_xor(); break; case O_AND: op_and(); break; case O_MOD: op_mod(); break; case O_OR: op_or(); break; case O_NOT: op_not(); break; case O_SHR: op_shr(); break; case O_SHL: op_shl(); break; case O_PUSH: op_push(); break; case O_POP: op_pop(); break; case O_STB: op_stb(); break; case O_LDB: op_ldb(); break; case O_STH: op_sth(); break; case O_LDH: op_ldh(); break; case O_STW: op_stw(); break; case O_LDW: op_ldw(); break; case O_LDF: op_ldf(); break; case O_STF: op_stf(); break; case O_CMP: op_cmp(); break; case O_B: op_b(0); break; case O_BC: op_b(1); break; case O_BEQ: op_bcond(ctr0_eq); break; case O_BNE: op_bcond(ctr0_ne); break; case O_BGT: op_bcond(ctr0_gt); break; case O_BLT: op_bcond(ctr0_lt); break; case O_BTC: op_btc(); break; case O_INC: op_inc(); break; case O_DEC: op_dec(); break; default: Error("Error: Unknown Opcode PC = %d OP = %08X\n", Registers[pc], OP); } Ticks++; }