Some fixes and code refactoring
This commit is contained in:
@@ -25,10 +25,12 @@ namespace Core.Cpu
|
||||
|
||||
public int InterruptMode { get; private set; } = 0;
|
||||
|
||||
|
||||
// Interrupt Flip-Flops
|
||||
public bool IFF1 { get; private set; } = false;
|
||||
public bool IFF2 { get; private set; } = false;
|
||||
public bool InterruptRequested { get; private set; } = false;
|
||||
private bool _eiPending = false;
|
||||
|
||||
// Main Register Set
|
||||
public RegisterPair AF;
|
||||
@@ -213,7 +215,8 @@ namespace Core.Cpu
|
||||
}
|
||||
|
||||
public int Step()
|
||||
{
|
||||
{
|
||||
bool triggerEi = _eiPending;
|
||||
|
||||
// Fetch the next opcode and increment the Program Counter
|
||||
byte opcode = ReadMemory(PC++);
|
||||
@@ -221,6 +224,13 @@ namespace Core.Cpu
|
||||
int tStates = ExecuteOpcode(opcode);
|
||||
TotalTStates += tStates;
|
||||
|
||||
if (triggerEi)
|
||||
{
|
||||
IFF1 = true;
|
||||
IFF2 = true;
|
||||
_eiPending = false;
|
||||
}
|
||||
|
||||
// Decode and execute
|
||||
return tStates;
|
||||
}
|
||||
@@ -240,9 +250,6 @@ namespace Core.Cpu
|
||||
$"C:{f & 1}";
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// MATH AND LOGIC HELPERS
|
||||
// =========================================================================
|
||||
|
||||
private void SubA(byte value, bool isCompare)
|
||||
{
|
||||
@@ -1272,6 +1279,7 @@ namespace Core.Cpu
|
||||
case 0xF3: // DI
|
||||
IFF1 = false;
|
||||
IFF2 = false;
|
||||
_eiPending = false;
|
||||
return 4;
|
||||
case 0xf5: //push af
|
||||
Push(AF.Word);
|
||||
@@ -1283,8 +1291,7 @@ namespace Core.Cpu
|
||||
SP = HL.Word;
|
||||
return 6;
|
||||
case 0xFB: // EI
|
||||
IFF1 = true;
|
||||
IFF2 = true;
|
||||
_eiPending = true;
|
||||
return 4;
|
||||
case 0xFD:
|
||||
return ExecuteFDPrefix();
|
||||
|
||||
@@ -42,6 +42,11 @@ namespace Core.Memory
|
||||
|
||||
public byte Read(ushort address)
|
||||
{
|
||||
if (address < 0xC000 && !_isCartridgeLoaded)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
if (address < 0x4000)
|
||||
{
|
||||
if (address < 0x0400)
|
||||
@@ -65,7 +70,7 @@ namespace Core.Memory
|
||||
return _cartridgeRom[(_romBank2 * 0x4000) + (address - 0x8000)];
|
||||
}
|
||||
|
||||
// THE FIX 1: Bitwise AND perfectly forces 0xE000-0xFFFF to mirror down to 0xC000!
|
||||
// Bitwise AND perfectly forces 0xE000-0xFFFF to mirror down to 0xC000!
|
||||
return _workRam[address & 0x1FFF];
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Core.Video
|
||||
_isSecondControlByte = false; // Reading data resets the control latch
|
||||
byte value = _readBuffer;
|
||||
_readBuffer = VRAM[_controlWord & 0x3FFF];
|
||||
_controlWord++;
|
||||
IncrementVdpAddress();
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Core.Video
|
||||
}
|
||||
|
||||
// THE FIX: The pointer MUST auto-increment so the CPU can blast data fast!
|
||||
_controlWord++;
|
||||
IncrementVdpAddress();
|
||||
}
|
||||
|
||||
public void WriteControlPort(byte value) // Port 0xBF
|
||||
@@ -104,7 +104,7 @@ namespace Core.Video
|
||||
if (command == 0) // Code 0: Prep for VRAM Read
|
||||
{
|
||||
_readBuffer = VRAM[_controlWord & 0x3FFF];
|
||||
_controlWord++;
|
||||
IncrementVdpAddress();
|
||||
}
|
||||
else if (command == 2) // Code 2: Write to Internal VDP Register
|
||||
{
|
||||
@@ -116,6 +116,18 @@ namespace Core.Video
|
||||
}
|
||||
}
|
||||
|
||||
private void IncrementVdpAddress()
|
||||
{
|
||||
// The VDP address register is only 14 bits
|
||||
// When it increments past 0x3FFF, it rolls over to 0x0000.
|
||||
// It can't overflow and corrupt the 2-bit command register (bits 14 and 15).
|
||||
ushort address = (ushort)(_controlWord & 0x3FFF);
|
||||
ushort command = (ushort)(_controlWord & 0xC000);
|
||||
|
||||
address = (ushort)((address + 1) & 0x3FFF);
|
||||
_controlWord = (ushort)(command | address);
|
||||
}
|
||||
|
||||
public byte ReadVCounter()
|
||||
{
|
||||
// NTSC Math: 262 lines. Counts 0 to 218, jumps to 213 (0xD5), counts to 255.
|
||||
|
||||
Reference in New Issue
Block a user