Lots of stylecop encouraged changes.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-02-19 00:56:16 +00:00
parent 23489b7127
commit 5714798756
4 changed files with 171 additions and 67 deletions

View File

@ -13,7 +13,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestLowByte()
{
ushort input = 0xf00f;
const ushort input = 0xf00f;
byte low = Chip.LowByte(input);
Assert.AreEqual(0xf, low);
}
@ -21,7 +21,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestHighByte()
{
ushort input = 0xf00f;
const ushort input = 0xf00f;
byte high = Chip.HighByte(input);
Assert.AreEqual(0xf0, high);
}
@ -109,7 +109,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestLowerPart()
{
ushort input = 0xf00f;
const ushort input = 0xf00f;
ushort lower = Chip.LowerPart(input);
Assert.AreEqual(0xf, lower);
}
@ -117,7 +117,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestHigherPart()
{
ushort input = 0xf00f;
const ushort input = 0xf00f;
ushort higher = Chip.HigherPart(input);
Assert.AreEqual(0xf000, higher);
}
@ -125,7 +125,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestDemoteByte()
{
ushort input = 0xf00f;
const ushort input = 0xf00f;
byte demoted = Chip.DemoteByte(input);
Assert.AreEqual(0xf0, demoted);
}
@ -133,7 +133,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestPromoteByte()
{
byte input = 0xf0;
const byte input = 0xf0;
ushort promoted = Chip.PromoteByte(input);
Assert.AreEqual(0xf000, promoted);
}
@ -141,7 +141,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestLowNibble()
{
byte input = 0xab;
const byte input = 0xab;
int nibble = Chip.LowNibble(input);
Assert.AreEqual(0xb, nibble);
}
@ -149,7 +149,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestHighNibble()
{
byte input = 0xab;
const byte input = 0xab;
int nibble = Chip.HighNibble(input);
Assert.AreEqual(0xa, nibble);
}
@ -157,7 +157,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestDemoteNibble()
{
byte input = 0xab;
const byte input = 0xab;
int nibble = Chip.DemoteNibble(input);
Assert.AreEqual(0xa, nibble);
}
@ -165,7 +165,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestPromoteNibble()
{
byte input = 0xab;
const byte input = 0xab;
int nibble = Chip.PromoteNibble(input);
Assert.AreEqual(0xb0, nibble);
}
@ -173,7 +173,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestHigherNibble()
{
byte input = 0xab;
const byte input = 0xab;
int nibble = Chip.HigherNibble(input);
Assert.AreEqual(0xa0, nibble);
}
@ -181,7 +181,7 @@ namespace UnitTestEightBit
[TestMethod]
public void TestLowerNibble()
{
byte input = 0xab;
const byte input = 0xab;
int nibble = Chip.LowerNibble(input);
Assert.AreEqual(0xb, nibble);
}

View File

@ -21,6 +21,12 @@
return FromByte(input);
}
public static RefreshRegister operator ++(RefreshRegister value) => Increment(value);
public static bool operator ==(RefreshRegister left, RefreshRegister right) => left.Equals(right);
public static bool operator !=(RefreshRegister left, RefreshRegister right) => !(left == right);
public static byte ToByte(RefreshRegister input)
{
return (byte)((input.high << 7) | input.variable);
@ -31,12 +37,6 @@
return new RefreshRegister(input);
}
public static RefreshRegister operator ++(RefreshRegister value) => Increment(value);
public static bool operator ==(RefreshRegister left, RefreshRegister right) => left.Equals(right);
public static bool operator !=(RefreshRegister left, RefreshRegister right) => !(left == right);
public static RefreshRegister Increment(RefreshRegister value)
{
++value.variable;

13
Z80/RegisterIndex.cs Normal file
View File

@ -0,0 +1,13 @@
// <copyright file="RegisterIndex.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
public enum RegisterIndex
{
IndexBC,
IndexDE,
IndexHL,
}
}

View File

