Try to minimise use of "Word" from Register16

This commit is contained in:
Adrian Conlon 2024-06-30 12:30:07 +01:00
parent 325bee8539
commit d8fad7b988
8 changed files with 157 additions and 68 deletions

View File

@ -50,7 +50,7 @@ namespace EightBit
return this.Read();
}
public byte Read(Register16 absolute) => this.Read(absolute.Word);
public byte Read(Register16 absolute) => this.Read(absolute.Low, absolute.High);
public byte Read(byte low, byte high)
{
@ -79,7 +79,7 @@ namespace EightBit
this.Write(value);
}
public void Write(Register16 absolute, byte value) => this.Write(absolute.Word, value);
public void Write(Register16 absolute, byte value) => this.Write(absolute.Low, absolute.High, value);
public void Write(byte low, byte high, byte value)
{

View File

@ -127,21 +127,32 @@ namespace EightBit
this.Jump(0);
}
protected sealed override void Push(byte value) => this.MemoryWrite(--this.SP.Word, value);
protected sealed override void Push(byte value)
{
--this.SP.Word;
this.MemoryWrite(this.SP, value);
}
protected sealed override byte Pop() => this.MemoryRead(this.SP.Word++);
protected sealed override byte Pop()
{
var returned = this.MemoryRead(this.SP);
this.SP.Word++;
return returned;
}
protected sealed override Register16 GetWord()
{
var returned = base.GetWord();
this.MEMPTR.Word = this.Bus.Address.Word;
this.MEMPTR.Low = this.Bus.Address.Low;
this.MEMPTR.High = this.Bus.Address.High;
return returned;
}
protected sealed override void SetWord(Register16 value)
{
base.SetWord(value);
this.MEMPTR.Word = this.Bus.Address.Word;
this.MEMPTR.Low = this.Bus.Address.Low;
this.MEMPTR.High = this.Bus.Address.High;
}
////
@ -150,15 +161,15 @@ namespace EightBit
{
this.MEMPTR.Low = address;
this.MEMPTR.High = 0;
this.Call(this.MEMPTR.Word);
this.Call(this.MEMPTR);
}
protected bool CallConditional(bool condition)
{
this.MEMPTR.Word = this.FetchWord().Word;
this.FetchWordMEMPTR();
if (condition)
{
this.Call(this.MEMPTR.Word);
this.Call(this.MEMPTR);
}
return condition;
@ -166,10 +177,10 @@ namespace EightBit
protected bool JumpConditional(bool condition)
{
this.MEMPTR.Word = this.FetchWord().Word;
this.FetchWordMEMPTR();
if (condition)
{
this.Jump(this.MEMPTR.Word);
this.Jump(this.MEMPTR);
}
return condition;
@ -185,18 +196,39 @@ namespace EightBit
return condition;
}
protected void FetchWordMEMPTR()
{
this.FetchWord();
this.MEMPTR.Low = this.Intermediate.Low;
this.MEMPTR.High = this.Intermediate.High;
}
protected void JumpIndirect()
{
this.FetchWordMEMPTR();
this.Jump(this.MEMPTR);
}
protected void CallIndirect()
{
this.FetchWordMEMPTR();
this.Call(this.MEMPTR);
}
protected void JumpRelative(sbyte offset)
{
this.MEMPTR.Word = (ushort)(this.PC.Word + offset);
this.Jump(this.MEMPTR.Word);
this.Jump(this.MEMPTR);
}
protected bool JumpRelativeConditional(bool condition)
{
var offsetAddress = this.PC.Word++;
this.Intermediate.Low = this.PC.Low;
this.Intermediate.High = this.PC.High;
++this.PC.Word;
if (condition)
{
var offset = (sbyte)this.MemoryRead(offsetAddress);
var offset = (sbyte)this.MemoryRead(this.Intermediate);
this.JumpRelative(offset);
}
@ -206,7 +238,8 @@ namespace EightBit
protected override sealed void Return()
{
base.Return();
this.MEMPTR.Word = this.PC.Word;
this.MEMPTR.Low = this.PC.Low;
this.MEMPTR.High = this.PC.High;
}
}
}

