Drop Register16 support (replaced with explicit ushort), add some unit tests (Chip class only at present)

Now runs some instructions before going wrong...

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-02-03 00:42:55 +00:00
parent 9a06b1743f
commit 3c5e292eae
18 changed files with 587 additions and 310 deletions

View File

@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "M6502", "M6502\M6502.csproj
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_M6502", "Test_M6502\Test_M6502.csproj", "{854EDE2F-B54D-425C-8F68-EDA68BDC797E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_M6502", "Test_M6502\Test_M6502.csproj", "{854EDE2F-B54D-425C-8F68-EDA68BDC797E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestEightBit", "UnitTestEightBit\UnitTestEightBit.csproj", "{AA8282A3-212A-42DE-B778-BBAEB7E6D986}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -55,6 +57,18 @@ Global
{854EDE2F-B54D-425C-8F68-EDA68BDC797E}.Release|x64.Build.0 = Release|Any CPU {854EDE2F-B54D-425C-8F68-EDA68BDC797E}.Release|x64.Build.0 = Release|Any CPU
{854EDE2F-B54D-425C-8F68-EDA68BDC797E}.Release|x86.ActiveCfg = Release|Any CPU {854EDE2F-B54D-425C-8F68-EDA68BDC797E}.Release|x86.ActiveCfg = Release|Any CPU
{854EDE2F-B54D-425C-8F68-EDA68BDC797E}.Release|x86.Build.0 = Release|Any CPU {854EDE2F-B54D-425C-8F68-EDA68BDC797E}.Release|x86.Build.0 = Release|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Debug|x64.ActiveCfg = Debug|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Debug|x64.Build.0 = Debug|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Debug|x86.Build.0 = Debug|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Release|Any CPU.Build.0 = Release|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Release|x64.ActiveCfg = Release|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Release|x64.Build.0 = Release|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Release|x86.ActiveCfg = Release|Any CPU
{AA8282A3-212A-42DE-B778-BBAEB7E6D986}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -7,67 +7,65 @@
{ {
} }
public override Register16 PeekWord(Register16 address) public override ushort PeekWord(ushort address)
{ {
var high = Bus.Peek(address); var high = Bus.Peek(address);
var low = Bus.Peek(++address); var low = Bus.Peek(++address);
return new Register16(low, high); return MakeWord(low, high);
} }
public override void PokeWord(Register16 address, Register16 value) public override void PokeWord(ushort address, ushort value)
{ {
Bus.Poke(address, value.High); Bus.Poke(address, LowByte(value));
Bus.Poke(++address, value.Low); Bus.Poke(++address, HighByte(value));
} }
protected override Register16 FetchWord() protected override ushort FetchWord()
{ {
var high = FetchByte(); var high = FetchByte();
var low = FetchByte(); var low = FetchByte();
return new Register16(low, high); return MakeWord(low, high);
} }
protected override Register16 GetWord() protected override ushort GetWord()
{ {
var high = BusRead(); var high = BusRead();
++Bus.Address.Word; ++Bus.Address;
var low = BusRead(); var low = BusRead();
return new Register16(low, high); return MakeWord(low, high);
} }
protected override Register16 GetWordPaged(byte page, byte offset) protected override ushort GetWordPaged(byte page, byte offset)
{ {
var high = GetBytePaged(page, offset); var high = GetBytePaged(page, offset);
++Bus.Address.Low; var low = GetBytePaged(page, (byte)(offset + 1));
var low = BusRead(); return MakeWord(low, high);
return new Register16(low, high);
} }
protected override Register16 PopWord() protected override ushort PopWord()
{ {
var high = Pop(); var high = Pop();
var low = Pop(); var low = Pop();
return new Register16(low, high); return MakeWord(low, high);
} }
protected override void PushWord(Register16 value) protected override void PushWord(ushort value)
{ {
Push(value.Low); Push(LowByte(value));
Push(value.High); Push(HighByte(value));
} }
protected override void SetWord(Register16 value) protected override void SetWord(ushort value)
{ {
BusWrite(value.High); BusWrite(HighByte(value));
++Bus.Address.Word; ++Bus.Address;
BusWrite(value.Low); BusWrite(LowByte(value));
} }
protected override void SetWordPaged(byte page, byte offset, Register16 value) protected override void SetWordPaged(byte page, byte offset, ushort value)
{ {
SetBytePaged(page, offset, value.High); SetBytePaged(page, offset, HighByte(value));
++Bus.Address.Low; SetBytePaged(page, (byte)(offset + 1), LowByte(value));
BusWrite(value.Low);
} }
} }
} }

View File

