protected void ValidateEffectiveAddress(EffectiveAddressMode mode, IEnumerable <EffectiveAddressMode> allowed) { if (allowed.Any(m => m == mode) == false) { throw new InvalidOpCodeException(); } }
protected string GetAssemblyForEffectiveAddress(EffectiveAddressMode mode, uint ea, byte xn) { switch (mode) { case EffectiveAddressMode.Immediate: switch (this.Size) { case Size.Long: return($"#{(int)ea}"); case Size.Word: return($"#{(short)ea}"); case Size.Byte: return($"#{(byte)ea}"); default: throw new NotImplementedException(); } case EffectiveAddressMode.AbsoluteWord: return($"0x{ea:X4}"); case EffectiveAddressMode.AbsoluteLong: return($"${ea:X8}"); case EffectiveAddressMode.AddressWithDisplacement: return($"(${(short)ea:X4},A{xn})"); case EffectiveAddressMode.ProgramCounterWithDisplacement: return($"(${(short)ea:X4},PC)"); case EffectiveAddressMode.Address: return($"(A{xn})"); case EffectiveAddressMode.AddressPostIncrement: return($"(A{xn})+"); case EffectiveAddressMode.AddressPreDecrement: return($"-(A{xn})"); case EffectiveAddressMode.DataRegister: return($"D{xn}"); case EffectiveAddressMode.AddressRegister: return($"A{xn}"); default: throw new NotImplementedException(mode.ToString()); } }
/// <summary> /// MOVEM will write to the register instead of the referenced address. /// </summary> /// <param name="ea">Effective Address Mode.</param> /// <param name="Xn">Xn value.</param> /// <param name="value">Value to write.</param> protected void WriteValueToEffectiveAddress(EffectiveAddressMode ea, uint Xn, uint value) { switch (ea) { case EffectiveAddressMode.AddressPostIncrement: switch (this.Size) { case Size.Byte: this.state.WriteAReg((byte)Xn, value); break; case Size.Word: this.state.WriteAReg((byte)Xn, value); break; case Size.Long: this.state.WriteAReg((byte)Xn, value); break; default: throw new InvalidStateException(); } break; case EffectiveAddressMode.Address: switch (this.Size) { case Size.Byte: this.state.WriteAReg((byte)Xn, value); break; case Size.Word: this.state.WriteAReg((byte)Xn, value); break; case Size.Long: this.state.WriteAReg((byte)Xn, value); break; default: throw new InvalidStateException(); } break; default: throw new InvalidStateException(); } }
protected string GetDescriptionForEffectiveAddress(EffectiveAddressMode mode, uint ea, byte xn) { switch (mode) { //case EffectiveAddressMode.Immediate: // switch (Size) // { // case Size.Long: // return string.Format("#{0}", (int)ea); // case Size.Word: // return string.Format("#{0}", (short)ea); // default: // throw new NotImplementedException(); // } case EffectiveAddressMode.AbsoluteWord: return($"0x{ea:X4}"); //case EffectiveAddressMode.AbsoluteLong: // return string.Format("0x{0:X8}", ea); //case EffectiveAddressMode.AddressWithDisplacement: // return $"(d16, A{xn})"; case EffectiveAddressMode.ProgramCounterWithDisplacement: return($"(d16, PC)"); //case EffectiveAddressMode.Address: // return string.Format("(A{0})", xn); //case EffectiveAddressMode.Address_PostIncremenet: // return string.Format("(A{0}+)", xn); //case EffectiveAddressMode.DataRegister: // return string.Format("D{0}", xn); //case EffectiveAddressMode.AddressRegister: // return string.Format("A{0}", xn); default: throw new NotImplementedException(mode.ToString()); } }
protected uint ReadAddressForEffectiveAddress(EffectiveAddressMode mode, uint ea, byte xn) { switch (mode) { // get the address stored in the address register case EffectiveAddressMode.Address: return(this.state.ReadAReg((byte)xn)); // get the address stored in the address register plus the displacement case EffectiveAddressMode.AddressWithDisplacement: return(this.state.ReadAReg((byte)xn) + ea); // get the address stored in the program counter plus the displacement case EffectiveAddressMode.ProgramCounterWithDisplacement: return(this.state.PC + ea - 2); case EffectiveAddressMode.AbsoluteWord: return((uint)this.ReadDataUsingPC(this.Size)); default: throw new InvalidStateException(); } }
protected uint FetchEffectiveAddress(EffectiveAddressMode ea, byte Xn) { switch (ea) { // get the address data immediately following the opcode case EffectiveAddressMode.AbsoluteLong: return((uint)this.ReadDataUsingPC(Size.Long)); // get the address data immediately following the opcode case EffectiveAddressMode.AbsoluteWord: return((uint)this.ReadDataUsingPC(Size.Long)); // get the immediate value follwoing the opcode case EffectiveAddressMode.Immediate: return((uint)this.ReadDataUsingPC(this.Size)); // get the address register number case EffectiveAddressMode.Address: return(Xn); // get the address register number case EffectiveAddressMode.AddressRegister: return(Xn); // get the data register number case EffectiveAddressMode.DataRegister: return(Xn); // get the displacement word immediately following the opcode case EffectiveAddressMode.AddressWithDisplacement: return((uint)this.ReadDataUsingPC(Size.Word)); // get the displacement word immediately following the opcode case EffectiveAddressMode.ProgramCounterWithDisplacement: return((uint)this.ReadDataUsingPC(Size.Word)); // get the reg value case EffectiveAddressMode.AddressPostIncrement: switch (this.Size) { case Size.Byte: return(this.state.ReadAReg(Xn)); case Size.Word: return(this.state.ReadAReg(Xn)); case Size.Long: return(this.state.ReadAReg(Xn)); default: throw new InvalidStateException(); } // get the reg value case EffectiveAddressMode.AddressPreDecrement: switch (this.Size) { case Size.Byte: return(this.state.ReadAReg(Xn)); case Size.Word: return(this.state.ReadAReg(Xn)); case Size.Long: return(this.state.ReadAReg(Xn)); default: throw new InvalidStateException(); } default: throw new NotImplementedException(ea.ToString()); } }
protected void WriteValueToEffectiveAddress(EffectiveAddressMode ea, uint effectiveAddress, uint Xn, uint value, bool addressProcessed) { switch (ea) { // write the value at the address to the specified data register case EffectiveAddressMode.DataRegister: switch (this.Size) { case Size.Byte: this.state.WriteDReg((byte)Xn, (uint)(byte)value); break; case Size.Word: this.state.WriteDReg((byte)Xn, (uint)(short)value); break; case Size.Long: this.state.WriteDReg((byte)Xn, (uint)value); break; default: throw new InvalidStateException(); } break; // write the value to the specified address register case EffectiveAddressMode.AddressRegister: this.state.WriteAReg((byte)Xn, value); break; // write the value to the specified address register case EffectiveAddressMode.AddressPostIncrement: switch (this.Size) { case Size.Byte: this.state.WriteByte(effectiveAddress, (byte)value); break; case Size.Word: this.state.WriteWord(effectiveAddress, (ushort)value); break; case Size.Long: this.state.WriteLong(effectiveAddress, (uint)value); break; default: throw new InvalidStateException(); } break; case EffectiveAddressMode.AddressPreDecrement: switch (this.Size) { case Size.Long: var regl = this.state.ReadAReg((byte)Xn); if (!addressProcessed) { regl -= 4; this.state.WriteAReg((byte)Xn, regl); } this.state.WriteLong(regl, value); break; case Size.Word: var regw = this.state.ReadAReg((byte)Xn); if (!addressProcessed) { regw -= 2; this.state.WriteAReg((byte)Xn, regw); } this.state.WriteWord(regw, (ushort)value); break; case Size.Byte: var regb = this.state.ReadAReg((byte)Xn); if (!addressProcessed) { regb -= 1; this.state.WriteAReg((byte)Xn, regb); } this.state.WriteByte(regb, (byte)value); break; default: throw new InvalidStateException(); } break; // write value to address specified in An case EffectiveAddressMode.Address: switch (this.Size) { case Size.Byte: this.state.WriteByte(this.state.ReadAReg((byte)Xn), (byte)value); break; case Size.Word: this.state.WriteWord(this.state.ReadAReg((byte)Xn), (ushort)value); break; case Size.Long: this.state.WriteLong(this.state.ReadAReg((byte)Xn), (uint)value); break; default: throw new InvalidStateException(); } break; case EffectiveAddressMode.AddressWithDisplacement: switch (this.Size) { case Size.Byte: var addrb = this.state.ReadAReg((byte)Xn); if (!addressProcessed) { addrb += effectiveAddress; } this.state.WriteByte(addrb, (byte)value); break; case Size.Word: throw new NotImplementedException(); case Size.Long: throw new NotImplementedException(); default: throw new InvalidStateException(); } break; default: throw new NotImplementedException(ea.ToString()); } }
/// <summary> /// Write the value to the location indicated by the effective address. /// </summary> /// <param name="ea"></param> /// <param name="Xn"></param> /// <param name="value"></param> protected void WriteValueToEffectiveAddress(EffectiveAddressMode ea, uint Xn, uint value) { this.WriteValueToEffectiveAddress(ea, this.EffectiveAddress, Xn, value, false); }
protected uint ReadValueForEffectiveAddress(EffectiveAddressMode mode, uint ea, byte xn) { switch (mode) { // get the immediate value case EffectiveAddressMode.Immediate: return(ea); // get the data in memory pointed to by the address register case EffectiveAddressMode.Address: switch (this.Size) { case Size.Long: return(this.state.ReadLong(this.state.ReadAReg(xn))); case Size.Word: return(this.state.ReadWord(this.state.ReadAReg(xn))); case Size.Byte: return(this.state.ReadByte(this.state.ReadAReg(xn))); default: throw new InvalidStateException(); } // get the data in memory pointed to by the address register (post increment register) case EffectiveAddressMode.AddressPostIncrement: switch (this.Size) { case Size.Long: var regl = this.state.ReadAReg(xn); var l = this.state.ReadLong(regl); this.state.WriteAReg(xn, regl + 4); return(l); case Size.Word: var regw = this.state.ReadAReg(xn); var w = this.state.ReadWord(regw); this.state.WriteAReg(xn, regw + 2); return(w); case Size.Byte: var regb = this.state.ReadAReg(xn); var b = this.state.ReadByte(regb); this.state.WriteAReg(xn, regb + 1); return(b); default: throw new InvalidStateException(); } // get the data in memory pointed to by the address register (pre decrement register) case EffectiveAddressMode.AddressPreDecrement: switch (this.Size) { case Size.Long: var regl = this.state.ReadAReg(xn); regl -= 4; var l = this.state.ReadLong(regl); this.state.WriteAReg(xn, regl); return(l); case Size.Word: var regw = this.state.ReadAReg(xn); regw -= 2; var w = this.state.ReadWord(regw); this.state.WriteAReg(xn, regw); return(w); case Size.Byte: var regb = this.state.ReadAReg(xn); regb -= 1; var b = this.state.ReadByte(regb); this.state.WriteAReg(xn, regb); return(b); default: throw new InvalidStateException(); } // get the number stored in the address register case EffectiveAddressMode.AddressRegister: return(this.state.ReadAReg(xn)); // get the number stored in the data register case EffectiveAddressMode.DataRegister: return(this.state.ReadDReg(xn)); // get the value from memory using the provided long address // TODO: should this return only LONG? case EffectiveAddressMode.AbsoluteLong: switch (this.Size) { case Size.Long: return(this.state.ReadLong(ea)); case Size.Word: return(this.state.ReadWord(ea)); default: throw new InvalidStateException(); } // get the value from memory using the provided long address // TODO: should this return only WORD? case EffectiveAddressMode.AbsoluteWord: switch (this.Size) { case Size.Long: return(this.state.ReadLong(ea)); case Size.Word: return(this.state.ReadWord(ea)); default: throw new InvalidStateException(); } // get the data addressed by the contents of the address register + displacement case EffectiveAddressMode.AddressWithDisplacement: var ad = (uint)(this.state.ReadAReg(xn) + (short)ea); switch (this.Size) { case Size.Long: return(this.state.ReadLong(ad)); case Size.Word: return(this.state.ReadWord(ad)); case Size.Byte: return(this.state.ReadByte(ad)); default: throw new InvalidStateException(); } // get the data addressed by PC + displacement (-2 so it is from opcode address) case EffectiveAddressMode.ProgramCounterWithDisplacement: var pcd = (uint)(this.state.PC - 2 + (short)ea); switch (this.Size) { case Size.Long: return(this.state.ReadLong(pcd)); case Size.Word: return(this.state.ReadWord(pcd)); case Size.Byte: return(this.state.ReadByte(pcd)); default: throw new InvalidStateException(); } default: throw new NotImplementedException(mode.ToString()); } }