Implemented a shit load more OpCodes
This commit is contained in:
191
Core/Cpu/Z80.cs
191
Core/Cpu/Z80.cs
@@ -474,15 +474,67 @@ namespace Core.Cpu
|
|||||||
case 0x03: // INC BC
|
case 0x03: // INC BC
|
||||||
BC.Word++;
|
BC.Word++;
|
||||||
return 6;
|
return 6;
|
||||||
case 0x04: // INC B
|
// --- 8-Bit Increments ---
|
||||||
BC.High = Inc8(BC.High);
|
case 0x04: BC.High = Inc8(BC.High); return 4; // INC B
|
||||||
return 4;
|
case 0x0C: BC.Low = Inc8(BC.Low); return 4; // INC C
|
||||||
|
case 0x14: DE.High = Inc8(DE.High); return 4; // INC D
|
||||||
|
case 0x1C: DE.Low = Inc8(DE.Low); return 4; // INC E
|
||||||
|
case 0x24: HL.High = Inc8(HL.High); return 4; // INC H
|
||||||
|
case 0x2C: HL.Low = Inc8(HL.Low); return 4; // INC L
|
||||||
|
case 0x34:
|
||||||
|
_memory.Write(HL.Word, Inc8(_memory.Read(HL.Word)));
|
||||||
|
return 11; // INC (HL) takes 11 T-States
|
||||||
|
case 0x3C: AF.High = Inc8(AF.High); return 4; // INC A
|
||||||
|
|
||||||
|
// --- 8-Bit Decrements ---
|
||||||
|
case 0x05: BC.High = Dec8(BC.High); return 4; // DEC B
|
||||||
|
case 0x0D: BC.Low = Dec8(BC.Low); return 4; // DEC C
|
||||||
|
case 0x15: DE.High = Dec8(DE.High); return 4; // DEC D
|
||||||
|
case 0x1D: DE.Low = Dec8(DE.Low); return 4; // DEC E
|
||||||
|
case 0x25: HL.High = Dec8(HL.High); return 4; // DEC H
|
||||||
|
case 0x2D: HL.Low = Dec8(HL.Low); return 4; // DEC L
|
||||||
|
case 0x35:
|
||||||
|
_memory.Write(HL.Word, Dec8(_memory.Read(HL.Word)));
|
||||||
|
return 11; // DEC (HL) takes 11 T-States
|
||||||
|
case 0x3D: AF.High = Dec8(AF.High); return 4; // DEC A
|
||||||
|
case 0x06: // LD B, n
|
||||||
|
BC.High = FetchByte();
|
||||||
|
return 7;
|
||||||
|
// --- ADD HL, rr (16-bit Addition) ---
|
||||||
|
case 0x09:
|
||||||
|
Add16(BC.Word);
|
||||||
|
return 11;
|
||||||
|
case 0x19:
|
||||||
|
Add16(DE.Word);
|
||||||
|
return 11;
|
||||||
|
case 0x29:
|
||||||
|
Add16(HL.Word); // This perfectly multiplies HL by 2!
|
||||||
|
return 11;
|
||||||
|
case 0x39:
|
||||||
|
Add16(SP);
|
||||||
|
return 11;
|
||||||
case 0x0B: // DEC BC
|
case 0x0B: // DEC BC
|
||||||
BC.Word--;
|
BC.Word--;
|
||||||
return 6;
|
return 6;
|
||||||
case 0x0E: // LD C, n
|
case 0x0E: // LD C, n
|
||||||
BC.Low = FetchByte();
|
BC.Low = FetchByte();
|
||||||
return 7; // Takes 7 T-States
|
return 7;
|
||||||
|
case 0x0F: // RRCA
|
||||||
|
// 1. Grab the bit that is about to fall off
|
||||||
|
byte bit0 = (byte)(AF.High & 0x01);
|
||||||
|
|
||||||
|
// 2. Shift right, and force the old Bit 0 into the Bit 7 position
|
||||||
|
AF.High = (byte)((AF.High >> 1) | (bit0 << 7));
|
||||||
|
|
||||||
|
// 3. Update Flags
|
||||||
|
// S (0x80), Z (0x40), and P/V (0x04) are completely PRESERVED.
|
||||||
|
// H (0x10) and N (0x02) are forcefully RESET to 0.
|
||||||
|
// ANDing with 0xC4 (Binary 1100 0100) does exactly this.
|
||||||
|
AF.Low &= 0xC4;
|
||||||
|
|
||||||
|
// Set the Carry Flag (Bit 0) to whatever fell off
|
||||||
|
AF.Low |= bit0;
|
||||||
|
return 4;
|
||||||
case 0x10: // DJNZ d
|
case 0x10: // DJNZ d
|
||||||
sbyte djnzOffset = (sbyte)FetchByte();
|
sbyte djnzOffset = (sbyte)FetchByte();
|
||||||
|
|
||||||
@@ -512,9 +564,9 @@ namespace Core.Cpu
|
|||||||
PC = (ushort)(PC + jumpDistance);
|
PC = (ushort)(PC + jumpDistance);
|
||||||
|
|
||||||
return 12;
|
return 12;
|
||||||
case 0x19: // ADD HL, DE
|
case 0x1A: // LD A, (DE)
|
||||||
Add16(DE.Word);
|
AF.High = _memory.Read(DE.Word);
|
||||||
return 11;
|
return 7;
|
||||||
case 0x1B: // DEC DE
|
case 0x1B: // DEC DE
|
||||||
DE.Word--;
|
DE.Word--;
|
||||||
return 6;
|
return 6;
|
||||||
@@ -579,17 +631,6 @@ namespace Core.Cpu
|
|||||||
case 0x33: // INC SP
|
case 0x33: // INC SP
|
||||||
SP++;
|
SP++;
|
||||||
return 6;
|
return 6;
|
||||||
case 0x35: // DEC (HL)
|
|
||||||
// Read the current byte from memory
|
|
||||||
byte memValue = _memory.Read(HL.Word);
|
|
||||||
|
|
||||||
// Decrement it and update flags
|
|
||||||
byte decremented = Dec8(memValue);
|
|
||||||
|
|
||||||
// Write the new value back to memory
|
|
||||||
_memory.Write(HL.Word, decremented);
|
|
||||||
|
|
||||||
return 11; // Takes 11 T-States
|
|
||||||
case 0x36: // LD (HL), n
|
case 0x36: // LD (HL), n
|
||||||
byte nValue = FetchByte();
|
byte nValue = FetchByte();
|
||||||
_memory.Write(HL.Word, nValue);
|
_memory.Write(HL.Word, nValue);
|
||||||
@@ -607,6 +648,10 @@ namespace Core.Cpu
|
|||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
return 7;
|
return 7;
|
||||||
|
case 0x3A: // LD A, (nn)
|
||||||
|
ushort address3A = FetchWord();
|
||||||
|
AF.High = _memory.Read(address3A);
|
||||||
|
return 13;
|
||||||
case 0x3B: // DEC SP
|
case 0x3B: // DEC SP
|
||||||
SP--;
|
SP--;
|
||||||
return 6;
|
return 6;
|
||||||
@@ -764,6 +809,16 @@ namespace Core.Cpu
|
|||||||
case 0xC6: // ADD A, n
|
case 0xC6: // ADD A, n
|
||||||
Add(FetchByte());
|
Add(FetchByte());
|
||||||
return 7;
|
return 7;
|
||||||
|
// --- RST Instructions (11 T-States) ---
|
||||||
|
// An RST is effectively a 1-byte CALL to a fixed Page 0 address.
|
||||||
|
case 0xC7: Push(PC); PC = 0x0000; return 11; // RST 00h (Equivalent to a hardware reset)
|
||||||
|
case 0xCF: Push(PC); PC = 0x0008; return 11; // RST 08h (Spectrum Error handler)
|
||||||
|
case 0xD7: Push(PC); PC = 0x0010; return 11; // RST 10h (Spectrum Print Character)
|
||||||
|
case 0xDF: Push(PC); PC = 0x0018; return 11; // RST 18h (Spectrum Collect Next Char)
|
||||||
|
case 0xE7: Push(PC); PC = 0x0020; return 11; // RST 20h (Spectrum Collect Next Char/Space)
|
||||||
|
case 0xEF: Push(PC); PC = 0x0028; return 11; // RST 28h (Spectrum Floating Point Calculator)
|
||||||
|
case 0xF7: Push(PC); PC = 0x0030; return 11; // RST 30h (Spectrum Make BC Spaces)
|
||||||
|
case 0xFF: Push(PC); PC = 0x0038; return 11; // RST 38h (Maskable Interrupt Handler)
|
||||||
case 0xC8: // RET Z
|
case 0xC8: // RET Z
|
||||||
// Check if the Zero Flag (Bit 6) IS set
|
// Check if the Zero Flag (Bit 6) IS set
|
||||||
if ((AF.Low & 0x40) != 0)
|
if ((AF.Low & 0x40) != 0)
|
||||||
@@ -775,6 +830,8 @@ namespace Core.Cpu
|
|||||||
case 0xC9: // RET
|
case 0xC9: // RET
|
||||||
PC = Pop();
|
PC = Pop();
|
||||||
return 10;
|
return 10;
|
||||||
|
case 0xCB:
|
||||||
|
return ExecuteCBPrefix();
|
||||||
case 0xCD: // CALL nn
|
case 0xCD: // CALL nn
|
||||||
ushort callAddress = FetchWord();
|
ushort callAddress = FetchWord();
|
||||||
Push(PC);
|
Push(PC);
|
||||||
@@ -806,6 +863,14 @@ namespace Core.Cpu
|
|||||||
case 0xD6: // SUB n
|
case 0xD6: // SUB n
|
||||||
Sub(FetchByte());
|
Sub(FetchByte());
|
||||||
return 7;
|
return 7;
|
||||||
|
case 0xD8: // RET C
|
||||||
|
// Check if the Carry Flag (Bit 0) IS set (1)
|
||||||
|
if ((AF.Low & 0x01) != 0)
|
||||||
|
{
|
||||||
|
PC = Pop();
|
||||||
|
return 11; // Condition met, took the return
|
||||||
|
}
|
||||||
|
return 5;
|
||||||
case 0xD9: // EXX
|
case 0xD9: // EXX
|
||||||
ushort tempBC = BC.Word;
|
ushort tempBC = BC.Word;
|
||||||
BC.Word = BC_Prime.Word;
|
BC.Word = BC_Prime.Word;
|
||||||
@@ -826,6 +891,20 @@ namespace Core.Cpu
|
|||||||
case 0xE1: // POP HL
|
case 0xE1: // POP HL
|
||||||
HL.Word = Pop();
|
HL.Word = Pop();
|
||||||
return 10;
|
return 10;
|
||||||
|
case 0xE3: // EX (SP), HL
|
||||||
|
// 1. Read the 16-bit value currently on top of the stack
|
||||||
|
byte spLow = _memory.Read(SP);
|
||||||
|
byte spHigh = _memory.Read((ushort)(SP + 1));
|
||||||
|
|
||||||
|
// 2. Write the current HL registers onto the stack in its place
|
||||||
|
_memory.Write(SP, HL.Low);
|
||||||
|
_memory.Write((ushort)(SP + 1), HL.High);
|
||||||
|
|
||||||
|
// 3. Update HL with the data we pulled off the stack
|
||||||
|
HL.Low = spLow;
|
||||||
|
HL.High = spHigh;
|
||||||
|
|
||||||
|
return 19;
|
||||||
case 0xe5: //push bc
|
case 0xe5: //push bc
|
||||||
Push(HL.Word);
|
Push(HL.Word);
|
||||||
return 11;
|
return 11;
|
||||||
@@ -852,6 +931,9 @@ namespace Core.Cpu
|
|||||||
case 0xf5: //push bc
|
case 0xf5: //push bc
|
||||||
Push(AF.Word);
|
Push(AF.Word);
|
||||||
return 11;
|
return 11;
|
||||||
|
case 0xF6: // OR n
|
||||||
|
Or(FetchByte());
|
||||||
|
return 7;
|
||||||
case 0xF9: // LD SP, HL
|
case 0xF9: // LD SP, HL
|
||||||
SP = HL.Word; // (Use SP.Word = HL.Word if you made SP a RegisterPair)
|
SP = HL.Word; // (Use SP.Word = HL.Word if you made SP a RegisterPair)
|
||||||
return 6;
|
return 6;
|
||||||
@@ -861,6 +943,9 @@ namespace Core.Cpu
|
|||||||
return 4;
|
return 4;
|
||||||
case 0xFD:
|
case 0xFD:
|
||||||
return ExecuteFDPrefix();
|
return ExecuteFDPrefix();
|
||||||
|
case 0xFE: // CP n
|
||||||
|
Cp(FetchByte());
|
||||||
|
return 7;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Opcode 0x{opcode:X2} at PC 0x{(PC - 1):X4} is not implemented.");
|
throw new NotImplementedException($"Opcode 0x{opcode:X2} at PC 0x{(PC - 1):X4} is not implemented.");
|
||||||
}
|
}
|
||||||
@@ -881,6 +966,11 @@ namespace Core.Cpu
|
|||||||
case 0x47: // LD I, A
|
case 0x47: // LD I, A
|
||||||
I = AF.High;
|
I = AF.High;
|
||||||
return 9;
|
return 9;
|
||||||
|
case 0x4B: // LD BC, (nn)
|
||||||
|
ushort src4B = FetchWord();
|
||||||
|
BC.Low = _memory.Read(src4B);
|
||||||
|
BC.High = _memory.Read((ushort)(src4B + 1));
|
||||||
|
return 20; // Takes 20 T-States
|
||||||
case 0x52: // SBC HL, DE
|
case 0x52: // SBC HL, DE
|
||||||
Sbc16(DE.Word);
|
Sbc16(DE.Word);
|
||||||
return 15;
|
return 15;
|
||||||
@@ -952,6 +1042,63 @@ namespace Core.Cpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int ExecuteCBPrefix()
|
||||||
|
{
|
||||||
|
byte cbOpcode = FetchByte();
|
||||||
|
byte memVal;
|
||||||
|
|
||||||
|
switch (cbOpcode)
|
||||||
|
{
|
||||||
|
case 0x7E: // BIT 7, (HL)
|
||||||
|
byte memValBit7 = _memory.Read(HL.Word);
|
||||||
|
|
||||||
|
// Preserve ONLY the Carry Flag (Bit 0). This clears N and everything else.
|
||||||
|
AF.Low &= 0x01;
|
||||||
|
|
||||||
|
// Half-Carry (Bit 4) is ALWAYS set to 1 for Z80 BIT instructions
|
||||||
|
AF.Low |= 0x10;
|
||||||
|
|
||||||
|
// Test Bit 7 (0x80 is Binary 1000 0000)
|
||||||
|
if ((memValBit7 & 0x80) == 0)
|
||||||
|
{
|
||||||
|
// If the bit is 0, turn ON the Zero Flag (Bit 6)
|
||||||
|
AF.Low |= 0x40;
|
||||||
|
|
||||||
|
// Parity/Overflow (Bit 2) is historically set along with the Zero flag on BIT
|
||||||
|
AF.Low |= 0x04;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If testing Bit 7 and it is 1, the Sign Flag (Bit 7) perfectly mirrors it
|
||||||
|
AF.Low |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 12;
|
||||||
|
case 0xAE: // RES 5, (HL)
|
||||||
|
memVal = _memory.Read(HL.Word);
|
||||||
|
|
||||||
|
// 0xDF is Binary 1101 1111
|
||||||
|
// ANDing preserves all other bits while forcing Bit 5 to 0
|
||||||
|
memVal &= 0xDF;
|
||||||
|
|
||||||
|
_memory.Write(HL.Word, memVal);
|
||||||
|
return 15;
|
||||||
|
|
||||||
|
case 0xC6: // SET 0, (HL)
|
||||||
|
memVal = _memory.Read(HL.Word);
|
||||||
|
|
||||||
|
// 0x01 is Binary 0000 0001
|
||||||
|
// ORing forces Bit 0 to 1 and perfectly preserves all other bits
|
||||||
|
memVal |= 0x01;
|
||||||
|
|
||||||
|
_memory.Write(HL.Word, memVal);
|
||||||
|
return 15;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException($"CB prefix opcode 0x{cbOpcode:X2} at PC 0x{(PC - 1):X4} is not implemented.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int ExecuteFDPrefix()
|
private int ExecuteFDPrefix()
|
||||||
{
|
{
|
||||||
byte opcode = FetchByte();
|
byte opcode = FetchByte();
|
||||||
@@ -981,6 +1128,14 @@ namespace Core.Cpu
|
|||||||
_memory.Write(targetAddress, nValue);
|
_memory.Write(targetAddress, nValue);
|
||||||
return 19; // Takes 19 T-States
|
return 19; // Takes 19 T-States
|
||||||
}
|
}
|
||||||
|
case 0x46: // LD B, (IY+d)
|
||||||
|
{
|
||||||
|
sbyte displacement = (sbyte)FetchByte();
|
||||||
|
targetAddress = (ushort)(IY.Word + displacement);
|
||||||
|
|
||||||
|
BC.High = _memory.Read(targetAddress);
|
||||||
|
return 19; // Takes 19 T-States
|
||||||
|
}
|
||||||
case 0x6E: // LD L, (IY+d)
|
case 0x6E: // LD L, (IY+d)
|
||||||
sbyte displacementVal = (sbyte)FetchByte();
|
sbyte displacementVal = (sbyte)FetchByte();
|
||||||
ushort targetAddr = (ushort)(IY.Word + displacementVal);
|
ushort targetAddr = (ushort)(IY.Word + displacementVal);
|
||||||
|
|||||||
@@ -264,14 +264,43 @@ namespace Desktop
|
|||||||
// --- 16-Bit Decrements ---
|
// --- 16-Bit Decrements ---
|
||||||
case 0x0B: mnemonic = "DEC BC"; break;
|
case 0x0B: mnemonic = "DEC BC"; break;
|
||||||
case 0x3B: mnemonic = "DEC SP"; break;
|
case 0x3B: mnemonic = "DEC SP"; break;
|
||||||
case 0x04:
|
// --- 8-Bit Increments ---
|
||||||
mnemonic = "INC B";
|
case 0x04: mnemonic = "INC B"; break;
|
||||||
|
case 0x0C: mnemonic = "INC C"; break;
|
||||||
|
case 0x14: mnemonic = "INC D"; break;
|
||||||
|
case 0x1C: mnemonic = "INC E"; break;
|
||||||
|
case 0x24: mnemonic = "INC H"; break;
|
||||||
|
case 0x2C: mnemonic = "INC L"; break;
|
||||||
|
case 0x34: mnemonic = "INC (HL)"; break;
|
||||||
|
case 0x3C: mnemonic = "INC A"; break;
|
||||||
|
|
||||||
|
// --- 8-Bit Decrements ---
|
||||||
|
case 0x05: mnemonic = "DEC B"; break;
|
||||||
|
case 0x0D: mnemonic = "DEC C"; break;
|
||||||
|
case 0x15: mnemonic = "DEC D"; break;
|
||||||
|
case 0x1D: mnemonic = "DEC E"; break;
|
||||||
|
case 0x25: mnemonic = "DEC H"; break;
|
||||||
|
case 0x2D: mnemonic = "DEC L"; break;
|
||||||
|
case 0x35: mnemonic = "DEC (HL)"; break;
|
||||||
|
case 0x3D: mnemonic = "DEC A"; break;
|
||||||
|
case 0x06:
|
||||||
|
byte bImm = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
|
mnemonic = $"LD B, 0x{bImm:X2}";
|
||||||
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
|
// --- ADD HL, rr ---
|
||||||
|
case 0x09: mnemonic = "ADD HL, BC"; break;
|
||||||
|
case 0x19: mnemonic = "ADD HL, DE"; break;
|
||||||
|
case 0x29: mnemonic = "ADD HL, HL"; break;
|
||||||
|
case 0x39: mnemonic = "ADD HL, SP"; break;
|
||||||
case 0x0E:
|
case 0x0E:
|
||||||
byte cImm = _memoryBus.Read((ushort)(currentPc + 1));
|
byte cImm = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
mnemonic = $"LD C, 0x{cImm:X2}";
|
mnemonic = $"LD C, 0x{cImm:X2}";
|
||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
|
case 0x0F:
|
||||||
|
mnemonic = "RRCA";
|
||||||
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
sbyte djnzOffset = (sbyte)_memoryBus.Read((ushort)(currentPc + 1));
|
sbyte djnzOffset = (sbyte)_memoryBus.Read((ushort)(currentPc + 1));
|
||||||
ushort djnzDest = (ushort)(currentPc + 2 + djnzOffset);
|
ushort djnzDest = (ushort)(currentPc + 2 + djnzOffset);
|
||||||
@@ -298,8 +327,8 @@ namespace Desktop
|
|||||||
mnemonic = $"JR 0x{targetAddressUnconditional:X4}";
|
mnemonic = $"JR 0x{targetAddressUnconditional:X4}";
|
||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
case 0x19:
|
case 0x1A:
|
||||||
mnemonic = "ADD HL, DE";
|
mnemonic = "LD A, (DE)";
|
||||||
break;
|
break;
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
mnemonic = "DEC DE";
|
mnemonic = "DEC DE";
|
||||||
@@ -359,9 +388,6 @@ namespace Desktop
|
|||||||
instructionLength = 3;
|
instructionLength = 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x35:
|
|
||||||
mnemonic = "DEC (HL)";
|
|
||||||
break;
|
|
||||||
case 0x36:
|
case 0x36:
|
||||||
byte memValue = _memoryBus.Read((ushort)(currentPc + 1));
|
byte memValue = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
mnemonic = $"LD (HL), 0x{memValue:X2}";
|
mnemonic = $"LD (HL), 0x{memValue:X2}";
|
||||||
@@ -377,6 +403,11 @@ namespace Desktop
|
|||||||
mnemonic = $"JR C, 0x{targetC:X4}";
|
mnemonic = $"JR C, 0x{targetC:X4}";
|
||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
|
case 0x3A:
|
||||||
|
ushort addr3A = (ushort)(_memoryBus.Read((ushort)(currentPc + 1)) | (_memoryBus.Read((ushort)(currentPc + 2)) << 8));
|
||||||
|
mnemonic = $"LD A, (0x{addr3A:X4})";
|
||||||
|
instructionLength = 3;
|
||||||
|
break;
|
||||||
case 0x3E:
|
case 0x3E:
|
||||||
mnemonic = $"LD A, 0x{_memoryBus.Read((ushort)(currentPc + 1)):X2}";
|
mnemonic = $"LD A, 0x{_memoryBus.Read((ushort)(currentPc + 1)):X2}";
|
||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
@@ -540,12 +571,42 @@ namespace Desktop
|
|||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// --- RST Instructions ---
|
||||||
|
case 0xC7: mnemonic = "RST 00h"; break;
|
||||||
|
case 0xCF: mnemonic = "RST 08h"; break;
|
||||||
|
case 0xD7: mnemonic = "RST 10h"; break;
|
||||||
|
case 0xDF: mnemonic = "RST 18h"; break;
|
||||||
|
case 0xE7: mnemonic = "RST 20h"; break;
|
||||||
|
case 0xEF: mnemonic = "RST 28h"; break;
|
||||||
|
case 0xF7: mnemonic = "RST 30h"; break;
|
||||||
|
case 0xFF: mnemonic = "RST 38h"; break;
|
||||||
case 0xC8:
|
case 0xC8:
|
||||||
mnemonic = "RET Z";
|
mnemonic = "RET Z";
|
||||||
break;
|
break;
|
||||||
case 0xC9:
|
case 0xC9:
|
||||||
mnemonic = "RET";
|
mnemonic = "RET";
|
||||||
break;
|
break;
|
||||||
|
case 0xCB:
|
||||||
|
byte cbOp = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
|
if (cbOp == 0x7E)
|
||||||
|
{
|
||||||
|
mnemonic = "BIT 7, (HL)";
|
||||||
|
}
|
||||||
|
else if (cbOp == 0xAE)
|
||||||
|
{
|
||||||
|
mnemonic = "RES 5, (HL)";
|
||||||
|
}
|
||||||
|
else if (cbOp == 0xC6)
|
||||||
|
{
|
||||||
|
mnemonic = "SET 0, (HL)";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mnemonic = $"CB UNKNOWN (0x{cbOp:X2})";
|
||||||
|
}
|
||||||
|
|
||||||
|
instructionLength = 2;
|
||||||
|
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}";
|
||||||
@@ -572,12 +633,18 @@ namespace Desktop
|
|||||||
mnemonic = $"SUB 0x{subImm:X2}";
|
mnemonic = $"SUB 0x{subImm:X2}";
|
||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
|
case 0xD8:
|
||||||
|
mnemonic = "RET C";
|
||||||
|
break;
|
||||||
case 0xDE:
|
case 0xDE:
|
||||||
byte sbcValue = _memoryBus.Read((ushort)(currentPc + 1));
|
byte sbcValue = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
mnemonic = $"SBC A, 0x{sbcValue:X2}";
|
mnemonic = $"SBC A, 0x{sbcValue:X2}";
|
||||||
instructionLength = 2;
|
instructionLength = 2;
|
||||||
break;
|
break;
|
||||||
case 0xE1: mnemonic = "POP HL"; break;
|
case 0xE1: mnemonic = "POP HL"; break;
|
||||||
|
case 0xE3:
|
||||||
|
mnemonic = "EX (SP), HL";
|
||||||
|
break;
|
||||||
case 0xE5:
|
case 0xE5:
|
||||||
mnemonic = "PUSH HL";
|
mnemonic = "PUSH HL";
|
||||||
break;
|
break;
|
||||||
@@ -606,6 +673,11 @@ namespace Desktop
|
|||||||
mnemonic = "LD I, A";
|
mnemonic = "LD I, A";
|
||||||
instructionLength = 2; // 0xED + 0x47
|
instructionLength = 2; // 0xED + 0x47
|
||||||
break;
|
break;
|
||||||
|
case 0x4B:
|
||||||
|
ushort addr4B = (ushort)(_memoryBus.Read((ushort)(currentPc + 2)) | (_memoryBus.Read((ushort)(currentPc + 3)) << 8));
|
||||||
|
mnemonic = $"LD BC, (0x{addr4B:X4})";
|
||||||
|
instructionLength = 4;
|
||||||
|
break;
|
||||||
case 0x52:
|
case 0x52:
|
||||||
mnemonic = "SBC HL, DE";
|
mnemonic = "SBC HL, DE";
|
||||||
instructionLength = 2; // ED 52
|
instructionLength = 2; // ED 52
|
||||||
@@ -638,10 +710,14 @@ namespace Desktop
|
|||||||
case 0xF3:
|
case 0xF3:
|
||||||
mnemonic = "DI";
|
mnemonic = "DI";
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
case 0xf5:
|
case 0xf5:
|
||||||
mnemonic = "PUSH AF";
|
mnemonic = "PUSH AF";
|
||||||
break;
|
break;
|
||||||
|
case 0xF6:
|
||||||
|
byte orImm = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
|
mnemonic = $"OR 0x{orImm:X2}";
|
||||||
|
instructionLength = 2;
|
||||||
|
break;
|
||||||
case 0xF9:
|
case 0xF9:
|
||||||
mnemonic = "LD SP, HL";
|
mnemonic = "LD SP, HL";
|
||||||
break;
|
break;
|
||||||
@@ -673,6 +749,14 @@ namespace Desktop
|
|||||||
mnemonic = $"LD (IY{sign}{d}), 0x{n:X2}";
|
mnemonic = $"LD (IY{sign}{d}), 0x{n:X2}";
|
||||||
instructionLength = 4;
|
instructionLength = 4;
|
||||||
}
|
}
|
||||||
|
else if (fdOpcode == 0x46) // LD B, (IY+d)
|
||||||
|
{
|
||||||
|
sbyte dB = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
|
string signB = dB >= 0 ? "+" : "";
|
||||||
|
|
||||||
|
mnemonic = $"LD B, (IY{signB}{dB})";
|
||||||
|
instructionLength = 3;
|
||||||
|
}
|
||||||
else if (fdOpcode == 0x6E)
|
else if (fdOpcode == 0x6E)
|
||||||
{
|
{
|
||||||
sbyte offsetL = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
sbyte offsetL = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
@@ -772,6 +856,11 @@ namespace Desktop
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0xFE:
|
||||||
|
byte cpImm = _memoryBus.Read((ushort)(currentPc + 1));
|
||||||
|
mnemonic = $"CP 0x{cpImm:X2}";
|
||||||
|
instructionLength = 2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mnemonic = $"UNKNOWN (0x{opcode:X2})";
|
mnemonic = $"UNKNOWN (0x{opcode:X2})";
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user