Not sure if this was a really good idea, but integrated StyleCop rules into the builds. Corrected all except documentation problems.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-02-04 23:52:21 +00:00
parent 30aa1b70bf
commit 224000c4c7
53 changed files with 2430 additions and 1575 deletions

View File

@ -12,6 +12,9 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestEightBit", "UnitTestEightBit\UnitTestEightBit.csproj", "{AA8282A3-212A-42DE-B778-BBAEB7E6D986}"
EndProject
Global
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64

View File

@ -1,7 +1,13 @@
namespace EightBit
// <copyright file="AccessLevel.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public enum AccessLevel
{
Unknown, ReadOnly, WriteOnly, ReadWrite
Unknown,
ReadOnly,
WriteOnly,
ReadWrite,
}
}

View File

@ -1,4 +1,7 @@
namespace EightBit
// <copyright file="BigEndianProcessor.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public abstract class BigEndianProcessor : Processor
{
@ -9,63 +12,63 @@
public override ushort PeekWord(ushort address)
{
var high = Bus.Peek(address);
var low = Bus.Peek(++address);
return MakeWord(low, high);
var high = this.Bus.Peek(address);
var low = this.Bus.Peek(++address);
return Chip.MakeWord(low, high);
}
public override void PokeWord(ushort address, ushort value)
{
Bus.Poke(address, LowByte(value));
Bus.Poke(++address, HighByte(value));
this.Bus.Poke(address, Chip.LowByte(value));
this.Bus.Poke(++address, Chip.HighByte(value));
}
protected override ushort FetchWord()
{
var high = FetchByte();
var low = FetchByte();
return MakeWord(low, high);
var high = this.FetchByte();
var low = this.FetchByte();
return Chip.MakeWord(low, high);
}
protected override ushort GetWord()
{
var high = BusRead();
++Bus.Address;
var low = BusRead();
return MakeWord(low, high);
var high = this.BusRead();
++this.Bus.Address;
var low = this.BusRead();
return Chip.MakeWord(low, high);
}
protected override ushort GetWordPaged(byte page, byte offset)
{
var high = BusRead(offset, page);
var low = BusRead((byte)(offset + 1), page);
return MakeWord(low, high);
var high = this.BusRead(offset, page);
var low = this.BusRead((byte)(offset + 1), page);
return Chip.MakeWord(low, high);
}
protected override ushort PopWord()
{
var high = Pop();
var low = Pop();
return MakeWord(low, high);
var high = this.Pop();
var low = this.Pop();
return Chip.MakeWord(low, high);
}
protected override void PushWord(ushort value)
{
Push(LowByte(value));
Push(HighByte(value));
this.Push(Chip.LowByte(value));
this.Push(Chip.HighByte(value));
}
protected override void SetWord(ushort value)
{
BusWrite(HighByte(value));
++Bus.Address;
BusWrite(LowByte(value));
this.BusWrite(Chip.HighByte(value));
++this.Bus.Address;
this.BusWrite(Chip.LowByte(value));
}
protected override void SetWordPaged(byte page, byte offset, ushort value)
{
BusWrite(offset, page, HighByte(value));
BusWrite((byte)(offset + 1), page, LowByte(value));
this.BusWrite(offset, page, Chip.HighByte(value));
this.BusWrite((byte)(offset + 1), page, Chip.LowByte(value));
}
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Bits.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
@ -21,6 +25,6 @@
Bit13 = Bit12 << 1,
Bit14 = Bit13 << 1,
Bit15 = Bit14 << 1,
Bit16 = Bit15 << 1
Bit16 = Bit15 << 1,
}
}

View File

@ -1,96 +1,115 @@
namespace EightBit
// <copyright file="Bus.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
abstract public class Bus : IMapper
public abstract class Bus : IMapper
{
private byte data;
private ushort address;
public event EventHandler<EventArgs> WritingByte;
public event EventHandler<EventArgs> WrittenByte;
public event EventHandler<EventArgs> ReadingByte;
public event EventHandler<EventArgs> ReadByte;
public byte Data { get => data; set => data = value; }
public ushort Address { get => address; set => address = value; }
public byte Data { get => this.data; set => this.data = value; }
public ushort Address { get => this.address; set => this.address = value; }
public abstract MemoryMapping Mapping(ushort absolute);
public byte Peek() => Reference();
public byte Peek(ushort absolute) => Reference(absolute);
public byte Peek(byte low, byte high) => Reference(low, high);
public byte Peek() => this.Reference();
public void Poke(byte value) => Reference() = value;
public byte Poke(ushort absolute, byte value) => Reference(absolute) = value;
public byte Poke(byte low, byte high, byte value) => Reference(low, high) = value;
public byte Peek(ushort absolute) => this.Reference(absolute);
public byte Peek(byte low, byte high) => this.Reference(low, high);
public void Poke(byte value) => this.Reference() = value;
public byte Poke(ushort absolute, byte value) => this.Reference(absolute) = value;
public byte Poke(byte low, byte high, byte value) => this.Reference(low, high) = value;
public byte Read()
{
OnReadingByte();
var returned = Data = Reference();
OnReadByte();
this.OnReadingByte();
var returned = this.Data = this.Reference();
this.OnReadByte();
return returned;
}
public byte Read(ushort absolute)
{
Address = absolute;
return Read();
this.Address = absolute;
return this.Read();
}
public byte Read(byte low, byte high) => Read(Chip.MakeWord(low, high));
public byte Read(byte low, byte high) => this.Read(Chip.MakeWord(low, high));
public void Write()
{
OnWritingByte();
Reference() = Data;
OnWrittenByte();
this.OnWritingByte();
this.Reference() = this.Data;
this.OnWrittenByte();
}
public void Write(byte value)
{
Data = value;
Write();
this.Data = value;
this.Write();
}
public void Write(ushort absolute, byte value)
{
Address = absolute;
Write(value);
this.Address = absolute;
this.Write(value);
}
public void Write(byte low, byte high, byte value) => Write(Chip.MakeWord(low, high), value);
public void Write(byte low, byte high, byte value) => this.Write(Chip.MakeWord(low, high), value);
public virtual void RaisePOWER() {}
public virtual void LowerPOWER() {}
public virtual void RaisePOWER()
{
}
public virtual void LowerPOWER()
{
}
public abstract void Initialize();
protected virtual void OnWritingByte() => WritingByte?.Invoke(this, EventArgs.Empty);
protected virtual void OnWrittenByte() => WrittenByte?.Invoke(this, EventArgs.Empty);
protected virtual void OnWritingByte() => this.WritingByte?.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 OnWrittenByte() => this.WrittenByte?.Invoke(this, EventArgs.Empty);
protected virtual void OnReadingByte() => this.ReadingByte?.Invoke(this, EventArgs.Empty);
protected virtual void OnReadByte() => this.ReadByte?.Invoke(this, EventArgs.Empty);
protected ref byte Reference(ushort absolute)
{
var mapped = Mapping(absolute);
var mapped = this.Mapping(absolute);
var offset = (ushort)((absolute - mapped.Begin) & mapped.Mask);
if (mapped.Access == AccessLevel.ReadOnly)
{
Data = mapped.Memory.Peek(offset);
return ref data;
this.Data = mapped.Memory.Peek(offset);
return ref this.data;
}
return ref mapped.Memory.Reference(offset);
}
protected ref byte Reference() => ref Reference(Address);
protected ref byte Reference() => ref this.Reference(this.Address);
protected ref byte Reference(byte low, byte high) => ref Reference(Chip.MakeWord(low, high));
protected ref byte Reference(byte low, byte high) => ref this.Reference(Chip.MakeWord(low, high));
//[[nodiscard]] static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path);
//void loadHexFile(std::string path);
////[[nodiscard]] static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path);
////void loadHexFile(std::string path);
}
}