@ -5,7 +5,7 @@
abstract public class Bus : IMapper abstract public class Bus : IMapper
{ {
private byte data; private byte data;
private Register16 address = new Register16(); private ushort address;
public event EventHandler<EventArgs> WritingByte; public event EventHandler<EventArgs> WritingByte;
public event EventHandler<EventArgs> WrittenByte; public event EventHandler<EventArgs> WrittenByte;
@ -19,22 +19,21 @@
set { data = value; } set { data = value; }
} }
public Register16 Address public ushort Address
{ {
get { return address; } get { return address; }
set { address = value; }
} }
public abstract MemoryMapping Mapping(Register16 absolute); public abstract MemoryMapping Mapping(ushort absolute);
public byte Peek() => Reference(); public byte Peek() => Reference();
public byte Peek(Register16 absolute) => Reference(absolute); public byte Peek(ushort absolute) => Reference(absolute);
public byte Peek(ushort absolute) => Peek(Chip.LowByte(absolute), Chip.HighByte(absolute)); public byte Peek(byte low, byte high) => Reference(low, high);
public byte Peek(byte low, byte high) => Reference(new Register16(low, high));
public void Poke(byte value) => Reference() = value; public void Poke(byte value) => Reference() = value;
public void Poke(Register16 absolute, byte value) => Reference(absolute) = value; public byte Poke(ushort absolute, byte value) => Reference(absolute) = value;
public byte Poke(ushort absolute, byte value) => Poke(Chip.LowByte(absolute), Chip.HighByte(absolute), value); public byte Poke(byte low, byte high, byte value) => Reference(low, high) = value;
public byte Poke(byte low, byte high, byte value) => Reference(new Register16(low, high)) = value;
public byte Read() public byte Read()
{ {
@ -44,12 +43,17 @@
return returned; return returned;
} }
public byte Read(Register16 absolute) public byte Read(ushort absolute)
{ {
Address.Word = absolute.Word; Address = absolute;
return Read(); return Read();
} }
public byte Read(byte low, byte high)
{
return Read(Chip.MakeWord(low, high));
}
public void Write() public void Write()
{ {
OnWritingByte(); OnWritingByte();
@ -63,12 +67,17 @@
Write(); Write();
} }
public void Write(Register16 absolute, byte value) public void Write(ushort absolute, byte value)
{ {
Address.Word = absolute.Word; Address = absolute;
Write(value); Write(value);
} }
public void Write(byte low, byte high, byte value)
{
Write(Chip.MakeWord(low, high), value);
}
public virtual void RaisePOWER() {} public virtual void RaisePOWER() {}
public virtual void LowerPOWER() {} public virtual void LowerPOWER() {}
@ -80,7 +89,7 @@
protected virtual void OnReadingByte() => ReadingByte?.Invoke(this, EventArgs.Empty); protected virtual void OnReadingByte() => ReadingByte?.Invoke(this, EventArgs.Empty);
protected virtual void OnReadByte() => ReadByte?.Invoke(this, EventArgs.Empty); protected virtual void OnReadByte() => ReadByte?.Invoke(this, EventArgs.Empty);
protected ref byte Reference(Register16 absolute) protected ref byte Reference(ushort absolute)
{ {
var mapped = Mapping(absolute); var mapped = Mapping(absolute);
var offset = (ushort)((absolute - mapped.Begin) & mapped.Mask); var offset = (ushort)((absolute - mapped.Begin) & mapped.Mask);
@ -94,13 +103,9 @@
protected ref byte Reference() => ref Reference(Address); protected ref byte Reference() => ref Reference(Address);
protected ref byte Reference(ushort absolute) => ref Reference(Chip.LowByte(absolute), Chip.HighByte(absolute));
protected ref byte Reference(byte low, byte high) protected ref byte Reference(byte low, byte high)
{ {
Address.Low = low; return ref Reference(Chip.MakeWord(low, high));
Address.High = high;
return ref Reference();
} }
//[[nodiscard]] static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path); //[[nodiscard]] static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path);

View File

@ -17,18 +17,20 @@
ClearFlag(ref f, flag); ClearFlag(ref f, flag);
} }
public static void ClearFlag(ref byte f, byte flag, int condition) => ClearFlag(ref f, flag, condition == 0); public static void ClearFlag(ref byte f, byte flag, int condition) => ClearFlag(ref f, flag, condition != 0);
public static void ClearFlag(ref byte f, byte flag, bool condition) => SetFlag(ref f, flag, !condition); public static void ClearFlag(ref byte f, byte flag, bool condition) => SetFlag(ref f, flag, !condition);
public static int HighByte(int value) => LowByte(value >> 8); public static byte HighByte(int value) => (byte)(value >> 8);
public static byte HighByte(ushort value) => (byte)LowByte((int)value); public static byte HighByte(ushort value) => HighByte((int)value);
public static int LowByte(int value) => value & (int)Mask.Mask8; public static byte LowByte(int value) => (byte)(value & (int)Mask.Mask8);
public static byte LowByte(ushort value) => (byte)LowByte((int)value); public static byte LowByte(ushort value) => LowByte((int)value);
public static int PromoteByte(int value) => value << 8; public static ushort PromoteByte(byte value) => (ushort)(value << 8);
public static ushort PromoteByte(byte value) => (ushort)PromoteByte((int)value); public static byte DemoteByte(ushort value) => HighByte(value);
public static int DemoteByte(int value) => HighByte(value); public static ushort HigherPart(ushort value) => (ushort)(value & 0xff00);
public static byte DemoteByte(ushort value) => (byte)HighByte((int)value); public static byte LowerPart(ushort value) => LowByte(value);
static public ushort MakeWord(byte low, byte high) => (ushort)(PromoteByte(high) | low);
public static int HighNibble(byte value) => value >> 4; public static int HighNibble(byte value) => value >> 4;
public static int LowNibble(byte value) => value & 0xf; public static int LowNibble(byte value) => value & 0xf;
@ -36,7 +38,7 @@
public static int HigherNibble(byte value) => value & 0xf0; public static int HigherNibble(byte value) => value & 0xf0;
public static int LowerNibble(byte value) => LowNibble(value); public static int LowerNibble(byte value) => LowNibble(value);
public static int PromoteNibble(byte value) => value << 4; public static int PromoteNibble(byte value) => LowByte(value << 4);
public static int DemoteNibble(byte value) => HighNibble(value); public static int DemoteNibble(byte value) => HighNibble(value);
} }
} }

View File

@ -68,7 +68,6 @@
<Compile Include="Processor.cs" /> <Compile Include="Processor.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Ram.cs" /> <Compile Include="Ram.cs" />
<Compile Include="Register16.cs" />
<Compile Include="Rom.cs" /> <Compile Include="Rom.cs" />
<Compile Include="UnusedMemory.cs" /> <Compile Include="UnusedMemory.cs" />
</ItemGroup> </ItemGroup>

View File

