diff options
Diffstat (limited to 'native')
| -rw-r--r-- | native/Noddybox.Emulation.EightBit.Z80.Test/Program.cs | 71 | ||||
| -rw-r--r-- | native/Noddybox.Emulation.EightBit.Z80.Test/TestMachine.cs | 260 | 
2 files changed, 328 insertions, 3 deletions
| diff --git a/native/Noddybox.Emulation.EightBit.Z80.Test/Program.cs b/native/Noddybox.Emulation.EightBit.Z80.Test/Program.cs index 0f2a19d..43dab10 100644 --- a/native/Noddybox.Emulation.EightBit.Z80.Test/Program.cs +++ b/native/Noddybox.Emulation.EightBit.Z80.Test/Program.cs @@ -19,6 +19,7 @@ using System;  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
 +using System.IO;
  namespace Noddybox.Emulation.EightBit.Z80.Test
  {
 @@ -28,9 +29,77 @@ namespace Noddybox.Emulation.EightBit.Z80.Test      /// </summary>
      class Program
      {
 +        static Queue<string> GetBlock(StreamReader str)
 +        {
 +            Queue<string> q = new Queue<string>();
 +            bool process = false;
 +
 +            while(!str.EndOfStream)
 +            {
 +                string s = str.ReadLine();
 +
 +                if (process)
 +                {
 +                    if (s.Trim().Length == 0)
 +                    {
 +                        return q;
 +                    }
 +                    
 +                    q.Enqueue(s);
 +                }
 +                else
 +                {
 +                    if (s.Trim().Length > 0)
 +                    {
 +                        process = true;
 +                        q.Enqueue(s);
 +                    }
 +                }
 +            }
 +
 +            return q;
 +        }
 +
          static void Main(string[] args)
          {
 -            new TestMachine("Test", null, null);
 +            try
 +            {
 +                StreamReader test = new StreamReader("tests.in");
 +                StreamReader expected = new StreamReader("tests.expected");
 +
 +                while(!test.EndOfStream)
 +                {
 +                    Queue<string> t = GetBlock(test);
 +                    Queue<string> e = GetBlock(expected);
 +
 +                    if (t.Count > 0)
 +                    {
 +                        if (t.Peek() != e.Peek())
 +                        {
 +                            throw new Exception(String.Format("Test name {0}, expected name {1}", t.Peek(), e.Peek()));
 +                        }
 +
 +                        TestMachine m = new TestMachine();
 +                        e.Dequeue();
 +
 +                        if (!m.Run(t.Dequeue(), t, e))
 +                        {
 +                            Console.ReadKey(true);
 +                        }
 +                    }
 +                }
 +
 +                test.Close();
 +                expected.Close();
 +            }
 +            catch (Exception e)
 +            {
 +                while (e != null)
 +                {
 +                    Console.WriteLine("**** {0}: {1}", e.GetType(), e.Message);
 +                    e = e.InnerException;
 +                }
 +            }
          }
      }
  }
 diff --git a/native/Noddybox.Emulation.EightBit.Z80.Test/TestMachine.cs b/native/Noddybox.Emulation.EightBit.Z80.Test/TestMachine.cs index 09e868b..b5d7810 100644 --- a/native/Noddybox.Emulation.EightBit.Z80.Test/TestMachine.cs +++ b/native/Noddybox.Emulation.EightBit.Z80.Test/TestMachine.cs @@ -26,7 +26,7 @@ namespace Noddybox.Emulation.EightBit.Z80.Test      {
          private readonly byte[] mem = new byte[0x10000];
          private readonly Z80Cpu z80 = new Z80Cpu();
 -        private readonly Clock clock = new Clock(100000, 50);
 +        private readonly Clock clock = new Clock(uint.MaxValue, uint.MaxValue);
          private void Output(ConsoleColor pen, ConsoleColor paper, string format, params object[] p)
          {
 @@ -36,6 +36,21 @@ namespace Noddybox.Emulation.EightBit.Z80.Test              Console.ResetColor();
          }
 +        private Queue<Register16> Decode(string i)
 +        {
 +            Queue<Register16> l = new Queue<Register16>();
 +
 +            foreach (string s in i.Split(new char[] {' ', '\t'}, StringSplitOptions.RemoveEmptyEntries))
 +            {
 +                if (s != "-1")
 +                {
 +                    l.Enqueue(new Register16(UInt16.Parse(s, System.Globalization.NumberStyles.HexNumber)));
 +                }
 +            }
 +
 +            return l;
 +        }
 +
          byte IMemory.Read(ushort address)
          {
              Output(ConsoleColor.Green, ConsoleColor.Black, "Reading {0:X2} from {1:X4}", mem[address], address);
 @@ -59,9 +74,250 @@ namespace Noddybox.Emulation.EightBit.Z80.Test              Output(ConsoleColor.Red, ConsoleColor.DarkGray, "Writing {0:X2} to device {1:X4}", value, device);
          }
 -        public TestMachine(string name, List<string> input, List<string> expected)
 +        public bool Run(string name, Queue<string> input, Queue<string> expected)
          {
              Output(ConsoleColor.Black, ConsoleColor.White, "Running test {0}", name);
 +
 +            Queue<Register16> line = Decode(input.Dequeue());
 +            Register16 r = line.Dequeue();
 +
 +            z80.Acummulator = r.high;
 +            z80.StatusFlags = (Z80Flags)r.low;
 +
 +            z80.BC_Register = line.Dequeue();
 +            z80.DE_Register = line.Dequeue();
 +            z80.HL_Register = line.Dequeue();
 +
 +            z80.AF_Alternate = line.Dequeue();
 +            z80.BC_Alternate = line.Dequeue();
 +            z80.DE_Alternate = line.Dequeue();
 +            z80.HL_Alternate = line.Dequeue();
 +
 +            z80.IX_Register = line.Dequeue();
 +            z80.IY_Register = line.Dequeue();
 +            z80.StackPointer = line.Dequeue().reg;
 +            z80.ProgramCounter = line.Dequeue().reg;
 +
 +            line = Decode(input.Dequeue());
 +
 +            z80.InterruptVector = line.Dequeue().low;
 +            z80.Refresh = line.Dequeue().low;
 +            z80.IFF1_Register = (line.Dequeue().reg != 0);
 +            z80.IFF2_Register = (line.Dequeue().reg != 0);
 +            z80.IM_Register = line.Dequeue().low;
 +            z80.HaltLine = (line.Dequeue().reg != 0);
 +
 +            int cyclesToRun = Convert.ToInt32(line.Dequeue().reg.ToString("X"));
 +
 +            while(input.Count > 0)
 +            {
 +                line = Decode(input.Dequeue());
 +
 +                if (line.Count > 1)
 +                {
 +                    ushort addr = line.Dequeue().reg;
 +
 +                    foreach (Register16 b in line)
 +                    {
 +                        mem[addr++] = b.low;
 +                    }
 +                }
 +            }
 +
 +            while(clock.Ticks < cyclesToRun)
 +            {
 +                z80.Step();
 +            }
 +
 +            bool ok = true;
 +
 +            while(expected.Peek().StartsWith(" "))
 +            {
 +                Output(ConsoleColor.DarkGray, ConsoleColor.Black, "Not yet handled - {0}", expected.Dequeue());
 +            }
 +
 +            line = Decode(expected.Dequeue());
 +
 +            r = line.Dequeue();
 +            if (r.high != z80.Acummulator)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in A, got {1:X}", r.high, z80.Acummulator);
 +                ok = false;
 +            }
 +
 +            if ((Z80Flags)r.low != z80.StatusFlags)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0} in F, got {1}", (Z80Flags)r.low, z80.StatusFlags);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.BC_Register.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in BC, got {1:X}", r.reg, z80.BC_Register.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.DE_Register.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in DE, got {1:X}", r.reg, z80.DE_Register.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.HL_Register.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in HL, got {1:X}", r.reg, z80.HL_Register.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.AF_Alternate.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in AF', got {1:X}", r.reg, z80.AF_Alternate.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.BC_Alternate.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in BC', got {1:X}", r.reg, z80.BC_Alternate.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.DE_Alternate.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in DE', got {1:X}", r.reg, z80.DE_Alternate.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.HL_Alternate.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in HL', got {1:X}", r.reg, z80.HL_Alternate.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.IX_Register.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in IX, got {1:X}", r.reg, z80.IX_Register.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.IY_Register.reg)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in IY, got {1:X}", r.reg, z80.IY_Register.reg);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.StackPointer)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in SP, got {1:X}", r.reg, z80.StackPointer);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.reg != z80.ProgramCounter)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in PC, got {1:X}", r.reg, z80.ProgramCounter);
 +                ok = false;
 +            }
 +
 +            line = Decode(expected.Dequeue());
 +
 +            r = line.Dequeue();
 +            if (r.low != z80.InterruptVector)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in I, got {1:X}", r.low, z80.InterruptVector);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.low != z80.Refresh)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in R, got {1:X}", r.low, z80.Refresh);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if ((r.reg != 0) != z80.IFF1_Register)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0} in IFF1, got {1}", (r.reg != 0), z80.IFF1_Register);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if ((r.reg != 0) != z80.IFF2_Register)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0} in IFF2, got {1}", (r.reg != 0), z80.IFF2_Register);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if (r.low != z80.IM_Register)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} in IM, got {1:X}", r.low, z80.IM_Register);
 +                ok = false;
 +            }
 +
 +            r = line.Dequeue();
 +            if ((r.reg != 0) != z80.HaltLine)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0} in HALT, got {1}", (r.reg != 0), z80.HaltLine);
 +                ok = false;
 +            }
 +
 +            int cyclesToTest = Convert.ToInt32(line.Dequeue().reg.ToString("X"));
 +
 +            if (cyclesToTest != clock.Ticks)
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0} cycles, got {1}", cyclesToTest, clock.Ticks);
 +                ok = false;
 +            }
 +
 +            while (expected.Count > 0)
 +            {
 +                line = Decode(expected.Dequeue());
 +
 +                if (line.Count > 1)
 +                {
 +                    ushort addr = line.Dequeue().reg;
 +
 +                    foreach (Register16 b in line)
 +                    {
 +                        if (mem[addr] != b.low)
 +                        {
 +                            Output(ConsoleColor.Red, ConsoleColor.Black, "Expected {0:X} at location {1:X}, got {2:X}", b.low, addr, mem[addr]);
 +                            ok = false;
 +                        }
 +
 +                        addr++;
 +                    }
 +                }
 +            }
 +
 +            if (ok)
 +            {
 +                Output(ConsoleColor.Yellow, ConsoleColor.Black, "Test passed");
 +            }
 +            else
 +            {
 +                Output(ConsoleColor.Red, ConsoleColor.Black, "Test FAILED");
 +            }
 +
 +            Console.WriteLine();
 +
 +            return ok;
 +        }
 +
 +        public TestMachine()
 +        {
 +            z80.Initialise(this, this, clock);
          }
      }
  }
 | 