View File

@ -1,35 +1,55 @@
namespace EightBit
// <copyright file="Chip.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public class Chip : Device
{
protected Chip() { }
protected Chip()
{
}
public static byte SetFlag(byte input, byte flag) => (byte)(input | flag);
public static byte SetFlag(byte input, byte flag, int condition) => SetFlag(input, flag, condition != 0);
public static byte SetFlag(byte input, byte flag, bool condition) => condition ? SetFlag(input, flag) : ClearFlag(input, flag);
public static byte ClearFlag(byte input, byte flag) => (byte)(input & (byte)~flag);
public static byte ClearFlag(byte input, byte flag, int condition) => ClearFlag(input, flag, condition != 0);
public static byte ClearFlag(byte input, byte flag, bool condition) => SetFlag(input, flag, !condition);
public static byte HighByte(int value) => (byte)(value >> 8);
public static byte HighByte(ushort value) => HighByte((int)value);
public static byte LowByte(int value) => (byte)(value & (int)Mask.Mask8);
public static byte LowByte(ushort value) => LowByte((int)value);
public static ushort PromoteByte(byte value) => (ushort)(value << 8);
public static byte DemoteByte(ushort value) => HighByte(value);
public static ushort HigherPart(ushort value) => (ushort)(value & 0xff00);
public static byte LowerPart(ushort value) => LowByte(value);
static public ushort MakeWord(byte low, byte high) => (ushort)(PromoteByte(high) | low);
public static ushort MakeWord(byte low, byte high) => (ushort)(PromoteByte(high) | low);
public static int HighNibble(byte value) => value >> 4;
public static int LowNibble(byte value) => value & 0xf;
public static int HigherNibble(byte value) => value & 0xf0;
public static int LowerNibble(byte value) => LowNibble(value);
public static int PromoteNibble(byte value) => LowByte(value << 4);
public static int DemoteNibble(byte value) => HighNibble(value);
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="ClockedChip.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
@ -6,26 +10,30 @@
{
private int cycles;
protected ClockedChip() { }
public int Cycles { get => cycles; protected set => cycles = value; }
protected ClockedChip()
{
}
public event EventHandler<EventArgs> Ticked;
public int Cycles { get => this.cycles; protected set => this.cycles = value; }
public void Tick(int extra)
{
for (int i = 0; i < extra; ++i)
Tick();
{
this.Tick();
}
}
public void Tick()
{
++Cycles;
OnTicked();
++this.Cycles;
this.OnTicked();
}
protected virtual void OnTicked() => Ticked?.Invoke(this, EventArgs.Empty);
protected virtual void OnTicked() => this.Ticked?.Invoke(this, EventArgs.Empty);
protected void ResetCycles() => Cycles = 0;
protected void ResetCycles() => this.Cycles = 0;
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Device.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
@ -6,35 +10,42 @@
{
private PinLevel powerLine;
protected Device() { }
protected Device()
{
}
public event EventHandler<EventArgs> RaisingPOWER;
public event EventHandler<EventArgs> RaisedPOWER;
public event EventHandler<EventArgs> LoweringPOWER;
public event EventHandler<EventArgs> LoweredPOWER;
public ref PinLevel POWER() => ref powerLine;
public bool Powered => this.POWER().Raised();
public bool Powered => POWER().Raised();
public ref PinLevel POWER() => ref this.powerLine;
public virtual void RaisePOWER()
{
OnRaisingPOWER();
POWER().Raise();
OnRaisedPOWER();
this.OnRaisingPOWER();
this.POWER().Raise();
this.OnRaisedPOWER();
}
public virtual void LowerPOWER()
{
OnLoweringPOWER();
POWER().Lower();
OnLoweredPOWER();
this.OnLoweringPOWER();
this.POWER().Lower();
this.OnLoweredPOWER();
}
protected virtual void OnRaisingPOWER() => RaisingPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedPOWER() => RaisedPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisingPOWER() => this.RaisingPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringPOWER() => LoweringPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredPOWER() => LoweredPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedPOWER() => this.RaisedPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringPOWER() => this.LoweringPOWER?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredPOWER() => this.LoweredPOWER?.Invoke(this, EventArgs.Empty);
}
}

View File

@ -33,6 +33,7 @@
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisIgnoreGeneratedCode>false</CodeAnalysisIgnoreGeneratedCode>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
@ -55,13 +56,12 @@
<Compile Include="Chip.cs" />
<Compile Include="ClockedChip.cs" />
<Compile Include="Device.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="IntelOpCodeDecoded.cs" />
<Compile Include="Memory.cs" />
<Compile Include="InputOutput.cs" />
<Compile Include="IntelProcessor.cs" />
<Compile Include="LittleEndianProcessor.cs" />
<Compile Include="Mapper.cs" />
<Compile Include="IMapper.cs" />
<Compile Include="Mask.cs" />
<Compile Include="MemoryMapping.cs" />
<Compile Include="PinLevel.cs" />
@ -73,5 +73,13 @@
<Compile Include="Rom.cs" />
<Compile Include="UnusedMemory.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Binary file not shown.

11
EightBit/IMapper.cs Normal file
View File

@ -0,0 +1,11 @@
// <copyright file="IMapper.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public interface IMapper
{
MemoryMapping Mapping(ushort address);
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="InputOutput.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
@ -12,37 +16,42 @@
}
public event EventHandler<PortEventArgs> ReadingPort;
public event EventHandler<PortEventArgs> ReadPort;
public event EventHandler<PortEventArgs> WritingPort;
public event EventHandler<PortEventArgs> WrittenPort;
byte Read(byte port) => ReadInputPort(port);
void Write(byte port, byte value) => WriteOutputPort(port, value);
public byte Read(byte port) => this.ReadInputPort(port);
byte ReadInputPort(byte port)
public void Write(byte port, byte value) => this.WriteOutputPort(port, value);
public byte ReadInputPort(byte port)
{
OnReadingPort(port);
var value = input[port];
OnReadPort(port);
this.OnReadingPort(port);
var value = this.input[port];
this.OnReadPort(port);
return value;
}
void WriteInputPort(byte port, byte value) => input[port] = value;
public void WriteInputPort(byte port, byte value) => this.input[port] = value;
byte ReadOutputPort(byte port) => output[port];
public byte ReadOutputPort(byte port) => this.output[port];
void WriteOutputPort(byte port, byte value)
public void WriteOutputPort(byte port, byte value)
{
OnWritingPort(port);
output[port] = value;
OnWrittenPort(port);
this.OnWritingPort(port);
this.output[port] = value;
this.OnWrittenPort(port);
}
private void OnReadingPort(byte port) => ReadingPort?.Invoke(this, new PortEventArgs(port));
private void OnReadPort(byte port) => ReadPort?.Invoke(this, new PortEventArgs(port));
private void OnReadingPort(byte port) => this.ReadingPort?.Invoke(this, new PortEventArgs(port));
private void OnWritingPort(byte port) => WritingPort?.Invoke(this, new PortEventArgs(port));
private void OnWrittenPort(byte port) => WrittenPort?.Invoke(this, new PortEventArgs(port));
private void OnReadPort(byte port) => this.ReadPort?.Invoke(this, new PortEventArgs(port));
private void OnWritingPort(byte port) => this.WritingPort?.Invoke(this, new PortEventArgs(port));
private void OnWrittenPort(byte port) => this.WrittenPort?.Invoke(this, new PortEventArgs(port));
}
}