@ -5,8 +5,8 @@
public abstract class IntelProcessor : LittleEndianProcessor public abstract class IntelProcessor : LittleEndianProcessor
{ {
private readonly IntelOpCodeDecoded[] decodedOpCodes; private readonly IntelOpCodeDecoded[] decodedOpCodes;
private Register16 sp; private ushort sp;
private Register16 memptr; private ushort memptr;
private PinLevel haltLine; private PinLevel haltLine;
@ -14,8 +14,8 @@
: base(bus) : base(bus)
{ {
decodedOpCodes = new IntelOpCodeDecoded[0x100]; decodedOpCodes = new IntelOpCodeDecoded[0x100];
sp = new Register16((ushort)Mask.Mask16); sp = (ushort)Mask.Mask16;
memptr = new Register16(); memptr = (ushort)Mask.Mask16;
for (int i = 0; i < 0x100; ++i) for (int i = 0; i < 0x100; ++i)
decodedOpCodes[i] = new IntelOpCodeDecoded((byte)i); decodedOpCodes[i] = new IntelOpCodeDecoded((byte)i);
@ -30,30 +30,30 @@
protected bool Halted => HALT().Lowered(); protected bool Halted => HALT().Lowered();
public Register16 SP { get => sp; set => sp = value; } public ushort SP { get => sp; set => sp = value; }
public Register16 MEMPTR { get => memptr; set => memptr = value; } public ushort MEMPTR { get => memptr; set => memptr = value; }
public abstract Register16 AF { get; set; } public abstract ushort AF { get; set; }
public byte A { get { return AF.High; } set { AF.High = value; } } public byte A { get { return HighByte(AF); } set { AF = (ushort)(LowerPart(AF) | PromoteByte(value)); } }
public byte F { get { return AF.Low; } set { AF.Low = value; } } public byte F { get { return LowByte(AF); } set { AF = (ushort)(HigherPart(AF) | value); } }
public abstract Register16 BC { get; set; } public abstract ushort BC { get; set; }
public byte B { get { return BC.High; } set { BC.High = value; } } public byte B { get { return HighByte(AF); } set { BC = (ushort)(LowerPart(BC) | PromoteByte(value)); } }
public byte C { get { return BC.Low; } set { BC.Low = value; } } public byte C { get { return LowByte(AF); } set { BC = (ushort)(HigherPart(BC) | value); } }
public abstract Register16 DE { get; set; } public abstract ushort DE { get; set; }
public byte D { get { return DE.High; } set { DE.High = value; } } public byte D { get { return HighByte(AF); } set { DE = (ushort)(LowerPart(DE) | PromoteByte(value)); } }
public byte E { get { return DE.Low; } set { DE.Low = value; } } public byte E { get { return LowByte(AF); } set { DE = (ushort)(HigherPart(DE) | value); } }
public abstract Register16 HL { get; set; } public abstract ushort HL { get; set; }
public byte H { get { return HL.High; } set { HL.High = value; } } public byte H { get { return HighByte(AF); } set { HL = (ushort)(LowerPart(AF) | PromoteByte(value)); } }
public byte L { get { return HL.Low; } set { HL.Low = value; } } public byte L { get { return LowByte(AF); } set { HL = (ushort)(HigherPart(AF) | value); } }
public override void RaisePOWER() public override void RaisePOWER()
{ {
base.RaisePOWER(); base.RaisePOWER();
RaiseHALT(); RaiseHALT();
SP = AF = BC = DE = HL = new Register16((ushort)Mask.Mask16); SP = AF = BC = DE = HL = (ushort)Mask.Mask16;
} }
public virtual void RaiseHALT() public virtual void RaiseHALT()
@ -79,20 +79,20 @@
protected override void HandleRESET() protected override void HandleRESET()
{ {
base.HandleRESET(); base.HandleRESET();
PC.Word = 0; PC = 0;
} }
protected sealed override void Push(byte value) => Bus.Write(--SP, value); protected sealed override void Push(byte value) => Bus.Write(--SP, value);
protected sealed override byte Pop() => Bus.Read(SP++); protected sealed override byte Pop() => Bus.Read(SP++);
protected sealed override Register16 GetWord() protected sealed override ushort GetWord()
{ {
var returned = base.GetWord(); var returned = base.GetWord();
MEMPTR = Bus.Address; MEMPTR = Bus.Address;
return returned; return returned;
} }
protected sealed override void SetWord(Register16 value) protected sealed override void SetWord(ushort value)
{ {
base.SetWord(value); base.SetWord(value);
MEMPTR = Bus.Address; MEMPTR = Bus.Address;
@ -102,8 +102,7 @@
protected void Restart(byte address) protected void Restart(byte address)
{ {
MEMPTR.Low = address; MEMPTR = address;
MEMPTR.High = 0;
Call(MEMPTR); Call(MEMPTR);
} }
@ -132,7 +131,7 @@
protected void JumpRelative(sbyte offset) protected void JumpRelative(sbyte offset)
{ {
MEMPTR.Word = (ushort)(PC.Word + offset); MEMPTR = (ushort)(PC + offset);
Jump(MEMPTR); Jump(MEMPTR);
} }

View File

@ -1,6 +1,4 @@
using System; namespace EightBit
namespace EightBit
{ {
public abstract class LittleEndianProcessor : Processor public abstract class LittleEndianProcessor : Processor
{ {
@ -9,75 +7,65 @@ namespace EightBit
{ {
} }
public override Register16 PeekWord(Register16 address) public override ushort PeekWord(ushort address)
{ {
var low = Bus.Peek(address); var low = Bus.Peek(address);
var high = Bus.Peek(++address); var high = Bus.Peek(++address);
return new Register16(low, high); return MakeWord(low, high);
} }
public override void PokeWord(Register16 address, Register16 value) public override void PokeWord(ushort address, ushort value)
{ {
if (value == null) Bus.Poke(address, LowByte(value));
throw new ArgumentNullException(nameof(value)); Bus.Poke(++address, HighByte(value));
Bus.Poke(address, value.Low);
Bus.Poke(++address, value.High);
} }
protected override Register16 FetchWord() protected override ushort FetchWord()
{ {
var low = FetchByte(); var low = FetchByte();
var high = FetchByte(); var high = FetchByte();
return new Register16(low, high); return MakeWord(low, high);
} }
protected override Register16 GetWord() protected override ushort GetWord()
{ {
var low = BusRead(); var low = BusRead();
++Bus.Address.Word; ++Bus.Address;
var high = BusRead(); var high = BusRead();
return new Register16(low, high); return MakeWord(low, high);
} }
protected override Register16 GetWordPaged(byte page, byte offset) protected override ushort GetWordPaged(byte page, byte offset)
{ {
var low = GetBytePaged(page, offset); var low = GetBytePaged(page, offset);
++Bus.Address.Low; var high = GetBytePaged(page, (byte)(offset + 1));
var high = BusRead(); return MakeWord(low, high);
return new Register16(low, high);
} }
protected override Register16 PopWord() protected override ushort PopWord()
{ {
var low = Pop(); var low = Pop();
var high = Pop(); var high = Pop();
return new Register16(low, high); return MakeWord(low, high);
} }
protected override void PushWord(Register16 value) protected override void PushWord(ushort value)
{ {
if (value == null) Push(HighByte(value));
throw new ArgumentNullException(nameof(value)); Push(LowByte(value));
Push(value.High);
Push(value.Low);
} }
protected override void SetWord(Register16 value) protected override void SetWord(ushort value)
{ {
if (value == null) BusWrite(LowByte(value));
throw new ArgumentNullException(nameof(value)); ++Bus.Address;
BusWrite(value.Low); BusWrite(HighByte(value));
++Bus.Address.Word;
BusWrite(value.High);
} }
protected override void SetWordPaged(byte page, byte offset, Register16 value) protected override void SetWordPaged(byte page, byte offset, ushort value)
{ {
if (value == null) SetBytePaged(page, offset, LowByte(value));
throw new ArgumentNullException(nameof(value)); SetBytePaged(page, (byte)(offset + 1), HighByte(value));
SetBytePaged(page, offset, value.Low);
++Bus.Address.Low;
BusWrite(value.High);
} }
} }
} }

View File

@ -2,6 +2,6 @@
{ {
public interface IMapper public interface IMapper
{ {
MemoryMapping Mapping(Register16 address); MemoryMapping Mapping(ushort address);
} }
} }

View File

@ -6,7 +6,7 @@
{ {
private Bus bus; private Bus bus;
private byte opcode; private byte opcode;
private Register16 pc; private ushort pc;
private PinLevel resetLine; private PinLevel resetLine;
private PinLevel intLine; private PinLevel intLine;
@ -14,7 +14,7 @@
protected Processor(Bus memory) protected Processor(Bus memory)
{ {
bus = memory; bus = memory;
pc = new Register16(); pc = 0;
} }
public event EventHandler<EventArgs> RaisingRESET; public event EventHandler<EventArgs> RaisingRESET;
@ -27,7 +27,7 @@
public event EventHandler<EventArgs> LoweringINT; public event EventHandler<EventArgs> LoweringINT;
public event EventHandler<EventArgs> LoweredINT; public event EventHandler<EventArgs> LoweredINT;
public Register16 PC { get => pc; set => pc = value; } public ushort PC { get => pc; set => pc = value; }
protected byte OpCode { get => opcode; set => opcode = value; } protected byte OpCode { get => opcode; set => opcode = value; }
public Bus Bus { get => bus; set => bus = value; } public Bus Bus { get => bus; set => bus = value; }
@ -51,11 +51,10 @@
return Execute(); return Execute();
} }
public abstract Register16 PeekWord(Register16 address); public abstract ushort PeekWord(ushort address);
public abstract void PokeWord(Register16 address, Register16 value); public abstract void PokeWord(ushort address, ushort value);
public Register16 PeekWord(byte low, byte high) => PeekWord(new Register16(low, high)); public ushort PeekWord(byte low, byte high) => PeekWord((ushort)(PromoteByte(high) | low));
public Register16 PeekWord(ushort address) => PeekWord(LowByte(address), HighByte(address));
public virtual void RaiseRESET() public virtual void RaiseRESET()
{ {
@ -100,14 +99,16 @@
protected virtual void HandleRESET() => RaiseRESET(); protected virtual void HandleRESET() => RaiseRESET();
protected virtual void HandleINT() => RaiseINT(); protected virtual void HandleINT() => RaiseINT();
protected void BusWrite(byte low, byte data) => BusWrite(low, 0, data); #region BusWrite
protected void BusWrite(Register16 address, byte data) => BusWrite(address.Low, address.High, data);
protected void BusWrite(byte low, byte high, byte data) protected void BusWrite(byte low, byte high, byte data)
{ {
Bus.Address.Low = low; BusWrite(MakeWord(low, high), data);
Bus.Address.High = high; }
protected void BusWrite(ushort address, byte data)
{
Bus.Address = address;
BusWrite(data); BusWrite(data);
} }
@ -117,59 +118,69 @@
BusWrite(); BusWrite();
} }
protected virtual void BusWrite() => Bus.Write(); protected virtual void BusWrite() => Bus.Write(); // N.B. Should be the only real call into the "Bus.Write" code.
protected byte BusRead(byte low) => BusRead(low, 0); #endregion
protected byte BusRead(Register16 address) => BusRead(address.Low, address.High); #region BusRead
protected byte BusRead(byte low, byte high) protected byte BusRead(byte low, byte high)
{ {
Bus.Address.Low = low; return BusRead(MakeWord(low, high));
Bus.Address.High = high; }
protected byte BusRead(ushort address)
{
Bus.Address = address;
return BusRead(); return BusRead();
} }
protected virtual byte BusRead() => Bus.Read(); protected virtual byte BusRead() => Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
protected byte GetBytePaged(byte page, byte offset) => BusRead(new Register16(offset, page)); #endregion
protected void SetBytePaged(byte page, byte offset, byte value) => BusWrite(new Register16(offset, page), value); #region Paged reader/writer wrappers
protected byte GetBytePaged(byte page, byte offset) => BusRead(offset, page);
protected void SetBytePaged(byte page, byte offset, byte value) => BusWrite(offset, page, value);
#endregion
protected byte FetchByte() => BusRead(PC++); protected byte FetchByte() => BusRead(PC++);
protected abstract Register16 GetWord(); protected abstract ushort GetWord();
protected abstract void SetWord(Register16 value); protected abstract void SetWord(ushort value);
protected abstract Register16 GetWordPaged(byte page, byte offset); protected abstract ushort GetWordPaged(byte page, byte offset);
protected abstract void SetWordPaged(byte page, byte offset, Register16 value); protected abstract void SetWordPaged(byte page, byte offset, ushort value);
protected abstract Register16 FetchWord(); protected abstract ushort FetchWord();
protected abstract void Push(byte value); protected abstract void Push(byte value);
protected abstract byte Pop(); protected abstract byte Pop();
protected abstract void PushWord(Register16 value); protected abstract void PushWord(ushort value);
protected abstract Register16 PopWord(); protected abstract ushort PopWord();
protected Register16 GetWord(Register16 address) protected ushort GetWord(ushort address)
{ {
Bus.Address.Word = address.Word; Bus.Address = address;
return GetWord(); return GetWord();
} }
protected void SetWord(Register16 address, Register16 value) protected void SetWord(ushort address, ushort value)
{ {
Bus.Address.Word = address.Word; Bus.Address = address;
SetWord(value); SetWord(value);
} }
protected void Jump(Register16 destination) protected void Jump(ushort destination)
{ {
PC = destination; PC = destination;
} }
protected void Call(Register16 destination) protected void Call(ushort destination)
{ {
PushWord(PC); PushWord(PC);
Jump(destination); Jump(destination);

View File

@ -1,86 +0,0 @@
namespace EightBit
{
public sealed class Register16
{
private byte low;
private byte high;
public Register16() { }
public Register16(ushort value) => Word = value;
public Register16(byte lowValue, byte highValue)
{
Low = lowValue;
High = highValue;
}
public byte Low { get => low; set => low = value; }
public byte High { get => high; set => high = value; }
public ushort Word
{
get
{
return (ushort)(Chip.PromoteByte(high) | low);
}
set
{
high = Chip.DemoteByte(value);
low = Chip.LowByte(value);
}
}
public static implicit operator ushort(Register16 value) { return ToUInt16(value); }
public static Register16 operator ++(Register16 left) => Increment(left);
public static Register16 operator --(Register16 left) => Decrement(left);
public static bool operator ==(Register16 left, Register16 right) => Equals(left, right);
public static bool operator !=(Register16 left, Register16 right) => !(left == right);
public static Register16 operator +(Register16 left, Register16 right) => Add(left, right);
public static Register16 operator -(Register16 left, Register16 right) => Subtract(left, right);
public static ushort ToUInt16(Register16 value) { return value.Word; }
public ushort ToUInt16() { return ToUInt16(this); }
public static Register16 Increment(Register16 left)
{
++left.Word;
return left;
}
public static Register16 Decrement(Register16 left)
{
--left.Word;
return left;
}
public static Register16 Add(Register16 left, Register16 right)
{
left.Word += right.Word;
return left;
}
public static Register16 Subtract(Register16 left, Register16 right)
{
left.Word -= right.Word;
return left;
}
public override int GetHashCode() => Word;
public override bool Equals(object obj)
{
var register = obj as Register16;
return Equals(register);
}
public bool Equals(Register16 register)
{
return register != null && low == register.low && high == register.high;
}
}
}

View File

@ -28,7 +28,7 @@
output.Append(" "); output.Append(" ");
var next = bus.Peek((ushort)(current + 1)); var next = bus.Peek((ushort)(current + 1));
var relative = (ushort)(processor.PC.Word + 2 + (sbyte)next); var relative = (ushort)(processor.PC + 2 + (sbyte)next);
var aaa = (cell & 0b11100000) >> 5; var aaa = (cell & 0b11100000) >> 5;
var bbb = (cell & 0b00011100) >> 2; var bbb = (cell & 0b00011100) >> 2;

View File

@ -14,7 +14,7 @@
private byte s; private byte s;
private byte p; private byte p;
private Register16 intermediate; private ushort intermediate;
private bool handlingRESET; private bool handlingRESET;
private bool handlingNMI; private bool handlingNMI;
@ -28,7 +28,6 @@
public M6502(Bus bus) public M6502(Bus bus)
: base(bus) : base(bus)
{ {
intermediate = new Register16();
} }
public event EventHandler<EventArgs> ExecutingInstruction; public event EventHandler<EventArgs> ExecutingInstruction;
@ -502,8 +501,8 @@
var software = !hardware; var software = !hardware;
if (reset) if (reset)
{ {
DummyPush(PC.High); DummyPush(HighByte(PC));
DummyPush(PC.Low); DummyPush(LowByte(PC));
DummyPush(P); DummyPush(P);
} }
else else
@ -521,67 +520,66 @@
{ {
Tick(); Tick();
Bus.Data = value; Bus.Data = value;
Bus.Address.Low = S--; Bus.Address = MakeWord(S--, 1);
Bus.Address.High = 1;
} }
// Addressing modes // Addressing modes
private Register16 Address_Absolute() => FetchWord(); private ushort Address_Absolute() => FetchWord();
private byte Address_ZeroPage() => FetchByte(); private byte Address_ZeroPage() => FetchByte();
private Register16 Address_ZeroPageIndirect() => GetWordPaged(0, Address_ZeroPage()); private ushort Address_ZeroPageIndirect() => GetWordPaged(0, Address_ZeroPage());
private Register16 Address_Indirect() private ushort Address_Indirect()
{ {
var address = Address_Absolute(); var address = Address_Absolute();
return GetWordPaged(address.High, address.Low); return GetWordPaged(HighByte(address), LowByte(address));
} }
private byte Address_ZeroPageX() private byte Address_ZeroPageX()
{ {
var address = Address_ZeroPage(); var address = Address_ZeroPage();
BusRead(address); BusRead(address);
return (byte)LowByte(address + X); return LowByte(address + X);
} }
private byte Address_ZeroPageY() private byte Address_ZeroPageY()
{ {
var address = Address_ZeroPage(); var address = Address_ZeroPage();
BusRead(address); BusRead(address);
return (byte)LowByte(address + Y); return LowByte(address + Y);
} }
private Tuple<Register16, byte> Address_AbsoluteX() private Tuple<ushort, byte> Address_AbsoluteX()
{ {
var address = Address_Absolute(); var address = Address_Absolute();
var page = address.High; var page = HighByte(address);
address.Word += X; address += X;
return new Tuple<Register16, byte>(address, page); return new Tuple<ushort, byte>(address, page);
} }
private Tuple<Register16, byte> Address_AbsoluteY() private Tuple<ushort, byte> Address_AbsoluteY()
{ {
var address = Address_Absolute(); var address = Address_Absolute();
var page = address.High; var page = HighByte(address);
address.Word += Y; address += Y;
return new Tuple<Register16, byte>(address, page); return new Tuple<ushort, byte>(address, page);
} }
private Register16 Address_IndexedIndirectX() => GetWordPaged(0, Address_ZeroPageX()); private ushort Address_IndexedIndirectX() => GetWordPaged(0, Address_ZeroPageX());
private Tuple<Register16, byte> Address_IndirectIndexedY() private Tuple<ushort, byte> Address_IndirectIndexedY()
{ {
var address = Address_ZeroPageIndirect(); var address = Address_ZeroPageIndirect();
var page = address.High; var page = HighByte(address);
address.Word += Y; address += Y;
return new Tuple<Register16, byte>(address, page); return new Tuple<ushort, byte>(address, page);
} }
private Register16 Address_relative_byte() private ushort Address_relative_byte()
{ {
intermediate.Word = (ushort)(PC + (byte)FetchByte()); intermediate = (ushort)(PC + (byte)FetchByte());
return intermediate; return intermediate;
} }
@ -598,8 +596,8 @@
var crossed = Address_AbsoluteX(); var crossed = Address_AbsoluteX();
var address = crossed.Item1; var address = crossed.Item1;
var page = crossed.Item2; var page = crossed.Item2;
var possible = GetBytePaged(page, address.Low); var possible = GetBytePaged(page, LowByte(address));
if ((behaviour == PageCrossingBehavior.AlwaysReadTwice) || (page != address.High)) if ((behaviour == PageCrossingBehavior.AlwaysReadTwice) || (page != HighByte(address)))
possible = BusRead(address); possible = BusRead(address);
return possible; return possible;
} }
@ -609,8 +607,8 @@
var crossed = Address_AbsoluteY(); var crossed = Address_AbsoluteY();
var address = crossed.Item1; var address = crossed.Item1;
var page = crossed.Item2; var page = crossed.Item2;
var possible = GetBytePaged(page, address.Low); var possible = GetBytePaged(page, LowByte(address));
if (page != address.High) if (page != HighByte(address))
possible = BusRead(address); possible = BusRead(address);
return possible; return possible;
} }
@ -626,8 +624,8 @@
var crossed = Address_IndirectIndexedY(); var crossed = Address_IndirectIndexedY();
var address = crossed.Item1; var address = crossed.Item1;
var page = crossed.Item2; var page = crossed.Item2;
var possible = GetBytePaged(page, address.Low); var possible = GetBytePaged(page, LowByte(address));
if (page != address.High) if (page != HighByte(address))
possible = BusRead(address); possible = BusRead(address);
return possible; return possible;
} }
@ -657,10 +655,10 @@
var destination = Address_relative_byte(); var destination = Address_relative_byte();
if (condition) { if (condition) {
BusRead(); BusRead();
var page = PC.High; var page = HighByte(PC);
Jump(destination); Jump(destination);
if (PC.High != page) if (HighByte(PC) != page)
BusRead(PC.Low, page); BusRead(LowByte(PC), page);
} }
} }
@ -686,9 +684,9 @@
var returned = SUB(operand, data, ~P & (int)StatusBits.CF); var returned = SUB(operand, data, ~P & (int)StatusBits.CF);
var difference = intermediate; var difference = intermediate;
AdjustNZ(difference.Low); AdjustNZ(LowByte(difference));
SetFlag(ref p, StatusBits.VF, (operand ^ data) & (operand ^ difference.Low) & (int)StatusBits.NF); SetFlag(ref p, StatusBits.VF, (operand ^ data) & (operand ^ LowByte(difference)) & (int)StatusBits.NF);
ClearFlag(ref p, StatusBits.CF, difference.High); ClearFlag(ref p, StatusBits.CF, HighByte(difference));
return returned; return returned;
} }
@ -700,13 +698,13 @@
private byte SUB_b(byte operand, byte data, int borrow) private byte SUB_b(byte operand, byte data, int borrow)
{ {
intermediate.Word = (ushort)(operand - data - borrow); intermediate = (ushort)(operand - data - borrow);
return intermediate.Low; return LowByte(intermediate);
} }
private byte SUB_d(byte operand, byte data, int borrow) private byte SUB_d(byte operand, byte data, int borrow)
{ {
intermediate.Word = (ushort)(operand - data - borrow); intermediate = (ushort)(operand - data - borrow);
byte low = (byte)(LowNibble(operand) - LowNibble(data) - borrow); byte low = (byte)(LowNibble(operand) - LowNibble(data) - borrow);
var lowNegative = low & (byte)StatusBits.NF; var lowNegative = low & (byte)StatusBits.NF;
@ -724,7 +722,7 @@
private byte ADC(byte operand, byte data) private byte ADC(byte operand, byte data)
{ {
var returned = ADD(operand, data, Carry); var returned = ADD(operand, data, Carry);
AdjustNZ(intermediate.Low); AdjustNZ(LowByte(intermediate));
return returned; return returned;
} }
@ -735,17 +733,17 @@
private byte ADD_b(byte operand, byte data, int carry) private byte ADD_b(byte operand, byte data, int carry)
{ {
intermediate.Word = (ushort)(operand + data + carry); intermediate = (ushort)(operand + data + carry);
SetFlag(ref p, StatusBits.VF, ~(operand ^ data) & (operand ^ intermediate.Low) & (int)StatusBits.NF); SetFlag(ref p, StatusBits.VF, ~(operand ^ data) & (operand ^ LowByte(intermediate)) & (int)StatusBits.NF);
SetFlag(ref p, StatusBits.CF, intermediate.High & (int)StatusBits.CF); SetFlag(ref p, StatusBits.CF, HighByte(intermediate) & (int)StatusBits.CF);
return intermediate.Low; return LowByte(intermediate);
} }
private byte ADD_d(byte operand, byte data, int carry) private byte ADD_d(byte operand, byte data, int carry)
{ {
intermediate.Word = (ushort)(operand + data + carry); intermediate = (ushort)(operand + data + carry);
byte low = (byte)(LowNibble(operand) + LowNibble(data) + carry); byte low = (byte)(LowNibble(operand) + LowNibble(data) + carry);
if (low > 9) if (low > 9)
@ -779,9 +777,9 @@
private void CMP(byte first, byte second) private void CMP(byte first, byte second)
{ {
intermediate.Word = (ushort)(first - second); intermediate = (ushort)(first - second);
AdjustNZ(intermediate.Low); AdjustNZ(LowByte(intermediate));
ClearFlag(ref p, StatusBits.CF, intermediate.High); ClearFlag(ref p, StatusBits.CF, HighByte(intermediate));
} }
private byte DEC(byte value) => Through(value - 1); private byte DEC(byte value) => Through(value - 1);
@ -795,8 +793,7 @@
var low = FetchByte(); var low = FetchByte();
GetBytePaged(1, S); // dummy read GetBytePaged(1, S); // dummy read
PushWord(PC); PushWord(PC);
PC.High = FetchByte(); PC = MakeWord(low, FetchByte());
PC.Low = low;
} }
private byte LSR(byte value) private byte LSR(byte value)
@ -866,7 +863,7 @@
private void AXS(byte value) private void AXS(byte value)
{ {
X = Through(SUB((byte)(A & X), value)); X = Through(SUB((byte)(A & X), value));
ClearFlag(ref p, StatusBits.CF, intermediate.High); ClearFlag(ref p, StatusBits.CF, HighByte(intermediate));
} }
private void DCP(byte value) private void DCP(byte value)
@ -912,7 +909,7 @@
var crossed = Address_AbsoluteX(); var crossed = Address_AbsoluteX();
var address = crossed.Item1; var address = crossed.Item1;
var page = crossed.Item2; var page = crossed.Item2;
GetBytePaged(page, address.Low); GetBytePaged(page, LowByte(address));
BusWrite(address, A); BusWrite(address, A);
} }
@ -921,7 +918,7 @@
var crossed = Address_AbsoluteY(); var crossed = Address_AbsoluteY();
var address = crossed.Item1; var address = crossed.Item1;
var page = crossed.Item2; var page = crossed.Item2;
GetBytePaged(page, address.Low); GetBytePaged(page, LowByte(address));
BusWrite(address, A); BusWrite(address, A);
} }
} }