View File

@ -149,7 +149,7 @@ namespace EightBit
this.MemoryWrite(data);
}
protected void MemoryWrite(Register16 address, byte data) => this.MemoryWrite(address.Word, data);
protected void MemoryWrite(Register16 address, byte data) => this.MemoryWrite(address.Low, address.High, data);
protected void MemoryWrite(byte data)
{
@ -174,13 +174,18 @@ namespace EightBit
return this.MemoryRead();
}
protected byte MemoryRead(Register16 address) => this.MemoryRead(address.Word);
protected byte MemoryRead(Register16 address) => this.MemoryRead(address.Low, address.High);
protected virtual byte MemoryRead() => this.BusRead();
protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
protected byte FetchByte() => this.MemoryRead(this.PC.Word++);
protected byte FetchByte()
{
var returned = this.MemoryRead(this.PC);
this.PC.Word++;
return returned;
}
protected abstract Register16 GetWord();
@ -216,6 +221,13 @@ namespace EightBit
protected abstract Register16 FetchWord();
protected void FetchWordAddress()
{
this.FetchWord();
this.Bus.Address.Low = this.Intermediate.Low;
this.Bus.Address.High = this.Intermediate.High;
}
protected abstract void Push(byte value);
protected abstract byte Pop();
@ -230,7 +242,12 @@ namespace EightBit
return this.GetWord();
}
protected Register16 GetWord(Register16 address) => this.GetWord(address.Word);
protected Register16 GetWord(Register16 address)
{
this.Bus.Address.Low = address.Low;
this.Bus.Address.High = address.High;
return this.GetWord();
}
protected void SetWord(ushort address, Register16 value)
{
@ -238,16 +255,33 @@ namespace EightBit
this.SetWord(value);
}
protected void SetWord(Register16 address, Register16 value) => this.SetWord(address.Word, value);
protected void SetWord(Register16 address, Register16 value)
{
this.Bus.Address.Low = address.Low;
this.Bus.Address.High = address.High;
this.SetWord(value);
}
protected void Jump(ushort destination) => this.PC.Word = destination;
protected virtual void Call(ushort destination)
protected void Jump(Register16 destination)
{
this.PC.Low = destination.Low;
this.PC.High = destination.High;
}
protected void Call(ushort destination)
{
this.Intermediate.Word = destination;
this.Call(this.Intermediate);
}
protected virtual void Call(Register16 destination)
{
this.PushWord(this.PC);
this.Jump(destination);
}
protected virtual void Return() => this.Jump(this.PopWord().Word);
protected virtual void Return() => this.Jump(this.PopWord());
}
}

View File