View File

@ -1,22 +1,28 @@
namespace EightBit
{
class IntelOpCodeDecoded
{
public int x;
public int y;
public int z;
public int p;
public int q;
// <copyright file="IntelOpCodeDecoded.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
public IntelOpCodeDecoded() { }
namespace EightBit
{
public class IntelOpCodeDecoded
{
private int x;
private int y;
private int z;
private int p;
private int q;
public IntelOpCodeDecoded()
{
}
public IntelOpCodeDecoded(byte opcode)
{
x = (opcode & 0b11000000) >> 6; // 0 - 3
y = (opcode & 0b00111000) >> 3; // 0 - 7
z = (opcode & 0b00000111); // 0 - 7
p = (y & 0b110) >> 1; // 0 - 3
q = (y & 1); // 0 - 1
this.x = (opcode & 0b11000000) >> 6; // 0 - 3
this.y = (opcode & 0b00111000) >> 3; // 0 - 7
this.z = opcode & 0b00000111; // 0 - 7
this.p = (this.y & 0b110) >> 1; // 0 - 3
this.q = this.y & 1; // 0 - 1
}
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="IntelProcessor.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
@ -13,151 +17,180 @@
protected IntelProcessor(Bus bus)
: base(bus)
{
sp = (ushort)Mask.Mask16;
memptr = (ushort)Mask.Mask16;
this.sp = (ushort)Mask.Mask16;
this.memptr = (ushort)Mask.Mask16;
for (int i = 0; i < 0x100; ++i)
decodedOpCodes[i] = new IntelOpCodeDecoded((byte)i);
{
this.decodedOpCodes[i] = new IntelOpCodeDecoded((byte)i);
}
}
public event EventHandler<EventArgs> RaisingHALT;
public event EventHandler<EventArgs> RaisedHALT;
public event EventHandler<EventArgs> LoweringHALT;
public event EventHandler<EventArgs> LoweredHALT;
public ref PinLevel HALT() => ref haltLine;
public ushort SP { get => this.sp; set => this.sp = value; }
protected bool Halted => HALT().Lowered();
public ushort SP { get => sp; set => sp = value; }
public ushort MEMPTR { get => memptr; set => memptr = value; }
public ushort MEMPTR { get => this.memptr; set => this.memptr = value; }
public abstract ushort AF { get; set; }
public byte A { get => HighByte(AF); set => AF = (ushort)(LowerPart(AF) | PromoteByte(value)); }
public byte F { get => LowByte(AF); set => AF = (ushort)(HigherPart(AF) | value); }
public byte A { get => Chip.HighByte(this.AF); set => this.AF = (ushort)(Chip.LowerPart(this.AF) | Chip.PromoteByte(value)); }
public byte F { get => Chip.LowByte(this.AF); set => this.AF = (ushort)(Chip.HigherPart(this.AF) | value); }
public abstract ushort BC { get; set; }
public byte B { get => HighByte(AF); set => BC = (ushort)(LowerPart(BC) | PromoteByte(value)); }
public byte C { get => LowByte(AF); set => BC = (ushort)(HigherPart(BC) | value); }
public byte B { get => Chip.HighByte(this.BC); set => this.BC = (ushort)(Chip.LowerPart(this.BC) | Chip.PromoteByte(value)); }
public byte C { get => Chip.LowByte(this.BC); set => this.BC = (ushort)(Chip.HigherPart(this.BC) | value); }
public abstract ushort DE { get; set; }
public byte D { get => HighByte(DE); set => DE = (ushort)(LowerPart(DE) | PromoteByte(value)); }
public byte E { get => LowByte(DE); set => DE = (ushort)(HigherPart(DE) | value); }
public byte D { get => Chip.HighByte(this.DE); set => this.DE = (ushort)(Chip.LowerPart(this.DE) | Chip.PromoteByte(value)); }
public byte E { get => Chip.LowByte(this.DE); set => this.DE = (ushort)(Chip.HigherPart(this.DE) | value); }
public abstract ushort HL { get; set; }
public byte H { get => HighByte(HL); set => HL = (ushort)(LowerPart(HL) | PromoteByte(value)); }
public byte L { get => LowByte(HL); set { HL = (ushort)(HigherPart(HL) | value); } }
public byte H { get => Chip.HighByte(this.HL); set => this.HL = (ushort)(Chip.LowerPart(this.HL) | Chip.PromoteByte(value)); }
public byte L { get => Chip.LowByte(this.HL); set => this.HL = (ushort)(Chip.HigherPart(this.HL) | value); }
protected bool Halted => this.HALT().Lowered();
public ref PinLevel HALT() => ref this.haltLine;
public override void RaisePOWER()
{
base.RaisePOWER();
RaiseHALT();
SP = AF = BC = DE = HL = (ushort)Mask.Mask16;
this.RaiseHALT();
this.SP = this.AF = this.BC = this.DE = this.HL = (ushort)Mask.Mask16;
}
public virtual void RaiseHALT()
{
OnRaisingHALT();
HALT().Raise();
OnRaisedHALT();
this.OnRaisingHALT();
this.HALT().Raise();
this.OnRaisedHALT();
}
public virtual void LowerHALT()
{
OnLoweringHALT();
HALT().Lower();
OnLoweredHALT();
this.OnLoweringHALT();
this.HALT().Lower();
this.OnLoweredHALT();
}
protected virtual void OnRaisingHALT() => RaisingHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedHALT() => RaisedHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisingHALT() => this.RaisingHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringHALT() => LoweringHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredHALT() => LoweredHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedHALT() => this.RaisedHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringHALT() => this.LoweringHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredHALT() => this.LoweredHALT?.Invoke(this, EventArgs.Empty);
protected override void HandleRESET()
{
base.HandleRESET();
PC = 0;
this.PC = 0;
}
protected sealed override void Push(byte value) => Bus.Write(--SP, value);
protected sealed override byte Pop() => Bus.Read(SP++);
protected sealed override void Push(byte value) => this.Bus.Write(--this.SP, value);
protected sealed override byte Pop() => this.Bus.Read(this.SP++);
protected sealed override ushort GetWord()
{
var returned = base.GetWord();
MEMPTR = Bus.Address;
return returned;
this.MEMPTR = this.Bus.Address;
return returned;
}
protected sealed override void SetWord(ushort value)
{
base.SetWord(value);
MEMPTR = Bus.Address;
this.MEMPTR = this.Bus.Address;
}
//
////
protected void Restart(byte address)
{
MEMPTR = address;
Call(MEMPTR);
this.MEMPTR = address;
this.Call(this.MEMPTR);
}
protected bool CallConditional(bool condition)
{
MEMPTR = FetchWord();
this.MEMPTR = this.FetchWord();
if (condition)
Call(MEMPTR);
{
this.Call(this.MEMPTR);
}
return condition;
}
protected bool JumpConditional(bool condition)
{
MEMPTR = FetchWord();
this.MEMPTR = this.FetchWord();
if (condition)
Jump(MEMPTR);
{
this.Jump(this.MEMPTR);
}
return condition;
}
protected bool ReturnConditional(bool condition)
{
if (condition)
Return();
{
this.Return();
}
return condition;
}
protected void JumpRelative(sbyte offset)
{
MEMPTR = (ushort)(PC + offset);
Jump(MEMPTR);
this.MEMPTR = (ushort)(this.PC + offset);
this.Jump(this.MEMPTR);
}
protected bool JumpRelativeConditional(bool condition)
{
var offset = (sbyte)FetchByte();
var offset = (sbyte)this.FetchByte();
if (condition)
JumpRelative(offset);
{
this.JumpRelative(offset);
}
return condition;
}
protected override sealed void Return()
{
base.Return();
MEMPTR = PC;
this.MEMPTR = this.PC;
}
protected void Halt()
{
--PC;
LowerHALT();
--this.PC;
this.LowerHALT();
}
protected void Proceed()
{
++PC;
RaiseHALT();
++this.PC;
this.RaiseHALT();
}
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="LittleEndianProcessor.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public abstract class LittleEndianProcessor : Processor
{
@ -9,63 +13,63 @@
public override ushort PeekWord(ushort address)
{
var low = Bus.Peek(address);
var high = Bus.Peek(++address);
return MakeWord(low, high);
var low = this.Bus.Peek(address);
var high = this.Bus.Peek(++address);
return Chip.MakeWord(low, high);
}
public override void PokeWord(ushort address, ushort value)
{
Bus.Poke(address, LowByte(value));
Bus.Poke(++address, HighByte(value));
this.Bus.Poke(address, Chip.LowByte(value));
this.Bus.Poke(++address, Chip.HighByte(value));
}
protected override ushort FetchWord()
{
var low = FetchByte();
var high = FetchByte();
return MakeWord(low, high);
var low = this.FetchByte();
var high = this.FetchByte();
return Chip.MakeWord(low, high);
}
protected override ushort GetWord()
{
var low = BusRead();
++Bus.Address;
var high = BusRead();
return MakeWord(low, high);
var low = this.BusRead();
++this.Bus.Address;
var high = this.BusRead();
return Chip.MakeWord(low, high);
}
protected override ushort GetWordPaged(byte page, byte offset)
{
var low = BusRead(offset, page);
var high = BusRead((byte)(offset + 1), page);
return MakeWord(low, high);
var low = this.BusRead(offset, page);
var high = this.BusRead((byte)(offset + 1), page);
return Chip.MakeWord(low, high);
}
protected override ushort PopWord()
{
var low = Pop();
var high = Pop();
return MakeWord(low, high);
var low = this.Pop();
var high = this.Pop();
return Chip.MakeWord(low, high);
}
protected override void PushWord(ushort value)
{
Push(HighByte(value));
Push(LowByte(value));
this.Push(Chip.HighByte(value));
this.Push(Chip.LowByte(value));
}
protected override void SetWord(ushort value)
{
BusWrite(LowByte(value));
++Bus.Address;
BusWrite(HighByte(value));
this.BusWrite(Chip.LowByte(value));
++this.Bus.Address;
this.BusWrite(Chip.HighByte(value));
}
protected override void SetWordPaged(byte page, byte offset, ushort value)
{
BusWrite(offset, page, LowByte(value));
BusWrite((byte)(offset + 1), page, HighByte(value));
this.BusWrite(offset, page, Chip.LowByte(value));
this.BusWrite((byte)(offset + 1), page, Chip.HighByte(value));
}
}
}

View File

@ -1,7 +0,0 @@
namespace EightBit
{
public interface IMapper
{
MemoryMapping Mapping(ushort address);
}
}

View File

@ -1,7 +1,11 @@
using System;
// <copyright file="Mask.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
public enum Mask
{
None = 0,
@ -20,6 +24,6 @@ namespace EightBit
Mask13 = Bits.Bit13 - 1,
Mask14 = Bits.Bit14 - 1,
Mask15 = Bits.Bit15 - 1,
Mask16 = Bits.Bit16 - 1
Mask16 = Bits.Bit16 - 1,
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Memory.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
using System.IO;
@ -18,7 +22,9 @@
}
public abstract int Load(FileStream file, int writeOffset = 0, int readOffset = 0, int limit = -1);
public abstract int Load(string path, int writeOffset = 0, int readOffset = 0, int limit = -1);
public abstract int Load(byte[] from, int writeOffset = 0, int readOffset = 0, int limit = -1);
protected abstract void Poke(ushort address, byte value);

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="MemoryMapping.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public class MemoryMapping
{
@ -15,9 +19,12 @@
this.access = access;
}
public Memory Memory { get => memory; set => memory = value; }
public ushort Begin { get => begin; set => begin = value; }
public ushort Mask { get => mask; set => mask = value; }
public AccessLevel Access { get => access; set => access = value; }
public Memory Memory { get => this.memory; set => this.memory = value; }
public ushort Begin { get => this.begin; set => this.begin = value; }
public ushort Mask { get => this.mask; set => this.mask = value; }
public AccessLevel Access { get => this.access; set => this.access = value; }
}
}

View File

@ -1,7 +1,12 @@
namespace EightBit
// <copyright file="PinLevel.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public enum PinLevel
{
Low, High
Low,
High,
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="PinLevelExtensions.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public static class PinLevelExtensions
{

View File

@ -1,13 +1,17 @@
using System;
// <copyright file="PortEventArgs.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
public sealed class PortEventArgs : EventArgs
{
private byte port;
public PortEventArgs(byte value) => port = value;
public PortEventArgs(byte value) => this.port = value;
public byte Port => port;
public byte Port => this.port;
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Processor.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
@ -13,161 +17,176 @@
protected Processor(Bus memory)
{
bus = memory;
this.bus = memory;
}
public event EventHandler<EventArgs> RaisingRESET;
public event EventHandler<EventArgs> RaisedRESET;
public event EventHandler<EventArgs> LoweringRESET;
public event EventHandler<EventArgs> LoweredRESET;
public event EventHandler<EventArgs> RaisingINT;
public event EventHandler<EventArgs> RaisedINT;
public event EventHandler<EventArgs> LoweringINT;
public event EventHandler<EventArgs> LoweredINT;
public ushort PC { get => pc; set => pc = value; }
protected byte OpCode { get => opcode; set => opcode = value; }
public Bus Bus { get => bus; }
public ushort PC { get => this.pc; set => this.pc = value; }
public ref PinLevel RESET() => ref resetLine;
public ref PinLevel INT() => ref intLine;
public Bus Bus { get => this.bus; }
protected byte OpCode { get => this.opcode; set => this.opcode = value; }
public ref PinLevel RESET() => ref this.resetLine;
public ref PinLevel INT() => ref this.intLine;
public abstract int Step();
public abstract int Execute();
public int Run(int limit)
{
int current = 0;
while (Powered && (current < limit))
current += Step();
while (this.Powered && (current < limit))
{
current += this.Step();
}
return current;
}
public int Execute(byte value)
{
OpCode = value;
return Execute();
this.OpCode = value;
return this.Execute();
}
public abstract ushort PeekWord(ushort address);
public abstract void PokeWord(ushort address, ushort value);
public ushort PeekWord(byte low, byte high) => PeekWord((ushort)(PromoteByte(high) | low));
public ushort PeekWord(byte low, byte high) => this.PeekWord((ushort)(Chip.PromoteByte(high) | low));
public virtual void RaiseRESET()
{
OnRaisingRESET();
RESET().Raise();
OnRaisedRESET();
this.OnRaisingRESET();
this.RESET().Raise();
this.OnRaisedRESET();
}
public virtual void LowerRESET()
{
OnLoweringRESET();
RESET().Lower();
OnLoweredRESET();
this.OnLoweringRESET();
this.RESET().Lower();
this.OnLoweredRESET();
}
public virtual void RaiseINT()
{
OnRaisingINT();
INT().Raise();
OnRaisedINT();
this.OnRaisingINT();
this.INT().Raise();
this.OnRaisedINT();
}
public virtual void LowerINT()
{
OnLoweringINT();
INT().Lower();
OnLoweredINT();
this.OnLoweringINT();
this.INT().Lower();
this.OnLoweredINT();
}
protected virtual void OnRaisingRESET() => RaisingRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedRESET() => RaisedRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisingRESET() => this.RaisingRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringRESET() => LoweringRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredRESET() => LoweredRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedRESET() => this.RaisedRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisingINT() => RaisingINT?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedINT() => RaisedINT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringRESET() => this.LoweringRESET?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringINT() => LoweringINT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredINT() => LoweredINT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredRESET() => this.LoweredRESET?.Invoke(this, EventArgs.Empty);
protected virtual void HandleRESET() => RaiseRESET();
protected virtual void HandleINT() => RaiseINT();
protected virtual void OnRaisingINT() => this.RaisingINT?.Invoke(this, EventArgs.Empty);
#region BusWrite
protected virtual void OnRaisedINT() => this.RaisedINT?.Invoke(this, EventArgs.Empty);
protected void BusWrite(byte low, byte high, byte data) => BusWrite(MakeWord(low, high), data);
protected virtual void OnLoweringINT() => this.LoweringINT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredINT() => this.LoweredINT?.Invoke(this, EventArgs.Empty);
protected virtual void HandleRESET() => this.RaiseRESET();
protected virtual void HandleINT() => this.RaiseINT();
protected void BusWrite(byte low, byte high, byte data) => this.BusWrite(Chip.MakeWord(low, high), data);
protected void BusWrite(ushort address, byte data)
{
Bus.Address = address;
BusWrite(data);
this.Bus.Address = address;
this.BusWrite(data);
}
protected void BusWrite(byte data)
{
Bus.Data = data;
BusWrite();
this.Bus.Data = data;
this.BusWrite();
}
protected virtual void BusWrite() => Bus.Write(); // N.B. Should be the only real call into the "Bus.Write" code.
protected virtual void BusWrite() => this.Bus.Write(); // N.B. Should be the only real call into the "Bus.Write" code.
#endregion
#region BusRead
protected byte BusRead(byte low, byte high) => BusRead(MakeWord(low, high));
protected byte BusRead(byte low, byte high) => this.BusRead(Chip.MakeWord(low, high));
protected byte BusRead(ushort address)
{
Bus.Address = address;
return BusRead();
this.Bus.Address = address;
return this.BusRead();
}
protected virtual byte BusRead() => Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
#endregion
protected byte FetchByte() => BusRead(PC++);
protected byte FetchByte() => this.BusRead(this.PC++);
protected abstract ushort GetWord();
protected abstract void SetWord(ushort value);
protected abstract ushort GetWordPaged(byte page, byte offset);
protected abstract void SetWordPaged(byte page, byte offset, ushort value);
protected abstract void SetWord(ushort value);
protected abstract ushort FetchWord();
protected abstract ushort GetWordPaged(byte page, byte offset);
protected abstract void Push(byte value);
protected abstract byte Pop();
protected abstract void SetWordPaged(byte page, byte offset, ushort value);
protected abstract void PushWord(ushort value);
protected abstract ushort PopWord();
protected abstract ushort FetchWord();
protected abstract void Push(byte value);
protected abstract byte Pop();
protected abstract void PushWord(ushort value);
protected abstract ushort PopWord();
protected ushort GetWord(ushort address)
{
Bus.Address = address;
return GetWord();
this.Bus.Address = address;
return this.GetWord();
}
protected void SetWord(ushort address, ushort value)
{
Bus.Address = address;
SetWord(value);
this.Bus.Address = address;
this.SetWord(value);
}
protected void Jump(ushort destination) => PC = destination;
protected void Jump(ushort destination) => this.PC = destination;
protected void Call(ushort destination)
{
PushWord(PC);
Jump(destination);
this.PushWord(this.PC);
this.Jump(destination);
}
protected virtual void Return() => Jump(PopWord());
protected virtual void Return() => this.Jump(this.PopWord());
}
}

View File

@ -1,5 +1,8 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// <copyright file="AssemblyInfo.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@ -8,9 +11,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("EightBit")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("Adrian Conlon")]
[assembly: AssemblyProduct("EightBit")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Ram.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public class Ram : Rom
{
@ -7,14 +11,8 @@
{
}
public override sealed ref byte Reference(ushort address)
{
return ref Bytes()[address];
}
public override sealed ref byte Reference(ushort address) => ref this.Bytes()[address];
public new void Poke(ushort address, byte value)
{
base.Poke(address, value);
}
public new void Poke(ushort address, byte value) => base.Poke(address, value);
}
}

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Rom.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
using System.IO;
@ -7,23 +11,28 @@
{
private byte[] bytes;
public Rom(int size) => bytes = new byte[size];
public Rom(int size) => this.bytes = new byte[size];
public Rom() : this(0) { }
public Rom()
: this(0)
{
}
public override int Size => bytes.Length;
public override int Size => this.bytes.Length;
protected ref byte[] Bytes() => ref bytes;
static public int Load(FileStream file, ref byte[] output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1)
public static int Load(FileStream file, ref byte[] output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1)
{
var size = (int)file.Length;
if ((maximumSize > 0) && ((size - readOffset) > maximumSize))
{
throw new InvalidOperationException("File is too large");
}
if ((limit < 0) || (limit > size))
{
limit = (int)size;
}
var extent = limit + writeOffset;
if (output.Length < extent)
@ -52,36 +61,40 @@
public override int Load(FileStream file, int writeOffset = 0, int readOffset = 0, int limit = -1)
{
var maximumSize = Size - writeOffset;
return Load(file, ref Bytes(), writeOffset, readOffset, limit, maximumSize);
var maximumSize = this.Size - writeOffset;
return Load(file, ref this.Bytes(), writeOffset, readOffset, limit, maximumSize);
}
public override int Load(string path, int writeOffset = 0, int readOffset = 0, int limit = -1)
{
var maximumSize = Size - writeOffset;
return Load(path, ref Bytes(), writeOffset, readOffset, limit, maximumSize);
var maximumSize = this.Size - writeOffset;
return Load(path, ref this.Bytes(), writeOffset, readOffset, limit, maximumSize);
}
public override int Load(byte[] from, int writeOffset = 0, int readOffset = 0, int limit = -1)
{
if (limit < 0)
limit = Size - readOffset;
var extent = limit + writeOffset;
if (Size < extent)
{
var updated = new byte[extent];
Array.Copy(Bytes(), updated, Size);
Bytes() = updated;
limit = this.Size - readOffset;
}
Array.Copy(from, readOffset, Bytes(), writeOffset, limit);
var extent = limit + writeOffset;
if (this.Size < extent)
{
var updated = new byte[extent];
Array.Copy(this.Bytes(), updated, this.Size);
this.Bytes() = updated;
}
Array.Copy(from, readOffset, this.Bytes(), writeOffset, limit);
return limit;
}
public override byte Peek(ushort address) => Bytes()[address];
public override byte Peek(ushort address) => this.Bytes()[address];
protected override void Poke(ushort address, byte value) => Bytes()[address] = value;
protected ref byte[] Bytes() => ref this.bytes;
protected override void Poke(ushort address, byte value) => this.Bytes()[address] = value;
}
}

219
EightBit/Settings.StyleCop Normal file
View File

@ -0,0 +1,219 @@
<StyleCopSettings Version="105">
<Analyzers>
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
<Rules>
<Rule Name="ElementsMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PartialElementsMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="EnumerationItemsMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationMustContainValidXml">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustHaveSummary">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PartialElementDocumentationMustHaveSummary">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustHaveSummaryText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PartialElementDocumentationMustHaveSummaryText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustNotHaveDefaultSummary">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParametersMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParameterDocumentationMustMatchElementParameters">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParameterDocumentationMustDeclareParameterName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParameterDocumentationMustHaveText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementReturnValueMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementReturnValueDocumentationMustHaveText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="VoidReturnValueMustNotBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParametersMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParametersMustBeDocumentedPartialClass">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParameterDocumentationMustMatchTypeParameters">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParameterDocumentationMustDeclareParameterName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParameterDocumentationMustHaveText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PropertySummaryDocumentationMustMatchAccessors">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PropertySummaryDocumentationMustOmitSetAccessorWithRestrictedAccess">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustNotBeCopiedAndPasted">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="SingleLineCommentsMustNotUseDocumentationStyleSlashes">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationTextMustNotBeEmpty">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationTextMustContainWhitespace">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationMustMeetCharacterPercentage">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ConstructorSummaryDocumentationMustBeginWithStandardText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DestructorSummaryDocumentationMustBeginWithStandardText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationHeadersMustNotContainBlankLines">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="IncludedDocumentationXPathDoesNotExist">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="IncludeNodeDoesNotContainValidFileAndPath">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="InheritDocMustBeUsedWithInheritingClass">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustBeSpelledCorrectly">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileMustHaveHeader">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustShowCopyright">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustHaveCopyrightText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustContainFileName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderFileNameDocumentationMustMatchFileName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustHaveValidCompanyText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderFileNameDocumentationMustMatchTypeName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings />
</Analyzer>
</Analyzers>
</StyleCopSettings>

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="UnusedMemory.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System.IO;
@ -7,19 +11,22 @@
private readonly int size;
private readonly byte unchanging;
UnusedMemory(int size, byte unchanging)
public UnusedMemory(int size, byte unchanging)
{
this.size = size;
this.unchanging = unchanging;
}
public override int Size => size;
public override int Size => this.size;
public override int Load(FileStream file, int writeOffset = 0, int readOffset = 0, int limit = -1) => throw new System.NotImplementedException();
public override int Load(string path, int writeOffset = 0, int readOffset = 0, int limit = -1) => throw new System.NotImplementedException();
public override int Load(byte[] from, int writeOffset = 0, int readOffset = 0, int limit = -1) => throw new System.NotImplementedException();
public override byte Peek(ushort address) => unchanging;
public override byte Peek(ushort address) => this.unchanging;
protected override void Poke(ushort address, byte value) => throw new System.NotImplementedException();
}
}