View File

@ -11,8 +11,7 @@
private readonly Symbols symbols; private readonly Symbols symbols;
private readonly Disassembly disassembler; private readonly Disassembly disassembler;
private Register16 oldPC; private ushort oldPC;
private bool stopped;
public Board(Configuration configuration) public Board(Configuration configuration)
{ {
@ -22,8 +21,7 @@
this.symbols = new Symbols(); this.symbols = new Symbols();
this.disassembler = new Disassembly(this, this.cpu, this.symbols); this.disassembler = new Disassembly(this, this.cpu, this.symbols);
this.oldPC = new Register16((ushort)Mask.Mask16); this.oldPC = (ushort)Mask.Mask16;
this.stopped = false;
} }
public M6502 CPU { get { return this.cpu; } } public M6502 CPU { get { return this.cpu; } }
@ -50,7 +48,7 @@
var programFilename = configuration.Program; var programFilename = configuration.Program;
var programPath = configuration.RomDirectory + "/" + configuration.Program; var programPath = configuration.RomDirectory + "/" + configuration.Program;
var loadAddress = configuration.LoadAddress; var loadAddress = configuration.LoadAddress;
ram.Load(programPath, loadAddress.Word); ram.Load(programPath, loadAddress);
if (configuration.DebugMode) if (configuration.DebugMode)
CPU.ExecutingInstruction += CPU_ExecutingInstruction; CPU.ExecutingInstruction += CPU_ExecutingInstruction;
@ -58,8 +56,8 @@
CPU.ExecutedInstruction += CPU_ExecutedInstruction; CPU.ExecutedInstruction += CPU_ExecutedInstruction;
Poke(0x00, 0x4c); Poke(0x00, 0x4c);
Poke(0x01, configuration.StartAddress.Low); Poke(0x01, Chip.LowByte(configuration.StartAddress));
Poke(0x02, configuration.StartAddress.High); Poke(0x02, Chip.HighByte(configuration.StartAddress));
} }
private void CPU_ExecutedInstruction(object sender, System.EventArgs e) private void CPU_ExecutedInstruction(object sender, System.EventArgs e)
@ -110,12 +108,12 @@
output.Append(Disassembly.Dump_ByteValue(CPU.S)); output.Append(Disassembly.Dump_ByteValue(CPU.S));
output.Append("\t"); output.Append("\t");
output.Append(disassembler.Disassemble(address.Word)); output.Append(disassembler.Disassemble(address));
System.Console.Out.WriteLine(output.ToString()); System.Console.Out.WriteLine(output.ToString());
} }
public override MemoryMapping Mapping(Register16 absolute) public override MemoryMapping Mapping(ushort absolute)
{ {
return new MemoryMapping(ram, 0x0000, (ushort)Mask.Mask16, AccessLevel.ReadWrite); return new MemoryMapping(ram, 0x0000, (ushort)Mask.Mask16, AccessLevel.ReadWrite);
} }

