public void TestSTA() { var rom = AssembleSource($@" org 00h STA 2477h HLT "); var registers = new CPURegisters(); registers.A = 0x42; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x42, state.Memory[0x2477]); Assert.Equal(0x42, state.Registers.A); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 13, state.Cycles); Assert.Equal(0x03, state.ProgramCounter); }
public void TestDAD_Carry(RegisterPair pair) { var rom = AssembleSource($@" org 00h DAD {pair.GetUpperRegister()} HLT "); var registers = new CPURegisters() { HL = 0xFFFE, [pair] = 0x0005, }; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x0005, state.Registers[pair]); Assert.Equal(0x0003, state.Registers.HL); Assert.False(state.Flags.Zero); Assert.False(state.Flags.Sign); Assert.False(state.Flags.Parity); Assert.True(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 10, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public BaseAddressingModeTests() { addressingMode = new T(); cpuMemory = new CPUMemory(); cpuRegisters = new CPURegisters(); }
public void TestDCR_M_NoFlags() { var rom = AssembleSource($@" org 00h DCR M HLT "); var registers = new CPURegisters() { HL = 0x2477, }; var memory = new byte[16384]; memory[0x2477] = 0x44; var initialState = new CPUConfig() { Registers = registers, MemorySize = memory.Length, }; var state = Execute(rom, memory, initialState); Assert.Equal(0x43, state.Memory[0x2477]); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 10, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void TestDCR_NoFlags(Register sourceReg) { var rom = AssembleSource($@" org 00h DCR {sourceReg} HLT "); var registers = new CPURegisters() { [sourceReg] = 0x44, }; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x43, state.Registers[sourceReg]); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 5, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void TestDAD_SP_Carry() { var rom = AssembleSource($@" org 00h DAD SP HLT "); var registers = new CPURegisters() { HL = 0xFFFE, }; var initialState = new CPUConfig() { Registers = registers, StackPointer = 0x0005, }; var state = Execute(rom, initialState); Assert.Equal(0x0005, state.StackPointer); Assert.Equal(0x0003, state.Registers.HL); Assert.False(state.Flags.Zero); Assert.False(state.Flags.Sign); Assert.False(state.Flags.Parity); Assert.True(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 10, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void Test_ADD_A_A_SignAndParityFlags() { var rom = AssembleSource($@" org 00h ADD A, A HALT "); var registers = new CPURegisters(); registers.A = 0x44; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x88, state.Registers.A); Assert.True(state.Flags.Sign); Assert.False(state.Flags.Zero); Assert.False(state.Flags.HalfCarry); Assert.True(state.Flags.ParityOverflow); Assert.False(state.Flags.Subtract); Assert.False(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(4 + 4, state.Cycles); Assert.Equal(0x01, state.Registers.PC); }
public void TestANA_A_ParityFlag() { var rom = AssembleSource($@" org 00h ANA A HLT "); var registers = new CPURegisters(); registers.A = 0b01101100; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0b01101100, state.Registers.A); Assert.False(state.Flags.Zero); Assert.False(state.Flags.Sign); Assert.True(state.Flags.Parity); Assert.False(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 4, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void Test_LD_A_MRR(RegisterPair registerPair) { var rom = AssembleSource($@" org 00h LD A, ({registerPair}) HALT "); var registers = new CPURegisters(); registers[registerPair] = 0x2477; var memory = new byte[16384]; memory[0x2477] = 0x42; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, memory, initialState); Assert.Equal(0x42, state.Memory[0x2477]); Assert.Equal(0x42, state.Registers.A); Assert.Equal(0x2477, state.Registers[registerPair]); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(4 + 7, state.Cycles); Assert.Equal(0x01, state.Registers.PC); }
public void TestADD_ZeroFlag(Register sourceReg) { var rom = AssembleSource($@" org 00h ADD {sourceReg} HLT "); var registers = new CPURegisters(); registers.A = 0xFE; registers[sourceReg] = 0x02; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x00, state.Registers.A); Assert.Equal(0x02, state.Registers[sourceReg]); Assert.True(state.Flags.Zero); Assert.False(state.Flags.Sign); Assert.True(state.Flags.Parity); Assert.True(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 4, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void TestPUSH(RegisterPair pair) { var rom = AssembleSource($@" org 00h PUSH {pair.GetUpperRegister()} HLT "); var registers = new CPURegisters() { [pair] = 0x2477, }; var initialState = new CPUConfig() { Registers = registers, StackPointer = 0x3000, }; var state = Execute(rom, initialState); Assert.Equal(0x2477, state.Registers[pair]); Assert.Equal(0x00, state.Memory[0x3000]); Assert.Equal(0x24, state.Memory[0x2FFF]); Assert.Equal(0x77, state.Memory[0x2FFE]); Assert.Equal(0x2FFE, state.StackPointer); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 11, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
/// <summary> /// Processes the statement with specified cpu context. Returns false if we couldn't read due to invalid memory address. /// </summary> /// <param name="cpu">The cpu.</param> /// <param name="parent">The parent.</param> /// <param name="stack">The stack.</param> /// <returns></returns> internal override bool Process(CPURegisters cpu, StatementBlock parent, List <IntPtr> stack) { if (!this.Operand1.Process(cpu, parent, stack)) { return(false); } IntPtr op1 = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); if (!this.Operand2.Process(cpu, parent, stack)) { return(false); } IntPtr op2 = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); ulong op2_t = Main.Is64Bit ? op2.ToUInt64() : op2.ToUInt32(); IntPtr result = this.Operator.Func(op1, op2_t); stack.Add(result); return(true); }
public void Test_LD_MNN_A() { var rom = AssembleSource($@" org 00h LD (2477h), A HALT "); var registers = new CPURegisters(); registers.A = 0x42; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x42, state.Memory[0x2477]); Assert.Equal(0x42, state.Registers.A); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(4 + 13, state.Cycles); Assert.Equal(0x03, state.Registers.PC); }
public void TestSTAX(Register destReg, Register destReg2) { var rom = AssembleSource($@" org 00h STAX {destReg} HLT "); var registers = new CPURegisters(); registers.A = 0x42; registers[destReg] = 0x24; registers[destReg2] = 0x77; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x42, state.Memory[0x2477]); Assert.Equal(0x42, state.Registers.A); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 7, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void TestDCX(RegisterPair pair) { var rom = AssembleSource($@" org 00h DCX {pair.GetUpperRegister()} DCX {pair.GetUpperRegister()} DCX {pair.GetUpperRegister()} HLT "); var registers = new CPURegisters() { [pair] = 0x3902, }; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x38FF, state.Registers[pair]); AssertFlagsFalse(state); Assert.Equal(4, state.Iterations); Assert.Equal(7 + (5 * 3), state.Cycles); Assert.Equal(0x03, state.ProgramCounter); }
public void Test_INC_MIY_NoFlags(int offset) { var rom = AssembleSource($@" org 00h INC (IY {(offset < 0 ? '-' : '+')} {Math.Abs(offset)}) HALT "); var registers = new CPURegisters() { IY = 0x2477, }; var memory = new byte[16384]; memory[0x2477 + offset] = 0x42; var initialState = new CPUConfig() { Registers = registers, Flags = new ConditionFlags() { Subtract = true, }, }; var state = Execute(rom, memory, initialState); Assert.Equal(0x43, state.Memory[0x2477 + offset]); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(4 + 23, state.Cycles); Assert.Equal(0x03, state.Registers.PC); }
/// <summary> /// Writes the native crash log for specified context. It does not actually treat this as a crash, it just writes out to file as if this was a crash. /// Warning: plugins may still treat this as a crash and modify registers or perform functions that would happen on crash! /// </summary> /// <param name="cpu">The cpu context.</param> /// <param name="nativeThreadId">The native thread identifier. Set int.MinValue for current thread.</param> /// <param name="filePath">The file path to write to (including file name). If file exists it will append.</param> /// <exception cref="System.ArgumentNullException">cpu</exception> public static bool WriteNativeCrashLog(CPURegisters cpu, int nativeThreadId, string filePath) { if (cpu == null) { throw new ArgumentNullException("cpu"); } if (string.IsNullOrEmpty(filePath)) { throw new ArgumentOutOfRangeException("filePath"); } if (nativeThreadId == int.MinValue) { nativeThreadId = Memory.GetCurrentNativeThreadId(); } int handled = 0; try { var cl = new NativeCrashLog(cpu); handled = cl.Write(true, filePath, true); } catch (Exception ex2) { Main.Log.Append(ex2); } return(handled > 0); }
public void Test_XOR_ParityFlag(Register sourceReg) { var rom = AssembleSource($@" org 00h XOR {sourceReg} HALT "); var registers = new CPURegisters(); registers.A = 0b01101101; registers[sourceReg] = 0b01001001; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0b00100100, state.Registers.A); Assert.Equal(0b01001001, state.Registers[sourceReg]); Assert.False(state.Flags.Sign); Assert.False(state.Flags.Zero); Assert.False(state.Flags.HalfCarry); Assert.True(state.Flags.ParityOverflow); Assert.False(state.Flags.Subtract); Assert.False(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(4 + 4, state.Cycles); Assert.Equal(0x01, state.Registers.PC); }
private static void _Hook_Disenchanting(CPURegisters ctx) { var item = MemoryObject.FromAddress <TESForm>(Memory.ReadPointer(ctx.R14)); var enchantment = MemoryObject.FromAddress <EffectSetting>(ctx.SI); float skill = 5.0f; var plr = PlayerCharacter.Instance; if (plr != null) { skill = plr.GetActorValue(ActorValueIndices.Enchanting); } float enchantmentValue = Memory.InvokeCdeclF(fn_Disenchant, enchantment.Address, 0); float xp = Formula_Disenchanting(Math.Max(0, item.GoldValue), enchantmentValue, skill); if (xp < 0.0f) { xp = 0.0f; } if (Settings.DebugMode > 0) { WriteToDebugFile("Disenchanting: original XP was " + ctx.XMM2f.ToString(System.Globalization.CultureInfo.InvariantCulture) + " and we replaced it with " + xp.ToString(System.Globalization.CultureInfo.InvariantCulture)); } ctx.XMM2f = xp; }
public void TestMVIToMemory() { var rom = AssembleSource($@" org 00h MVI M, 42h HLT "); var registers = new CPURegisters(); registers[Register.H] = 0x22; registers[Register.L] = 0x33; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(0x42, state.Memory[0x2233]); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(10 + 7, state.Cycles); Assert.Equal(0x02, state.ProgramCounter); }
/// <summary> /// Processes the statement with specified cpu context. Returns false if we couldn't read due to invalid memory address. /// </summary> /// <param name="cpu">The cpu.</param> /// <param name="parent">The parent.</param> /// <param name="stack">The stack.</param> /// <returns></returns> internal override bool Process(CPURegisters cpu, StatementBlock parent, List <IntPtr> stack) { var ptr = this.Func(cpu); stack.Add(ptr); return(true); }
public void TestMOVFromRegisterToRegister(Register destReg, Register sourceReg) { var rom = AssembleSource($@" org 00h MOV {destReg}, {sourceReg} HLT "); var registers = new CPURegisters(); registers[sourceReg] = 42; var initialState = new CPUConfig() { Registers = registers, }; var state = Execute(rom, initialState); Assert.Equal(42, state.Registers[destReg]); Assert.Equal(42, state.Registers[sourceReg]); AssertFlagsFalse(state); Assert.Equal(2, state.Iterations); Assert.Equal(5 + 7, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
public void TestADC_A_SignFlag() { var rom = AssembleSource($@" org 00h ADC A HLT "); var registers = new CPURegisters(); registers.A = 0x44; var flags = new ConditionFlags() { Carry = true, }; var initialState = new CPUConfig() { Registers = registers, Flags = flags, }; var state = Execute(rom, initialState); Assert.Equal(0x89, state.Registers.A); Assert.False(state.Flags.Zero); Assert.True(state.Flags.Sign); Assert.False(state.Flags.Parity); Assert.False(state.Flags.Carry); Assert.Equal(2, state.Iterations); Assert.Equal(7 + 4, state.Cycles); Assert.Equal(0x01, state.ProgramCounter); }
private static void _Hook_Enchanting(CPURegisters ctx) { var item = MemoryObject.FromAddress <TESForm>(Memory.ReadPointer(ctx.R15)); var soul = MemoryObject.FromAddress <TESForm>(Memory.ReadPointer(Memory.ReadPointer(ctx.BX + 0x18))); float skill = 5.0f; var plr = PlayerCharacter.Instance; if (plr != null) { skill = plr.GetActorValue(ActorValueIndices.Enchanting); } float xp = Formula_Enchanting(Math.Max(0, item.GoldValue), Math.Max(0, soul.GoldValue), skill); if (xp < 0.0f) { xp = 0.0f; } if (Settings.DebugMode > 0) { WriteToDebugFile("Enchanting: original XP was " + ctx.XMM2f.ToString(System.Globalization.CultureInfo.InvariantCulture) + " and we replaced it with " + xp.ToString(System.Globalization.CultureInfo.InvariantCulture)); } ctx.XMM2f = xp; }
/// <summary> /// Unhandled exception filter. /// </summary> /// <param name="cpu">The cpu context.</param> /// <returns></returns> internal static bool UnhandledExceptionFilter(CPURegisters cpu) { int handled = 0; string logmsg = "Unhandled native exception occurred at " + cpu.IP.ToHexString() + CrashLog.GetAddressInModule(cpu.IP, System.Diagnostics.Process.GetCurrentProcess().Modules, " ") + " on thread " + Memory.GetCurrentNativeThreadId() + "!"; try { var cl = new NativeCrashLog(cpu); handled = cl.Write(true); if (cl.Skipped) { logmsg = null; } } catch (Exception ex2) { Main.Log.Append(ex2); } if (logmsg != null) { Log.AppendLine(logmsg); } return(handled > 0); }
public string GetSyntax(CPUMemory memory, CPURegisters registers, byte operand1, byte operand2) { var indexedAddress = (byte)(operand1 + registers.X); var address = memory[indexedAddress] | memory[(byte)(indexedAddress + 1)] << 0x08; return($"(${operand1:X02},X) @ {indexedAddress:X02} = {address:X04}"); }
public ushort GetAddress(CPUMemory memory, CPURegisters registers, byte operand1, byte operand2, out bool pageBoundaryCrossed) { var address = registers.PC + (sbyte)operand1; pageBoundaryCrossed = (address & 0xFF00) != (registers.PC & 0xFF00); return((ushort)address); }
public string GetSyntax(CPUMemory memory, CPURegisters registers, byte operand1, byte operand2) { var address = (memory[operand1] | memory[(byte)(operand1 + 1)] << 0x08); var indexedAddress = (ushort)(address + registers.Y); return($"(${operand1:X02}),Y = {address:X04} @ {indexedAddress:X04}"); }
public ushort GetAddress(CPUMemory memory, CPURegisters registers, byte operand1, byte operand2, out bool pageBoundaryCrossed) { var address = (operand1 | operand2 << 0x08) + registers.Y; pageBoundaryCrossed = (address & 0xFF00) != operand2 << 0x08; return((ushort)address); }
public Memory(Cartridge cartridge, GPU gpu, CPURegisters cpuRegisters, GPURegisters gpuRegisters, Keyboard keyboard) { this.cartridge = cartridge; this.gpu = gpu; this.cpuRegisters = cpuRegisters; this.gpuRegisters = gpuRegisters; this.keyboard = keyboard; }
public static void SBC(CPURegisters registers, ref byte substractee, byte substractor, byte extraSub) { // Need more range for flags int _A = substractee; int _B = substractor; int _C = extraSub; registers.FH = (byte)(((_A & 0x0F) < ((_B & 0x0F) + _C)) ? 1 : 0); registers.FC = (byte)((_A < (_B + _C)) ? 1 : 0); substractee -= substractor; substractee -= extraSub; registers.FZ = (byte)((registers.A == 0) ? 1 : 0); registers.FN = 1; }