private void LEAAddr(U8Cmd cmd) { // this inst loads the EA register with a specified word value // TODO: figure out Disp16[ERm] //this.Registers.EA = (0x10000) + cmd.sWord; this.Registers.PC += 4; }
private void PopHandler(U8Cmd cmd) { // keep track of stack address // another switch to keep it clean? switch(cmd.Type) { case U8_OP.POP_R: // 8bit StackPtr += 2; break; case U8_OP.POP_ER: // 16 bit StackPtr += 4; break; case U8_OP.POP_XR: // 32 bit StackPtr += 8; break; case U8_OP.POP_QR: // 64 bit StackPtr += 16; break; case U8_OP.POP_RL: // wtf? - assume thats a 8bit? StackPtr += 2; break; default: break; } }
private void LRegER(U8Cmd cmd) { this.Registers.SetRegisterByIndex((byte)cmd.Op1, this.Registers.GetRegisterByIndex((byte)cmd.Op2)); this.Registers.PSW.Z = this.Registers.GetRegisterByIndex((byte)cmd.Op1) == 0; // S this.Registers.PC += 2; }
private void LQRegEA(U8Cmd cmd) { this.Registers.SetQRegisterByIndex((byte)cmd.Op1, this.Registers.EA); this.Registers.PSW.Z = this.Registers.GetQRegisterByIndex((byte)cmd.Op1) == 0; // S this.Registers.PC += 2; }
private void MOVOCR(U8Cmd cmd) { // this inst saves the contents of the specified coprocessor byte-sized register at the // specified byte address in the EA register // TODO }
private void MOVOCQR(U8Cmd cmd) { // this instr saves the contents of the specified coprocessor squad word-sized register // at the specified word address in the EA register // TODO }
private void MOVPSWO(U8Cmd cmd) { // this inst loads the program status word (PSW) from the specified byte-sized obj // NOTE: place NOP right after to fix cycle delay this.Registers.PSW.Set((byte)cmd.Op2);// unsigned8 this.Registers.PC += 2; }
private void MOVOCXR(U8Cmd cmd) { // this inst saves the contents of the specified coprocessor double word-sized // register at the specified word address in the EA register // TODO }
private void TBReg(U8Cmd cmd) { // this instr test the specified bit by reading it from memory, inverting it, and // storing the result in the Z flag // bit_offset us an integer between 0 and 7 specifying the bit position within the register // TODO: Z = ~Rn[bit_offset] }
private void MOVPSWReg(U8Cmd cmd) { // this inst loads the program status word (PSW) from the specified byte-sized obj // NOTE: place NOP right after to fix cycle delay this.Registers.PSW.Set(this.Registers.GetRegisterByIndex((byte)cmd.Op2)); this.Registers.PC += 2; }
private void MOVEregEreg(U8Cmd cmd) { // this inst loads the first word-sized register from the second this.Registers.SetERegisterByIndex((byte)cmd.Op1, this.Registers.GetERegisterByIndex((byte)cmd.Op2)); this.Registers.PSW.Z = this.Registers.GetERegisterByIndex((byte)cmd.Op1) == 0; // S this.Registers.PC += 2; }
private void SubHandler(U8Cmd cmd) { // check subtraction from stack if(cmd.Type == U8_OP.MOV_SP_ER) { StackPtr = EA; } }
private void MOVRegO(U8Cmd cmd) { // this inst loads the specified byte-sized register from the specified byte-sized imm8 this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)cmd.Op2); // #imm8? this.Registers.PSW.Z = this.Registers.GetRegisterByIndex((byte)cmd.Op1) == 0; // S this.Registers.PC += 2; }
private void MOVERegO(U8Cmd cmd) { // this inst loads the sign-extended imm7 into the specified word-sized register // More precisely, it loads the immediate value into Rn, the lower half of the register, and // copies bit 6 from the immediate value in Rn bit 7 amd all bits of Rn+1 // TODO }
private void MOVCEREA(U8Cmd cmd) { //TODO: CER? // this instr loads t he specified coprocessor word-sized register from // the specified word address //this.Registers. this.Registers.PC += 2; }
private void SBDbit(U8Cmd cmd) { // this instr test the specified bit by reading it form memory, invesing it, and // storing the result in the Z flag, it then sets the original bit tp 1 // this bit address DBitadr has the format Badr16bit where bit is an integer between 0 and // 7 specifying the bit position within the memory byte // TODO }
private void ORRegO(U8Cmd cmd) { // this instr ORs the contents of the specified byte-sized register and object and stores the result // in the register this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)cmd.Op2); this.Registers.PSW.Z = (byte)cmd.Op2 == 0; // S this.Registers.PC += 2; }
private void TBDbit(U8Cmd cmd) { // this instr test the specified bit by reading the from memory, inverting it, and // storing the result in the Z flag // the bit address Dbitaddr has the format Dadr16.bit, where bit is an integer betweem 0 and // 7 specifying the bit position within the memory byte // TODO: Z ~[Dbit] }
public string[] Disassemble(int LineCount = 1, bool PrintLines = false) { int ret = 2; // word List <string> tmpResult = new List <string>(); while (tmpResult.Count < LineCount) { string result = $"{ this.Index.ToString("X8")} "; // TODO: FIX THIS MESS WTF? int grabSize = 6; if ((this.Index + grabSize) - this.Buffer.Length > 0) { grabSize = (this.Index + grabSize) - this.Buffer.Length; } byte[] buf = new byte[grabSize]; // FIX End of array error? // fill temp buff for (int b = 0; b < buf.Length; b++) { buf[b] = this.Buffer[this.Index + b]; } U8Cmd cmd = new U8Cmd(); ret = U8Decoder.DecodeOpcode(buf, ref cmd); if (ret == -1) { result += "err"; tmpResult.Add(result); if (PrintLines) { PrintDisasm(result); } break; } this.Index += ret; string bytestr = ""; for (int j = 0; j < ret; j += 2) { bytestr += BitConverter.ToUInt16(buf, j).ToString("X4") + " "; } result += bytestr.PadRight(15) + cmd.Instruction.PadRight(10) + cmd.Operands; tmpResult.Add(result); _CacheDisassembly(this.Index, result); if (PrintLines) { PrintDisasm(result); } } return(tmpResult.ToArray()); }
private void MULERegReg(U8Cmd cmd) { // this instr multiplies the contents of the two specified byte-size registers and stores // the 16-bit product in the word-zied register corresponding to the first register var res = this.Registers.GetRegisterByIndex((byte)cmd.Op1) * this.Registers.GetRegisterByIndex((byte)cmd.Op2); this.Registers.SetERegisterByIndex((byte)cmd.Op1, (ushort)res); this.Registers.PSW.Z = res == 0; this.Registers.PC += 2; }
private void RT(U8Cmd cmd) { // this instr is for returning from a subroutine called with a BL instr. // it restores the address of the instruction the BL instruction by loading the // code segment register from the local code segment (LCSR) and the program // counter (PC) from the link register (LR) this.Registers.CSR = this.Registers.LCSR; this.Registers.PC = this.Registers.LR; this.Registers.PC += 2; }
private void AndRegO(U8Cmd cmd) { var res = this.Registers.GetRegisterByIndex((byte)cmd.Op1) & (byte)cmd.Op2; this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)res); this.Registers.PC += 2; this.Registers.PSW.Z = res == 0; // TODO: S }
private void EXTBWEreg(U8Cmd cmd) { // this instruction extends the content of the Rn register to signed 16-bit format and stores // it in the ERn register // The contents of the Rn+1 are filled with bit 7 of the Rn register, as the result // TODO: look into again this.Registers.PC += 2; }
private void XORO(U8Cmd cmd) { // this insts XORs the contents of the specified byte-sized register and object and // stores the result in the register this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)(this.Registers.GetRegisterByIndex((byte)cmd.Op1) ^ (byte)cmd.Op2)); this.Registers.PSW.Z = this.Registers.GetRegisterByIndex((byte)cmd.Op1) == 0; // S this.Registers.PC += 2; }
private void MOVRegEPSW(U8Cmd cmd) { // this instr loads the specified byte-sized register from the exception program // status word (EPSW1 to EPSW3) register for the current exception level (ELEVEL) // setting if ELEVEL is nonzero if (this.Registers.PSW.ELEVEL != 0) { this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)this.Registers.GetEPSWByIndex(this.Registers.PSW.ELEVEL)); } this.Registers.PC += 2; }
public void Execute(U8Cmd cmd) { if (this.HandlerTable.ContainsKey(cmd.Type)) { this.HandlerTable[cmd.Type].Invoke(cmd); } else { throw new Exception("opcode not yet supported"); } }
private void NEGReg(U8Cmd cmd) { // this inst calculate the two complement of the contents of the specified // byte-size register and stores the result in the register this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)(0 - this.Registers.GetRegisterByIndex((byte)cmd.Op1))); // C this.Registers.PSW.Z = this.Registers.GetRegisterByIndex((byte)cmd.Op1) == 0; // S this.Registers.PSW.OV = false; // can this even overflow? // HC this.Registers.PC += 2; }
private void AndRegReg(U8Cmd cmd) { // this inst ANDs the content of the specified byte-sized register // and object and stores the result in the register var res = this.Registers.GetRegisterByIndex((byte)cmd.Op1) & this.Registers.GetRegisterByIndex((byte)cmd.Op2); this.Registers.SetRegisterByIndex((byte)cmd.Op1, (byte)res); this.Registers.PC += 2; this.Registers.PSW.Z = res == 0; // TODO: S }
private void DECea(U8Cmd cmd) { // this inst subtracts one from the EA register int res = this.Registers.EA - 1; this.Registers.EA = (byte)res; this.Registers.PSW.Z = this.Registers.EA == 0; // S this.Registers.PSW.OV = (byte)(res + 1) == 0; // HC this.Registers.PC += 2; }
private void INCea(U8Cmd cmd) { // this inst adds one to the byte at the address in the EA register int res = this.Registers.EA + 1; // byte? this.Registers.EA = (ushort)res; this.Registers.PSW.Z = this.Registers.EA == 0; // S this.Registers.PSW.OV = res > ushort.MaxValue; // HC this.Registers.PC += 2; }