View File

@ -5,8 +5,8 @@
internal class Configuration internal class Configuration
{ {
private bool debugMode = false; private bool debugMode = false;
private readonly Register16 loadAddress = new Register16(0x400); private readonly ushort loadAddress = 0x400;
private readonly Register16 startAddress = new Register16(0x400); private readonly ushort startAddress = 0x400;
private readonly string romDirectory = "roms"; private readonly string romDirectory = "roms";
private readonly string program = "6502_functional_test.bin"; private readonly string program = "6502_functional_test.bin";
@ -17,8 +17,8 @@
set { debugMode = value; } set { debugMode = value; }
} }
public Register16 LoadAddress { get { return loadAddress; } } public ushort LoadAddress { get { return loadAddress; } }
public Register16 StartAddress { get { return startAddress; } } public ushort StartAddress { get { return startAddress; } }
public string RomDirectory { get { return romDirectory; } } public string RomDirectory { get { return romDirectory; } }
public string Program { get { return program; } } public string Program { get { return program; } }

View File

@ -0,0 +1,253 @@
namespace UnitTestEightBit
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EightBit;
[TestClass]
public class ChipUnitTest
{
#region LowByte
[TestMethod]
public void TestLowByte()
{
ushort input = 0xf00f;
byte low = Chip.LowByte(input);
Assert.AreEqual(0xf, low);
}
#endregion
#region HighByte
[TestMethod]
public void TestHighByte()
{
ushort input = 0xf00f;
byte high = Chip.HighByte(input);
Assert.AreEqual(0xf0, high);
}
#endregion
#region ClearFlag
[TestMethod]
public void TestClearFlag()
{
byte flags = 0xff;
EightBit.Chip.ClearFlag(ref flags, 0x80);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestClearFlagNonZero()
{
byte flags = 0xff;
EightBit.Chip.ClearFlag(ref flags, 0x80, 1);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestClearFlagZero()
{
byte flags = 0xff;
EightBit.Chip.ClearFlag(ref flags, 0x80, 0);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestClearFlagFalse()
{
byte flags = 0xff;
EightBit.Chip.ClearFlag(ref flags, 0x80, false);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestClearFlagTrue()
{
byte flags = 0xff;
EightBit.Chip.ClearFlag(ref flags, 0x80, true);
Assert.AreEqual(0x7f, flags);
}
#endregion
#region SetFlag
[TestMethod]
public void TestSetFlag()
{
byte flags = 0x7f;
EightBit.Chip.SetFlag(ref flags, 0x80);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestSetFlagNonZero()
{
byte flags = 0x7f;
EightBit.Chip.SetFlag(ref flags, 0x80, 1);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestSetFlagZero()
{
byte flags = 0x7f;
EightBit.Chip.SetFlag(ref flags, 0x80, 0);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestSetFlagFalse()
{
byte flags = 0x7f;
EightBit.Chip.SetFlag(ref flags, 0x80, false);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestSetFlagTrue()
{
byte flags = 0x7f;
EightBit.Chip.SetFlag(ref flags, 0x80, true);
Assert.AreEqual(0xff, flags);
}
#endregion
#region LowerPart
[TestMethod]
public void TestLowerPart()
{
ushort input = 0xf00f;
ushort lower = Chip.LowerPart(input);
Assert.AreEqual(0xf, lower);
}
#endregion
#region HigherPart
[TestMethod]
public void TestHigherPart()
{
ushort input = 0xf00f;
ushort higher = Chip.HigherPart(input);
Assert.AreEqual(0xf000, higher);
}
#endregion
#region DemoteByte
[TestMethod]
public void TestDemoteByte()
{
ushort input = 0xf00f;
byte demoted = Chip.DemoteByte(input);
Assert.AreEqual(0xf0, demoted);
}
#endregion
#region PromoteByte
[TestMethod]
public void TestPromoteByte()
{
byte input = 0xf0;
ushort promoted = Chip.PromoteByte(input);
Assert.AreEqual(0xf000, promoted);
}
#endregion
#region LowNibble
[TestMethod]
public void TestLowNibble()
{
byte input = 0xab;
int nibble = Chip.LowNibble(input);
Assert.AreEqual(0xb, nibble);
}
#endregion
#region HighNibble
[TestMethod]
public void TestHighNibble()
{
byte input = 0xab;
int nibble = Chip.HighNibble(input);
Assert.AreEqual(0xa, nibble);
}
#endregion
#region DemoteNibble
[TestMethod]
public void TestDemoteNibble()
{
byte input = 0xab;
int nibble = Chip.DemoteNibble(input);
Assert.AreEqual(0xa, nibble);
}
#endregion
#region PromoteNibble
[TestMethod]
public void TestPromoteNibble()
{
byte input = 0xab;
int nibble = Chip.PromoteNibble(input);
Assert.AreEqual(0xb0, nibble);
}
#endregion
#region HigherNibble
[TestMethod]
public void TestHigherNibble()
{
byte input = 0xab;
int nibble = Chip.HigherNibble(input);
Assert.AreEqual(0xa0, nibble);
}
#endregion
#region LowerNibble
[TestMethod]
public void TestLowerNibble()
{
byte input = 0xab;
int nibble = Chip.LowerNibble(input);
Assert.AreEqual(0xb, nibble);
}
#endregion
#region MakeWord
[TestMethod]
public void TestMakeWord()
{
ushort word = Chip.MakeWord(0xcd, 0xab);
Assert.AreEqual(0xabcd, word);
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("UnitTestEightBit")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UnitTestEightBit")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("aa8282a3-212a-42de-b778-bbaeb7e6d986")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{AA8282A3-212A-42DE-B778-BBAEB7E6D986}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UnitTestEightBit</RootNamespace>
<AssemblyName>UnitTestEightBit</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChipUnitTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EightBit\EightBit.csproj">
<Project>{6ebf8857-62a3-4ef4-af21-c1844031d7e4}</Project>
<Name>EightBit</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props'))" />
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets'))" />
</Target>
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" />
</Project>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MSTest.TestAdapter" version="1.3.2" targetFramework="net472" />
<package id="MSTest.TestFramework" version="1.3.2" targetFramework="net472" />
</packages>