public void CheckAnd_Ani_() { // ANDI #<data>,<ea> // 0000 0010 0001 1001 0x0219 // 0000 0000 0000 0101 0x000A // ANDI #10,(A1) byte[] data = new byte[] { 0x02, 0x19, 0x00, 0x0A }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x1, 0x00FF0000); state.WriteByte(0x00FF0000, 0xFF); state.WriteByte(0x00FF0002, 0xAA); state.WriteDReg(0x1, 0xFF); state.FetchOpCode(); var opcode = new ANDI(state); Assert.That(opcode.Assembly, Is.EqualTo("ANDI #10,(A1)+")); Assert.That(state.PC, Is.EqualTo(0x04)); Assert.That(state.ReadAReg(0x1), Is.EqualTo(0x00FF0001)); Assert.That(state.ReadByte(0x00FF0000), Is.EqualTo(0x0000000A)); }
public void CheckAddD1To_A0_() { // ADD Dn,<ea> // 1101 dddD ssmm mxxx // 1101 0011 0001 0000 0xD310 // ADD D1,(A0) byte[] data = new byte[] { 0xD3, 0x10 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteDReg(0x1, 0x22221111); state.WriteAReg(0x0, 0x00FF0000); state.WriteByte(0x00FF0000, 0x22); state.FetchOpCode(); var opcode = new ADD(state); Assert.That(opcode.Assembly, Is.EqualTo("ADD.B D1,(A0)")); Assert.That(state.PC, Is.EqualTo(0x02)); Assert.That(state.ReadAReg(0x0), Is.EqualTo(0x00FF0000)); Assert.That(state.ReadDReg(0x1), Is.EqualTo(0x22221111)); Assert.That(state.ReadByte(0x00FF0000), Is.EqualTo(0x33)); }
public void CheckMoveNumberToDRegister(byte number, DataRegister register) { // 0111ddd0bbbbbbbb // MOVEQ #0,D0 byte hi = 0x70; byte lo = number; hi |= (byte)((byte)register << 1); byte[] data = new byte[] { hi, lo }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x5, 0xFF0000); for (int i = 0; i < 16; i++) { state.WriteByte((uint)(0xFF0000 + i), (byte)(0x00 + i)); } state.FetchOpCode(); var opcode = new MOVEQ(state); Assert.That(opcode.Assembly, Is.EqualTo($"MOVEQ #{number},{register}")); Assert.That(opcode.Size, Is.EqualTo(Size.Long)); Assert.That(state.ReadDReg((byte)register), Is.EqualTo(number)); }
public void CheckLoad_A0_ToA1() { // LEA <ea>,An // 0100 0011 1101 0000 0x43D0 // LEA (A0),A1 byte[] data = new byte[] { 0x43, 0xD0 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x0, 0x00FF0000); state.WriteByte(0x00FF0000, 0xAA); state.FetchOpCode(); var opcode = new LEA(state); Assert.That(opcode.Assembly, Is.EqualTo("LEA (A0),A1")); Assert.That(opcode.Size, Is.EqualTo(Size.Long)); Assert.That(state.PC, Is.EqualTo(0x00000002)); Assert.That(state.ReadAReg(0x0), Is.EqualTo(0x00FF0000)); Assert.That(state.ReadAReg(0x1), Is.EqualTo(0x00FF0000)); }
public void CheckMove_A0i_ToA1() { // 00ss aaa0 01mm mxxx // 0010 0010 0101 1000 0x2258 // MOVEM <ea>,An // MOVEM (A0)+,A1 byte[] data = new byte[] { 0x22, 0x58 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteByte(0x00FF0000, 0xAA); state.WriteByte(0x00FF0001, 0xBB); state.WriteByte(0x00FF0002, 0xCC); state.WriteByte(0x00FF0003, 0xDD); state.WriteAReg(0x0, 0x00FF0000); state.FetchOpCode(); var opcode = new MOVEA(state); Assert.That(opcode.Assembly, Is.EqualTo($"MOVEA (A0)+,A1")); Assert.That(opcode.Size, Is.EqualTo(Size.Long)); Assert.That(state.ReadAReg(0x0), Is.EqualTo(0x00FF0004)); Assert.That(state.ReadAReg(0x1), Is.EqualTo(0xAABBCCDD)); }
public void CheckA5PostIncMoveLongToReg() { // MOVEM <ea>,<ea> // 0100 1100 1101 1101 0x4CDD // 0001 1111 0000 0000 0x1F00 // MOVEM (A5)+,0001111100000000 byte[] data = new byte[] { 0x4C, 0xDD, 0x1F, 0x00 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x5, 0xFF0000); for (int i = 0; i < 64; i++) { state.WriteByte((uint)(0xFF0000 + i), (byte)(0x00 + i)); } state.FetchOpCode(); var opcode = new MOVEM(state); Assert.That(opcode.Assembly, Is.EqualTo("MOVEM (A5)+,%0001111100000000")); Assert.That(opcode.Size, Is.EqualTo(Size.Long)); Assert.That(state.ReadAReg(0x0), Is.EqualTo(0x00010203)); Assert.That(state.ReadAReg(0x1), Is.EqualTo(0x04050607)); Assert.That(state.ReadAReg(0x2), Is.EqualTo(0x08090A0B)); Assert.That(state.ReadAReg(0x3), Is.EqualTo(0x0C0D0E0F)); Assert.That(state.ReadAReg(0x4), Is.EqualTo(0x10111213)); Assert.That(state.ReadAReg(0x5), Is.EqualTo(0x00FF0014)); Assert.That(state.ReadAReg(0x6), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x7), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x0), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x1), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x2), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x3), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x4), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x5), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x6), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x7), Is.EqualTo(0x0000)); Assert.That(state.PC, Is.EqualTo(0x00000004)); Assert.That(state.ReadAReg(0x5), Is.EqualTo(0x00FF0014)); }
public void CheckA5PostIncMoveWordToReg() { // MOVEM <ea>,<ea> // 0100 1100 1001 1101 0x4C9D // 0000 0000 1110 0000 0x00E0 // MOVEM (A5)+,0000000011100000 byte[] data = new byte[] { 0x4C, 0x9D, 0x00, 0xE0 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x5, 0xFF0000); for (int i = 0; i < 16; i++) { state.WriteByte((uint)(0xFF0000 + i), (byte)(0x00 + i)); } state.FetchOpCode(); var opcode = new MOVEM(state); Assert.That(opcode.Assembly, Is.EqualTo("MOVEM (A5)+,%0000000011100000")); Assert.That(opcode.Size, Is.EqualTo(Size.Word)); Assert.That(state.ReadAReg(0x0), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x1), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x2), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x3), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x4), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x5), Is.EqualTo(0xFF0006)); Assert.That(state.ReadAReg(0x6), Is.EqualTo(0x0000)); Assert.That(state.ReadAReg(0x7), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x0), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x1), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x2), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x3), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x4), Is.EqualTo(0x0000)); Assert.That(state.ReadDReg(0x5), Is.EqualTo(0x0001)); Assert.That(state.ReadDReg(0x6), Is.EqualTo(0x0203)); Assert.That(state.ReadDReg(0x7), Is.EqualTo(0x0405)); Assert.That(state.PC, Is.EqualTo(0x00000004)); Assert.That(state.ReadAReg(0x5), Is.EqualTo(0x00FF0006)); }
public void CheckLoadA0ToA1() { // LEA <ea>,An // 0100 0011 1100 1000 0x43C8 // LEA A0,A1 byte[] data = new byte[] { 0x43, 0xC8 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x0, 0xAABBCCDD); state.FetchOpCode(); Assert.Throws <InvalidOpCodeException>(() => new LEA(state)); }
public void CheckLoad_dA0_ToA1() { // LEA <ea>,An // 0100 0011 1110 0000 0x43E0 // LEA -(A0),A1 byte[] data = new byte[] { 0x43, 0xE0 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x0, 0x00FF0004); state.WriteByte(0x00FF0000, 0xAA); state.FetchOpCode(); Assert.Throws <InvalidOpCodeException>(() => new LEA(state)); }
public void CheckAddD1ToA0() { // ADD Dn,<ea> // 1101 dddD ssmm mxxx // 1101 0011 0000 1000 0xD308 // ADD.B D1,A0 byte[] data = new byte[] { 0xD3, 0x08 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteDReg(0x0, 0x22221111); state.WriteAReg(0x1, 0x33332222); state.FetchOpCode(); Assert.Throws <InvalidOpCodeException>(() => new ADD(state)); }
public void CheckMoveA0ToD1() { // MOVE <ea>,<ea> // 0001 0010 0000 1000 0x1208 // MOVE A0,D1 byte[] data = new byte[] { 0x12, 0x08 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x0, 0xAABBCCDD); state.FetchOpCode(); var opcode = new MOVE(state); Assert.That(opcode.Assembly, Is.EqualTo("MOVE.b A0,D1")); Assert.That(state.PC, Is.EqualTo(0x02)); Assert.That(state.ReadDReg(0x1), Is.EqualTo(0x000000DD)); }
public void CheckMoveA0ToA1() { // 00ss aaa0 01mm mxxx // 0001 0010 0100 1000 0x1248 // MOVEM <ea>,An // MOVEM A0,A1 byte[] data = new byte[] { 0x12, 0x48 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x0, 0xAABBCCDD); state.FetchOpCode(); var opcode = new MOVEA(state); Assert.That(opcode.Assembly, Is.EqualTo($"MOVEA A0,A1")); Assert.That(opcode.Size, Is.EqualTo(Size.Word)); Assert.That(state.ReadAReg(0x1), Is.EqualTo(0xCCDD)); }
public void CheckMove_A0_ToD1() { // MOVE <ea>,<ea> // 0001 0010 0001 0000 0x1210 // MOVE (A0), D1 byte[] data = new byte[] { 0x12, 0x10 }; MegadriveState state = new MegadriveState(new Data(data), 0x00000000, 0x00000000, 0x000000, 0x3FFFFF, 0x0FF0000, 0xFFFFFF); state.WriteAReg(0x0, 0x00FF0000); state.WriteByte(0x00FF0000, 0xAA); state.FetchOpCode(); var opcode = new MOVE(state); Assert.That(opcode.Assembly, Is.EqualTo("MOVE.b (A0),D1")); Assert.That(state.PC, Is.EqualTo(0x02)); Assert.That(state.ReadDReg(0x1), Is.EqualTo(0x000000AA)); }
/// <summary> /// Initializes a new instance of the <see cref="MOVEM"/> class. /// </summary> /// <param name="state">machine state.</param> public MOVEM(MegadriveState state) : base("01001D001smmmxxx", state) { this.mask = state.ReadWord(state.PC); state.PC += 2; this.EffectiveAddress = this.FetchEffectiveAddress(); // TODO: should the increment only include values that are beingset? switch (this.Size) { case Size.Word: switch (this.GetDirection()) { case MoveDirection.MemoryToRegister: ushort maskCheck = 1; int count = 0; for (int i = 0; i < 8; i++) { uint d = state.ReadWord((uint)(this.EffectiveAddress + (count * 2))); if ((this.mask & maskCheck) == maskCheck) { state.WriteDReg((byte)i, d); count++; } maskCheck += maskCheck; } for (int i = 0; i < 8; i++) { uint d = state.ReadWord((uint)(this.EffectiveAddress + (count * 2))); if ((this.mask & maskCheck) == maskCheck) { state.WriteAReg((byte)i, d); count++; } maskCheck += maskCheck; } this.WriteValueToEffectiveAddress(this.DecodeEffectiveAddressMode(), this.GetXn(), (uint)(this.EffectiveAddress + (count * 2))); break; case MoveDirection.RegisterToMemory: throw new System.NotImplementedException(); default: throw new InvalidStateException(); } break; case Size.Long: switch (this.GetDirection()) { case MoveDirection.MemoryToRegister: ushort maskCheck = 1; int count = 0; for (int i = 0; i < 8; i++) { uint d = state.ReadLong((uint)(this.EffectiveAddress + (count * 4))); if ((this.mask & maskCheck) == maskCheck) { state.WriteDReg((byte)i, d); count++; } maskCheck += maskCheck; } for (int i = 0; i < 8; i++) { uint d = state.ReadLong((uint)(this.EffectiveAddress + (count * 4))); if ((this.mask & maskCheck) == maskCheck) { state.WriteAReg((byte)i, d); count++; } maskCheck += maskCheck; } this.WriteValueToEffectiveAddress(this.DecodeEffectiveAddressMode(), this.GetXn(), (uint)(this.EffectiveAddress + (count * 4))); break; case MoveDirection.RegisterToMemory: throw new System.NotImplementedException(); default: throw new InvalidStateException(); } break; default: throw new InvalidStateException(); } }