Push more core processor handling into base classes.

This commit is contained in:
Adrian Conlon
2025-05-04 10:53:23 +01:00
parent 47374e591d
commit 2336222c97
8 changed files with 63 additions and 73 deletions

View File

@@ -84,6 +84,10 @@ namespace EightBit
} }
} }
protected abstract void DisableInterrupts();
protected abstract void EnableInterrupts();
protected override void IncrementPC() protected override void IncrementPC()
{ {
if (this.HALT.Raised()) if (this.HALT.Raised())
@@ -120,6 +124,7 @@ namespace EightBit
protected override void HandleRESET() protected override void HandleRESET()
{ {
base.HandleRESET(); base.HandleRESET();
this.DisableInterrupts();
this.Jump(0); this.Jump(0);
} }

View File

@@ -224,10 +224,15 @@ namespace EightBit
protected virtual void DecrementPC() => --this.PC.Word; protected virtual void DecrementPC() => --this.PC.Word;
protected virtual byte FetchByte() protected virtual void ImmediateAddress()
{ {
this.Bus.Address.Assign(this.PC); this.Bus.Address.Assign(this.PC);
IncrementPC(); this.IncrementPC();
}
protected virtual byte FetchByte()
{
this.ImmediateAddress();
return this.MemoryRead(); return this.MemoryRead();
} }

View File

@@ -7,17 +7,11 @@ namespace Intel8080
{ {
using EightBit; using EightBit;
public class Intel8080 : IntelProcessor public class Intel8080(Bus bus, InputOutput ports) : IntelProcessor(bus)
{ {
public Intel8080(Bus bus, InputOutput ports)
: base(bus)
{
this.ports = ports;
}
private readonly Register16 af = new(); private readonly Register16 af = new();
private readonly InputOutput ports; private readonly InputOutput ports = ports;
private bool interruptEnable; private bool interruptEnable;
@@ -62,6 +56,7 @@ namespace Intel8080
} }
else if (this.HALT.Lowered()) else if (this.HALT.Lowered())
{ {
_ = this.FetchByte();
this.Execute(0); // NOP this.Execute(0); // NOP
} }
else else
@@ -73,7 +68,6 @@ namespace Intel8080
protected override void HandleRESET() protected override void HandleRESET()
{ {
base.HandleRESET(); base.HandleRESET();
this.DisableInterrupts();
this.Tick(3); this.Tick(3);
} }
@@ -172,9 +166,9 @@ namespace Intel8080
private static byte AdjustAuxiliaryCarrySub(byte input, byte before, byte value, int calculation) => ClearBit(input, StatusBits.AC, CalculateHalfCarrySub(before, value, calculation)); private static byte AdjustAuxiliaryCarrySub(byte input, byte before, byte value, int calculation) => ClearBit(input, StatusBits.AC, CalculateHalfCarrySub(before, value, calculation));
private void DisableInterrupts() => this.interruptEnable = false; protected override void DisableInterrupts() => this.interruptEnable = false;
private void EnableInterrupts() => this.interruptEnable = true; protected override void EnableInterrupts() => this.interruptEnable = true;
private byte R(int r) => r switch private byte R(int r) => r switch
{ {
@@ -489,7 +483,7 @@ namespace Intel8080
this.Tick(10); this.Tick(10);
break; break;
case 2: // JP HL case 2: // JP HL
this.Jump(this.HL.Word); this.Jump(this.HL);
this.Tick(4); this.Tick(4);
break; break;
case 3: // LD SP,HL case 3: // LD SP,HL

View File

@@ -238,7 +238,6 @@ namespace LR35902
protected override void HandleRESET() protected override void HandleRESET()
{ {
base.HandleRESET(); base.HandleRESET();
this.DI();
this.SP.Word = (ushort)(Mask.Sixteen - 1); this.SP.Word = (ushort)(Mask.Sixteen - 1);
this.TickMachine(4); this.TickMachine(4);
} }
@@ -247,7 +246,7 @@ namespace LR35902
{ {
base.HandleINT(); base.HandleINT();
this.RaiseHALT(); this.RaiseHALT();
this.DI(); this.DisableInterrupts();
this.Restart(this.Bus.Data); this.Restart(this.Bus.Data);
} }
@@ -387,9 +386,9 @@ namespace LR35902
private static byte Set(int n, byte operand) => SetBit(operand, Bit(n)); private static byte Set(int n, byte operand) => SetBit(operand, Bit(n));
private void DI() => this.IME = false; protected override void DisableInterrupts() => this.IME = false;
private void EI() => this.IME = true; protected override void EnableInterrupts() => this.IME = true;
private void Stop() => this.Stopped = true; private void Stop() => this.Stopped = true;
@@ -834,10 +833,10 @@ namespace LR35902
this.Execute(this.FetchByte()); this.Execute(this.FetchByte());
break; break;
case 6: // DI case 6: // DI
this.DI(); this.DisableInterrupts();
break; break;
case 7: // EI case 7: // EI
this.EI(); this.EnableInterrupts();
break; break;
default: default:
break; break;
@@ -1147,7 +1146,7 @@ namespace LR35902
private void RetI() private void RetI()
{ {
this.Return(); this.Return();
this.EI(); this.EnableInterrupts();
} }
} }
} }

View File

@@ -330,7 +330,7 @@ namespace M6502
case 0x05: this.ZeroPageRead(); this.OrR(); break; // ORA (zero page) case 0x05: this.ZeroPageRead(); this.OrR(); break; // ORA (zero page)
case 0x06: this.ZeroPageRead(); this.ModifyWrite(this.ASL()); break; // ASL (zero page) case 0x06: this.ZeroPageRead(); this.ModifyWrite(this.ASL()); break; // ASL (zero page)
case 0x08: this.SwallowRead(); this.PHP(); break; // PHP (implied) case 0x08: this.SwallowRead(); this.PHP(); break; // PHP (implied)
case 0x09: this.ImmediateRead(); this.OrR(); break; // ORA (immediate) case 0x09: this.FetchByte(); this.OrR(); break; // ORA (immediate)
case 0x0a: this.SwallowRead(); this.A = this.ASL(this.A); break; // ASL A (implied) case 0x0a: this.SwallowRead(); this.A = this.ASL(this.A); break; // ASL A (implied)
case 0x0d: this.AbsoluteRead(); this.OrR(); break; // ORA (absolute) case 0x0d: this.AbsoluteRead(); this.OrR(); break; // ORA (absolute)
case 0x0e: this.AbsoluteRead(); this.ModifyWrite(this.ASL()); break; // ASL (absolute) case 0x0e: this.AbsoluteRead(); this.ModifyWrite(this.ASL()); break; // ASL (absolute)
@@ -350,7 +350,7 @@ namespace M6502
case 0x25: this.ZeroPageRead(); this.AndR(); break; // AND (zero page) case 0x25: this.ZeroPageRead(); this.AndR(); break; // AND (zero page)
case 0x26: this.ZeroPageRead(); this.ModifyWrite(this.ROL()); break; // ROL (zero page) case 0x26: this.ZeroPageRead(); this.ModifyWrite(this.ROL()); break; // ROL (zero page)
case 0x28: this.SwallowRead(); this.PLP(); break; // PLP (implied) case 0x28: this.SwallowRead(); this.PLP(); break; // PLP (implied)
case 0x29: this.ImmediateRead(); this.AndR(); break; // AND (immediate) case 0x29: this.FetchByte(); this.AndR(); break; // AND (immediate)
case 0x2a: this.SwallowRead(); this.A = this.ROL(this.A); break; // ROL A (implied) case 0x2a: this.SwallowRead(); this.A = this.ROL(this.A); break; // ROL A (implied)
case 0x2c: this.AbsoluteRead(); this.BIT(); break; // BIT (absolute) case 0x2c: this.AbsoluteRead(); this.BIT(); break; // BIT (absolute)
case 0x2d: this.AbsoluteRead(); this.AndR(); break; // AND (absolute) case 0x2d: this.AbsoluteRead(); this.AndR(); break; // AND (absolute)
@@ -371,7 +371,7 @@ namespace M6502
case 0x45: this.ZeroPageRead(); this.EorR(); break; // EOR (zero page) case 0x45: this.ZeroPageRead(); this.EorR(); break; // EOR (zero page)
case 0x46: this.ZeroPageRead(); this.ModifyWrite(this.LSR()); break; // LSR (zero page) case 0x46: this.ZeroPageRead(); this.ModifyWrite(this.LSR()); break; // LSR (zero page)
case 0x48: this.SwallowRead(); this.Push(this.A); break; // PHA (implied) case 0x48: this.SwallowRead(); this.Push(this.A); break; // PHA (implied)
case 0x49: this.ImmediateRead(); this.EorR(); break; // EOR (immediate) case 0x49: this.FetchByte(); this.EorR(); break; // EOR (immediate)
case 0x4a: this.SwallowRead(); this.A = this.LSR(this.A); break; // LSR A (implied) case 0x4a: this.SwallowRead(); this.A = this.LSR(this.A); break; // LSR A (implied)
case 0x4c: this.AbsoluteAddress(); this.Jump(this.Bus.Address); break; // JMP (absolute) case 0x4c: this.AbsoluteAddress(); this.Jump(this.Bus.Address); break; // JMP (absolute)
case 0x4d: this.AbsoluteRead(); this.EorR(); break; // EOR (absolute) case 0x4d: this.AbsoluteRead(); this.EorR(); break; // EOR (absolute)
@@ -392,7 +392,7 @@ namespace M6502
case 0x65: this.ZeroPageRead(); this.ADC(); break; // ADC (zero page) case 0x65: this.ZeroPageRead(); this.ADC(); break; // ADC (zero page)
case 0x66: this.ZeroPageRead(); this.ModifyWrite(this.ROR()); break; // ROR (zero page) case 0x66: this.ZeroPageRead(); this.ModifyWrite(this.ROR()); break; // ROR (zero page)
case 0x68: this.SwallowRead(); this.SwallowPop(); this.A = this.Through(this.Pop()); break; // PLA (implied) case 0x68: this.SwallowRead(); this.SwallowPop(); this.A = this.Through(this.Pop()); break; // PLA (implied)
case 0x69: this.ImmediateRead(); this.ADC(); break; // ADC (immediate) case 0x69: this.FetchByte(); this.ADC(); break; // ADC (immediate)
case 0x6a: this.SwallowRead(); this.A = this.ROR(this.A); break; // ROR A (implied) case 0x6a: this.SwallowRead(); this.A = this.ROR(this.A); break; // ROR A (implied)
case 0x6c: this.IndirectAddress(); this.Jump(this.Bus.Address); break; // JMP (indirect) case 0x6c: this.IndirectAddress(); this.Jump(this.Bus.Address); break; // JMP (indirect)
case 0x6d: this.AbsoluteRead(); this.ADC(); break; // ADC (absolute) case 0x6d: this.AbsoluteRead(); this.ADC(); break; // ADC (absolute)
@@ -408,7 +408,7 @@ namespace M6502
case 0x7e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute, X) case 0x7e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute, X)
case 0x81: this.IndexedIndirectXAddress(); this.MemoryWrite(this.A); break; // STA (indexed indirect X) case 0x81: this.IndexedIndirectXAddress(); this.MemoryWrite(this.A); break; // STA (indexed indirect X)
case 0x82: this.ImmediateRead(); break; // *NOP (immediate) case 0x82: this.FetchByte(); break; // *NOP (immediate)
case 0x84: this.ZeroPageAddress(); this.MemoryWrite(this.Y); break; // STY (zero page) case 0x84: this.ZeroPageAddress(); this.MemoryWrite(this.Y); break; // STY (zero page)
case 0x85: this.ZeroPageAddress(); this.MemoryWrite(this.A); break; // STA (zero page) case 0x85: this.ZeroPageAddress(); this.MemoryWrite(this.A); break; // STA (zero page)
case 0x86: this.ZeroPageAddress(); this.MemoryWrite(this.X); break; // STX (zero page) case 0x86: this.ZeroPageAddress(); this.MemoryWrite(this.X); break; // STX (zero page)
@@ -428,14 +428,14 @@ namespace M6502
case 0x9a: this.SwallowRead(); this.S = this.X; break; // TXS (implied) case 0x9a: this.SwallowRead(); this.S = this.X; break; // TXS (implied)
case 0x9d: this.AbsoluteXAddress(); this.Fixup(); this.MemoryWrite(this.A); break; // STA (absolute, X) case 0x9d: this.AbsoluteXAddress(); this.Fixup(); this.MemoryWrite(this.A); break; // STA (absolute, X)
case 0xa0: this.ImmediateRead(); this.Y = this.Through(); break; // LDY (immediate) case 0xa0: this.FetchByte(); this.Y = this.Through(); break; // LDY (immediate)
case 0xa1: this.IndexedIndirectXRead(); this.A = this.Through(); break; // LDA (indexed indirect X) case 0xa1: this.IndexedIndirectXRead(); this.A = this.Through(); break; // LDA (indexed indirect X)
case 0xa2: this.ImmediateRead(); this.X = this.Through(); break; // LDX (immediate) case 0xa2: this.FetchByte(); this.X = this.Through(); break; // LDX (immediate)
case 0xa4: this.ZeroPageRead(); this.Y = this.Through(); break; // LDY (zero page) case 0xa4: this.ZeroPageRead(); this.Y = this.Through(); break; // LDY (zero page)
case 0xa5: this.ZeroPageRead(); this.A = this.Through(); break; // LDA (zero page) case 0xa5: this.ZeroPageRead(); this.A = this.Through(); break; // LDA (zero page)
case 0xa6: this.ZeroPageRead(); this.X = this.Through(); break; // LDX (zero page) case 0xa6: this.ZeroPageRead(); this.X = this.Through(); break; // LDX (zero page)
case 0xa8: this.SwallowRead(); this.Y = this.Through(this.A); break; // TAY (implied) case 0xa8: this.SwallowRead(); this.Y = this.Through(this.A); break; // TAY (implied)
case 0xa9: this.ImmediateRead(); this.A = this.Through(); break; // LDA (immediate) case 0xa9: this.FetchByte(); this.A = this.Through(); break; // LDA (immediate)
case 0xaa: this.SwallowRead(); this.X = this.Through(this.A); break; // TAX (implied) case 0xaa: this.SwallowRead(); this.X = this.Through(this.A); break; // TAX (implied)
case 0xac: this.AbsoluteRead(); this.Y = this.Through(); break; // LDY (absolute) case 0xac: this.AbsoluteRead(); this.Y = this.Through(); break; // LDY (absolute)
case 0xad: this.AbsoluteRead(); this.A = this.Through(); break; // LDA (absolute) case 0xad: this.AbsoluteRead(); this.A = this.Through(); break; // LDA (absolute)
@@ -453,14 +453,14 @@ namespace M6502
case 0xbd: this.AbsoluteXRead(); this.A = this.Through(); break; // LDA (absolute, X) case 0xbd: this.AbsoluteXRead(); this.A = this.Through(); break; // LDA (absolute, X)
case 0xbe: this.AbsoluteYRead(); this.X = this.Through(); break; // LDX (absolute, Y) case 0xbe: this.AbsoluteYRead(); this.X = this.Through(); break; // LDX (absolute, Y)
case 0xc0: this.ImmediateRead(); this.CMP(this.Y); break; // CPY (immediate) case 0xc0: this.FetchByte(); this.CMP(this.Y); break; // CPY (immediate)
case 0xc1: this.IndexedIndirectXRead(); this.CMP(this.A); break; // CMP (indexed indirect X) case 0xc1: this.IndexedIndirectXRead(); this.CMP(this.A); break; // CMP (indexed indirect X)
case 0xc2: this.ImmediateRead(); break; // *NOP (immediate) case 0xc2: this.FetchByte(); break; // *NOP (immediate)
case 0xc4: this.ZeroPageRead(); this.CMP(this.Y); break; // CPY (zero page) case 0xc4: this.ZeroPageRead(); this.CMP(this.Y); break; // CPY (zero page)
case 0xc5: this.ZeroPageRead(); this.CMP(this.A); break; // CMP (zero page) case 0xc5: this.ZeroPageRead(); this.CMP(this.A); break; // CMP (zero page)
case 0xc6: this.ZeroPageRead(); this.ModifyWrite(this.DEC()); break; // DEC (zero page) case 0xc6: this.ZeroPageRead(); this.ModifyWrite(this.DEC()); break; // DEC (zero page)
case 0xc8: this.SwallowRead(); this.Y = this.INC(this.Y); break; // INY (implied) case 0xc8: this.SwallowRead(); this.Y = this.INC(this.Y); break; // INY (implied)
case 0xc9: this.ImmediateRead(); this.CMP(this.A); break; // CMP (immediate) case 0xc9: this.FetchByte(); this.CMP(this.A); break; // CMP (immediate)
case 0xca: this.SwallowRead(); this.X = this.DEC(this.X); break; // DEX (implied) case 0xca: this.SwallowRead(); this.X = this.DEC(this.X); break; // DEX (implied)
case 0xcc: this.AbsoluteRead(); this.CMP(this.Y); break; // CPY (absolute) case 0xcc: this.AbsoluteRead(); this.CMP(this.Y); break; // CPY (absolute)
case 0xcd: this.AbsoluteRead(); this.CMP(this.A); break; // CMP (absolute) case 0xcd: this.AbsoluteRead(); this.CMP(this.A); break; // CMP (absolute)
@@ -476,14 +476,14 @@ namespace M6502
case 0xdd: this.AbsoluteXRead(); this.CMP(this.A); break; // CMP (absolute, X) case 0xdd: this.AbsoluteXRead(); this.CMP(this.A); break; // CMP (absolute, X)
case 0xde: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.DEC()); break; // DEC (absolute, X) case 0xde: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.DEC()); break; // DEC (absolute, X)
case 0xe0: this.ImmediateRead(); this.CMP(this.X); break; // CPX (immediate) case 0xe0: this.FetchByte(); this.CMP(this.X); break; // CPX (immediate)
case 0xe1: this.IndexedIndirectXRead(); this.SBC(); break; // SBC (indexed indirect X) case 0xe1: this.IndexedIndirectXRead(); this.SBC(); break; // SBC (indexed indirect X)
case 0xe2: this.ImmediateRead(); break; // *NOP (immediate) case 0xe2: this.FetchByte(); break; // *NOP (immediate)
case 0xe4: this.ZeroPageRead(); this.CMP(this.X); break; // CPX (zero page) case 0xe4: this.ZeroPageRead(); this.CMP(this.X); break; // CPX (zero page)
case 0xe5: this.ZeroPageRead(); this.SBC(); break; // SBC (zero page) case 0xe5: this.ZeroPageRead(); this.SBC(); break; // SBC (zero page)
case 0xe6: this.ZeroPageRead(); this.ModifyWrite(this.INC()); break; // INC (zero page) case 0xe6: this.ZeroPageRead(); this.ModifyWrite(this.INC()); break; // INC (zero page)
case 0xe8: this.SwallowRead(); this.X = this.INC(this.X); break; // INX (implied) case 0xe8: this.SwallowRead(); this.X = this.INC(this.X); break; // INX (implied)
case 0xe9: this.ImmediateRead(); this.SBC(); break; // SBC (immediate) case 0xe9: this.FetchByte(); this.SBC(); break; // SBC (immediate)
case 0xea: this.SwallowRead(); break; // NOP (implied) case 0xea: this.SwallowRead(); break; // NOP (implied)
case 0xec: this.AbsoluteRead(); this.CMP(this.X); break; // CPX (absolute) case 0xec: this.AbsoluteRead(); this.CMP(this.X); break; // CPX (absolute)
case 0xed: this.AbsoluteRead(); this.SBC(); break; // SBC (absolute) case 0xed: this.AbsoluteRead(); this.SBC(); break; // SBC (absolute)
@@ -541,7 +541,7 @@ namespace M6502
this.LowerSYNC(); this.LowerSYNC();
System.Diagnostics.Debug.Assert(this.Cycles == 1, "An extra cycle has occurred"); System.Diagnostics.Debug.Assert(this.Cycles == 1, "An extra cycle has occurred");
// Can't use fetchByte, since that would add an extra tick. // Can't use "FetchByte", since that would add an extra tick.
this.ImmediateAddress(); this.ImmediateAddress();
this.OpCode = this.ReadFromBus(); this.OpCode = this.ReadFromBus();
@@ -661,12 +661,6 @@ namespace M6502
this.Bus.Address.Assign(this.Intermediate); this.Bus.Address.Assign(this.Intermediate);
} }
protected void ImmediateAddress()
{
this.Bus.Address.Assign(this.PC);
this.IncrementPC();
}
protected void AbsoluteAddress() => this.FetchWordAddress(); protected void AbsoluteAddress() => this.FetchWordAddress();
protected void ZeroPageAddress() => this.Bus.Address.Assign(this.FetchByte(), 0); protected void ZeroPageAddress() => this.Bus.Address.Assign(this.FetchByte(), 0);
@@ -715,12 +709,6 @@ namespace M6502
#region Address and read #region Address and read
protected void ImmediateRead()
{
this.ImmediateAddress();
_ = this.MemoryRead();
}
protected void AbsoluteRead() protected void AbsoluteRead()
{ {
this.AbsoluteAddress(); this.AbsoluteAddress();
@@ -781,7 +769,7 @@ namespace M6502
protected void Branch(bool condition) protected void Branch(bool condition)
{ {
this.ImmediateRead(); this.FetchByte();
if (condition) if (condition)
{ {
var relative = (sbyte)this.Bus.Data; var relative = (sbyte)this.Bus.Data;

View File

@@ -24,7 +24,7 @@ namespace M6502
case 0x03: this.IndexedIndirectXRead(); this.SLO(); break; // *SLO (indexed indirect X) case 0x03: this.IndexedIndirectXRead(); this.SLO(); break; // *SLO (indexed indirect X)
case 0x04: this.ZeroPageRead(); break; // *NOP (zero page) case 0x04: this.ZeroPageRead(); break; // *NOP (zero page)
case 0x07: this.ZeroPageRead(); this.SLO(); break; // *SLO (zero page) case 0x07: this.ZeroPageRead(); this.SLO(); break; // *SLO (zero page)
case 0x0b: this.ImmediateRead(); this.ANC(); break; // *ANC (immediate) case 0x0b: this.FetchByte(); this.ANC(); break; // *ANC (immediate)
case 0x0c: this.AbsoluteRead(); break; // *NOP (absolute) case 0x0c: this.AbsoluteRead(); break; // *NOP (absolute)
case 0x0f: this.AbsoluteRead(); this.SLO(); break; // *SLO (absolute) case 0x0f: this.AbsoluteRead(); this.SLO(); break; // *SLO (absolute)
@@ -40,7 +40,7 @@ namespace M6502
case 0x22: this.Jam(); break; // *JAM case 0x22: this.Jam(); break; // *JAM
case 0x23: this.IndexedIndirectXRead(); this.RLA(); ; break; // *RLA (indexed indirect X) case 0x23: this.IndexedIndirectXRead(); this.RLA(); ; break; // *RLA (indexed indirect X)
case 0x27: this.ZeroPageRead(); this.RLA(); ; break; // *RLA (zero page) case 0x27: this.ZeroPageRead(); this.RLA(); ; break; // *RLA (zero page)
case 0x2b: this.ImmediateRead(); this.ANC(); break; // *ANC (immediate) case 0x2b: this.FetchByte(); this.ANC(); break; // *ANC (immediate)
case 0x2f: this.AbsoluteRead(); this.RLA(); break; // *RLA (absolute) case 0x2f: this.AbsoluteRead(); this.RLA(); break; // *RLA (absolute)
case 0x32: this.Jam(); break; // *JAM case 0x32: this.Jam(); break; // *JAM
@@ -55,7 +55,7 @@ namespace M6502
case 0x42: this.Jam(); break; // *JAM case 0x42: this.Jam(); break; // *JAM
case 0x43: this.IndexedIndirectXRead(); this.SRE(); break; // *SRE (indexed indirect X) case 0x43: this.IndexedIndirectXRead(); this.SRE(); break; // *SRE (indexed indirect X)
case 0x47: this.ZeroPageRead(); this.SRE(); break; // *SRE (zero page) case 0x47: this.ZeroPageRead(); this.SRE(); break; // *SRE (zero page)
case 0x4b: this.ImmediateRead(); this.ASR(); break; // *ASR (immediate) case 0x4b: this.FetchByte(); this.ASR(); break; // *ASR (immediate)
case 0x4f: this.AbsoluteRead(); this.SRE(); break; // *SRE (absolute) case 0x4f: this.AbsoluteRead(); this.SRE(); break; // *SRE (absolute)
case 0x52: this.Jam(); break; // *JAM case 0x52: this.Jam(); break; // *JAM
@@ -70,7 +70,7 @@ namespace M6502
case 0x63: this.IndexedIndirectXRead(); this.RRA(); break; // *RRA (indexed indirect X) case 0x63: this.IndexedIndirectXRead(); this.RRA(); break; // *RRA (indexed indirect X)
case 0x64: this.ZeroPageRead(); break; // *NOP (zero page) case 0x64: this.ZeroPageRead(); break; // *NOP (zero page)
case 0x67: this.ZeroPageRead(); this.RRA(); break; // *RRA (zero page) case 0x67: this.ZeroPageRead(); this.RRA(); break; // *RRA (zero page)
case 0x6b: this.ImmediateRead(); this.ARR(); break; // *ARR (immediate) case 0x6b: this.FetchByte(); this.ARR(); break; // *ARR (immediate)
case 0x6f: this.AbsoluteRead(); this.RRA(); break; // *RRA (absolute) case 0x6f: this.AbsoluteRead(); this.RRA(); break; // *RRA (absolute)
case 0x72: this.Jam(); break; // *JAM case 0x72: this.Jam(); break; // *JAM
@@ -82,11 +82,11 @@ namespace M6502
case 0x7c: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) case 0x7c: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X)
case 0x7f: this.AbsoluteXAddress(); this.FixupRead(); this.RRA(); break; // *RRA (absolute, X) case 0x7f: this.AbsoluteXAddress(); this.FixupRead(); this.RRA(); break; // *RRA (absolute, X)
case 0x80: this.ImmediateRead(); break; // *NOP (immediate) case 0x80: this.FetchByte(); break; // *NOP (immediate)
case 0x83: this.IndexedIndirectXAddress(); this.SAX(); break; // *SAX (indexed indirect X) case 0x83: this.IndexedIndirectXAddress(); this.SAX(); break; // *SAX (indexed indirect X)
case 0x87: this.ZeroPageAddress(); this.SAX(); break; // *SAX (zero page) case 0x87: this.ZeroPageAddress(); this.SAX(); break; // *SAX (zero page)
case 0x89: this.ImmediateRead(); break; // *NOP (immediate) case 0x89: this.FetchByte(); break; // *NOP (immediate)
case 0x8b: this.ImmediateRead(); this.ANE(); break; // *ANE (immediate) case 0x8b: this.FetchByte(); this.ANE(); break; // *ANE (immediate)
case 0x8f: this.AbsoluteAddress(); this.SAX(); break; // *SAX (absolute) case 0x8f: this.AbsoluteAddress(); this.SAX(); break; // *SAX (absolute)
case 0x92: this.Jam(); break; // *JAM case 0x92: this.Jam(); break; // *JAM
@@ -99,7 +99,7 @@ namespace M6502
case 0xa3: this.IndexedIndirectXRead(); this.LAX(); break; // *LAX (indexed indirect X) case 0xa3: this.IndexedIndirectXRead(); this.LAX(); break; // *LAX (indexed indirect X)
case 0xa7: this.ZeroPageRead(); this.LAX(); break; // *LAX (zero page) case 0xa7: this.ZeroPageRead(); this.LAX(); break; // *LAX (zero page)
case 0xab: this.ImmediateRead(); this.ATX(); break; // *ATX (immediate) case 0xab: this.FetchByte(); this.ATX(); break; // *ATX (immediate)
case 0xaf: this.AbsoluteRead(); this.LAX(); break; // *LAX (absolute) case 0xaf: this.AbsoluteRead(); this.LAX(); break; // *LAX (absolute)
case 0xb2: this.Jam(); break; // *JAM case 0xb2: this.Jam(); break; // *JAM
@@ -110,7 +110,7 @@ namespace M6502
case 0xc3: this.IndexedIndirectXRead(); this.DCP(); break; // *DCP (indexed indirect X) case 0xc3: this.IndexedIndirectXRead(); this.DCP(); break; // *DCP (indexed indirect X)
case 0xc7: this.ZeroPageRead(); this.DCP(); break; // *DCP (zero page) case 0xc7: this.ZeroPageRead(); this.DCP(); break; // *DCP (zero page)
case 0xcb: this.ImmediateRead(); this.AXS(); break; // *AXS (immediate) case 0xcb: this.FetchByte(); this.AXS(); break; // *AXS (immediate)
case 0xcf: this.AbsoluteRead(); this.DCP(); break; // *DCP (absolute) case 0xcf: this.AbsoluteRead(); this.DCP(); break; // *DCP (absolute)
case 0xd2: this.Jam(); break; // *JAM case 0xd2: this.Jam(); break; // *JAM
@@ -123,7 +123,7 @@ namespace M6502
case 0xe3: this.IndexedIndirectXRead(); this.ISB(); break; // *ISB (indexed indirect X) case 0xe3: this.IndexedIndirectXRead(); this.ISB(); break; // *ISB (indexed indirect X)
case 0xe7: this.ZeroPageRead(); this.ISB(); break; // *ISB (zero page) case 0xe7: this.ZeroPageRead(); this.ISB(); break; // *ISB (zero page)
case 0xeb: this.ImmediateRead(); this.SBC(); break; // *SBC (immediate) case 0xeb: this.FetchByte(); this.SBC(); break; // *SBC (immediate)
case 0xef: this.AbsoluteRead(); this.ISB(); break; // *ISB (absolute) case 0xef: this.AbsoluteRead(); this.ISB(); break; // *ISB (absolute)
case 0xf2: this.Jam(); break; // *JAM case 0xf2: this.Jam(); break; // *JAM

View File

@@ -228,8 +228,15 @@
var pc_good = this.Check("PC", final.PC, cpu.PC); var pc_good = this.Check("PC", final.PC, cpu.PC);
var sp_good = this.Check("SP", final.SP, cpu.SP); var sp_good = this.Check("SP", final.SP, cpu.SP);
var a_good = this.Check("A", final.A, cpu.A); //byte xyMask = 0;
//unchecked
//{
// xyMask = (byte)~(StatusBits.XF | StatusBits.YF);
//}
//var f_good = this.Check("F", (byte)(final.F & xyMask), (byte)(cpu.F & xyMask));
var f_good = this.Check("F", final.F, cpu.F); var f_good = this.Check("F", final.F, cpu.F);
var a_good = this.Check("A", final.A, cpu.A);
var b_good = this.Check("B", final.B, cpu.B); var b_good = this.Check("B", final.B, cpu.B);
var c_good = this.Check("C", final.C, cpu.C); var c_good = this.Check("C", final.C, cpu.C);
var d_good = this.Check("D", final.D, cpu.D); var d_good = this.Check("D", final.D, cpu.D);

View File

@@ -158,7 +158,7 @@ namespace Z80
// received from the memory is ignored and an NOP instruction is forced internally to the // received from the memory is ignored and an NOP instruction is forced internally to the
// CPU.The HALT acknowledge signal is active during this time indicating that the processor // CPU.The HALT acknowledge signal is active during this time indicating that the processor
// is in the HALT state. // is in the HALT state.
_ = this.ReadInitialOpCode(); _ = this.FetchInitialOpCode();
this.Execute(0); // NOP this.Execute(0); // NOP
handled = true; handled = true;
} }
@@ -519,7 +519,6 @@ namespace Z80
protected override void HandleRESET() protected override void HandleRESET()
{ {
base.HandleRESET(); base.HandleRESET();
this.DisableInterrupts();
this.IV = this.REFRESH = 0; this.IV = this.REFRESH = 0;
this.SP.Word = this.AF.Word = (ushort)Mask.Sixteen; this.SP.Word = this.AF.Word = (ushort)Mask.Sixteen;
this.Tick(3); this.Tick(3);
@@ -708,9 +707,9 @@ namespace Z80
private static byte SET(int n, byte operand) => SetBit(operand, Bit(n)); private static byte SET(int n, byte operand) => SetBit(operand, Bit(n));
private void DisableInterrupts() => this.IFF1 = this.IFF2 = false; protected override void DisableInterrupts() => this.IFF1 = this.IFF2 = false;
private void EnableInterrupts() => this.IFF1 = this.IFF2 = true; protected override void EnableInterrupts() => this.IFF1 = this.IFF2 = true;
private Register16 HL2() => this._prefixDD ? this.IX : this._prefixFD ? this.IY : this.HL; private Register16 HL2() => this._prefixDD ? this.IX : this._prefixFD ? this.IY : this.HL;
@@ -1669,13 +1668,6 @@ namespace Z80
private void FetchDisplacement() => this._displacement = (sbyte)this.FetchByte(); private void FetchDisplacement() => this._displacement = (sbyte)this.FetchByte();
private byte FetchInitialOpCode()
{
var returned = this.ReadInitialOpCode();
this.IncrementPC();
return returned;
}
// ** From the Z80 CPU User Manual // ** From the Z80 CPU User Manual
// Figure 5 depicts the timing during an M1 (op code fetch) cycle. The Program Counter is // Figure 5 depicts the timing during an M1 (op code fetch) cycle. The Program Counter is
// placed on the address bus at the beginning of the M1 cycle. One half clock cycle later, the // placed on the address bus at the beginning of the M1 cycle. One half clock cycle later, the
@@ -1688,10 +1680,10 @@ namespace Z80
// before the RD signal becomes inactive. Clock states T3 and T4 of a fetch cycle are used to // before the RD signal becomes inactive. Clock states T3 and T4 of a fetch cycle are used to
// _refresh dynamic memories. The CPU uses this time to decode and execute the fetched // _refresh dynamic memories. The CPU uses this time to decode and execute the fetched
// instruction so that no other concurrent operation can be performed. // instruction so that no other concurrent operation can be performed.
private byte ReadInitialOpCode() private byte FetchInitialOpCode()
{ {
this.LowerM1(); this.LowerM1();
var returned = this.MemoryRead(this.PC); var returned = this.FetchByte();
this.RaiseM1(); this.RaiseM1();
return returned; return returned;
} }