/* Copyright (C) 2006 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../pic-instructions.h" #include "dspic-processors.h" #include "dspic-instructions.h" using namespace dspic; using namespace dspic_instructions; namespace dspic { extern Trace *gTrace; // Points to gpsim's global trace object. extern Cycle_Counter *gCycles; // Points to gpsim's global cycle counter. } struct dsPicInstructionConstructor { unsigned int inst_mask; unsigned int opcode; instruction * (*inst_constructor) (Processor *cpu, unsigned int inst,unsigned int addr); }; struct dsPicInstructionConstructor op_dsPic[] = { { 0xff8000, 0xb00000, ADDR::construct }, // Lit { 0xf80000, 0x400000, ADDR::construct }, // Wb + Lit -> Wd { 0xff7fff, 0xcb0000, ADD::construct }, // add accumulators { 0xff8000, 0xb48000, ADDC::construct }, // f to W { 0xff8000, 0xb08000, ADDC::construct }, // Lit { 0xf80000, 0x480000, ADDC::construct }, // Wb + Lit -> Wd { 0xff8000, 0xb60000, AND::construct }, // f to W { 0xff8000, 0xb20000, AND::construct }, // Lit { 0xf80000, 0x600060, AND::construct }, // Wb + Lit -> Wd { 0xf80000, 0x600000, AND::construct }, { 0xff8000, 0xd58000, ASR::construct }, // f to W { 0xff8000, 0xd18000, ASR::construct }, // Lit { 0xff8070, 0xde8000, ASR::construct }, // Wb + Lit -> Wd { 0xff0000, 0xa90000, BCLR::construct }, { 0xff0b80, 0xa10000, BCLR::construct }, { 0xf00000, 0x300000, BRA::construct }, // branch literal offset { 0xfffff0, 0x016000, BRA::construct }, // computed branch { 0xfc0000, 0x0c0000, BRA::construct }, // branch on accumulator state { 0xff0000, 0xa80000, BSET::construct }, { 0xff0b80, 0xa00000, BSET::construct }, { 0xff0780, 0xad0000, BSW::construct }, { 0xff0000, 0xaa0000, BTG::construct }, { 0xff0000, 0xaf0000, BTS::construct }, { 0xff0000, 0xab0000, BTST::construct }, { 0xff0780, 0xa30000, BTST::construct }, { 0xff0780, 0xa50000, BTST::construct }, { 0xff0000, 0xac0000, BTSTS::construct }, { 0xff0780, 0xa40000, BTSTS::construct }, { 0xff0001, 0x020000, CALL::construct }, { 0xfffff0, 0x010000, CALL::construct }, { 0xff8000, 0xef0000, CLR::construct }, { 0xff807f, 0xeb0000, CLR::construct }, { 0xff4000, 0xc30000, CLR::construct }, { 0xffffff, 0xfe6000, CLRWDT::construct }, { 0xff8000, 0xee8000, COM::construct }, { 0xff8000, 0xea8000, COM::construct }, { 0xffa000, 0xe30000, CP::construct }, { 0xff83e0, 0xe10060, CP::construct }, { 0xff8380, 0xe10000, CP::construct }, { 0xffa000, 0xe20000, CP0::construct }, { 0xfffb80, 0xe00000, CP0::construct }, { 0xffa000, 0xe38000, CPB::construct }, { 0xff83e0, 0xe18060, CPB::construct }, { 0xff8380, 0xe18000, CPB::construct }, { 0xfe03f0, 0xe60000, CPS::construct }, { 0xfffff0, 0xfd4000, DAW::construct }, { 0xff8000, 0xed0000, DEC::construct }, { 0xff8000, 0xe90000, DEC::construct }, { 0xff8000, 0xed8000, DEC::construct }, // DEC2 { 0xff8000, 0xe98000, DEC::construct }, // DEC2 { 0xffc000, 0xfc0000, DISI::construct }, { 0xff8030, 0xd80000, DIV::construct }, { 0xff8030, 0xd88000, DIV::construct }, { 0xff87f0, 0xd90000, DIV::construct }, { 0xffc000, 0x080000, DO::construct }, { 0xfffff0, 0x088000, DO::construct }, { 0xfc4c03, 0xf04003, ED::construct }, { 0xfc4c03, 0xf04002, ED::construct }, { 0xfff870, 0xfd0000, EXCH::construct }, { 0xfff800, 0xdf0000, FB::construct }, // FBCL { 0xfff800, 0xcf8000, FB::construct }, // FF1L { 0xfff800, 0xcf0000, FB::construct }, // FF1R { 0xff0000, 0x040000, GOTO::construct }, { 0xfffff0, 0x014000, GOTO::construct }, { 0xff8000, 0xec0000, DEC::construct }, { 0xff8000, 0xe80000, DEC::construct }, { 0xff8000, 0xec8000, DEC::construct }, // INC2 { 0xff8000, 0xe88000, DEC::construct }, // DEC2 { 0xff8000, 0xb70000, IOR::construct }, // f to W { 0xff8000, 0xb30000, IOR::construct }, // Lit { 0xf80000, 0x700000, IOR::construct }, // Wb + Lit -> Wd { 0xff0000, 0xca0000, LAC::construct }, { 0xffc001, 0xfa0000, LNK::construct }, { 0xff8000, 0xd50000, LSR::construct }, // Note LSR is similar to ASR { 0xff8000, 0xd10000, LSR::construct }, // Lit { 0xff8070, 0xde0000, LSR::construct }, // Wb + Lit -> Wd { 0xf84000, 0xc00000, MAC::construct }, { 0xfc4003, 0xf00000, MAC::construct }, { 0xff8000, 0xbf8000, MOV::construct }, { 0xffa000, 0xb7a000, MOV::construct }, { 0xf80000, 0x800000, MOV::construct }, { 0xf80000, 0x880000, MOV::construct }, { 0xfff000, 0xb3c000, MOV::construct }, //MOV.B { 0xf00000, 0x200000, MOV::construct }, { 0xf80000, 0x900000, MOV::construct }, { 0xf80000, 0x980000, MOV::construct }, { 0xf80000, 0x780000, MOV::construct }, { 0xfff880, 0xbe0000, MOV::construct }, //MOV.D { 0xffc071, 0xbe8000, MOV::construct }, //MOV.D { 0xff4000, 0xc70000, MOVSAC::construct }, { 0xf84003, 0xc00003, MPY::construct }, // degenerate to MAC { 0xf84003, 0xc04003, MPY::construct }, // MPY.N and MSC { 0xffa000, 0xbc0000, MUL::construct }, { 0xff8000, 0xb98000, MUL::construct }, //MUL.SS { 0xff8060, 0xb90000, MUL::construct }, //MUL.SU { 0xff8000, 0xb88000, MUL::construct }, //MUL.US { 0xff8060, 0xb80000, MUL::construct }, //MUL.UU { 0xff8000, 0xee0000, NEG::construct }, { 0xff8000, 0xea0000, NEG::construct }, { 0xff7fff, 0xcb1000, NEG::construct }, { 0xff0000, 0x000000, NOP::construct }, { 0xff0000, 0xff0000, NOP::construct }, { 0xff0001, 0xf90000, POP::construct }, { 0xf8407f, 0x78004f, POP::construct }, { 0xfff8ff, 0xbe004f, POP::construct }, { 0xffffff, 0xfe8000, POP::construct }, // POP.S { 0xff0001, 0xf80000, PUSH::construct }, { 0xf87f80, 0x781f80, PUSH::construct }, { 0xfffff1, 0xbe9f80, PUSH::construct }, { 0xffffff, 0xfea000, PUSH::construct }, // PUSH.S { 0xfffffe, 0xfe4000, PWRSAV::construct }, { 0xff0000, 0x070000, RCALL::construct }, { 0xfffff0, 0x012000, RCALL::construct }, { 0xffc000, 0x090000, REPEAT::construct }, { 0xfffff0, 0x098000, REPEAT::construct }, { 0xffffff, 0xfe0000, RESET::construct }, { 0xffffff, 0x064000, RET::construct }, // RETFIE { 0xff8000, 0x050000, RET::construct }, // RETLW { 0xffffff, 0x060000, RET::construct }, // RETURN { 0xff8000, 0xd68000, ROT::construct }, // RLC { 0xff8000, 0xd28000, ROT::construct }, // RLC { 0xff8000, 0xd60000, ROT::construct }, // RLNC { 0xff8000, 0xd20000, ROT::construct }, // RLNC { 0xff8000, 0xd78000, ROT::construct }, // RRC { 0xff8000, 0xd38000, ROT::construct }, // RRC { 0xff8000, 0xd70000, ROT::construct }, // RNC { 0xff8000, 0xd30000, ROT::construct }, // RNC { 0xff0000, 0xcc0000, SAC::construct }, { 0xff0000, 0xcd0000, SAC::construct }, // SAC.R { 0xfff800, 0xfb0000, SE::construct }, { 0xff8000, 0xef8000, SETM::construct }, { 0xff807f, 0xeb8000, SETM::construct }, { 0xff7fc0, 0xc80040, SFTAC::construct }, { 0xff7ff0, 0xc80000, SFTAC::construct }, { 0xff8000, 0xd40000, SL::construct }, { 0xff8000, 0xd00000, SL::construct }, { 0xff8070, 0xdd0040, SL::construct }, { 0xff8070, 0xdd0000, SL::construct }, { 0xff8000, 0xb50000, SUB::construct }, { 0xff8000, 0xb10000, SUB::construct }, { 0xf80000, 0x500000, SUB::construct }, { 0xff7fff, 0xcb3000, SUB::construct }, { 0xff8000, 0xb58000, SUB::construct }, //SUBB { 0xff8000, 0xb18000, SUB::construct }, { 0xf80000, 0x580000, SUB::construct }, { 0xff8000, 0xbd8000, SUB::construct }, //SUBBR { 0xf80000, 0x180000, SUB::construct }, { 0xff8000, 0xbd0000, SUB::construct }, //SUBR { 0xf80000, 0x100000, SUB::construct }, { 0xffbff0, 0xfd8000, SWAP::construct }, { 0xff8000, 0xba8000, TBLRD::construct }, //TBLRDH { 0xff8000, 0xba0000, TBLRD::construct }, //TBLRDL { 0xff8000, 0xbb8000, TBLWT::construct }, //TBLWTH { 0xff8000, 0xbb0000, TBLWT::construct }, //TBLWTL { 0xffffff, 0xfa8000, ULNK::construct }, { 0xff8000, 0xb68000, XOR::construct }, // f to W { 0xff8000, 0xb28000, XOR::construct }, // Lit { 0xf80000, 0x680000, XOR::construct }, // Wb + Lit -> Wd { 0xffc000, 0xfb8000, ZE::construct } }; const int NUM_OP_DSPIC = sizeof(op_dsPic) / sizeof(op_dsPic[0]); instruction * dsPicProcessor::disasm (unsigned int address, unsigned int inst) { //printf("dspic disasm addr 0x%x, opcode 0x%x\n",address,inst); instruction *pi; pi = 0; for(int i =0; iregisters[m_addr]->name().c_str()); return buff; } //-------------------------------------------------- RegDirectAddrMode::RegDirectAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"%s") { } RegisterValue RegDirectAddrMode::get() { return m_cpu->registers[m_addr]->getRV(); } void RegDirectAddrMode::put(RegisterValue &n_rv) { m_cpu->registers[m_addr]->putRV(n_rv); } //-------------------------------------------------- RegIndirectAddrMode::RegIndirectAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[%s]") { } RegisterValue RegIndirectAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); return rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); } void RegIndirectAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); } //-------------------------------------------------- RegIndirectPostDecAddrMode::RegIndirectPostDecAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[%s--]") { } RegisterValue RegIndirectPostDecAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); return retRV; } void RegIndirectPostDecAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); } //-------------------------------------------------- RegIndirectPostIncAddrMode::RegIndirectPostIncAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[%s++]") { } RegisterValue RegIndirectPostIncAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); return retRV; } void RegIndirectPostIncAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); } //-------------------------------------------------- RegIndirectPreDecAddrMode::RegIndirectPreDecAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[--%s]") { } RegisterValue RegIndirectPreDecAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); return retRV; } void RegIndirectPreDecAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); } //-------------------------------------------------- RegIndirectPreIncAddrMode::RegIndirectPreIncAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[++%s]") { } RegisterValue RegIndirectPreIncAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); return retRV; } void RegIndirectPreIncAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); } //-------------------------------------------------- MultiWordInstruction::MultiWordInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr), word2_opcode(0), PMaddress(addr), PMindex(addr/2), initialized(false) { } //-------------------------------------------------- MultiWordBranch::MultiWordBranch(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : MultiWordInstruction(new_cpu, new_opcode, addr) { } void MultiWordBranch::runtime_initialize() { if(cpu_dsPic->program_memory[PMindex+1] != &bad_instruction) { word2_opcode = cpu_dsPic->program_memory[PMindex+1]->get_opcode(); cpu_dsPic->program_memory[PMindex+1]-> update_line_number(file_id,src_line, lst_line, 0, 0); // extract the destination address from the two-word opcode destination_index = ((word2_opcode & 0x7f)<<15) | ((opcode>>1) & 0x7fff); initialized = true; } } char * MultiWordBranch::name(char *return_str,int len) { if(!initialized) runtime_initialize(); snprintf(return_str,len,"%s\t0x%05x", gpsimValue::name().c_str(), destination_index<<1); return(return_str); } //-------------------------------------------------- LiteralBranch::LiteralBranch(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name) : instruction(new_cpu, new_opcode, addr), mcP_conditionName("") { new_name(_name); unsigned int signExtendedOffset = ((new_opcode&0xffff)<<1) | ((new_opcode & (1<<15)) ? 0xfffe0000 : 0); m_destination = (addr + 2 + signExtendedOffset) & 0xfffffe; } char *LiteralBranch::name(char *buff,int len) { if (buff) { char sign = (opcode & (1<<15)) ? '-' : '+'; int offset= (((sign=='-') ? ((opcode^0xffff)+1) : opcode) << 1) & 0x1fffe; snprintf(buff, len, "%s\t%s#0x%06x\t; $%c0x%x", instruction::name().c_str(), mcP_conditionName, m_destination, sign, offset); } return buff; } //-------------------------------------------------- ImmediateInstruction::ImmediateInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr), m_L(new_opcode & 0xfffe) { } char *ImmediateInstruction::name(char *buff,int len) { if (buff) { snprintf(buff, len, "%s\t#0x%04x", instruction::name().c_str(),m_L); } return buff; } //-------------------------------------------------- RegisterInstruction::RegisterInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name) : instruction(new_cpu, new_opcode, addr), m_bByteOperation((new_opcode & (1<<14)) != 0), m_base(0), m_source(0), m_destination(0) { new_name(_name); } //-------------------------------------------------- //-------------------------------------------------- RegisterToRegisterInstruction::RegisterToRegisterInstruction (Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name, eAddressingModes addrMode ) : RegisterInstruction(new_cpu, new_opcode, addr, _name), m_addrMode(addrMode) { switch(m_addrMode) { case eRegisterDirect: m_base = new RegDirectAddrMode(cpu_dsPic,opcode & 0xf); m_destination = new RegDirectAddrMode(cpu_dsPic,opcode & 0xf); m_source = new LiteralAddressingMode(cpu_dsPic, (opcode>>4) & (opcode & (1<<14) ? 0xff: 0x3ff)); break; case eRegisterIndirect: m_base = new RegDirectAddrMode(cpu_dsPic, (opcode>>15) & 0xf); m_source = AddressingMode::construct(cpu_dsPic, (opcode >> 4) & 0x7, opcode & 0x1f); m_destination = AddressingMode::construct(cpu_dsPic, (opcode >> 11) & 0x7, (opcode >> 7) & 0xf); break; default: assert(0); } } char *RegisterToRegisterInstruction::name(char *buff,int len) { if (!buff) return buff; char cpBase[256]; char cpSource[256]; char cpDestination[256]; switch(m_addrMode) { case eRegisterDirect: snprintf(buff, len, "%s%s\t%s, %s", instruction::name().c_str(), (m_bByteOperation ? ".b" :""), m_source->name(cpBase,sizeof(cpBase)), m_destination->name(cpDestination,sizeof(cpDestination)) ); break; case eRegisterIndirect: snprintf(buff, len, "%s%s\t%s,%s,%s", instruction::name().c_str(), (m_bByteOperation ? ".b" :""), m_base->name(cpBase,sizeof(cpBase)), m_source->name(cpSource,sizeof(cpSource)), m_destination->name(cpDestination,sizeof(cpDestination)) ); break; default: break; } return buff; } //-------------------------------------------------- ADDR::ADDR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr, eAddressingModes addrMode) : RegisterToRegisterInstruction(new_cpu, new_opcode, addr,"add",addrMode) { } void ADDR::execute() { RegisterValue baseRV(m_base ? m_base->get() : m_destination->get()); RegisterValue srcRV (m_source->get()); RegisterValue resRV (srcRV); resRV.data += baseRV.data; resRV.init |= baseRV.init; m_destination->put(resRV); unsigned flags = ((resRV.data & 0xffff ) ? 0 : eZ) | ((resRV.data & 0x10000 ) ? eC : 0) | (((resRV.data ^ baseRV.data ^ srcRV.data)&0x10) ? eDC : 0) | (((resRV.data & ~baseRV.data & ~srcRV.data | ~resRV.data & baseRV.data & srcRV.data) & 0x8000) ? eOV : 0) | ((resRV.data & 0x8000 ) ? eN : 0); cpu_dsPic->m_status.putFlags(flags, eC|eZ|eOV|eN|eDC, 0); cpu_dsPic->pc->increment(); } //-------------------------------------------------- /* ADDL::ADDL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : RegisterDirectLiteralInstruction(new_cpu, new_opcode, addr,"add") { } void ADDL::execute() { cpu_dsPic->pc->increment(); } */ //-------------------------------------------------- ADD::ADD (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("add"); printf("constructing a ADD\n"); } void ADD::execute() { cpu_dsPic->pc->increment(); } //-------------------------------------------------- ADDC::ADDC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("addc"); printf("constructing a ADDC\n"); } void ADDC::execute() { } //-------------------------------------------------- AND::AND (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("and"); printf("constructing a AND\n"); } void AND::execute() { } //-------------------------------------------------- ASR::ASR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("asr"); printf("constructing a ASR\n"); } void ASR::execute() { } //-------------------------------------------------- BCLR::BCLR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bclr"); printf("constructing a BCLR\n"); } void BCLR::execute() { } //-------------------------------------------------- BRA::BRA (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : LiteralBranch(new_cpu, new_opcode, addr, "bra") { new_name("bra"); switch ((opcode>>16) & 0x0f) { case OV: // Overflow mcP_conditionName = "OV,"; break; case C: // Carry and GEU mcP_conditionName = "C,"; break; case Z: // Zero mcP_conditionName = "Z,"; break; case N: // Negative mcP_conditionName = "N,"; break; case LE: // Less than or equal to mcP_conditionName = "LE,"; break; case LT: // Less than mcP_conditionName = "LT,"; break; case LEU: // Less than or equal unsigned mcP_conditionName = "LEU,"; break; case UN: // Unconditionally mcP_conditionName = ""; break; case NOV: // No overflow mcP_conditionName = "NOV,"; break; case NC: // No Carry and LTU (less than unsigned) mcP_conditionName = "NC,"; break; case NZ: // Not zero mcP_conditionName = "NZ,"; break; case NN: // Not Negative mcP_conditionName = "NN,"; break; case GT: // Greater than mcP_conditionName = "GT,"; break; case GE: // Greater than or equal mcP_conditionName = "GE,"; break; case GTU: // Greater than unsigned mcP_conditionName = "GTU,"; break; case NU: // not used... default: break; } } void BRA::execute() { if (m_condition) cpu_dsPic->pc->jump(m_destination>>1); else cpu_dsPic->pc->increment(); } //-------------------------------------------------- BSET::BSET (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bset"); printf("constructing a BSET\n"); } void BSET::execute() { } //-------------------------------------------------- BSW::BSW (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bsw "); printf("constructing a BSW\n"); } void BSW::execute() { } //-------------------------------------------------- BTG::BTG (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("btg "); printf("constructing a BTG\n"); } void BTG::execute() { } //-------------------------------------------------- BTS::BTS (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bts"); printf("constructing a BTS\n"); } void BTS::execute() { } //-------------------------------------------------- BTST::BTST (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("btst"); printf("constructing a BTST\n"); } void BTST::execute() { } //-------------------------------------------------- BTSTS::BTSTS (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("btsts"); printf("constructing a BTSTS\n"); } void BTSTS::execute() { } //-------------------------------------------------- CALL::CALL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("call"); printf("constructing a CALL\n"); } void CALL::execute() { } //-------------------------------------------------- CLR::CLR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("clr"); printf("constructing a CLR\n"); } void CLR::execute() { } //-------------------------------------------------- CLRWDT::CLRWDT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("clrwdt"); printf("constructing a CLRWDT\n"); } void CLRWDT::execute() { } //-------------------------------------------------- COM::COM (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("com"); printf("constructing a COM\n"); } void COM::execute() { } //-------------------------------------------------- CP::CP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cp"); printf("constructing a CP\n"); } void CP::execute() { } //-------------------------------------------------- CP0::CP0 (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cp0"); printf("constructing a CP0\n"); } void CP0::execute() { } //-------------------------------------------------- CPB::CPB (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cpb"); printf("constructing a CPB\n"); } void CPB::execute() { } //-------------------------------------------------- CPS::CPS (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cps"); printf("constructing a CPS\n"); } void CPS::execute() { } //-------------------------------------------------- DAW::DAW (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("daw"); printf("constructing a DAW\n"); } void DAW::execute() { } //-------------------------------------------------- DEC::DEC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("dec"); printf("constructing a DEC\n"); } void DEC::execute() { } //-------------------------------------------------- DISI::DISI (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("disi"); printf("constructing a DISI\n"); } void DISI::execute() { } //-------------------------------------------------- DIV::DIV (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("div"); printf("constructing a DIV\n"); } void DIV::execute() { } //-------------------------------------------------- DO::DO (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("do"); printf("constructing a DO\n"); } void DO::execute() { } //-------------------------------------------------- ED::ED (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ed"); printf("constructing a ED\n"); } void ED::execute() { } //-------------------------------------------------- EXCH::EXCH (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("exch"); printf("constructing a EXCH\n"); } void EXCH::execute() { } //-------------------------------------------------- FB::FB (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("fb"); printf("constructing a FB\n"); } void FB::execute() { } //-------------------------------------------------- GOTO::GOTO (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : MultiWordBranch(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("goto"); printf("constructing a GOTO\n"); } void GOTO::execute() { if(!initialized) runtime_initialize(); cpu_dsPic->pc->jump(destination_index); } //-------------------------------------------------- INC::INC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("inc"); printf("constructing a INC\n"); } void INC::execute() { } //-------------------------------------------------- IOR::IOR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ior"); printf("constructing a IOR\n"); } void IOR::execute() { } //-------------------------------------------------- LAC::LAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("lac"); printf("constructing a LAC\n"); } void LAC::execute() { } //-------------------------------------------------- LNK::LNK (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : ImmediateInstruction(new_cpu, new_opcode, addr) { new_name("lnk"); } void LNK::execute() { unsigned int tos = cpu_dsPic->W[15].get_value(); unsigned int tos_index = tos>>1; cpu_dsPic->registers[tos_index]->put(cpu_dsPic->W[14].get()); cpu_dsPic->W[14].put(tos+2); cpu_dsPic->W[15].put(tos+2+m_L); cpu_dsPic->pc->increment(); } //-------------------------------------------------- LSR::LSR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("lsr"); printf("constructing a LSR\n"); } void LSR::execute() { } //-------------------------------------------------- MAC::MAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("mac"); printf("constructing a MAC\n"); } void MAC::execute() { } //-------------------------------------------------- MOV::MOV (Processor *new_cpu, unsigned int new_opcode, unsigned int addr, eAddressingModes addrMode) : RegisterToRegisterInstruction(new_cpu, new_opcode, addr,"mov",addrMode) { printf("MOV instruction opcode:0x%x mode=%d\n",opcode,m_addrMode); } void MOV::execute() { RegisterValue baseRV(m_base ? m_base->get() : m_destination->get()); RegisterValue srcRV (m_source->get()); RegisterValue resRV (srcRV); resRV.data += baseRV.data; resRV.init |= baseRV.init; m_destination->put(resRV); unsigned flags = ((resRV.data & 0xffff ) ? 0 : eZ) | ((resRV.data & 0x10000 ) ? eC : 0) | (((resRV.data ^ baseRV.data ^ srcRV.data)&0x10) ? eDC : 0) | (((resRV.data & ~baseRV.data & ~srcRV.data | ~resRV.data & baseRV.data & srcRV.data) & 0x8000) ? eOV : 0) | ((resRV.data & 0x8000 ) ? eN : 0); cpu_dsPic->m_status.putFlags(flags, eC|eZ|eOV|eN|eDC, 0); cpu_dsPic->pc->increment(); } //-------------------------------------------------- MOVSAC::MOVSAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("movsac"); printf("constructing a MOVSAC\n"); } void MOVSAC::execute() { } //-------------------------------------------------- MPY::MPY (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("mpy"); printf("constructing a MPY\n"); } void MPY::execute() { } //-------------------------------------------------- MUL::MUL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("mul"); printf("constructing a MUL\n"); } void MUL::execute() { } //-------------------------------------------------- NEG::NEG (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("neg"); printf("constructing a NEG\n"); } void NEG::execute() { } //-------------------------------------------------- NOP::NOP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("nop"); // For the 18cxxx family, this 'nop' may in fact be the // 2nd word in a 2-word opcode. So just to be safe, let's // initialize the cross references to the source file. // (Subsequent initialization code will overwrite this, // but there is a chance that this info will be accessed // before that occurs). //printf("constructing a NOP\n"); } void NOP::execute() { //cpu_pic->pc->increment(); } //-------------------------------------------------- POP::POP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("pop"); printf("constructing a POP\n"); } void POP::execute() { } //-------------------------------------------------- PUSH::PUSH (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("push"); printf("constructing a PUSH\n"); } void PUSH::execute() { } //-------------------------------------------------- PWRSAV::PWRSAV (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("pwrsav"); printf("constructing a PWRSAV\n"); } void PWRSAV::execute() { } //-------------------------------------------------- RCALL::RCALL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : LiteralBranch(new_cpu, new_opcode, addr,"rcall") { } void RCALL::execute() { cpu_dsPic->m_stack.push(); cpu_dsPic->pc->jump(m_destination>>1); } //-------------------------------------------------- REPEAT::REPEAT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("repeat"); printf("constructing a REPEAT\n"); } void REPEAT::execute() { } //-------------------------------------------------- RESET::RESET (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("reset"); printf("constructing a RESET\n"); } void RESET::execute() { } //-------------------------------------------------- RET::RET (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ret"); printf("constructing a RET\n"); } void RET::execute() { } //-------------------------------------------------- ROT::ROT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("rot"); printf("constructing a ROT\n"); } void ROT::execute() { } //-------------------------------------------------- SAC::SAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sac"); printf("constructing a SAC\n"); } void SAC::execute() { } //-------------------------------------------------- SE::SE (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("se"); printf("constructing a SE\n"); } void SE::execute() { } //-------------------------------------------------- SETM::SETM (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("setm"); printf("constructing a SETM\n"); } void SETM::execute() { } //-------------------------------------------------- SFTAC::SFTAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sftac"); printf("constructing a SFTAC\n"); } void SFTAC::execute() { } //-------------------------------------------------- SL::SL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sl"); printf("constructing a SL\n"); } void SL::execute() { } //-------------------------------------------------- SUB::SUB (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sub"); printf("constructing a SUB\n"); } void SUB::execute() { } //-------------------------------------------------- SWAP::SWAP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("swap"); printf("constructing a SWAP\n"); } void SWAP::execute() { } //-------------------------------------------------- TBLRD::TBLRD (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("tblrd"); printf("constructing a TBLRD\n"); } void TBLRD::execute() { } //-------------------------------------------------- TBLWT::TBLWT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("tblwt"); printf("constructing a TBLWT\n"); } void TBLWT::execute() { } //-------------------------------------------------- ULNK::ULNK (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ulnk"); printf("constructing a ULNK\n"); } void ULNK::execute() { } //-------------------------------------------------- XOR::XOR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("xor"); printf("constructing a XOR\n"); } void XOR::execute() { } //-------------------------------------------------- ZE::ZE (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ZE"); printf("constructing a ZE\n"); } void ZE::execute() { } };