Snapshot and TAP quick loading working. Manic Miner fully emulated
This commit is contained in:
@@ -1021,7 +1021,12 @@ namespace Core.Cpu
|
||||
PC = (ushort)(PC + offset);
|
||||
return 12; // Jump taken
|
||||
}
|
||||
return 7; // Jump not taken
|
||||
return 7;
|
||||
case 0x31: // LD SP, nn
|
||||
{
|
||||
SP = FetchWord();
|
||||
return 10;
|
||||
}
|
||||
case 0x32: // LD (nn), A
|
||||
{
|
||||
ushort destAddress = FetchWord();
|
||||
@@ -1608,6 +1613,34 @@ namespace Core.Cpu
|
||||
case 0x56: // IM 1
|
||||
InterruptMode = 1;
|
||||
return 8;
|
||||
case 0x58: // IN E, (C)
|
||||
// 1. Read from the I/O port.
|
||||
// CRITICAL: We must pass the FULL BC register, not just C!
|
||||
byte inVal58 = ReadPort(BC.Word);
|
||||
|
||||
// 2. Store the hardware data in register E (Low byte of DE)
|
||||
DE.Low = inVal58;
|
||||
|
||||
// 3. Update the Flags Register (F)
|
||||
// The Carry flag (C) is strictly preserved. H and N are always reset to 0.
|
||||
byte flags58 = (byte)(AF.Low & 0x01);
|
||||
|
||||
if ((inVal58 & 0x80) != 0) flags58 |= 0x80; // S: Sign flag
|
||||
if (inVal58 == 0) flags58 |= 0x40; // Z: Zero flag
|
||||
|
||||
// P/V: Parity flag. Collapse the bits to check if the number of 1s is even
|
||||
byte p58 = inVal58;
|
||||
p58 ^= (byte)(p58 >> 4);
|
||||
p58 ^= (byte)(p58 >> 2);
|
||||
p58 ^= (byte)(p58 >> 1);
|
||||
if ((p58 & 1) == 0) flags58 |= 0x04; // Set if Parity is Even
|
||||
|
||||
// Undocumented bits 3 and 5 are copied directly from the input byte
|
||||
flags58 |= (byte)(inVal58 & 0x28);
|
||||
|
||||
AF.Low = flags58;
|
||||
|
||||
return 12;
|
||||
case 0x5A: // ADC HL, DE
|
||||
Adc16(DE.Word);
|
||||
return 15;
|
||||
@@ -2448,6 +2481,36 @@ namespace Core.Cpu
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x19: // ADD IY, DE
|
||||
// 1. Perform the 16-bit addition using a 32-bit integer to catch the carry
|
||||
int result19 = IY.Word + DE.Word;
|
||||
|
||||
// 2. Update the Flags Register (F)
|
||||
// We start by stripping out N, H, C, and bits 3/5, but strictly PRESERVING S, Z, and P/V (0xC4)
|
||||
byte flags19 = (byte)(AF.Low & 0xC4);
|
||||
|
||||
// H: Set if there is a carry from bit 11
|
||||
if (((IY.Word & 0x0FFF) + (DE.Word & 0x0FFF)) > 0x0FFF)
|
||||
{
|
||||
flags19 |= 0x10;
|
||||
}
|
||||
|
||||
// C: Set if the result overflows 16 bits (carry from bit 15)
|
||||
if (result19 > 0xFFFF)
|
||||
{
|
||||
flags19 |= 0x01;
|
||||
}
|
||||
|
||||
// Undocumented bits 3 and 5 are copied directly from the high byte of the result
|
||||
flags19 |= (byte)((result19 >> 8) & 0x28);
|
||||
|
||||
// N (Subtract) is naturally left as 0 because of our initial bitmask
|
||||
AF.Low = flags19;
|
||||
|
||||
// 3. Store the clean 16-bit result back into IY
|
||||
IY.Word = (ushort)result19;
|
||||
|
||||
return 15;
|
||||
case 0x21: // LD IY, nn
|
||||
IY.Word = FetchWord();
|
||||
return 14;
|
||||
@@ -2550,6 +2613,17 @@ namespace Core.Cpu
|
||||
// 3. Read the memory and store it in E (the low byte of DE)
|
||||
DE.Low = ReadMemory(address5E);
|
||||
|
||||
return 19;
|
||||
case 0x66: // LD H, (IY+d)
|
||||
// 1. Fetch the displacement byte and cast it to a signed sbyte
|
||||
sbyte offset66 = (sbyte)FetchByte();
|
||||
|
||||
// 2. Calculate the exact memory address (IY + offset)
|
||||
ushort address66 = (ushort)(IY.Word + offset66);
|
||||
|
||||
// 3. Read the byte from memory and drop it into the H register (High byte of HL)
|
||||
HL.High = ReadMemory(address66);
|
||||
|
||||
return 19;
|
||||
case 0x6E: // LD L, (IY+d)
|
||||
sbyte displacementVal = (sbyte)FetchByte();
|
||||
@@ -2602,6 +2676,17 @@ namespace Core.Cpu
|
||||
targetAddress = (ushort)(IY.Word + offset75);
|
||||
// Write the low byte of HL to memory
|
||||
WriteMemory(targetAddress, HL.Low);
|
||||
return 19;
|
||||
case 0x77: // LD (IY+d), A
|
||||
// 1. Fetch the displacement byte and cast it to a signed sbyte
|
||||
sbyte offset77 = (sbyte)FetchByte();
|
||||
|
||||
// 2. Calculate the exact memory address (IY + offset)
|
||||
ushort address77 = (ushort)(IY.Word + offset77);
|
||||
|
||||
// 3. Write the Accumulator (A) into memory
|
||||
WriteMemory(address77, AF.High);
|
||||
|
||||
return 19;
|
||||
case 0x7E: // LD A, (IY+d)
|
||||
// 1. Fetch the displacement byte and cast it to a signed sbyte
|
||||
|
||||
Reference in New Issue
Block a user