@ -499,7 +499,7 @@ namespace EightBit
switch (y)
{
case 0: // JP nn
this.Jump(this.FetchWord().Word);
this.JumpIndirect();
this.Tick(10);
break;
case 2: // OUT (n),A
@ -548,7 +548,7 @@ namespace EightBit
switch (p)
{
case 0: // CALL nn
this.Call(this.FetchWord().Word);
this.CallIndirect();
this.Tick(17);
break;
}

View File

@ -746,7 +746,7 @@ namespace EightBit.GameBoy
switch (y)
{
case 0: // JP nn
this.Jump(this.FetchWord().Word);
this.JumpIndirect();
this.Tick(4);
break;
case 1: // CB prefix
@ -786,7 +786,7 @@ namespace EightBit.GameBoy
switch (p)
{
case 0: // CALL nn
this.Call(this.FetchWord().Word);
this.CallIndirect();
this.Tick(6);
break;
}

View File

@ -233,7 +233,7 @@ namespace EightBit
this.Push((byte)(this.P | (source == InterruptSource.hardware ? 0 : (byte)StatusBits.BF)));
}
this.SetFlag(StatusBits.IF); // Disable IRQ
this.Jump(this.GetWordPaged(0xff, vector).Word);
this.Jump(this.GetWordPaged(0xff, vector));
}
#region Interrupt etc. handlers
@ -341,7 +341,7 @@ namespace EightBit
#region Cycle wastage
protected void SwallowRead() => this.MemoryRead(this.PC.Word);
protected void SwallowRead() => this.MemoryRead(this.PC);
protected void SwallowPop() => this.MemoryRead(this.S, 1);
@ -408,7 +408,7 @@ namespace EightBit
case 0x48: this.SwallowRead(); this.Push(this.A); break; // PHA (implied)
case 0x49: this.ImmediateRead(); this.EorR(); break; // EOR (immediate)
case 0x4a: this.SwallowRead(); this.A = this.LSR(this.A); break; // LSR A (implied)
case 0x4c: this.AbsoluteAddress(); this.Jump(this.Bus.Address.Word); 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 0x4e: this.AbsoluteRead(); this.ModifyWrite(this.LSR()); break; // LSR (absolute)
@ -428,7 +428,7 @@ namespace EightBit
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 0x6a: this.SwallowRead(); this.A = this.ROR(this.A); break; // ROR A (implied)
case 0x6c: this.IndirectAddress(); this.Jump(this.Bus.Address.Word); 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 0x6e: this.AbsoluteRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute)
@ -718,9 +718,14 @@ namespace EightBit
this.Bus.Address.Low = this.Intermediate.Low;
}
protected void ImmediateAddress() => this.Bus.Address.Word = this.PC.Word++;
protected void ImmediateAddress()
{
this.Bus.Address.Low = this.PC.Low;
this.Bus.Address.High = this.PC.High;
++this.PC.Word;
}
protected void AbsoluteAddress() => this.Bus.Address.Word = this.FetchWord().Word;
protected void AbsoluteAddress() => this.FetchWordAddress();
protected void ZeroPageAddress()
{
@ -731,13 +736,17 @@ namespace EightBit
protected void ZeroPageIndirectAddress()
{
this.ZeroPageAddress();
this.Bus.Address.Word = this.GetWordPaged().Word;
this.GetWordPaged();
this.Bus.Address.Low = this.Intermediate.Low;
this.Bus.Address.High = this.Intermediate.High;
}
protected void IndirectAddress()
{
this.AbsoluteAddress();
this.Bus.Address.Word = this.GetWordPaged().Word;
this.GetWordPaged();
this.Bus.Address.Low = this.Intermediate.Low;
this.Bus.Address.High = this.Intermediate.High;
}
protected void ZeroPageWithIndexAddress(byte index)
@ -763,7 +772,9 @@ namespace EightBit
protected void IndexedIndirectXAddress()
{
this.ZeroPageXAddress();
this.Bus.Address.Word = this.GetWordPaged().Word;
this.GetWordPaged();
this.Bus.Address.Low = this.Intermediate.Low;
this.Bus.Address.High = this.Intermediate.High;
}
protected void IndirectIndexedYAddress()
@ -849,7 +860,7 @@ namespace EightBit
this.SwallowRead();
this.NoteFixedAddress(this.PC.Word + relative);
this.MaybeFixup();
this.Jump(this.Bus.Address.Word);
this.Jump(this.Bus.Address);
}
}

View File

