public void StoreRegs() { Chip8State state = new Chip8State(); state.I = 0x300; byte[] ROM = new byte[] { 0x60, 1, 0x61, 2, 0x62, 3, 0x63, 4, 0xF3, 0x55 }; Helper.JITAndExecuteROM(ROM, state) .AssertReg(0, 1) .AssertReg(1, 2) .AssertReg(2, 3) .AssertReg(3, 4) .AssertRegsZeroExcept(0, 1, 2, 3); Assert.AreEqual(1, state.RAM.Span[state.I + 0]); Assert.AreEqual(2, state.RAM.Span[state.I + 1]); Assert.AreEqual(3, state.RAM.Span[state.I + 2]); Assert.AreEqual(4, state.RAM.Span[state.I + 3]); }
public static void SNER(Chip8State state, ref byte regx, ref byte regy) { if (regx != regy) { state.PC += 2; } }
public static void SNEI(Chip8State state, ref byte reg, byte imm) { if (reg != imm) { state.PC += 2; } }
public static void JMP(Chip8State state, UInt16 imm) { if (state.PC == imm) { state.Terminated = true; } state.Jump(imm); }
public static Chip8State JITAndExecuteROM(Span <byte> ROM, Chip8State state = null) { if (state == null) { state = new Chip8State(); } ROM.CopyTo(state.ProgramRegion.Span); new Chip8Sharp.JIT.JIT().JITROM(ROM)(state, ref state.Registers); return(state); }
public static Chip8State AssertRegsZeroExcept(this Chip8State state, params int[] values) { var regs = state.Registers.AsSpan(); for (int i = 0; i < regs.Length; i++) { if (!values.Contains(i)) { Assert.AreEqual(0, regs[i]); } } return(state); }
public void ReadDT() { Chip8State state = new Chip8State(); state.DT = 10; byte[] ROM = new byte[] { 0xF0, 0x07, }; Helper.JITAndExecuteROM(ROM, state); state.AssertReg(0, 10).AssertRegsZeroExcept(0); }
public void ClearScreen() { Chip8State state = new Chip8State(); state.VMEM.Span.Fill(0xFF); byte[] ROM = new byte[] { 0x00, 0xE0 }; Helper.JITAndExecuteROM(ROM, state) .AssertRegsZeroExcept(); Assert.IsTrue(state.VMEM.Span.SequenceEqual(new byte[state.VMEM.Length])); }
public void AddRegToI() { Chip8State state = new Chip8State(); state.I = 10; byte[] ROM = new byte[] { 0x60, 20, 0xF0, 0x1E }; Helper.JITAndExecuteROM(ROM, state) .AssertReg(0, 20) .AssertI(30) .AssertRegsZeroExcept(0); }
public void StoreBCD() { Chip8State state = new Chip8State(); state.I = 0x300; byte[] ROM = new byte[] { 0x60, 123, 0xF0, 0x33 }; Helper.JITAndExecuteROM(ROM, state) .AssertReg(0, 123) .AssertRegsZeroExcept(0); Assert.AreEqual(1, state.RAM.Span[state.I + 0]); Assert.AreEqual(2, state.RAM.Span[state.I + 1]); Assert.AreEqual(3, state.RAM.Span[state.I + 2]); }
public void LoadRegs() { Chip8State state = new Chip8State(); state.I = 0x300; state.RAM.Span[state.I] = 1; state.RAM.Span[state.I + 1] = 2; state.RAM.Span[state.I + 2] = 3; byte[] ROM = new byte[] { 0xF2, 0x65 }; Helper.JITAndExecuteROM(ROM, state) .AssertReg(0, 1) .AssertReg(1, 2) .AssertReg(2, 3) .AssertRegsZeroExcept(0, 1, 2); }
public static void DRW(Chip8State state, ref byte regx, ref byte regy, byte imm4) { Span <byte> sprite = state.RAM.Span.Slice(state.I, imm4); Span <byte> vmem = state.VMEM.Span; state.Registers.VF = 0; var unset = false; for (int i = 0; i < imm4; i++) { var sprSrc = sprite[i]; var y = regy + i; var actualY = (y >= Chip8State.DisplayH) ? (y - Chip8State.DisplayH) : y; var offset = regx + actualY * Chip8State.DisplayW; var byteoffset = offset / 8; var bitoffset = offset % 8; var slice = vmem.Slice(byteoffset, 2); ref var block0 = ref slice[0]; ref var block1 = ref slice[1];
public static void AND(Chip8State state, ref byte regx, ref byte regy) { regx &= regy; }
public static Chip8State AssertST(this Chip8State state, ushort value) { Assert.AreEqual(value, state.ST); return(state); }
public static void LDI(Chip8State state, ref byte reg, byte imm) { reg = imm; }
public static void ADDI(Chip8State state, ref byte reg, byte imm) { unchecked { reg += imm; } }
public static void SHL(Chip8State state, ref byte regx, ref byte regy) { state.Registers.VF = (byte)((regx & 0x80) != 0 ? 1 : 0); regx <<= 1; }
public static void SHR(Chip8State state, ref byte regx, ref byte regy) { state.Registers.VF = (byte)(regx & 1); regx >>= 1; }
public static void SUB(Chip8State state, ref byte regx, ref byte regy) { state.Registers.VF = (byte)(regx > regy ? 1 : 0); unchecked { regx -= regy; } }
public static void ADD(Chip8State state, ref byte regx, ref byte regy) { state.Registers.VF = (byte)(regx + regy > 0xFF ? 1 : 0); unchecked { regx += regy; } }
public void Execute(Chip8State state, ParsedInstruction instruction) => CallTable[instruction.Instruction](state, instruction);
public static void XOR(Chip8State state, ref byte regx, ref byte regy) { regx ^= regy; }
public static void CALL(Chip8State state, UInt16 imm) { state.SP++; state.StackRegion[state.SP] = (UInt16)(state.PC + 2); state.Jump(imm); }
public static void JMP0(Chip8State state, UInt16 imm) { state.Jump((UInt16)(state.Registers.V0 + imm)); }
public static Chip8State AssertNReg(this Chip8State state, byte register, byte value) { Assert.AreNotEqual(value, state.Register(register)); return(state); }
public static void RND(Chip8State state, ref byte regx, byte imm) { regx = (byte)(rnd.Next(0, 256) & imm); }
public static void SUBN(Chip8State state, ref byte regx, ref byte regy) { state.Registers.VF = (byte)(regx < regy ? 1 : 0); unchecked { regx = (byte)(regy - regx); } }
public static void LD(Chip8State state, ref byte regx, ref byte regy) { regx = regy; }
public DisassemblyProvider(byte[] ROM, Chip8State state) { dism = new Disassembler(); bin = dism.DisassembleProgram(ROM); this.state = state; }
public static void LRI(Chip8State state, UInt16 imm) { state.I = imm; }