5
EightBit/packages.config Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="StyleCop.Analyzers" version="1.1.1-beta.61" targetFramework="net472" developmentDependency="true" />
<package id="StyleCop.Analyzers.Unstable" version="1.1.1.61" targetFramework="net472" developmentDependency="true" />
</packages>

19
EightBit/stylecop.json Normal file
View File

@ -0,0 +1,19 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"documentInterfaces": false,
"documentExposedElements": false,
"documentInternalElements": false,
"documentPrivateElements": false,
"documentPrivateFields": false,
"companyName": "Adrian Conlon"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<StyleCopTreatErrorsAsWarnings>True</StyleCopTreatErrorsAsWarnings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -58,5 +59,13 @@
<Name>EightBit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -1,7 +1,12 @@
namespace EightBit
// <copyright file="PageCrossingBehavior.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public enum PageCrossingBehavior
{
AlwaysReadTwice, MaybeReadTwice
AlwaysReadTwice,
MaybeReadTwice,
}
}

View File

@ -1,5 +1,8 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// <copyright file="AssemblyInfo.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

222
M6502/Settings.StyleCop Normal file
View File

@ -0,0 +1,222 @@
<StyleCopSettings Version="105">
<GlobalSettings>
<StringProperty Name="Culture">en-GB</StringProperty>
</GlobalSettings>
<Analyzers>
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
<Rules>
<Rule Name="ElementsMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PartialElementsMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="EnumerationItemsMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationMustContainValidXml">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustHaveSummary">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PartialElementDocumentationMustHaveSummary">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustHaveSummaryText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PartialElementDocumentationMustHaveSummaryText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustNotHaveDefaultSummary">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParametersMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParameterDocumentationMustMatchElementParameters">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParameterDocumentationMustDeclareParameterName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementParameterDocumentationMustHaveText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementReturnValueMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementReturnValueDocumentationMustHaveText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="VoidReturnValueMustNotBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParametersMustBeDocumented">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParametersMustBeDocumentedPartialClass">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParameterDocumentationMustMatchTypeParameters">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParameterDocumentationMustDeclareParameterName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="GenericTypeParameterDocumentationMustHaveText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PropertySummaryDocumentationMustMatchAccessors">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PropertySummaryDocumentationMustOmitSetAccessorWithRestrictedAccess">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustNotBeCopiedAndPasted">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="SingleLineCommentsMustNotUseDocumentationStyleSlashes">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationTextMustNotBeEmpty">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationTextMustContainWhitespace">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationMustMeetCharacterPercentage">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ConstructorSummaryDocumentationMustBeginWithStandardText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DestructorSummaryDocumentationMustBeginWithStandardText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationHeadersMustNotContainBlankLines">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="IncludedDocumentationXPathDoesNotExist">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="IncludeNodeDoesNotContainValidFileAndPath">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="InheritDocMustBeUsedWithInheritingClass">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="ElementDocumentationMustBeSpelledCorrectly">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileMustHaveHeader">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustShowCopyright">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustHaveCopyrightText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustContainFileName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderFileNameDocumentationMustMatchFileName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderMustHaveValidCompanyText">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderFileNameDocumentationMustMatchTypeName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings />
</Analyzer>
</Analyzers>
</StyleCopSettings>

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="StatusBits.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;

