I am writing a Z80 Emulator in C#, second time. First time was incredibly slow using a bunch of if statements and function calls, so I am rewriting using using switch/case instead. VS2019 C# .NET 4
For simple instruction execution there aren't many lines of code, but some instructions pretty much require tons of code and adding so much code inline makes the code difficult to read.
So I am wondering whether to use function calls for the flags, especially the ones that require a lot of code or take the line count hit for the sake of speed.
ex:
case 188:
byteCount = 1;
mnemonic = "CP H ";
dest = int.Parse(txtRegA.Text, System.Globalization.NumberStyles.HexNumber);
src = int.Parse(txtRegH.Text, System.Globalization.NumberStyles.HexNumber);
result = dest - src;
// Zero Flag
if (result == 0) { ZeroFlag.Text = "1"; } else { ZeroFlag.Text = "0"; }
// Carry Flag
if (dest < result) { CarryFlag.Text = "1"; } else { CarryFlag.Text = "0"; }
SignFlag.Text = "1";
//N Flag
if (result > 127) { AddSubFlag.Text = "1"; } else { AddSubFlag.Text = "0"; }
// Overflow
//Subtract
if ((src>127 & dest >127) | ( src< 127 & dest <127)) { POFlag.Text = "0"; } else { POFlag.Text = "1"; }
// Add
//if ((src > 127 & dest <= 127) | (src < 127 & dest >= 127)) { POFlag.Text = "0"; } else { POFlag.Text = "1"; }
// Half Carry - Note: The Registers are already in HEX format
dest = Convert.ToInt32(txtRegA.Text.Substring(4, 4));
src = Convert.ToInt32(txtRegH.Text.Substring(4, 4));
// Subtract
if (dest < src) { HalfCarryFlag.Text = "1"; } else { HalfCarryFlag.Text = "0"; }
// Add
//result = dest + src;
//if ((dest + src)>31) { HalfCarryFlag.Text = "1"; } else { HalfCarryFlag.Text = "1"; }
run = true;
break;
I am not at all sure about whether my half carry and overflow flags will work properly at all.
Not all instructions affect all flags so some in-line will be better. But, the multi-line flags...
Thoughts comments
The golden rule of optimization is to profile first. Sometimes formulated as Premature optimization is the root of all evil:
Over time you tend to get a little bit better at guessing what will be slow or not. I would observe that it looks like your code is doing a few different things:
Each of these things are order of magnitudes different with regards to performance. Something like updating the UI is many order of magnitudes slower than a simple method call.
My recommendations would be to
You might also consider running the emulation on a background thread, but doing so will require your program to be thread safe. So I would only consider this if you are familiar with thread safety, or are prepared to learn about it before you attempt it.