@ -8,10 +8,11 @@ namespace EightBit
public class Z80 : IntelProcessor
{
public enum RegisterIndex { IndexBC, IndexDE, IndexHL };
private readonly InputOutput ports;
private readonly Register16[] accumulatorFlags = new Register16[2];
private readonly Register16[,] registers = new Register16[2, 3];
private RefreshRegister refresh = new RefreshRegister(0x7f);
private bool prefixCB = false;
@ -22,10 +23,8 @@ namespace EightBit
private PinLevel nmiLine = PinLevel.Low;
private PinLevel m1Line = PinLevel.Low;
private readonly Register16[] accumulatorFlags = new Register16[2];
private int accumulatorFlagsSet = 0;
private readonly Register16[,] registers = new Register16[2,3];
private int registerSet = 0;
private Register16 ix = new Register16(0xffff);
@ -73,7 +72,7 @@ namespace EightBit
get
{
var returned = (this.prefixDD ? this.IX() : this.IY()).Word + this.displacement;
return MEMPTR().Word = (ushort)returned;
return this.MEMPTR().Word = (ushort)returned;
}
}
@ -177,9 +176,13 @@ namespace EightBit
if (prefixed)
{
if (this.prefixCB)
{
this.ExecuteCB(x, y, z);
}
else if (this.prefixED)
{
this.ExecuteED(x, y, z, p, q);
}
}
else
{
@ -218,6 +221,7 @@ namespace EightBit
this.Execute(this.FetchByte());
}
}
this.OnExecutedInstruction();
return this.Cycles;
}
@ -258,7 +262,7 @@ namespace EightBit
this.DisableInterrupts();
switch (this.IM)
{
case 0: // i8080 equivalent
case 0: // i8080 equivalent
this.Execute(this.Bus.Data);
break;
case 1:
@ -266,7 +270,7 @@ namespace EightBit
this.Tick(13);
break;
case 2:
this.Call(this.MEMPTR() = new Register16(this.Bus.Data, IV));
this.Call(this.MEMPTR() = new Register16(this.Bus.Data, this.IV));
this.Tick(19);
break;
default:
@ -310,7 +314,7 @@ namespace EightBit
private static byte AdjustSZP(byte input, byte value)
{
AdjustSZ(input, value);
input = AdjustSZ(input, value);
return AdjustParity(input, value);
}
@ -364,6 +368,16 @@ namespace EightBit
return AdjustOverflowSub(input, before & (byte)StatusBits.SF, value & (byte)StatusBits.SF, calculation & (byte)StatusBits.SF);
}
private static byte RES(int n, byte operand)
{
return (byte)(operand & ~(1 << n));
}
private static byte SET(int n, byte operand)
{
return (byte)(operand | (1 << n));
}
private void DisableInterrupts() => this.IFF1 = this.IFF2 = false;
private void EnableInterrupts() => this.IFF1 = this.IFF2 = true;
@ -502,7 +516,7 @@ namespace EightBit
this.Bus.Write(this.HL(), value);
break;
case 7:
A() = value;
this.A() = value;
break;
default:
throw new ArgumentOutOfRangeException(nameof(r));
@ -515,11 +529,11 @@ namespace EightBit
var memoryZ = z == 6;
var indirect = (!this.displaced && memoryZ) || this.displaced;
var direct = !indirect;
var operand = !this.displaced ? R(z) : Bus.Read(this.DisplacedAddress);
var operand = !this.displaced ? this.R(z) : this.Bus.Read(this.DisplacedAddress);
var update = x != 1; // BIT does not update
switch (x)
{
case 0: // rot[y] r[z]
case 0: // rot[y] r[z]
switch (y)
{
case 0:
@ -549,6 +563,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.F() = AdjustSZP(this.F(), operand);
this.Tick(8);
break;
@ -564,6 +579,7 @@ namespace EightBit
this.F() = AdjustXY(this.F(), this.MEMPTR().High);
this.Tick(4);
}
break;
case 2: // RES y, r[z]
this.Tick(8);
@ -576,6 +592,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
if (update)
{
if (!this.displaced)
@ -612,8 +629,11 @@ namespace EightBit
this.MEMPTR() = this.Bus.Address() = this.BC();
this.MEMPTR()++;
this.ReadPort();
if (y != 6) // IN r[y],(C)
this.R(y, this.Bus.Data);
if (y != 6)
{
this.R(y, this.Bus.Data); // IN r[y],(C)
}
this.F() = AdjustSZPXY(this.F(), this.Bus.Data);
this.F() = ClearFlag(this.F(), StatusBits.NF | StatusBits.HC);
this.Tick(12);
@ -621,10 +641,15 @@ namespace EightBit
case 1: // Output to port with 16-bit address
this.MEMPTR() = this.Bus.Address() = this.BC();
this.MEMPTR()++;
if (y != 6) // OUT (C),r[y]
this.Bus.Data = R(y);
else // OUT (C),0
this.Bus.Data = 0;
if (y != 6)
{
this.Bus.Data = this.R(y); // OUT (C),r[y]
}
else
{
this.Bus.Data = 0; // OUT (C),0
}
this.WritePort();
this.Tick(12);
break;
@ -640,6 +665,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(15);
break;
case 3: // Retrieve/store register pair from/to immediate address
@ -655,6 +681,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(20);
break;
case 4: // Negate accumulator
@ -671,6 +698,7 @@ namespace EightBit
this.RetN(); // RETN
break;
}
this.Tick(14);
break;
case 6: // Set interrupt mode
@ -693,6 +721,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(8);
break;
case 7: // Assorted ops
@ -709,13 +738,13 @@ namespace EightBit
case 2: // LD A,I
this.F() = AdjustSZXY(this.F(), this.A() = this.IV);
this.F() = ClearFlag(this.F(), StatusBits.NF | StatusBits.HC);
this.F() = SetFlag(this.F(), StatusBits.PF, IFF2);
this.F() = SetFlag(this.F(), StatusBits.PF, this.IFF2);
this.Tick(9);
break;
case 3: // LD A,R
this.F() = AdjustSZXY(this.F(), this.A() = REFRESH());
this.F() = AdjustSZXY(this.F(), this.A() = this.REFRESH());
this.F() = ClearFlag(this.F(), StatusBits.NF | StatusBits.HC);
this.F() = SetFlag(this.F(), StatusBits.PF, IFF2);
this.F() = SetFlag(this.F(), StatusBits.PF, this.IFF2);
this.Tick(9);
break;
case 4: // RRD
@ -733,10 +762,12 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 2:
switch (z)
@ -757,6 +788,7 @@ namespace EightBit
--this.PC();
this.Tick(5);
}
break;
case 7: // LDDR
if (this.LDDR())
@ -765,8 +797,10 @@ namespace EightBit
--this.PC();
this.Tick(5);
}
break;
}
break;
case 1: // CP
switch (y)
@ -784,6 +818,7 @@ namespace EightBit
--this.PC();
this.Tick(5);
}
break;
case 7: // CPDR
if (this.CPDR())
@ -796,8 +831,10 @@ namespace EightBit
{
this.MEMPTR().Word = (ushort)(this.PC().Word - 2);
}
break;
}
break;
case 2: // IN
switch (y)
@ -814,6 +851,7 @@ namespace EightBit
this.PC().Word -= 2;
this.Tick(5);
}
break;
case 7: // INDR
if (this.INDR())
@ -821,8 +859,10 @@ namespace EightBit
this.PC().Word -= 2;
this.Tick(5);
}
break;
}
break;
case 3: // OUT
switch (y)
@ -839,6 +879,7 @@ namespace EightBit
this.PC().Word -= 2;
this.Tick(5);
}
break;
case 7: // OTDR
if (this.OTDR())
@ -846,10 +887,13 @@ namespace EightBit
this.PC().Word -= 2;
this.Tick(5);
}
break;
}
break;
}
this.Tick(16);
break;
}
@ -876,7 +920,10 @@ namespace EightBit
break;
case 2: // DJNZ d
if (this.JumpRelativeConditional(--this.B() != 0))
{
this.Tick(5);
}
this.Tick(8);
break;
case 3: // JR d
@ -888,12 +935,16 @@ namespace EightBit
case 6:
case 7:
if (this.JumpRelativeConditionalFlag(y - 4))
{
this.Tick(5);
}
this.Tick(5);
break;
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 1: // 16-bit load immediate/add
switch (q)
@ -909,6 +960,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 2: // Indirect loading
switch (q)
@ -945,6 +997,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 1:
switch (p)
@ -975,10 +1028,12 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 3: // 16-bit INC/DEC
switch (q)
@ -992,11 +1047,15 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(6);
break;
case 4: // 8-bit INC
if (this.displaced && memoryY)
{
this.FetchDisplacement();
}
this.R(y, this.Increment(this.R(y)));
this.Tick(4);
break;
@ -1005,8 +1064,11 @@ namespace EightBit
{
this.Tick(7);
if (this.displaced)
{
this.FetchDisplacement();
}
}
this.R(y, this.Decrement(this.R(y)));
this.Tick(4);
break;
@ -1015,8 +1077,11 @@ namespace EightBit
{
this.Tick(3);
if (this.displaced)
{
this.FetchDisplacement();
}
}
this.R(y, this.FetchByte()); // LD r,n
this.Tick(7);
break;
@ -1050,11 +1115,13 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(4);
break;
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 1: // 8-bit loading
if (!(memoryZ && memoryY))
@ -1063,7 +1130,10 @@ namespace EightBit
if (this.displaced)
{
if (memoryZ || memoryY)
{
this.FetchDisplacement();
}
if (memoryZ)
{
switch (y)
@ -1078,6 +1148,7 @@ namespace EightBit
break;
}
}
if (memoryY)
{
switch (z)
@ -1093,15 +1164,23 @@ namespace EightBit
}
}
}
if (normal)
{
this.R(y, this.R(z));
if (memoryY || memoryZ) // M operations
}
// M operations
if (memoryY || memoryZ)
{
this.Tick(3);
}
}
else
{ // Exception (replaces LD (HL), (HL))
this.Halt();
{
this.Halt(); // Exception (replaces LD (HL), (HL))
}
this.Tick(4);
break;
case 2:
@ -1110,9 +1189,12 @@ namespace EightBit
{
this.Tick(3);
if (this.displaced)
{
this.FetchDisplacement();
}
}
var value = R(z);
var value = this.R(z);
switch (y)
{
case 0: // ADD A,r
@ -1142,15 +1224,20 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(4);
break;
}
case 3:
switch (z)
{
case 0: // Conditional return
if (this.ReturnConditionalFlag(y))
{
this.Tick(6);
}
this.Tick(5);
break;
case 1: // POP & various ops
@ -1182,10 +1269,12 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 2: // Conditional jump
this.JumpConditionalFlag(y);
@ -1201,7 +1290,10 @@ namespace EightBit
case 1: // CB prefix
this.prefixCB = true;
if (this.displaced)
{
this.FetchDisplacement();
}
this.LowerM1();
this.Execute(this.FetchByte());
break;
@ -1232,10 +1324,14 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 4: // Conditional call: CALL cc[y], nn
if (this.CallConditionalFlag(y))
{
this.Tick(7);
}
this.Tick(10);
break;
case 5: // PUSH & various ops
@ -1270,10 +1366,12 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
case 6:
{ // Operate on accumulator and immediate operand: alu[y] n
@ -1307,9 +1405,11 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
this.Tick(7);
break;
}
case 7: // Restart: RST y * 8
this.Restart((byte)(y << 3));
this.Tick(11);
@ -1317,6 +1417,7 @@ namespace EightBit
default:
throw new NotSupportedException("Invalid operation mode");
}
break;
}
}
@ -1475,7 +1576,7 @@ namespace EightBit
var valueNegative = value.High & (byte)StatusBits.SF;
var result = this.MEMPTR().Word - value.Word - (this.F() & (byte)StatusBits.CF);
HL2().Word = (ushort)result;
this.HL2().Word = (ushort)result;
var afterNegative = this.HL2().High & (byte)StatusBits.SF;
@ -1541,15 +1642,15 @@ namespace EightBit
this.F() = AdjustSZXY(this.F(), this.A() = result.Low);
}
private void ADC(byte value) => Add(value, this.F() & (byte)StatusBits.CF);
private void ADC(byte value) => this.Add(value, this.F() & (byte)StatusBits.CF);
private void SUB(byte value, int carry = 0)
{
this.A() = Subtract(this.A(), value, carry);
this.A() = this.Subtract(this.A(), value, carry);
this.F() = AdjustXY(this.F(), this.A());
}
private void SBC(byte value) => SUB(value, this.F() & (byte)StatusBits.CF);
private void SBC(byte value) => this.SUB(value, this.F() & (byte)StatusBits.CF);
private void AndR(byte value)
{
@ -1572,7 +1673,7 @@ namespace EightBit
private void Compare(byte value)
{
this.F() = Subtract(this.A(), value);
this.F() = this.Subtract(this.A(), value);
this.F() = AdjustXY(this.F(), value);
}
@ -1662,21 +1763,11 @@ namespace EightBit
this.F() = ClearFlag(this.F(), StatusBits.PF, discarded);
}
private static byte RES(int n, byte operand)
{
return (byte)(operand & ~(1 << n));
}
private static byte SET(int n, byte operand)
{
return (byte)(operand | (1 << n));
}
private void DAA()
{
var updated = this.A();
var lowAdjust = ((this.F() & (byte)StatusBits.HC) != 0) || (LowNibble(A()) > 9);
var lowAdjust = ((this.F() & (byte)StatusBits.HC) != 0) || (LowNibble(this.A()) > 9);
var highAdjust = ((this.F() & (byte)StatusBits.CF) != 0) || (this.A() > 0x99);
if ((this.F() & (byte)StatusBits.NF) != 0)
@ -1768,7 +1859,7 @@ namespace EightBit
private bool CPIR()
{
this.CPI();
return ((this.F() & (byte)StatusBits.PF) != 0) && ((this.F() & (byte)StatusBits.ZF) == 0); // See CPI
return ((this.F() & (byte)StatusBits.PF) != 0) && ((this.F() & (byte)StatusBits.ZF) == 0); // See CPI
}
private void CPD()
@ -1780,7 +1871,7 @@ namespace EightBit
private bool CPDR()
{
this.CPD();
return ((this.F() & (byte)StatusBits.PF) != 0) && ((this.F() & (byte)StatusBits.ZF) == 0); // See CPD
return ((this.F() & (byte)StatusBits.PF) != 0) && ((this.F() & (byte)StatusBits.ZF) == 0); // See CPD
}
private void BlockLoad(Register16 source, Register16 destination, Register16 counter)
@ -1790,7 +1881,7 @@ namespace EightBit
var xy = this.A() + value;
this.F() = SetFlag(this.F(), StatusBits.XF, xy & (int)Bits.Bit3);
this.F() = SetFlag(this.F(), StatusBits.YF, xy & (int)Bits.Bit1);
F() = ClearFlag(this.F(), StatusBits.NF | StatusBits.HC);
this.F() = ClearFlag(this.F(), StatusBits.NF | StatusBits.HC);
this.F() = SetFlag(this.F(), StatusBits.PF, --counter.Word);
}
@ -1802,7 +1893,7 @@ namespace EightBit
private bool LDIR()
{
this.LDI();
return (this.F() & (byte)StatusBits.PF) != 0; // See LDI
return (this.F() & (byte)StatusBits.PF) != 0; // See LDI
}
private void LDD()
@ -1813,7 +1904,7 @@ namespace EightBit
private bool LDDR()
{
this.LDD();
return (this.F() & (byte)StatusBits.PF) == 0; // See LDD
return (this.F() & (byte)StatusBits.PF) == 0; // See LDD
}
private void BlockIn(Register16 source, Register16 destination)
@ -1834,7 +1925,7 @@ namespace EightBit
private bool INIR()
{
this.INI();
return (this.F() & (byte)StatusBits.ZF) == 0; // See INI
return (this.F() & (byte)StatusBits.ZF) == 0; // See INI
}
private void IND()
@ -1846,7 +1937,7 @@ namespace EightBit
private bool INDR()
{
this.IND();
return (this.F() & (byte)StatusBits.ZF) == 0; // See IND
return (this.F() & (byte)StatusBits.ZF) == 0; // See IND
}
private void BlockOut(Register16 source, Register16 destination)
@ -1870,7 +1961,7 @@ namespace EightBit
private bool OTIR()
{
this.OUTI();
return (this.F() & (byte)StatusBits.ZF) == 0; // See OUTI
return (this.F() & (byte)StatusBits.ZF) == 0; // See OUTI
}
private void OUTD()
@ -1882,7 +1973,7 @@ namespace EightBit
private bool OTDR()
{
this.OUTD();
return (this.F() & (byte)StatusBits.ZF) == 0; // See OUTD
return (this.F() & (byte)StatusBits.ZF) == 0; // See OUTD
}
private void NEG()