Further Z80 timing fixes: 290 failures

This commit is contained in:
Adrian Conlon
2025-05-03 00:09:19 +01:00
parent 175069d6bf
commit e1aa220409
11 changed files with 143 additions and 360 deletions
-223
View File
@@ -1,223 +0,0 @@
// <copyright file="ChipUnitTest.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class ChipUnitTest
{
[TestMethod]
public void TestLowByte()
{
const ushort input = 0xf00f;
var low = Chip.LowByte(input);
Assert.AreEqual(0xf, low);
}
[TestMethod]
public void TestHighByte()
{
const ushort input = 0xf00f;
var high = Chip.HighByte(input);
Assert.AreEqual(0xf0, high);
}
[TestMethod]
public void TestClearBit()
{
byte flags = 0xff;
flags = Chip.ClearBit(flags, 0x80);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestClearBitNonZero()
{
byte flags = 0xff;
flags = Chip.ClearBit(flags, 0x80, 1);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestClearBitZero()
{
byte flags = 0xff;
flags = Chip.ClearBit(flags, 0x80, 0);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestClearBitFalse()
{
byte flags = 0xff;
flags = Chip.ClearBit(flags, 0x80, false);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestClearBitTrue()
{
byte flags = 0xff;
flags = Chip.ClearBit(flags, 0x80, true);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestSetBit()
{
byte flags = 0x7f;
flags = Chip.SetBit(flags, 0x80);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestSetBitNonZero()
{
byte flags = 0x7f;
flags = Chip.SetBit(flags, 0x80, 1);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestSetBitZero()
{
byte flags = 0x7f;
flags = Chip.SetBit(flags, 0x80, 0);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestSetBitFalse()
{
byte flags = 0x7f;
flags = Chip.SetBit(flags, 0x80, false);
Assert.AreEqual(0x7f, flags);
}
[TestMethod]
public void TestSetBitTrue()
{
byte flags = 0x7f;
flags = Chip.SetBit(flags, 0x80, true);
Assert.AreEqual(0xff, flags);
}
[TestMethod]
public void TestLowerPart()
{
const ushort input = 0xf00f;
ushort lower = Chip.LowerPart(input);
Assert.AreEqual(0xf, lower);
}
[TestMethod]
public void TestHigherPart()
{
const ushort input = 0xf00f;
var higher = Chip.HigherPart(input);
Assert.AreEqual(0xf000, higher);
}
[TestMethod]
public void TestDemoteByte()
{
const ushort input = 0xf00f;
var demoted = Chip.DemoteByte(input);
Assert.AreEqual(0xf0, demoted);
}
[TestMethod]
public void TestPromoteByte()
{
const byte input = 0xf0;
var promoted = Chip.PromoteByte(input);
Assert.AreEqual(0xf000, promoted);
}
[TestMethod]
public void TestLowNibble()
{
const byte input = 0xab;
var nibble = Chip.LowNibble(input);
Assert.AreEqual(0xb, nibble);
}
[TestMethod]
public void TestHighNibble()
{
const byte input = 0xab;
var nibble = Chip.HighNibble(input);
Assert.AreEqual(0xa, nibble);
}
[TestMethod]
public void TestDemoteNibble()
{
const byte input = 0xab;
var nibble = Chip.DemoteNibble(input);
Assert.AreEqual(0xa, nibble);
}
[TestMethod]
public void TestPromoteNibble()
{
const byte input = 0xab;
var nibble = Chip.PromoteNibble(input);
Assert.AreEqual(0xb0, nibble);
}
[TestMethod]
public void TestHigherNibble()
{
const byte input = 0xab;
var nibble = Chip.HigherNibble(input);
Assert.AreEqual(0xa0, nibble);
}
[TestMethod]
public void TestLowerNibble()
{
const byte input = 0xab;
var nibble = Chip.LowerNibble(input);
Assert.AreEqual(0xb, nibble);
}
[TestMethod]
public void TestMakeWord()
{
var word = Chip.MakeWord(0xcd, 0xab);
Assert.AreEqual(0xabcd, word);
}
[TestMethod]
public void TestFindFirstSet_1()
{
var position = Chip.FindFirstSet(12);
Assert.AreEqual(3, position);
}
[TestMethod]
public void TestFindFirstSet_2()
{
var position = Chip.FindFirstSet(1);
Assert.AreEqual(1, position);
}
[TestMethod]
public void TestFindFirstSet_3()
{
var position = Chip.FindFirstSet(128);
Assert.AreEqual(8, position);
}
[TestMethod]
public void TestFindFirstSet_4()
{
var position = Chip.FindFirstSet(0);
Assert.AreEqual(0, position);
}
}
}
@@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>False</GenerateDocumentationFile>
<SignAssembly>False</SignAssembly>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<AnalysisLevel>latest</AnalysisLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<WarningLevel>7</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<WarningLevel>7</WarningLevel>
</PropertyGroup>
</Project>
+95 -79
View File
@@ -7,13 +7,13 @@ namespace LR35902
using EightBit;
using System.Globalization;
public enum IoRegister
{
Abbreviated, // FF00 + dd
Absolute, // FFdd
Register, // C
Unused, // Unused!
}
//public enum IoRegister
//{
// Abbreviated, // FF00 + dd
// Absolute, // FFdd
// Register, // C
// Unused, // Unused!
//}
public sealed class Disassembler(Bus bus)
{
@@ -120,56 +120,70 @@ namespace LR35902
private static string IO(byte value) => value switch
{
// Port/Mode Registers
IoRegisters.P1 => "P1",
IoRegisters.SB => "SB",
IoRegisters.SC => "SC",
IoRegisters.DIV => "DIV",
IoRegisters.TIMA => "TIMA",
IoRegisters.TMA => "TMA",
IoRegisters.TAC => "TAC",
IoRegisters.P1 => "IO:P1",
IoRegisters.SB => "IO:SB",
IoRegisters.SC => "IO:SC",
IoRegisters.DIV => "IO:DIV",
IoRegisters.TIMA => "IO:TIMA",
IoRegisters.TMA => "IO:TMA",
IoRegisters.TAC => "IO:TAC",
// Interrupt Flags
IoRegisters.IF => "IF",
IoRegisters.IE => "IE",
IoRegisters.IF => "IO:IF",
IoRegisters.IE => "IO:IE",
// LCD Display Registers
IoRegisters.LCDC => "LCDC",
IoRegisters.STAT => "STAT",
IoRegisters.SCY => "SCY",
IoRegisters.SCX => "SCX",
IoRegisters.LY => "LY",
IoRegisters.LYC => "LYC",
IoRegisters.DMA => "DMA",
IoRegisters.BGP => "BGP",
IoRegisters.OBP0 => "OBP0",
IoRegisters.OBP1 => "OBP1",
IoRegisters.WY => "WY",
IoRegisters.WX => "WX",
IoRegisters.LCDC => "IO:LCDC",
IoRegisters.STAT => "IO:STAT",
IoRegisters.SCY => "IO:SCY",
IoRegisters.SCX => "IO:SCX",
IoRegisters.LY => "IO:LY",
IoRegisters.LYC => "IO:LYC",
IoRegisters.DMA => "IO:DMA",
IoRegisters.BGP => "IO:BGP",
IoRegisters.OBP0 => "IO:OBP0",
IoRegisters.OBP1 => "IO:OBP1",
IoRegisters.WY => "IO:WY",
IoRegisters.WX => "IO:WX",
// Sound Registers
IoRegisters.NR10 => "NR10",
IoRegisters.NR11 => "NR11",
IoRegisters.NR12 => "NR12",
IoRegisters.NR13 => "NR13",
IoRegisters.NR14 => "NR14",
IoRegisters.NR21 => "NR21",
IoRegisters.NR22 => "NR22",
IoRegisters.NR23 => "NR23",
IoRegisters.NR24 => "NR24",
IoRegisters.NR30 => "NR30",
IoRegisters.NR31 => "NR31",
IoRegisters.NR32 => "NR32",
IoRegisters.NR33 => "NR33",
IoRegisters.NR34 => "NR34",
IoRegisters.NR41 => "NR41",
IoRegisters.NR42 => "NR42",
IoRegisters.NR43 => "NR43",
IoRegisters.NR44 => "NR44",
IoRegisters.NR50 => "NR50",
IoRegisters.NR51 => "NR51",
IoRegisters.NR52 => "NR52",
IoRegisters.WAVE_PATTERN_RAM_START => "WAVE_PATTERN_RAM_START",
IoRegisters.WAVE_PATTERN_RAM_END => "WAVE_PATTERN_RAM_END",
IoRegisters.NR10 => "IO:NR10",
IoRegisters.NR11 => "IO:NR11",
IoRegisters.NR12 => "IO:NR12",
IoRegisters.NR13 => "IO:NR13",
IoRegisters.NR14 => "IO:NR14",
IoRegisters.NR21 => "IO:NR21",
IoRegisters.NR22 => "IO:NR22",
IoRegisters.NR23 => "IO:NR23",
IoRegisters.NR24 => "IO:NR24",
IoRegisters.NR30 => "IO:NR30",
IoRegisters.NR31 => "IO:NR31",
IoRegisters.NR32 => "IO:NR32",
IoRegisters.NR33 => "IO:NR33",
IoRegisters.NR34 => "IO:NR34",
IoRegisters.NR41 => "IO:NR41",
IoRegisters.NR42 => "IO:NR42",
IoRegisters.NR43 => "IO:NR43",
IoRegisters.NR44 => "IO:NR44",
IoRegisters.NR50 => "IO:NR50",
IoRegisters.NR51 => "IO:NR51",
IoRegisters.NR52 => "IO:NR52",
IoRegisters.WAVE_PATTERN_RAM_START => $"IO:WAVE_PATTERN_RAM+0",
IoRegisters.WAVE_PATTERN_RAM_START + 1 => $"IO:WAVE_PATTERN_RAM+1",
IoRegisters.WAVE_PATTERN_RAM_START + 2 => $"IO:WAVE_PATTERN_RAM+2",
IoRegisters.WAVE_PATTERN_RAM_START + 3 => $"IO:WAVE_PATTERN_RAM+3",
IoRegisters.WAVE_PATTERN_RAM_START + 4 => $"IO:WAVE_PATTERN_RAM+4",
IoRegisters.WAVE_PATTERN_RAM_START + 5 => $"IO:WAVE_PATTERN_RAM+5",
IoRegisters.WAVE_PATTERN_RAM_START + 6 => $"IO:WAVE_PATTERN_RAM+6",
IoRegisters.WAVE_PATTERN_RAM_START + 7 => $"IO:WAVE_PATTERN_RAM+7",
IoRegisters.WAVE_PATTERN_RAM_START + 8 => $"IO:WAVE_PATTERN_RAM+8",
IoRegisters.WAVE_PATTERN_RAM_START + 9 => $"IO:WAVE_PATTERN_RAM+9",
IoRegisters.WAVE_PATTERN_RAM_START + 10 => $"IO:WAVE_PATTERN_RAM+A",
IoRegisters.WAVE_PATTERN_RAM_START + 11 => $"IO:WAVE_PATTERN_RAM+B",
IoRegisters.WAVE_PATTERN_RAM_START + 12 => $"IO:WAVE_PATTERN_RAM+C",
IoRegisters.WAVE_PATTERN_RAM_START + 13 => $"IO:WAVE_PATTERN_RAM+D",
IoRegisters.WAVE_PATTERN_RAM_START + 14 => $"IO:WAVE_PATTERN_RAM+E",
IoRegisters.WAVE_PATTERN_RAM_END => "IO:WAVE_PATTERN_RAM+F",
// Boot rom control
IoRegisters.BOOT_DISABLE => "BOOT_DISABLE",
_ => $"{value:x2}",
IoRegisters.BOOT_DISABLE => "IO:BOOT_DISABLE",
_ => $"FF{value:x2}H",
};
private static string CC(int flag) => flag switch
@@ -271,7 +285,7 @@ namespace LR35902
var indexedImmediate = this.Bus.Peek((ushort)(pc + 1));
var dumpCount = 0;
var ioRegister = IoRegister.Unused;
//var ioRegister = IoRegister.Unused;
var output = $"{opCode:x2}";
@@ -282,7 +296,7 @@ namespace LR35902
}
else
{
output += this.DisassembleOther(cpu, pc, ref specification, ref dumpCount, ref ioRegister, x, y, z, p, q);
output += this.DisassembleOther(cpu, pc, ref specification, ref dumpCount, /*ref ioRegister, */x, y, z, p, q);
}
for (var i = 0; i < dumpCount; ++i)
@@ -291,29 +305,29 @@ namespace LR35902
}
output += '\t';
output += string.Format(CultureInfo.InvariantCulture, specification, (int)immediate, (int)absolute, relative, (int)displacement, indexedImmediate);
output += string.Format(CultureInfo.InvariantCulture, specification, (int)immediate, (int)absolute, relative, (int)displacement, indexedImmediate, IO(immediate));
switch (ioRegister)
{
case IoRegister.Abbreviated:
output += $"; register {IO(immediate)}";
break;
case IoRegister.Absolute:
output += "; register (Absolute)";
break;
case IoRegister.Register:
output += $"; register C:{IO(cpu.C)}";
break;
case IoRegister.Unused:
break;
default:
break;
}
//switch (ioRegister)
//{
// case IoRegister.Abbreviated:
// output += $"; register {IO(immediate)}";
// break;
// case IoRegister.Absolute:
// output += "; register (Absolute)";
// break;
// case IoRegister.Register:
// output += $"; register C:{IO(cpu.C)}";
// break;
// case IoRegister.Unused:
// break;
// default:
// break;
//}
return output;
}
private string DisassembleOther(LR35902 cpu, ushort pc, ref string specification, ref int dumpCount, ref IoRegister ioRegister, int x, int y, int z, int p, int q)
private string DisassembleOther(LR35902 cpu, ushort pc, ref string specification, ref int dumpCount, /*ref IoRegister ioRegister, */int x, int y, int z, int p, int q)
{
var output = string.Empty;
switch (x)
@@ -496,8 +510,9 @@ namespace LR35902
specification = $"RET {CC(y)}";
break;
case 4:
specification = "LD (FF00H+{0:X2}H),A";
ioRegister = IoRegister.Abbreviated;
//specification = "LD (FF00H+{0:X2}H),A";
specification = "LD ({5}),A";
//ioRegister = IoRegister.Abbreviated;
dumpCount++;
break;
case 5:
@@ -505,8 +520,9 @@ namespace LR35902
dumpCount++;
break;
case 6:
specification = "LD A,(FF00H+{0:X2}H)";
ioRegister = IoRegister.Abbreviated;
//specification = "LD A,(FF00H+{0:X2}H)";
specification = "LD A,({5})";
//ioRegister = IoRegister.Abbreviated;
dumpCount++;
break;
case 7:
@@ -561,7 +577,7 @@ namespace LR35902
break;
case 4:
specification = "LD (FF00H+C),A";
ioRegister = IoRegister.Register;
//ioRegister = IoRegister.Register;
break;
case 5:
specification = "LD ({1:X4}H),A";
@@ -569,7 +585,7 @@ namespace LR35902
break;
case 6:
specification = "LD A,(FF00H+C)";
ioRegister = IoRegister.Register;
//ioRegister = IoRegister.Register;
break;
case 7:
specification = "LD A,({1:X4}H)";
+14 -14
View File
@@ -11,26 +11,26 @@ namespace LR35902.BlarggTest
var configuration = new Configuration();
#if DEBUG
////configuration.DebugMode = true;
configuration.DebugMode = true;
#endif
////configuration.DebugMode = true;
//configuration.DebugMode = true;
var computer = new Computer(configuration);
//computer.Plug("blargg/cpu_instrs.gb"); // Passed
////computer.Plug("blargg/01-special.gb"); // Passed
////computer.Plug("blargg/02-interrupts.gb"); // Passed
////computer.Plug("blargg/03-op sp,hl.gb"); // Passed
////computer.Plug("blargg/04-op r,imm.gb"); // Passed
////computer.Plug("blargg/05-op rp.gb"); // Passed
////computer.Plug("blargg/06-ld r,r.gb"); // Passed
////computer.Plug("blargg/07-jr,jp,call,ret,rst.gb"); // Passed
////computer.Plug("blargg/08-misc instrs.gb"); // Passed
////computer.Plug("blargg/09-op r,r.gb"); // Passed
////computer.Plug("blargg/10-bit ops.gb"); // Passed
////computer.Plug("blargg/11-op a,(hl).gb"); // Passed
//computer.Plug("blargg/01-special.gb"); // Passed
computer.Plug("blargg/02-interrupts.gb"); // Passed
//computer.Plug("blargg/03-op sp,hl.gb"); // Passed
//computer.Plug("blargg/04-op r,imm.gb"); // Passed
//computer.Plug("blargg/05-op rp.gb"); // Passed
//computer.Plug("blargg/06-ld r,r.gb"); // Passed
//computer.Plug("blargg/07-jr,jp,call,ret,rst.gb"); // Passed
//computer.Plug("blargg/08-misc instrs.gb"); // Passed
//computer.Plug("blargg/09-op r,r.gb"); // Passed
//computer.Plug("blargg/10-bit ops.gb"); // Passed
//computer.Plug("blargg/11-op a,(hl).gb"); // Passed
computer.Plug("blargg/instr_timing.gb"); // Failed #255
//computer.Plug("blargg/instr_timing.gb"); // Passed
//computer.Plug("blargg/interrupt_time.gb"); // Failed
computer.RaisePOWER();
+13 -1
View File
@@ -13,6 +13,8 @@ namespace LR35902
{
this.bus = bus;
this.RaisedPOWER += this.LR35902_RaisedPOWER;
this.LoweringHALT += this.LR35902_LoweringHALT;
this.RaisedHALT += this.LR35902_RaisedHALT;
}
private void LR35902_RaisedPOWER(object? sender, EventArgs e)
@@ -22,6 +24,16 @@ namespace LR35902
this.RaiseMWR();
}
private void LR35902_RaisedHALT(object? sender, EventArgs e)
{
++this.PC.Word; // Release the PC from HALT instruction
}
private void LR35902_LoweringHALT(object? sender, EventArgs e)
{
--this.PC.Word; // Keep the PC on the HALT instruction (i.e. executing NOP)
}
private readonly Bus bus;
private readonly Register16 af = new((int)Mask.Sixteen);
private bool prefixCB;
@@ -677,8 +689,8 @@ namespace LR35902
if (z == 6 && y == 6)
{
this.LowerHALT(); // Exception (replaces LD (HL), (HL))
this.PC.Word++;
this.TickMachine(2);
//this.PC.Word++;
}
else
{
-1
View File
@@ -308,7 +308,6 @@
}
}
private void Runner_ReadByte(object? sender, EventArgs e) => this.AddActualCycle(this.Runner.Address, this.Runner.Data, "r-m");
private void Runner_WrittenByte(object? sender, EventArgs e) => this.AddActualCycle(this.Runner.Address, this.Runner.Data, "-wm");
+1 -1
View File
@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<AnalysisLevel>latest-all</AnalysisLevel>
<AnalysisLevel>latest-recommended</AnalysisLevel>
</PropertyGroup>
<ItemGroup>
+8 -7
View File
@@ -90,12 +90,12 @@ namespace M6502
case 0x8f: this.AbsoluteAddress(); this.SAX(); break; // *SAX (absolute)
case 0x92: this.Jam(); break; // *JAM
case 0x93: this.IndirectIndexedYAddress(); this.Fixup(); this.SHA(); break; // *SHA (indirect indexed, Y)
case 0x93: this.IndirectIndexedYAddress(); this.Fixup(); this.SHA(); break; // *SHA (indirect indexed, Y) (XXXX)
case 0x97: this.ZeroPageYAddress(); this.SAX(); break; // *SAX (zero page, Y)
case 0x9b: this.AbsoluteYAddress(); this.Fixup(); this.TAS(); break; // *TAS (absolute, Y)
case 0x9c: this.AbsoluteXAddress(); this.Fixup(); this.SYA(); break; // *SYA (absolute, X)
case 0x9e: this.AbsoluteYAddress(); this.Fixup(); this.SXA(); break; // *SXA (absolute, Y)
case 0x9f: this.AbsoluteYAddress(); this.Fixup(); this.SHA(); break; // *SHA (absolute, Y)
case 0x9b: this.AbsoluteYAddress(); this.Fixup(); this.TAS(); break; // *TAS (absolute, Y) (XXXX)
case 0x9c: this.AbsoluteXAddress(); this.Fixup(); this.SYA(); break; // *SYA (absolute, X) (XXXX)
case 0x9e: this.AbsoluteYAddress(); this.Fixup(); this.SXA(); break; // *SXA (absolute, Y) (XXXX)
case 0x9f: this.AbsoluteYAddress(); this.Fixup(); this.SHA(); break; // *SHA (absolute, Y) (XXXX)
case 0xa3: this.IndexedIndirectXRead(); this.LAX(); break; // *LAX (indexed indirect X)
case 0xa7: this.ZeroPageRead(); this.LAX(); break; // *LAX (zero page)
@@ -239,13 +239,14 @@ namespace M6502
if (this.Fixed)
{
updated = (byte)(data & this.FixedPage);
this.Bus.Address.High = updated;
//this.Bus.Address.High = updated;
}
else
{
updated = (byte)(data & this.UnfixedPage);
this.Bus.Address.High = updated;
//this.Bus.Address.High = updated;
}
this.Bus.Address.High = updated;
this.MemoryWrite(updated);
}
@@ -18,10 +18,6 @@
<WarningLevel>9999</WarningLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSTest.TestFramework" Version="3.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\EightBit\EightBit.csproj" />
<ProjectReference Include="..\MC6809.csproj" />
+4 -1
View File
@@ -6,7 +6,10 @@
public IEnumerable<OpcodeTestSuite> OpcodeTests()
{
foreach (var filename in Directory.EnumerateFiles(this.Location, "0?.json"))
//var pattern = "fd 7e.json";
//var pattern = "7e.json";
var pattern = "*.json";
foreach (var filename in Directory.EnumerateFiles(this.Location, pattern))
{
var fileInformation = new FileInfo(filename);
if (fileInformation.Length > 0)
+8 -8
View File
@@ -861,6 +861,8 @@ namespace Z80
case 1: // BIT y, r[z]
this.BIT(y, operand);
this.F = AdjustXY(this.F, direct ? operand : this.MEMPTR.High);
if (indirect)
this.Tick();
break;
case 2: // RES y, r[z]
operand = RES(y, operand);
@@ -1437,12 +1439,8 @@ namespace Z80
if (normal)
{
if (this._displaced)
{
this.Tick(5);
}
this.R(y, this.R(z));
var value = this.R(z);
this.R(y, value);
}
}
else
@@ -1456,7 +1454,7 @@ namespace Z80
if (memoryZ && this._displaced)
{
this.FetchDisplacement();
this.Tick(5);
this.Tick(4);
}
var value = this.R(z);
@@ -2262,12 +2260,14 @@ namespace Z80
private void WritePort()
{
this.Tick();
this.Tick(2);
this.LowerIORQ();
this.LowerWR();
this._ports.Write(this.Bus.Address.Low, this.Bus.Data);
this.Tick();
this.RaiseWR();
this.RaiseIORQ();
this.Tick();
}
private void ReadPort(byte port)