View File

@ -1,4 +1,8 @@
namespace EightBit
// <copyright file="Symbols.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using System;
using System.Collections.Generic;
@ -12,45 +16,51 @@
private readonly Dictionary<string, ushort> addresses;
private readonly Dictionary<string, Dictionary<string, Dictionary<string, string>>> parsed;
public Symbols() : this("") { }
public Symbols()
: this(string.Empty)
{
}
public Symbols(string path)
{
labels = new Dictionary<ushort, string>();
constants = new Dictionary<ushort, string>();
scopes = new Dictionary<string, ushort>();
addresses = new Dictionary<string, ushort>();
parsed = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
this.labels = new Dictionary<ushort, string>();
this.constants = new Dictionary<ushort, string>();
this.scopes = new Dictionary<string, ushort>();
this.addresses = new Dictionary<string, ushort>();
this.parsed = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
if (path.Length > 0)
{
Parse(path);
AssignSymbols();
AssignScopes();
this.Parse(path);
this.AssignSymbols();
this.AssignScopes();
}
}
public Dictionary<ushort, string> Labels => labels;
public Dictionary<ushort, string> Constants => constants;
public Dictionary<string, ushort> Scopes => scopes;
public Dictionary<string, ushort> Addresses => addresses;
public Dictionary<ushort, string> Labels => this.labels;
public Dictionary<ushort, string> Constants => this.constants;
public Dictionary<string, ushort> Scopes => this.scopes;
public Dictionary<string, ushort> Addresses => this.addresses;
private void AssignScopes()
{
var parsedScopes = parsed["scope"];
var parsedScopes = this.parsed["scope"];
foreach (var parsedScopeElement in parsedScopes)
{
var parsedScope = parsedScopeElement.Value;
var name = parsedScope["name"];
var trimmedName = name.Substring(1, name.Length - 2);
var size = parsedScope["size"];
scopes[trimmedName] = ushort.Parse(size);
this.scopes[trimmedName] = ushort.Parse(size);
}
}
private void AssignSymbols()
{
var symbols = parsed["sym"];
var symbols = this.parsed["sym"];
foreach (var symbolElement in symbols)
{
var symbol = symbolElement.Value;
@ -61,12 +71,12 @@
var symbolType = symbol["type"];
if (symbolType == "lab")
{
labels[number] = trimmedName;
addresses[trimmedName] = number;
this.labels[number] = trimmedName;
this.addresses[trimmedName] = number;
}
else if (symbolType == "equ")
{
constants[number] = trimmedName;
this.constants[number] = trimmedName;
}
}
}
@ -88,16 +98,21 @@
{
var definition = dataElement.Split('=');
if (definition.Length == 2)
{
data[definition[0]] = definition[1];
}
}
if (data.ContainsKey("id"))
{
if (!parsed.ContainsKey(type))
parsed[type] = new Dictionary<string, Dictionary<string, string>>();
if (!this.parsed.ContainsKey(type))
{
this.parsed[type] = new Dictionary<string, Dictionary<string, string>>();
}
var id = data["id"];
data.Remove("id");
parsed[type][id] = data;
this.parsed[type][id] = data;
}
}
}