@ -753,9 +753,7 @@ namespace EightBit
private Register16 ST(Register16 data) => this.Through(data);
private void Jump(Register16 destination) => this.Jump(destination.Word);
private bool Branch(ushort destination, bool condition)
private bool Branch(Register16 destination, bool condition)
{
if (condition)
{
@ -765,8 +763,6 @@ namespace EightBit
return condition;
}
private bool Branch(Register16 destination, bool condition) => this.Branch(destination.Word, condition);
private void BranchShort(bool condition) => this.Branch(this.Address_relative_byte(), condition);
private void BranchLong(bool condition)
@ -1431,9 +1427,7 @@ namespace EightBit
return result;
}
private void JSR(ushort address) => this.Call(address);
private void JSR(Register16 address) => this.JSR(address.Word);
private void JSR(Register16 address) => this.Call(address);
private byte LSR(byte operand)
{

View File

@ -539,14 +539,14 @@ namespace EightBit
this.Tick(7);
this.MEMPTR.Low = data;
this.MEMPTR.High = this.IV;
this.Call(this.MEMPTR.Word);
this.Call(this.MEMPTR);
break;
default:
throw new NotSupportedException("Invalid interrupt mode");
}
}
protected override void Call(ushort destination)
protected override void Call(Register16 destination)
{
this.Tick();
base.Call(destination);
@ -715,7 +715,7 @@ namespace EightBit
this.L = value;
break;
case 6:
this.MemoryWrite(this.HL.Word, value);
this.MemoryWrite(this.HL, value);
break;
case 7:
this.A = value;
@ -803,7 +803,8 @@ namespace EightBit
switch (z)
{
case 0: // Input from port with 16-bit address
this.MEMPTR.Word = this.Bus.Address.Word = this.BC.Word;
this.MEMPTR.Low = this.Bus.Address.Low = this.BC.Low;
this.MEMPTR.High = this.Bus.Address.High = this.BC.High;
this.MEMPTR.Word++;
this.ReadPort();
if (y != 6)
@ -815,7 +816,8 @@ namespace EightBit
this.F = ClearBit(this.F, StatusBits.NF | StatusBits.HC);
break;
case 1: // Output to port with 16-bit address
this.MEMPTR.Word = this.Bus.Address.Word = this.BC.Word;
this.MEMPTR.Low = this.Bus.Address.Low = this.BC.Low;
this.MEMPTR.High = this.Bus.Address.High = this.BC.High;
this.MEMPTR.Word++;
this.Bus.Data = y != 6 ? this.R(y) : (byte)0;
this.WritePort();
@ -829,7 +831,7 @@ namespace EightBit
};
break;
case 3: // Retrieve/store register pair from/to immediate address
this.Bus.Address.Word = this.FetchWord().Word;
this.FetchWordAddress();
switch (q)
{
case 0: // LD (nn), rp[p]
@ -920,7 +922,9 @@ namespace EightBit
case 6: // LDIR
if (this.LDIR())
{
this.MEMPTR.Word = --this.PC.Word;
--this.PC.Word;
this.MEMPTR.Low = this.PC.Low;
this.MEMPTR.High = this.PC.High;
--this.PC.Word;
}
@ -929,7 +933,9 @@ namespace EightBit
case 7: // LDDR
if (this.LDDR())
{
this.MEMPTR.Word = --this.PC.Word;
--this.PC.Word;
this.MEMPTR.Low = this.PC.Low;
this.MEMPTR.High = this.PC.High;
--this.PC.Word;
}
@ -950,7 +956,9 @@ namespace EightBit
case 6: // CPIR
if (this.CPIR())
{
this.MEMPTR.Word = --this.PC.Word;
--this.PC.Word;
this.MEMPTR.Low = this.PC.Low;
this.MEMPTR.High = this.PC.High;
--this.PC.Word;
this.Tick(5);
}
@ -960,7 +968,9 @@ namespace EightBit
case 7: // CPDR
if (this.CPDR())
{
this.MEMPTR.Word = --this.PC.Word;
--this.PC.Word;
this.MEMPTR.Low = this.PC.Low;
this.MEMPTR.High = this.PC.High;
--this.PC.Word;
this.Tick(3);
}
@ -1099,23 +1109,27 @@ namespace EightBit
switch (p)
{
case 0: // LD (BC),A
this.MEMPTR.Word = this.Bus.Address.Word = this.BC.Word;
this.MEMPTR.Low = this.Bus.Address.Low = this.BC.Low;
this.MEMPTR.High = this.Bus.Address.High = this.BC.High;
++this.MEMPTR.Word;
this.MEMPTR.High = this.Bus.Data = this.A;
this.MemoryWrite();
break;
case 1: // LD (DE),A
this.MEMPTR.Word = this.Bus.Address.Word = this.DE.Word;
this.MEMPTR.Low = this.Bus.Address.Low = this.DE.Low;
this.MEMPTR.High = this.Bus.Address.High = this.DE.High;
++this.MEMPTR.Word;
this.MEMPTR.High = this.Bus.Data = this.A;
this.MemoryWrite();
break;
case 2: // LD (nn),HL
this.Bus.Address.Word = this.FetchWord().Word;
this.FetchWordAddress();
this.SetWord(this.HL2());
break;
case 3: // LD (nn),A
this.MEMPTR.Word = this.Bus.Address.Word = this.FetchWord().Word;
this.FetchWordMEMPTR();
this.Bus.Address.Low = this.MEMPTR.Low;
this.Bus.Address.High = this.MEMPTR.High;
++this.MEMPTR.Word;
this.MEMPTR.High = this.Bus.Data = this.A;
this.MemoryWrite();
@ -1129,21 +1143,25 @@ namespace EightBit
switch (p)
{
case 0: // LD A,(BC)
this.MEMPTR.Word = this.Bus.Address.Word = this.BC.Word;
this.MEMPTR.Low = this.Bus.Address.Low = this.BC.Low;
this.MEMPTR.High = this.Bus.Address.High = this.BC.High;
++this.MEMPTR.Word;
this.A = this.MemoryRead();
break;
case 1: // LD A,(DE)
this.MEMPTR.Word = this.Bus.Address.Word = this.DE.Word;
this.MEMPTR.Low = this.Bus.Address.Low = this.DE.Low;
this.MEMPTR.High = this.Bus.Address.High = this.DE.High;
++this.MEMPTR.Word;
this.A = this.MemoryRead();
break;
case 2: // LD HL,(nn)
this.Bus.Address.Word = this.FetchWord().Word;
this.FetchWordAddress();
this.HL2().Word = this.GetWord().Word;
break;
case 3: // LD A,(nn)
this.MEMPTR.Word = this.Bus.Address.Word = this.FetchWord().Word;
this.FetchWordMEMPTR();
this.Bus.Address.Low = this.MEMPTR.Low;
this.Bus.Address.High = this.MEMPTR.High;
++this.MEMPTR.Word;
this.A = this.MemoryRead();
break;
@ -1395,7 +1413,7 @@ namespace EightBit
this.Exx();
break;
case 2: // JP HL
this.Jump(this.HL2().Word);
this.Jump(this.HL2());
break;
case 3: // LD SP,HL
this.SP.Word = this.HL2().Word;
@ -1417,7 +1435,7 @@ namespace EightBit
switch (y)
{
case 0: // JP nn
this.Jump(this.MEMPTR.Word = this.FetchWord().Word);
this.JumpIndirect();
break;
case 1: // CB prefix
this.prefixCB = true;
@ -1469,8 +1487,7 @@ namespace EightBit
switch (p)
{
case 0: // CALL nn
this.MEMPTR.Word = this.FetchWord().Word;
this.Call(this.MEMPTR.Word);
this.CallIndirect();
break;
case 1: // DD prefix
this.displaced = this.prefixDD = true;
@ -1578,7 +1595,7 @@ namespace EightBit
{
this.Tick();
this.LowerM1();
var returned = this.MemoryRead(this.PC.Word);
var returned = this.MemoryRead(this.PC);
this.RaiseM1();
this.Bus.Address.Low = this.REFRESH;
this.Bus.Address.High = this.IV;
@ -1911,7 +1928,7 @@ namespace EightBit
private void XHTL(Register16 exchange)
{
this.MEMPTR.Low = this.MemoryRead(this.SP.Word);
this.MEMPTR.Low = this.MemoryRead(this.SP);
++this.Bus.Address.Word;
this.MEMPTR.High = this.MemoryRead();
this.Tick();