Implemented many more OpCodes
This commit is contained in:
@@ -50,13 +50,33 @@ namespace Core.Cpu
|
|||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
PC = 0x0000;
|
PC = 0x0000;
|
||||||
// The Z80 initializes SP to 0xFFFF on boot
|
SP = 0xFFFF; // The Z80 initializes SP to 0xFFFF on boot
|
||||||
SP = 0xFFFF;
|
|
||||||
|
|
||||||
|
// Main Registers
|
||||||
AF.Word = 0;
|
AF.Word = 0;
|
||||||
BC.Word = 0;
|
BC.Word = 0;
|
||||||
DE.Word = 0;
|
DE.Word = 0;
|
||||||
HL.Word = 0;
|
HL.Word = 0;
|
||||||
|
|
||||||
|
// Alternate Registers
|
||||||
|
AF_Prime.Word = 0;
|
||||||
|
BC_Prime.Word = 0;
|
||||||
|
DE_Prime.Word = 0;
|
||||||
|
HL_Prime.Word = 0;
|
||||||
|
|
||||||
|
// Index Registers
|
||||||
|
IX.Word = 0;
|
||||||
|
IY.Word = 0;
|
||||||
|
|
||||||
|
// Internal Registers
|
||||||
|
I = 0;
|
||||||
|
R = 0;
|
||||||
|
|
||||||
|
// Hardware State
|
||||||
|
IFF1 = false;
|
||||||
|
IFF2 = false;
|
||||||
|
InterruptMode = 0;
|
||||||
|
TotalTStates = 0; // Reset the system clock!
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Step()
|
public int Step()
|
||||||
@@ -96,6 +116,36 @@ namespace Core.Cpu
|
|||||||
$"C:{f & 1}";
|
$"C:{f & 1}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Sub(byte value)
|
||||||
|
{
|
||||||
|
byte a = AF.High;
|
||||||
|
int result = a - value;
|
||||||
|
|
||||||
|
// Save the result back to the Accumulator
|
||||||
|
AF.High = (byte)result;
|
||||||
|
|
||||||
|
// --- Update Flags (F Register) ---
|
||||||
|
AF.Low = 0; // Clear all flags
|
||||||
|
|
||||||
|
// Sign Flag (Bit 7)
|
||||||
|
if ((result & 0x80) != 0) AF.Low |= 0x80;
|
||||||
|
|
||||||
|
// Zero Flag (Bit 6)
|
||||||
|
if ((byte)result == 0) AF.Low |= 0x40;
|
||||||
|
|
||||||
|
// Half-Carry Flag (Bit 4) - Set if borrow from bit 4
|
||||||
|
if (((a & 0x0F) - (value & 0x0F)) < 0) AF.Low |= 0x10;
|
||||||
|
|
||||||
|
// Overflow Flag (Bit 2) - Set if operands have different signs and result sign changes
|
||||||
|
if ((((a ^ value) & 0x80) != 0) && (((a ^ result) & 0x80) != 0)) AF.Low |= 0x04;
|
||||||
|
|
||||||
|
// Subtract Flag (Bit 1) - ALWAYS set for CP/SUB
|
||||||
|
AF.Low |= 0x02;
|
||||||
|
|
||||||
|
// Carry Flag (Bit 0) - Set if the overall result dropped below 0
|
||||||
|
if (result < 0) AF.Low |= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
private void Sbc(byte value)
|
private void Sbc(byte value)
|
||||||
{
|
{
|
||||||
byte a = AF.High;
|
byte a = AF.High;
|
||||||
@@ -309,6 +359,17 @@ namespace Core.Cpu
|
|||||||
_memory.Write(SP, (byte)(value & 0xFF));
|
_memory.Write(SP, (byte)(value & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ushort Pop()
|
||||||
|
{
|
||||||
|
// The Z80 is Little-Endian. Low byte comes off the stack first.
|
||||||
|
byte low = _memory.Read(SP++);
|
||||||
|
|
||||||
|
// High byte comes off second.
|
||||||
|
byte high = _memory.Read(SP++);
|
||||||
|
|
||||||
|
return (ushort)((high << 8) | low);
|
||||||
|
}
|
||||||
|
|
||||||
private int ExecuteOpcode(byte opcode)
|
private int ExecuteOpcode(byte opcode)
|
||||||
{
|
{
|
||||||
sbyte offset = 0;
|
sbyte offset = 0;
|
||||||
@@ -340,6 +401,9 @@ namespace Core.Cpu
|
|||||||
case 0x11: //LD DE, nn
|
case 0x11: //LD DE, nn
|
||||||
DE.Word = FetchWord();
|
DE.Word = FetchWord();
|
||||||
return 10;
|
return 10;
|
||||||
|
case 0x16: // LD D, n
|
||||||
|
DE.High = FetchByte();
|
||||||
|
return 7;
|
||||||
case 0x19: // ADD HL, DE
|
case 0x19: // ADD HL, DE
|
||||||
Add16(DE.Word);
|
Add16(DE.Word);
|
||||||
return 11;
|
return 11;
|
||||||
@@ -429,9 +493,15 @@ namespace Core.Cpu
|
|||||||
case 0x77: // LD (HL), A
|
case 0x77: // LD (HL), A
|
||||||
_memory.Write(HL.Word, AF.High);
|
_memory.Write(HL.Word, AF.High);
|
||||||
return 7;
|
return 7;
|
||||||
|
case 0x91: // SUB C
|
||||||
|
Sub(BC.Low);
|
||||||
|
return 4; // Takes 4 T-States
|
||||||
case 0xA7: // AND A
|
case 0xA7: // AND A
|
||||||
And(AF.High);
|
And(AF.High);
|
||||||
return 4;
|
return 4;
|
||||||
|
case 0x5F: // LD E, A
|
||||||
|
DE.Low = AF.High;
|
||||||
|
return 4;
|
||||||
case 0xAF: // XOR A
|
case 0xAF: // XOR A
|
||||||
AF.High = 0;
|
AF.High = 0;
|
||||||
AF.Low = 0x44;
|
AF.Low = 0x44;
|
||||||
@@ -442,6 +512,9 @@ namespace Core.Cpu
|
|||||||
case 0xC3:
|
case 0xC3:
|
||||||
PC = FetchWord();
|
PC = FetchWord();
|
||||||
return 10;
|
return 10;
|
||||||
|
case 0xC9: // RET
|
||||||
|
PC = Pop();
|
||||||
|
return 10;
|
||||||
case 0xCD: // CALL nn
|
case 0xCD: // CALL nn
|
||||||
ushort callAddress = FetchWord();
|
ushort callAddress = FetchWord();
|
||||||
Push(PC);
|
Push(PC);
|
||||||
@@ -604,6 +677,24 @@ namespace Core.Cpu
|
|||||||
byte decVal = Dec8(memVal);
|
byte decVal = Dec8(memVal);
|
||||||
_memory.Write(targetAddress, decVal);
|
_memory.Write(targetAddress, decVal);
|
||||||
return 23;
|
return 23;
|
||||||
|
case 0x36: // LD (IY+d), n
|
||||||
|
{
|
||||||
|
sbyte offset36 = (sbyte)FetchByte();
|
||||||
|
byte nValue = FetchByte();
|
||||||
|
targetAddress = (ushort)(IY.Word + offset36);
|
||||||
|
|
||||||
|
_memory.Write(targetAddress, nValue);
|
||||||
|
return 19; // Takes 19 T-States
|
||||||
|
}
|
||||||
|
case 0x71: // LD (IY+d), C
|
||||||
|
{
|
||||||
|
sbyte offset71 = (sbyte)FetchByte();
|
||||||
|
targetAddress = (ushort)(IY.Word + offset71);
|
||||||
|
|
||||||
|
// Write the C register (low byte of BC) to memory
|
||||||
|
_memory.Write(targetAddress, BC.Low);
|
||||||
|
return 19; // Takes 19 T-States
|
||||||
|
}
|
||||||
case 0x75: // LD (IY+d), L
|
case 0x75: // LD (IY+d), L
|
||||||
sbyte offset75 = (sbyte)FetchByte();
|
sbyte offset75 = (sbyte)FetchByte();
|
||||||
targetAddress = (ushort)(IY.Word + offset75);
|
targetAddress = (ushort)(IY.Word + offset75);
|
||||||
|
|||||||
@@ -42,5 +42,10 @@ namespace Core.Memory
|
|||||||
// Copy the ROM
|
// Copy the ROM
|
||||||
Array.Copy(romData, 0, _memory, 0, romData.Length);
|
Array.Copy(romData, 0, _memory, 0, romData.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearRam()
|
||||||
|
{
|
||||||
|
//To Do
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
121
Desktop/DebuggerForm.Designer.cs
generated
121
Desktop/DebuggerForm.Designer.cs
generated
@@ -53,94 +53,95 @@
|
|||||||
lblIff1 = new Label();
|
lblIff1 = new Label();
|
||||||
lblIff2 = new Label();
|
lblIff2 = new Label();
|
||||||
lblIE = new Label();
|
lblIE = new Label();
|
||||||
|
btnReset = new Button();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// lblAF
|
// lblAF
|
||||||
//
|
//
|
||||||
lblAF.AutoSize = true;
|
lblAF.AutoSize = true;
|
||||||
lblAF.Location = new Point(10, 7);
|
lblAF.Location = new Point(12, 9);
|
||||||
lblAF.Margin = new Padding(2, 0, 2, 0);
|
lblAF.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblAF.Name = "lblAF";
|
lblAF.Name = "lblAF";
|
||||||
lblAF.Size = new Size(26, 20);
|
lblAF.Size = new Size(33, 25);
|
||||||
lblAF.TabIndex = 0;
|
lblAF.TabIndex = 0;
|
||||||
lblAF.Text = "AF";
|
lblAF.Text = "AF";
|
||||||
//
|
//
|
||||||
// lblBC
|
// lblBC
|
||||||
//
|
//
|
||||||
lblBC.AutoSize = true;
|
lblBC.AutoSize = true;
|
||||||
lblBC.Location = new Point(9, 48);
|
lblBC.Location = new Point(11, 60);
|
||||||
lblBC.Margin = new Padding(2, 0, 2, 0);
|
lblBC.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblBC.Name = "lblBC";
|
lblBC.Name = "lblBC";
|
||||||
lblBC.Size = new Size(27, 20);
|
lblBC.Size = new Size(33, 25);
|
||||||
lblBC.TabIndex = 1;
|
lblBC.TabIndex = 1;
|
||||||
lblBC.Text = "BC";
|
lblBC.Text = "BC";
|
||||||
//
|
//
|
||||||
// lblDE
|
// lblDE
|
||||||
//
|
//
|
||||||
lblDE.AutoSize = true;
|
lblDE.AutoSize = true;
|
||||||
lblDE.Location = new Point(10, 100);
|
lblDE.Location = new Point(12, 125);
|
||||||
lblDE.Margin = new Padding(2, 0, 2, 0);
|
lblDE.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblDE.Name = "lblDE";
|
lblDE.Name = "lblDE";
|
||||||
lblDE.Size = new Size(28, 20);
|
lblDE.Size = new Size(34, 25);
|
||||||
lblDE.TabIndex = 2;
|
lblDE.TabIndex = 2;
|
||||||
lblDE.Text = "DE";
|
lblDE.Text = "DE";
|
||||||
//
|
//
|
||||||
// lblHL
|
// lblHL
|
||||||
//
|
//
|
||||||
lblHL.AutoSize = true;
|
lblHL.AutoSize = true;
|
||||||
lblHL.Location = new Point(10, 150);
|
lblHL.Location = new Point(12, 188);
|
||||||
lblHL.Margin = new Padding(2, 0, 2, 0);
|
lblHL.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblHL.Name = "lblHL";
|
lblHL.Name = "lblHL";
|
||||||
lblHL.Size = new Size(27, 20);
|
lblHL.Size = new Size(33, 25);
|
||||||
lblHL.TabIndex = 3;
|
lblHL.TabIndex = 3;
|
||||||
lblHL.Text = "HL";
|
lblHL.Text = "HL";
|
||||||
//
|
//
|
||||||
// lblPC
|
// lblPC
|
||||||
//
|
//
|
||||||
lblPC.AutoSize = true;
|
lblPC.AutoSize = true;
|
||||||
lblPC.Location = new Point(9, 200);
|
lblPC.Location = new Point(11, 250);
|
||||||
lblPC.Margin = new Padding(2, 0, 2, 0);
|
lblPC.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblPC.Name = "lblPC";
|
lblPC.Name = "lblPC";
|
||||||
lblPC.Size = new Size(26, 20);
|
lblPC.Size = new Size(33, 25);
|
||||||
lblPC.TabIndex = 4;
|
lblPC.TabIndex = 4;
|
||||||
lblPC.Text = "PC";
|
lblPC.Text = "PC";
|
||||||
//
|
//
|
||||||
// lblSP
|
// lblSP
|
||||||
//
|
//
|
||||||
lblSP.AutoSize = true;
|
lblSP.AutoSize = true;
|
||||||
lblSP.Location = new Point(9, 252);
|
lblSP.Location = new Point(11, 315);
|
||||||
lblSP.Margin = new Padding(2, 0, 2, 0);
|
lblSP.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblSP.Name = "lblSP";
|
lblSP.Name = "lblSP";
|
||||||
lblSP.Size = new Size(25, 20);
|
lblSP.Size = new Size(32, 25);
|
||||||
lblSP.TabIndex = 6;
|
lblSP.TabIndex = 6;
|
||||||
lblSP.Text = "SP";
|
lblSP.Text = "SP";
|
||||||
//
|
//
|
||||||
// lblFlags
|
// lblFlags
|
||||||
//
|
//
|
||||||
lblFlags.AutoSize = true;
|
lblFlags.AutoSize = true;
|
||||||
lblFlags.Location = new Point(88, 52);
|
lblFlags.Location = new Point(110, 65);
|
||||||
lblFlags.Margin = new Padding(2, 0, 2, 0);
|
lblFlags.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblFlags.Name = "lblFlags";
|
lblFlags.Name = "lblFlags";
|
||||||
lblFlags.Size = new Size(43, 20);
|
lblFlags.Size = new Size(53, 25);
|
||||||
lblFlags.TabIndex = 7;
|
lblFlags.TabIndex = 7;
|
||||||
lblFlags.Text = "Flags";
|
lblFlags.Text = "Flags";
|
||||||
//
|
//
|
||||||
// lblTStates
|
// lblTStates
|
||||||
//
|
//
|
||||||
lblTStates.AutoSize = true;
|
lblTStates.AutoSize = true;
|
||||||
lblTStates.Location = new Point(88, 7);
|
lblTStates.Location = new Point(110, 9);
|
||||||
lblTStates.Margin = new Padding(2, 0, 2, 0);
|
lblTStates.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblTStates.Name = "lblTStates";
|
lblTStates.Name = "lblTStates";
|
||||||
lblTStates.Size = new Size(63, 20);
|
lblTStates.Size = new Size(75, 25);
|
||||||
lblTStates.TabIndex = 8;
|
lblTStates.TabIndex = 8;
|
||||||
lblTStates.Text = "T-States";
|
lblTStates.Text = "T-States";
|
||||||
//
|
//
|
||||||
// txtMemoryStart
|
// txtMemoryStart
|
||||||
//
|
//
|
||||||
txtMemoryStart.Location = new Point(300, 21);
|
txtMemoryStart.Location = new Point(375, 26);
|
||||||
txtMemoryStart.Margin = new Padding(2);
|
txtMemoryStart.Margin = new Padding(2);
|
||||||
txtMemoryStart.Name = "txtMemoryStart";
|
txtMemoryStart.Name = "txtMemoryStart";
|
||||||
txtMemoryStart.Size = new Size(121, 27);
|
txtMemoryStart.Size = new Size(150, 31);
|
||||||
txtMemoryStart.TabIndex = 9;
|
txtMemoryStart.TabIndex = 9;
|
||||||
txtMemoryStart.Text = "Memory Start";
|
txtMemoryStart.Text = "Memory Start";
|
||||||
txtMemoryStart.TextAlign = HorizontalAlignment.Center;
|
txtMemoryStart.TextAlign = HorizontalAlignment.Center;
|
||||||
@@ -148,10 +149,10 @@
|
|||||||
//
|
//
|
||||||
// btnStep
|
// btnStep
|
||||||
//
|
//
|
||||||
btnStep.Location = new Point(6, 418);
|
btnStep.Location = new Point(8, 522);
|
||||||
btnStep.Margin = new Padding(2);
|
btnStep.Margin = new Padding(2);
|
||||||
btnStep.Name = "btnStep";
|
btnStep.Name = "btnStep";
|
||||||
btnStep.Size = new Size(90, 27);
|
btnStep.Size = new Size(112, 34);
|
||||||
btnStep.TabIndex = 12;
|
btnStep.TabIndex = 12;
|
||||||
btnStep.Text = "Step";
|
btnStep.Text = "Step";
|
||||||
btnStep.UseVisualStyleBackColor = true;
|
btnStep.UseVisualStyleBackColor = true;
|
||||||
@@ -159,10 +160,10 @@
|
|||||||
//
|
//
|
||||||
// btnRun
|
// btnRun
|
||||||
//
|
//
|
||||||
btnRun.Location = new Point(119, 418);
|
btnRun.Location = new Point(149, 522);
|
||||||
btnRun.Margin = new Padding(2);
|
btnRun.Margin = new Padding(2);
|
||||||
btnRun.Name = "btnRun";
|
btnRun.Name = "btnRun";
|
||||||
btnRun.Size = new Size(90, 27);
|
btnRun.Size = new Size(112, 34);
|
||||||
btnRun.TabIndex = 13;
|
btnRun.TabIndex = 13;
|
||||||
btnRun.Text = "Run";
|
btnRun.Text = "Run";
|
||||||
btnRun.UseVisualStyleBackColor = true;
|
btnRun.UseVisualStyleBackColor = true;
|
||||||
@@ -170,10 +171,10 @@
|
|||||||
//
|
//
|
||||||
// btnRefreshMemory
|
// btnRefreshMemory
|
||||||
//
|
//
|
||||||
btnRefreshMemory.Location = new Point(425, 21);
|
btnRefreshMemory.Location = new Point(531, 26);
|
||||||
btnRefreshMemory.Margin = new Padding(2);
|
btnRefreshMemory.Margin = new Padding(2);
|
||||||
btnRefreshMemory.Name = "btnRefreshMemory";
|
btnRefreshMemory.Name = "btnRefreshMemory";
|
||||||
btnRefreshMemory.Size = new Size(90, 27);
|
btnRefreshMemory.Size = new Size(112, 34);
|
||||||
btnRefreshMemory.TabIndex = 14;
|
btnRefreshMemory.TabIndex = 14;
|
||||||
btnRefreshMemory.Text = "Refresh Memory";
|
btnRefreshMemory.Text = "Refresh Memory";
|
||||||
btnRefreshMemory.UseVisualStyleBackColor = true;
|
btnRefreshMemory.UseVisualStyleBackColor = true;
|
||||||
@@ -181,37 +182,39 @@
|
|||||||
//
|
//
|
||||||
// txtMemoryView
|
// txtMemoryView
|
||||||
//
|
//
|
||||||
txtMemoryView.Location = new Point(88, 80);
|
txtMemoryView.Location = new Point(110, 100);
|
||||||
txtMemoryView.Margin = new Padding(2);
|
txtMemoryView.Margin = new Padding(2);
|
||||||
txtMemoryView.Name = "txtMemoryView";
|
txtMemoryView.Name = "txtMemoryView";
|
||||||
txtMemoryView.Size = new Size(416, 195);
|
txtMemoryView.Size = new Size(519, 243);
|
||||||
txtMemoryView.TabIndex = 15;
|
txtMemoryView.TabIndex = 15;
|
||||||
txtMemoryView.Text = "Memory View Window";
|
txtMemoryView.Text = "Memory View Window";
|
||||||
//
|
//
|
||||||
// lstDisassembly
|
// lstDisassembly
|
||||||
//
|
//
|
||||||
lstDisassembly.FormattingEnabled = true;
|
lstDisassembly.FormattingEnabled = true;
|
||||||
lstDisassembly.Location = new Point(523, 11);
|
lstDisassembly.ItemHeight = 25;
|
||||||
|
lstDisassembly.Location = new Point(654, 14);
|
||||||
lstDisassembly.Margin = new Padding(2);
|
lstDisassembly.Margin = new Padding(2);
|
||||||
lstDisassembly.Name = "lstDisassembly";
|
lstDisassembly.Name = "lstDisassembly";
|
||||||
lstDisassembly.Size = new Size(252, 264);
|
lstDisassembly.Size = new Size(314, 329);
|
||||||
lstDisassembly.TabIndex = 16;
|
lstDisassembly.TabIndex = 16;
|
||||||
//
|
//
|
||||||
// lstStack
|
// lstStack
|
||||||
//
|
//
|
||||||
lstStack.FormattingEnabled = true;
|
lstStack.FormattingEnabled = true;
|
||||||
lstStack.Location = new Point(779, 11);
|
lstStack.ItemHeight = 25;
|
||||||
|
lstStack.Location = new Point(974, 14);
|
||||||
lstStack.Margin = new Padding(2);
|
lstStack.Margin = new Padding(2);
|
||||||
lstStack.Name = "lstStack";
|
lstStack.Name = "lstStack";
|
||||||
lstStack.Size = new Size(130, 264);
|
lstStack.Size = new Size(162, 329);
|
||||||
lstStack.TabIndex = 17;
|
lstStack.TabIndex = 17;
|
||||||
//
|
//
|
||||||
// btnExit
|
// btnExit
|
||||||
//
|
//
|
||||||
btnExit.Location = new Point(815, 416);
|
btnExit.Location = new Point(1019, 520);
|
||||||
btnExit.Margin = new Padding(2);
|
btnExit.Margin = new Padding(2);
|
||||||
btnExit.Name = "btnExit";
|
btnExit.Name = "btnExit";
|
||||||
btnExit.Size = new Size(90, 27);
|
btnExit.Size = new Size(112, 34);
|
||||||
btnExit.TabIndex = 18;
|
btnExit.TabIndex = 18;
|
||||||
btnExit.Text = "Full Exit";
|
btnExit.Text = "Full Exit";
|
||||||
btnExit.UseVisualStyleBackColor = true;
|
btnExit.UseVisualStyleBackColor = true;
|
||||||
@@ -220,80 +223,97 @@
|
|||||||
// label1
|
// label1
|
||||||
//
|
//
|
||||||
label1.AutoSize = true;
|
label1.AutoSize = true;
|
||||||
label1.Location = new Point(200, 278);
|
label1.Location = new Point(250, 348);
|
||||||
|
label1.Margin = new Padding(4, 0, 4, 0);
|
||||||
label1.Name = "label1";
|
label1.Name = "label1";
|
||||||
label1.Size = new Size(81, 20);
|
label1.Size = new Size(97, 25);
|
||||||
label1.TabIndex = 19;
|
label1.TabIndex = 19;
|
||||||
label1.Text = "Breakpoint";
|
label1.Text = "Breakpoint";
|
||||||
//
|
//
|
||||||
// txtBreakpoint
|
// txtBreakpoint
|
||||||
//
|
//
|
||||||
txtBreakpoint.Location = new Point(376, 281);
|
txtBreakpoint.Location = new Point(470, 351);
|
||||||
|
txtBreakpoint.Margin = new Padding(4);
|
||||||
txtBreakpoint.Name = "txtBreakpoint";
|
txtBreakpoint.Name = "txtBreakpoint";
|
||||||
txtBreakpoint.Size = new Size(125, 27);
|
txtBreakpoint.Size = new Size(155, 31);
|
||||||
txtBreakpoint.TabIndex = 20;
|
txtBreakpoint.TabIndex = 20;
|
||||||
//
|
//
|
||||||
// label2
|
// label2
|
||||||
//
|
//
|
||||||
label2.AutoSize = true;
|
label2.AutoSize = true;
|
||||||
label2.Location = new Point(233, 21);
|
label2.Location = new Point(291, 26);
|
||||||
|
label2.Margin = new Padding(4, 0, 4, 0);
|
||||||
label2.Name = "label2";
|
label2.Name = "label2";
|
||||||
label2.Size = new Size(62, 20);
|
label2.Size = new Size(77, 25);
|
||||||
label2.TabIndex = 21;
|
label2.TabIndex = 21;
|
||||||
label2.Text = "Address";
|
label2.Text = "Address";
|
||||||
//
|
//
|
||||||
// lblIX
|
// lblIX
|
||||||
//
|
//
|
||||||
lblIX.AutoSize = true;
|
lblIX.AutoSize = true;
|
||||||
lblIX.Location = new Point(9, 298);
|
lblIX.Location = new Point(11, 372);
|
||||||
lblIX.Margin = new Padding(2, 0, 2, 0);
|
lblIX.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblIX.Name = "lblIX";
|
lblIX.Name = "lblIX";
|
||||||
lblIX.Size = new Size(22, 20);
|
lblIX.Size = new Size(28, 25);
|
||||||
lblIX.TabIndex = 22;
|
lblIX.TabIndex = 22;
|
||||||
lblIX.Text = "IX";
|
lblIX.Text = "IX";
|
||||||
//
|
//
|
||||||
// lblIY
|
// lblIY
|
||||||
//
|
//
|
||||||
lblIY.AutoSize = true;
|
lblIY.AutoSize = true;
|
||||||
lblIY.Location = new Point(10, 344);
|
lblIY.Location = new Point(12, 430);
|
||||||
lblIY.Margin = new Padding(2, 0, 2, 0);
|
lblIY.Margin = new Padding(2, 0, 2, 0);
|
||||||
lblIY.Name = "lblIY";
|
lblIY.Name = "lblIY";
|
||||||
lblIY.Size = new Size(21, 20);
|
lblIY.Size = new Size(27, 25);
|
||||||
lblIY.TabIndex = 23;
|
lblIY.TabIndex = 23;
|
||||||
lblIY.Text = "IY";
|
lblIY.Text = "IY";
|
||||||
//
|
//
|
||||||
// lblIff1
|
// lblIff1
|
||||||
//
|
//
|
||||||
lblIff1.AutoSize = true;
|
lblIff1.AutoSize = true;
|
||||||
lblIff1.Location = new Point(88, 298);
|
lblIff1.Location = new Point(110, 372);
|
||||||
|
lblIff1.Margin = new Padding(4, 0, 4, 0);
|
||||||
lblIff1.Name = "lblIff1";
|
lblIff1.Name = "lblIff1";
|
||||||
lblIff1.Size = new Size(35, 20);
|
lblIff1.Size = new Size(45, 25);
|
||||||
lblIff1.TabIndex = 24;
|
lblIff1.TabIndex = 24;
|
||||||
lblIff1.Text = "IFF1";
|
lblIff1.Text = "IFF1";
|
||||||
//
|
//
|
||||||
// lblIff2
|
// lblIff2
|
||||||
//
|
//
|
||||||
lblIff2.AutoSize = true;
|
lblIff2.AutoSize = true;
|
||||||
lblIff2.Location = new Point(88, 345);
|
lblIff2.Location = new Point(110, 431);
|
||||||
|
lblIff2.Margin = new Padding(4, 0, 4, 0);
|
||||||
lblIff2.Name = "lblIff2";
|
lblIff2.Name = "lblIff2";
|
||||||
lblIff2.Size = new Size(35, 20);
|
lblIff2.Size = new Size(45, 25);
|
||||||
lblIff2.TabIndex = 25;
|
lblIff2.TabIndex = 25;
|
||||||
lblIff2.Text = "IFF2";
|
lblIff2.Text = "IFF2";
|
||||||
//
|
//
|
||||||
// lblIE
|
// lblIE
|
||||||
//
|
//
|
||||||
lblIE.AutoSize = true;
|
lblIE.AutoSize = true;
|
||||||
lblIE.Location = new Point(200, 345);
|
lblIE.Location = new Point(250, 431);
|
||||||
|
lblIE.Margin = new Padding(4, 0, 4, 0);
|
||||||
lblIE.Name = "lblIE";
|
lblIE.Name = "lblIE";
|
||||||
lblIE.Size = new Size(109, 20);
|
lblIE.Size = new Size(133, 25);
|
||||||
lblIE.TabIndex = 26;
|
lblIE.TabIndex = 26;
|
||||||
lblIE.Text = "Interrupt Mode";
|
lblIE.Text = "Interrupt Mode";
|
||||||
//
|
//
|
||||||
|
// btnReset
|
||||||
|
//
|
||||||
|
btnReset.Location = new Point(883, 520);
|
||||||
|
btnReset.Name = "btnReset";
|
||||||
|
btnReset.Size = new Size(112, 34);
|
||||||
|
btnReset.TabIndex = 27;
|
||||||
|
btnReset.Text = "Hard Reset";
|
||||||
|
btnReset.UseVisualStyleBackColor = true;
|
||||||
|
btnReset.Click += btnReset_Click;
|
||||||
|
//
|
||||||
// DebuggerForm
|
// DebuggerForm
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(8F, 20F);
|
AutoScaleDimensions = new SizeF(10F, 25F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
ClientSize = new Size(928, 454);
|
ClientSize = new Size(1160, 568);
|
||||||
|
Controls.Add(btnReset);
|
||||||
Controls.Add(lblIE);
|
Controls.Add(lblIE);
|
||||||
Controls.Add(lblIff2);
|
Controls.Add(lblIff2);
|
||||||
Controls.Add(lblIff1);
|
Controls.Add(lblIff1);
|
||||||
@@ -352,6 +372,7 @@
|
|||||||
private Label lblIff1;
|
private Label lblIff1;
|
||||||
private Label lblIff2;
|
private Label lblIff2;
|
||||||
private Label lblIE;
|
private Label lblIE;
|
||||||
|
private Button btnReset;
|
||||||
//private TextBox textBox4;
|
//private TextBox textBox4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,6 +117,30 @@ namespace Desktop
|
|||||||
UpdateDisplay();
|
UpdateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnReset_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// 1. Safely stop the emulator if it is currently in a Run loop
|
||||||
|
if (_isRunning)
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
btnRun.Text = "Run";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Power cycle the CPU
|
||||||
|
_cpu.Reset();
|
||||||
|
|
||||||
|
// Note: A true hard reset also wipes the RAM.
|
||||||
|
// If you add a RAM clear method to your MemoryBus later, call it here!
|
||||||
|
_memoryBus.ClearRam(); //To Do
|
||||||
|
|
||||||
|
// 3. Clear the UI tracking lists
|
||||||
|
lstDisassembly.Items.Clear();
|
||||||
|
lstStack.Items.Clear();
|
||||||
|
|
||||||
|
// 4. Force a full UI refresh to show the clean slate
|
||||||
|
UpdateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
private void btnExit_Click(object sender, EventArgs e)
|
private void btnExit_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
@@ -253,6 +277,11 @@ namespace Desktop
|
|||||||
mnemonic = $"LD DE, 0x{deHigh:X2}{deLow:X2}";
|
mnemonic = $"LD DE, 0x{deHigh:X2}{deLow:X2}";
|
||||||
instructionLength = 3;
|
instructionLength = 3;
|
||||||
break;
|
break;
|
||||||
|
case 0x16:
|
||||||
|
byte dImm = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
|
mnemonic = $"LD D, 0x{dImm:X2}";
|
||||||
|
instructionLength = 2;
|
||||||
|
break;
|
||||||
case 0x19:
|
case 0x19:
|
||||||
mnemonic = "ADD HL, DE";
|
mnemonic = "ADD HL, DE";
|
||||||
break;
|
break;
|
||||||
@@ -321,6 +350,9 @@ namespace Desktop
|
|||||||
case 0x47:
|
case 0x47:
|
||||||
mnemonic = "LD B, A";
|
mnemonic = "LD B, A";
|
||||||
break;
|
break;
|
||||||
|
case 0x5F:
|
||||||
|
mnemonic = "LD E, A";
|
||||||
|
break;
|
||||||
case 0x62:
|
case 0x62:
|
||||||
mnemonic = "LD H, D";
|
mnemonic = "LD H, D";
|
||||||
break;
|
break;
|
||||||
@@ -330,6 +362,9 @@ namespace Desktop
|
|||||||
case 0x77:
|
case 0x77:
|
||||||
mnemonic = "LD (HL), A";
|
mnemonic = "LD (HL), A";
|
||||||
break;
|
break;
|
||||||
|
case 0x91:
|
||||||
|
mnemonic = "SUB C";
|
||||||
|
break;
|
||||||
case 0xA7:
|
case 0xA7:
|
||||||
mnemonic = "AND A";
|
mnemonic = "AND A";
|
||||||
break;
|
break;
|
||||||
@@ -346,6 +381,9 @@ namespace Desktop
|
|||||||
mnemonic = $"JP 0x{jpHigh:X2}{jpLow:X2}";
|
mnemonic = $"JP 0x{jpHigh:X2}{jpLow:X2}";
|
||||||
instructionLength = 3;
|
instructionLength = 3;
|
||||||
break;
|
break;
|
||||||
|
case 0xC9:
|
||||||
|
mnemonic = "RET";
|
||||||
|
break;
|
||||||
case 0xCD:
|
case 0xCD:
|
||||||
ushort callDest = (ushort)(_memoryBus.Read((ushort)(currentPc + 1)) | (_memoryBus.Read((ushort)(currentPc + 2)) << 8));
|
ushort callDest = (ushort)(_memoryBus.Read((ushort)(currentPc + 1)) | (_memoryBus.Read((ushort)(currentPc + 2)) << 8));
|
||||||
mnemonic = $"CALL 0x{callDest:X4}";
|
mnemonic = $"CALL 0x{callDest:X4}";
|
||||||
@@ -435,6 +473,14 @@ namespace Desktop
|
|||||||
mnemonic = $"DEC (IY{sign}{d})";
|
mnemonic = $"DEC (IY{sign}{d})";
|
||||||
instructionLength = 3;
|
instructionLength = 3;
|
||||||
}
|
}
|
||||||
|
else if (fdOpcode == 0x36) // LD (IY+d), n
|
||||||
|
{
|
||||||
|
sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
|
byte n = _memoryBus.Read((ushort)(currentPc + 3));
|
||||||
|
string sign = d >= 0 ? "+" : "";
|
||||||
|
mnemonic = $"LD (IY{sign}{d}), 0x{n:X2}";
|
||||||
|
instructionLength = 4;
|
||||||
|
}
|
||||||
else if (fdOpcode == 0xCB) // FD CB prefix
|
else if (fdOpcode == 0xCB) // FD CB prefix
|
||||||
{
|
{
|
||||||
sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
@@ -454,6 +500,13 @@ namespace Desktop
|
|||||||
}
|
}
|
||||||
instructionLength = 4;
|
instructionLength = 4;
|
||||||
}
|
}
|
||||||
|
else if (fdOpcode == 0x71) // LD (IY+d), C
|
||||||
|
{
|
||||||
|
sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
|
string sign = d >= 0 ? "+" : "";
|
||||||
|
mnemonic = $"LD (IY{sign}{d}), C";
|
||||||
|
instructionLength = 3;
|
||||||
|
}
|
||||||
else if (fdOpcode == 0x75) // LD (IY+d), L
|
else if (fdOpcode == 0x75) // LD (IY+d), L
|
||||||
{
|
{
|
||||||
sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
|
|||||||
Reference in New Issue
Block a user