5
M6502/packages.config Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="StyleCop.Analyzers" version="1.1.1-beta.61" targetFramework="net472" developmentDependency="true" />
<package id="StyleCop.Analyzers.Unstable" version="1.1.1.61" targetFramework="net472" developmentDependency="true" />
</packages>

19
M6502/stylecop.json Normal file
View File

@ -0,0 +1,19 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"documentInterfaces": false,
"documentExposedElements": false,
"documentInternalElements": false,
"documentPrivateElements": false,
"documentPrivateFields": false,
"companyName": "Adrian Conlon"
}
}
}

View File

@ -1,7 +1,11 @@
namespace Test
// <copyright file="Board.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace Test
{
using EightBit;
using System.Text;
using EightBit;
internal class Board : Bus
{
@ -24,52 +28,59 @@
this.oldPC = (ushort)Mask.Mask16;
}
public M6502 CPU { get { return this.cpu; } }
public M6502 CPU { get => this.cpu; }
public override void RaisePOWER()
{
base.RaisePOWER();
CPU.RaisePOWER();
CPU.RaiseRESET();
CPU.RaiseINT();
CPU.RaiseNMI();
CPU.RaiseSO();
CPU.RaiseRDY();
this.CPU.RaisePOWER();
this.CPU.RaiseRESET();
this.CPU.RaiseINT();
this.CPU.RaiseNMI();
this.CPU.RaiseSO();
this.CPU.RaiseRDY();
}
public override void LowerPOWER()
{
CPU.LowerPOWER();
this.CPU.LowerPOWER();
base.LowerPOWER();
}
public override void Initialize()
{
var programFilename = configuration.Program;
var programPath = configuration.RomDirectory + "/" + configuration.Program;
var loadAddress = configuration.LoadAddress;
ram.Load(programPath, loadAddress);
var programFilename = this.configuration.Program;
var programPath = this.configuration.RomDirectory + "/" + this.configuration.Program;
var loadAddress = this.configuration.LoadAddress;
this.ram.Load(programPath, loadAddress);
if (configuration.DebugMode)
CPU.ExecutingInstruction += CPU_ExecutingInstruction;
if (this.configuration.DebugMode)
{
this.CPU.ExecutingInstruction += this.CPU_ExecutingInstruction;
}
CPU.ExecutedInstruction += CPU_ExecutedInstruction;
this.CPU.ExecutedInstruction += this.CPU_ExecutedInstruction;
Poke(0x00, 0x4c);
cpu.PokeWord(0x01, configuration.StartAddress);
this.Poke(0x00, 0x4c);
this.cpu.PokeWord(0x01, this.configuration.StartAddress);
}
public override MemoryMapping Mapping(ushort absolute)
{
return new MemoryMapping(this.ram, 0x0000, (ushort)Mask.Mask16, AccessLevel.ReadWrite);
}
private void CPU_ExecutedInstruction(object sender, System.EventArgs e)
{
var pc = CPU.PC;
if (oldPC != pc)
var pc = this.CPU.PC;
if (this.oldPC != pc)
{
oldPC = pc;
this.oldPC = pc;
}
else
{
LowerPOWER();
var test = Peek(0x0200);
this.LowerPOWER();
var test = this.Peek(0x0200);
System.Console.Out.WriteLine();
System.Console.Out.Write("** Test=");
System.Console.Out.WriteLine(Disassembly.Dump_ByteValue(test));
@ -78,8 +89,8 @@
private void CPU_ExecutingInstruction(object sender, System.EventArgs e)
{
var address = CPU.PC;
var cell = Peek(address);
var address = this.CPU.PC;
var cell = this.Peek(address);
var output = new StringBuilder();
@ -88,33 +99,28 @@
output.Append(":");
output.Append("P=");
output.Append(Disassembly.Dump_Flags(CPU.P));
output.Append(Disassembly.Dump_Flags(this.CPU.P));
output.Append(", ");
output.Append("A=");
output.Append(Disassembly.Dump_ByteValue(CPU.A));
output.Append(Disassembly.Dump_ByteValue(this.CPU.A));
output.Append(", ");
output.Append("X=");
output.Append(Disassembly.Dump_ByteValue(CPU.X));
output.Append(Disassembly.Dump_ByteValue(this.CPU.X));
output.Append(", ");
output.Append("Y=");
output.Append(Disassembly.Dump_ByteValue(CPU.Y));
output.Append(Disassembly.Dump_ByteValue(this.CPU.Y));
output.Append(", ");
output.Append("S=");
output.Append(Disassembly.Dump_ByteValue(CPU.S));
output.Append(Disassembly.Dump_ByteValue(this.CPU.S));
output.Append("\t");
output.Append(disassembler.Disassemble(address));
output.Append(this.disassembler.Disassemble(address));
System.Console.Out.WriteLine(output.ToString());
}
public override MemoryMapping Mapping(ushort absolute)
{
return new MemoryMapping(ram, 0x0000, (ushort)Mask.Mask16, AccessLevel.ReadWrite);
}
}
}

View File

@ -1,26 +1,35 @@
namespace Test
// <copyright file="Configuration.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace Test
{
using EightBit;
internal class Configuration
{
private bool debugMode = false;
private readonly ushort loadAddress = 0x400;
private readonly ushort startAddress = 0x400;
private readonly string romDirectory = "roms";
private readonly string program = "6502_functional_test.bin";
private bool debugMode = false;
public Configuration() {}
public bool DebugMode {
get { return debugMode; }
set { debugMode = value; }
public Configuration()
{
}
public ushort LoadAddress { get { return loadAddress; } }
public ushort StartAddress { get { return startAddress; } }
public bool DebugMode
{
get => this.debugMode;
set => this.debugMode = value;
}
public string RomDirectory { get { return romDirectory; } }
public string Program { get { return program; } }
public ushort LoadAddress { get => this.loadAddress; }
public ushort StartAddress { get => this.startAddress; }
public string RomDirectory { get => this.romDirectory; }
public string Program { get => this.program; }
}
}

View File

@ -1,12 +1,16 @@
namespace Test
// <copyright file="Program.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace Test
{
class Program
public class Program
{
static void Main(string[] args)
public static void Main(string[] args)
{
var configuration = new Configuration();
//configuration.DebugMode = true;
////configuration.DebugMode = true;
var harness = new TestHarness(configuration);
harness.Run();

View File

@ -1,5 +1,8 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// <copyright file="AssemblyInfo.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@ -1,4 +1,8 @@
namespace Test
// <copyright file="TestHarness.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace Test
{
internal class TestHarness
{
@ -6,18 +10,20 @@
public TestHarness(Configuration configuration)
{
board = new Board(configuration);
this.board = new Board(configuration);
}
public void Run()
{
board.Initialize();
board.RaisePOWER();
this.board.Initialize();
this.board.RaisePOWER();
var cpu = board.CPU;
var cpu = this.board.CPU;
while (cpu.Powered)
{
cpu.Step();
}
}
}
}

View File

@ -54,6 +54,8 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EightBit\EightBit.csproj">
@ -65,5 +67,9 @@
<Name>M6502</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="StyleCop.Analyzers" version="1.1.1-beta.61" targetFramework="net472" developmentDependency="true" />
<package id="StyleCop.Analyzers.Unstable" version="1.1.1.61" targetFramework="net472" developmentDependency="true" />
</packages>

19
Test_M6502/stylecop.json Normal file
View File

@ -0,0 +1,19 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"documentInterfaces": false,
"documentExposedElements": false,
"documentInternalElements": false,
"documentPrivateElements": false,
"documentPrivateFields": false,
"companyName": "Adrian Conlon"
}
}
}

View File

@ -1,13 +1,15 @@
namespace UnitTestEightBit
// <copyright file="ChipUnitTest.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace UnitTestEightBit
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EightBit;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class ChipUnitTest
{
#region LowByte
[TestMethod]
public void TestLowByte()
{
@ -16,10 +18,6 @@
Assert.AreEqual(0xf, low);
}
#endregion
#region HighByte
[TestMethod]
public void TestHighByte()
{
@ -28,10 +26,6 @@
Assert.AreEqual(0xf0, high);
}
#endregion
#region ClearFlag
[TestMethod]
public void TestClearFlag()
{
@ -72,10 +66,6 @@
Assert.AreEqual(0x7f, flags);
}
#endregion
#region SetFlag
[TestMethod]
public void TestSetFlag()
{
@ -116,10 +106,6 @@
Assert.AreEqual(0xff, flags);
}
#endregion
#region LowerPart
[TestMethod]
public void TestLowerPart()
{
@ -128,10 +114,6 @@
Assert.AreEqual(0xf, lower);
}
#endregion
#region HigherPart
[TestMethod]
public void TestHigherPart()
{
@ -140,10 +122,6 @@
Assert.AreEqual(0xf000, higher);
}
#endregion
#region DemoteByte
[TestMethod]
public void TestDemoteByte()
{
@ -152,10 +130,6 @@
Assert.AreEqual(0xf0, demoted);
}
#endregion
#region PromoteByte
[TestMethod]
public void TestPromoteByte()
{
@ -164,10 +138,6 @@
Assert.AreEqual(0xf000, promoted);
}
#endregion
#region LowNibble
[TestMethod]
public void TestLowNibble()
{
@ -176,10 +146,6 @@
Assert.AreEqual(0xb, nibble);
}
#endregion
#region HighNibble
[TestMethod]
public void TestHighNibble()
{
@ -188,10 +154,6 @@
Assert.AreEqual(0xa, nibble);
}
#endregion
#region DemoteNibble
[TestMethod]
public void TestDemoteNibble()
{
@ -200,10 +162,6 @@
Assert.AreEqual(0xa, nibble);
}
#endregion
#region PromoteNibble
[TestMethod]
public void TestPromoteNibble()
{
@ -212,10 +170,6 @@
Assert.AreEqual(0xb0, nibble);
}
#endregion
#region HigherNibble
[TestMethod]
public void TestHigherNibble()
{
@ -224,10 +178,6 @@
Assert.AreEqual(0xa0, nibble);
}
#endregion
#region LowerNibble
[TestMethod]
public void TestLowerNibble()
{
@ -236,18 +186,11 @@
Assert.AreEqual(0xb, nibble);
}
#endregion
#region MakeWord
[TestMethod]
public void TestMakeWord()
{
ushort word = Chip.MakeWord(0xcd, 0xab);
Assert.AreEqual(0xabcd, word);
}
#endregion
}
}

View File

@ -1,5 +1,8 @@
// <copyright file="AssemblyInfo.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("UnitTestEightBit")]

View File

@ -56,6 +56,7 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EightBit\EightBit.csproj">
@ -63,6 +64,10 @@
<Name>EightBit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.Unstable.1.1.1.61\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</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">

View File

@ -2,4 +2,6 @@
<packages>
<package id="MSTest.TestAdapter" version="1.3.2" targetFramework="net472" />
<package id="MSTest.TestFramework" version="1.3.2" targetFramework="net472" />
<package id="StyleCop.Analyzers" version="1.1.1-beta.61" targetFramework="net472" developmentDependency="true" />
<package id="StyleCop.Analyzers.Unstable" version="1.1.1.61" targetFramework="net472" developmentDependency="true" />
</packages>

View File

@ -0,0 +1,19 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"documentInterfaces": false,
"documentExposedElements": false,
"documentInternalElements": false,
"documentPrivateElements": false,
"documentPrivateFields": false,
"companyName": "Adrian Conlon"
}
}
}