public void RunTest(string in_file_name) { TestMemory mem = new TestMemory(); // load test mem.LoadFile(in_file_name, 0x0100); // prepare memory for CP/M compatibility mem[5] = 0xc9; // RET mem[6] = 0; // Address for Stack determination (0xc000) mem[7] = 0xc0; Stopwatch timer = new Stopwatch(); timer.Start(); Z80Emu Z80_CPU = new Z80Emu(mem, null, null, true); Z80_CPU.Reset(); Z80_CPU.Registers.PC = 0x0100; Z80_CPU.Registers.SP = 0xc000; Z80_CPU.TotalTState = 0; while (Z80_CPU.Registers.PC != 0) { // handle BDOS call if (Z80_CPU.Registers.PC == 0x0005) { switch (Z80_CPU.Registers.C) { case 2: Console.Write((char)(Z80_CPU.Registers.E & 0xff)); break; case 9: { ushort i = Z80_CPU.Registers.DE; while (mem[i] != '$') { Console.Write((char)mem[i]); i++; } } break; } } Z80_CPU.Step(); } timer.Stop(); Console.WriteLine(string.Format("Ellapsed time: {0} ({1} ms) CPU speed: {2}MHz", timer.Elapsed, timer.ElapsedMilliseconds, Z80_CPU.TotalTState / (ulong)timer.ElapsedMilliseconds / 1000)); Console.WriteLine(); }
public void SetCPU(Z80Emu in_cpu) { m_cpu = in_cpu; }
public void RunTest(string in_file_name, string expected_file_name) { TestMemory mem = new TestMemory(); TestPorts port = new TestPorts(); Z80Emu cpu = new Z80Emu(mem, port, null, true); uint planned_t_state; uint ellapsed_t_state; int failed_tests = 0; Z80Registers expected_registers = new Z80Registers(); string line; using (var expected_file = File.OpenText(expected_file_name)) { using (var in_file = File.OpenText(in_file_name)) { while ((line = in_file.ReadLine()) != null) { if (string.IsNullOrEmpty(line.Trim())) { continue; } // reset CPU cpu.Reset(); // test found read name m_test_name = line; // read registers line = in_file.ReadLine(); ReadRegisters(line, cpu.Registers); // read other registers and tsatate line = in_file.ReadLine(); cpu.Registers.I = byte.Parse(line.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture); cpu.Registers.R = byte.Parse(line.Substring(3, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture); cpu.IFF1 = (byte)(line[6] - '0'); cpu.IFF2 = (byte)(line[8] - '0'); cpu.IM = (Z80Emu.IMMode)(line[10] - '0'); cpu.Halted = line[12] != '0'; planned_t_state = uint.Parse(line.Substring(13).Trim()); // read memory do { line = in_file.ReadLine(); if (line != "-1") { ParseMemoryData(line, mem); } } while (line != "-1"); // start simulation Console.Write("Running test {0}", m_test_name); ellapsed_t_state = 0; while (ellapsed_t_state < planned_t_state || !cpu.InstructionDone) { ellapsed_t_state += cpu.Step(); } // compare result with the expected // compare test names if (m_test_name != expected_file.ReadLine()) { Console.WriteLine("Unmatched test name"); } // skip events do { line = expected_file.ReadLine(); } while (line[0] == ' '); // load registers ReadRegisters(line, expected_registers); // compare cpu state line = expected_file.ReadLine(); byte temp; bool ok = true; temp = byte.Parse(line.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture); if (temp != cpu.Registers.I) { Console.WriteLine(string.Format("\n Register mismatch I={0:X2} -- expected {1:X2}", cpu.Registers.I, temp)); ok = false; } temp = byte.Parse(line.Substring(3, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture); if (temp != cpu.Registers.R) { Console.WriteLine(string.Format("\n Register mismatch R={0:X2} -- expected {1:X2}", cpu.Registers.R, temp)); ok = false; } // check IFF1 temp = (byte)(line[6] - '0'); if (cpu.IFF1 != temp) { Console.WriteLine(string.Format("\n IFF1 flag mismatch {0} -- expected {1}", cpu.IFF1, temp)); ok = false; } // check IFF2 temp = (byte)(line[8] - '0'); if (cpu.IFF2 != temp) { Console.WriteLine(string.Format("\n IFF2 flag mismatch {0} -- expected {1}", cpu.IFF2, temp)); ok = false; } // check IM Z80Emu.IMMode im_mode = (Z80Emu.IMMode)(line[10] - '0'); if (cpu.IM != im_mode) { Console.WriteLine(string.Format("\n IM mode mismatch {0} -- expected {1}", cpu.IM, im_mode)); ok = false; } // check halted bool halted = line[12] != '0'; if (cpu.Halted != halted) { Console.WriteLine(string.Format("\n Halted mode mismatch {0} -- expected {1}", cpu.Halted, halted)); ok = false; } // check T state uint expected_t_state = uint.Parse(line.Substring(13).Trim()); if (expected_t_state != ellapsed_t_state) { Console.WriteLine(string.Format("\n T state mismathed T={0:d} -- expected {1:d}", ellapsed_t_state, expected_t_state)); ok = false; } // compare registers ok = CompareRegisters(ok, (ushort)(cpu.Registers.AF), (ushort)(expected_registers.AF), "AF"); ok = CompareRegisters(ok, cpu.Registers.BC, expected_registers.BC, "BC"); ok = CompareRegisters(ok, cpu.Registers.DE, expected_registers.DE, "DE"); ok = CompareRegisters(ok, cpu.Registers.HL, expected_registers.HL, "HL"); ok = CompareRegisters(ok, cpu.Registers._AF_, expected_registers._AF_, "_AF_"); ok = CompareRegisters(ok, cpu.Registers._BC_, expected_registers._BC_, "_BC_"); ok = CompareRegisters(ok, cpu.Registers._DE_, expected_registers._DE_, "_DE_"); ok = CompareRegisters(ok, cpu.Registers._HL_, expected_registers._HL_, "_HL_"); ok = CompareRegisters(ok, cpu.Registers.IX, expected_registers.IX, "IX"); ok = CompareRegisters(ok, cpu.Registers.IY, expected_registers.IY, "IY"); ok = CompareRegisters(ok, cpu.Registers.SP, expected_registers.SP, "SP"); ok = CompareRegisters(ok, cpu.Registers.PC, expected_registers.PC, "PC"); ok = CompareRegisters(ok, cpu.Registers.WZ, expected_registers.WZ, "WZ"); do { line = expected_file.ReadLine(); if (!string.IsNullOrEmpty(line)) { // check memory ok = CheckMemoryData(ok, line, mem); } } while (!string.IsNullOrEmpty(line)); if (ok) { Console.WriteLine(" -- OK"); } else { failed_tests++; } } Console.WriteLine("Tests failed: " + failed_tests.ToString()); Console.WriteLine(); } } }
// ------------------------------------------------------------------------------------------------- // Initialises the emulator // ------------------------------------------------------------------------------------------------- private void InitEmulator() { EmulatorMemory = new TestMemory(); EmulatorPorts = new TestPorts(); Emulatorcpu = new Z80Emu(EmulatorMemory, EmulatorPorts, null, true); }