Rationalise use of "intermediate" Register16

This commit is contained in:
Adrian Conlon
2024-06-29 13:38:55 +01:00
parent 7f0ca27412
commit 6e46c8e47f
5 changed files with 65 additions and 70 deletions

View File

@@ -5,13 +5,11 @@ namespace EightBit
{ {
public abstract class BigEndianProcessor(Bus memory) : Processor(memory) public abstract class BigEndianProcessor(Bus memory) : Processor(memory)
{ {
private readonly Register16 intermediate = new();
public override Register16 PeekWord(ushort address) public override Register16 PeekWord(ushort address)
{ {
this.intermediate.High = this.Bus.Peek(address); this.Intermediate.High = this.Bus.Peek(address);
this.intermediate.Low = this.Bus.Peek(++address); this.Intermediate.Low = this.Bus.Peek(++address);
return this.intermediate; return this.Intermediate;
} }
public override void PokeWord(ushort address, Register16 value) public override void PokeWord(ushort address, Register16 value)
@@ -22,32 +20,32 @@ namespace EightBit
protected override Register16 FetchWord() protected override Register16 FetchWord()
{ {
this.intermediate.High = this.FetchByte(); this.Intermediate.High = this.FetchByte();
this.intermediate.Low = this.FetchByte(); this.Intermediate.Low = this.FetchByte();
return this.intermediate; return this.Intermediate;
} }
protected override Register16 GetWord() protected override Register16 GetWord()
{ {
this.intermediate.High = this.MemoryRead(); this.Intermediate.High = this.MemoryRead();
++this.Bus.Address.Word; ++this.Bus.Address.Word;
this.intermediate.Low = this.MemoryRead(); this.Intermediate.Low = this.MemoryRead();
return this.intermediate; return this.Intermediate;
} }
protected override Register16 GetWordPaged() protected override Register16 GetWordPaged()
{ {
this.intermediate.High = this.MemoryRead(); this.Intermediate.High = this.MemoryRead();
++this.Bus.Address.Low; ++this.Bus.Address.Low;
this.intermediate.Low = this.MemoryRead(); this.Intermediate.Low = this.MemoryRead();
return this.intermediate; return this.Intermediate;
} }
protected override Register16 PopWord() protected override Register16 PopWord()
{ {
this.intermediate.High = this.Pop(); this.Intermediate.High = this.Pop();
this.intermediate.Low = this.Pop(); this.Intermediate.Low = this.Pop();
return this.intermediate; return this.Intermediate;
} }
protected override void PushWord(Register16 value) protected override void PushWord(Register16 value)

View File

@@ -20,7 +20,7 @@ namespace EightBit
public byte Data { get => this.data; set => this.data = value; } public byte Data { get => this.data; set => this.data = value; }
public Register16 Address { get; } = new Register16(); public Register16 Address { get; } = new();
public abstract MemoryMapping Mapping(ushort absolute); public abstract MemoryMapping Mapping(ushort absolute);
@@ -30,16 +30,12 @@ namespace EightBit
public byte Peek(Register16 absolute) => this.Peek(absolute.Word); public byte Peek(Register16 absolute) => this.Peek(absolute.Word);
public byte Peek(byte low, byte high) => this.Reference(low, high);
public void Poke(byte value) => this.Reference() = value; public void Poke(byte value) => this.Reference() = value;
public void Poke(ushort absolute, byte value) => this.Reference(absolute) = value; public void Poke(ushort absolute, byte value) => this.Reference(absolute) = value;
public void Poke(Register16 absolute, byte value) => this.Poke(absolute.Word, value); public void Poke(Register16 absolute, byte value) => this.Poke(absolute.Word, value);
public void Poke(byte low, byte high, byte value) => this.Reference(low, high) = value;
public byte Read() public byte Read()
{ {
this.OnReadingByte(); this.OnReadingByte();
@@ -127,8 +123,6 @@ namespace EightBit
protected ref byte Reference() => ref this.Reference(this.Address); protected ref byte Reference() => ref this.Reference(this.Address);
protected ref byte Reference(byte low, byte high) => ref this.Reference(new Register16(low, high).Word);
protected void LoadHexFile(string path) protected void LoadHexFile(string path)
{ {
using var file = new IntelHexFile(path); using var file = new IntelHexFile(path);

View File

@@ -6,13 +6,11 @@ namespace EightBit
{ {
public abstract class LittleEndianProcessor(Bus memory) : Processor(memory) public abstract class LittleEndianProcessor(Bus memory) : Processor(memory)
{ {
private readonly Register16 intermediate = new();
public override Register16 PeekWord(ushort address) public override Register16 PeekWord(ushort address)
{ {
this.intermediate.Low = this.Bus.Peek(address); this.Intermediate.Low = this.Bus.Peek(address);
this.intermediate.High = this.Bus.Peek(++address); this.Intermediate.High = this.Bus.Peek(++address);
return this.intermediate; return this.Intermediate;
} }
public override void PokeWord(ushort address, Register16 value) public override void PokeWord(ushort address, Register16 value)
@@ -23,32 +21,32 @@ namespace EightBit
protected override Register16 FetchWord() protected override Register16 FetchWord()
{ {
this.intermediate.Low = this.FetchByte(); this.Intermediate.Low = this.FetchByte();
this.intermediate.High = this.FetchByte(); this.Intermediate.High = this.FetchByte();
return this.intermediate; return this.Intermediate;
} }
protected override Register16 GetWord() protected override Register16 GetWord()
{ {
this.intermediate.Low = this.MemoryRead(); this.Intermediate.Low = this.MemoryRead();
++this.Bus.Address.Word; ++this.Bus.Address.Word;
this.intermediate.High = this.MemoryRead(); this.Intermediate.High = this.MemoryRead();
return this.intermediate; return this.Intermediate;
} }
protected override Register16 GetWordPaged() protected override Register16 GetWordPaged()
{ {
this.intermediate.Low = this.MemoryRead(); this.Intermediate.Low = this.MemoryRead();
++this.Bus.Address.Low; ++this.Bus.Address.Low;
this.intermediate.High = this.MemoryRead(); this.Intermediate.High = this.MemoryRead();
return this.intermediate; return this.Intermediate;
} }
protected override Register16 PopWord() protected override Register16 PopWord()
{ {
this.intermediate.Low = this.Pop(); this.Intermediate.Low = this.Pop();
this.intermediate.High = this.Pop(); this.Intermediate.High = this.Pop();
return this.intermediate; return this.Intermediate;
} }
protected override void PushWord(Register16 value) protected override void PushWord(Register16 value)

View File

@@ -33,7 +33,9 @@ namespace EightBit
public Bus Bus { get; } = memory; public Bus Bus { get; } = memory;
public Register16 PC { get; } = new Register16(); public Register16 PC { get; } = new();
public Register16 Intermediate { get; } = new();
protected byte OpCode { get; set; } protected byte OpCode { get; set; }
@@ -194,7 +196,8 @@ namespace EightBit
protected Register16 GetWordPaged(byte page, byte offset) protected Register16 GetWordPaged(byte page, byte offset)
{ {
this.Bus.Address.Word = new Register16(offset, page).Word; this.Bus.Address.Low = offset;
this.Bus.Address.High = page;
return this.GetWordPaged(); return this.GetWordPaged();
} }
@@ -208,7 +211,8 @@ namespace EightBit
protected void SetWordPaged(byte page, byte offset, Register16 value) protected void SetWordPaged(byte page, byte offset, Register16 value)
{ {
this.Bus.Address.Word = new Register16(offset, page).Word; this.Bus.Address.Low = offset;
this.Bus.Address.High = page;
this.SetWordPaged(value); this.SetWordPaged(value);
} }

View File

@@ -21,8 +21,6 @@ namespace EightBit
}, },
}; };
private readonly Register16 intermediate = new();
private RefreshRegister refresh = new(0x7f); private RefreshRegister refresh = new(0x7f);
private bool prefixCB = false; private bool prefixCB = false;
@@ -539,7 +537,9 @@ namespace EightBit
break; break;
case 2: case 2:
this.Tick(7); this.Tick(7);
this.Call(this.MEMPTR.Word = new Register16(data, this.IV).Word); this.MEMPTR.Low = data;
this.MEMPTR.High = this.IV;
this.Call(this.MEMPTR.Word);
break; break;
default: default:
throw new NotSupportedException("Invalid interrupt mode"); throw new NotSupportedException("Invalid interrupt mode");
@@ -762,7 +762,7 @@ namespace EightBit
break; break;
case 1: // BIT y, r[z] case 1: // BIT y, r[z]
this.BIT(y, operand); this.BIT(y, operand);
this.F = direct ? AdjustXY(this.F, operand) : AdjustXY(this.F, this.MEMPTR.High); this.F = AdjustXY(this.F, direct ? operand : this.MEMPTR.High);
break; break;
case 2: // RES y, r[z] case 2: // RES y, r[z]
operand = RES(y, operand); operand = RES(y, operand);
@@ -1591,14 +1591,14 @@ namespace EightBit
private byte Subtract(byte operand, byte value, int carry = 0) private byte Subtract(byte operand, byte value, int carry = 0)
{ {
this.intermediate.Word = (ushort)(operand - value - carry); this.Intermediate.Word = (ushort)(operand - value - carry);
var result = this.intermediate.Low; var result = this.Intermediate.Low;
this.F = AdjustHalfCarrySub(this.F, operand, value, result); this.F = AdjustHalfCarrySub(this.F, operand, value, result);
this.F = AdjustOverflowSub(this.F, operand, value, result); this.F = AdjustOverflowSub(this.F, operand, value, result);
this.F = SetBit(this.F, StatusBits.NF); this.F = SetBit(this.F, StatusBits.NF);
this.F = SetBit(this.F, StatusBits.CF, this.intermediate.High & (byte)StatusBits.CF); this.F = SetBit(this.F, StatusBits.CF, this.Intermediate.High & (byte)StatusBits.CF);
this.F = AdjustSZ(this.F, result); this.F = AdjustSZ(this.F, result);
return result; return result;
@@ -1663,66 +1663,66 @@ namespace EightBit
private ushort SBC(Register16 operand, Register16 value) private ushort SBC(Register16 operand, Register16 value)
{ {
var subtraction = operand.Word - value.Word - (this.F & (byte)StatusBits.CF); var subtraction = operand.Word - value.Word - (this.F & (byte)StatusBits.CF);
this.intermediate.Word = (ushort)subtraction; this.Intermediate.Word = (ushort)subtraction;
this.F = SetBit(this.F, StatusBits.NF); this.F = SetBit(this.F, StatusBits.NF);
this.F = ClearBit(this.F, StatusBits.ZF, this.intermediate.Word); this.F = ClearBit(this.F, StatusBits.ZF, this.Intermediate.Word);
this.F = SetBit(this.F, StatusBits.CF, subtraction & (int)Bits.Bit16); this.F = SetBit(this.F, StatusBits.CF, subtraction & (int)Bits.Bit16);
this.F = AdjustHalfCarrySub(this.F, operand.High, value.High, this.intermediate.High); this.F = AdjustHalfCarrySub(this.F, operand.High, value.High, this.Intermediate.High);
this.F = AdjustXY(this.F, this.intermediate.High); this.F = AdjustXY(this.F, this.Intermediate.High);
var beforeNegative = operand.High & (byte)StatusBits.SF; var beforeNegative = operand.High & (byte)StatusBits.SF;
var valueNegative = value.High & (byte)StatusBits.SF; var valueNegative = value.High & (byte)StatusBits.SF;
var afterNegative = this.intermediate.High & (byte)StatusBits.SF; var afterNegative = this.Intermediate.High & (byte)StatusBits.SF;
this.F = SetBit(this.F, StatusBits.SF, afterNegative); this.F = SetBit(this.F, StatusBits.SF, afterNegative);
this.F = AdjustOverflowSub(this.F, beforeNegative, valueNegative, afterNegative); this.F = AdjustOverflowSub(this.F, beforeNegative, valueNegative, afterNegative);
this.MEMPTR.Word = (ushort)(operand.Word + 1); this.MEMPTR.Word = (ushort)(operand.Word + 1);
return this.intermediate.Word; return this.Intermediate.Word;
} }
private ushort ADC(Register16 operand, Register16 value) private ushort ADC(Register16 operand, Register16 value)
{ {
this.Add(operand, value, this.F & (byte)StatusBits.CF); // Leaves result in intermediate anyway this.Add(operand, value, this.F & (byte)StatusBits.CF); // Leaves result in intermediate anyway
this.F = ClearBit(this.F, StatusBits.ZF, this.intermediate.Word); this.F = ClearBit(this.F, StatusBits.ZF, this.Intermediate.Word);
var beforeNegative = operand.High & (byte)StatusBits.SF; var beforeNegative = operand.High & (byte)StatusBits.SF;
var valueNegative = value.High & (byte)StatusBits.SF; var valueNegative = value.High & (byte)StatusBits.SF;
var afterNegative = this.intermediate.High & (byte)StatusBits.SF; var afterNegative = this.Intermediate.High & (byte)StatusBits.SF;
this.F = SetBit(this.F, StatusBits.SF, afterNegative); this.F = SetBit(this.F, StatusBits.SF, afterNegative);
this.F = AdjustOverflowAdd(this.F, beforeNegative, valueNegative, afterNegative); this.F = AdjustOverflowAdd(this.F, beforeNegative, valueNegative, afterNegative);
return this.intermediate.Word; return this.Intermediate.Word;
} }
private ushort Add(Register16 operand, Register16 value, int carry = 0) private ushort Add(Register16 operand, Register16 value, int carry = 0)
{ {
var addition = operand.Word + value.Word + carry; var addition = operand.Word + value.Word + carry;
this.intermediate.Word = (ushort)addition; this.Intermediate.Word = (ushort)addition;
this.F = ClearBit(this.F, StatusBits.NF); this.F = ClearBit(this.F, StatusBits.NF);
this.F = SetBit(this.F, StatusBits.CF, addition & (int)Bits.Bit16); this.F = SetBit(this.F, StatusBits.CF, addition & (int)Bits.Bit16);
this.F = AdjustHalfCarryAdd(this.F, operand.High, value.High, this.intermediate.High); this.F = AdjustHalfCarryAdd(this.F, operand.High, value.High, this.Intermediate.High);
this.F = AdjustXY(this.F, this.intermediate.High); this.F = AdjustXY(this.F, this.Intermediate.High);
this.MEMPTR.Word = (ushort)(operand.Word + 1); this.MEMPTR.Word = (ushort)(operand.Word + 1);
return this.intermediate.Word; return this.Intermediate.Word;
} }
private byte Add(byte operand, byte value, int carry = 0) private byte Add(byte operand, byte value, int carry = 0)
{ {
this.intermediate.Word = (ushort)(operand + value + carry); this.Intermediate.Word = (ushort)(operand + value + carry);
var result = this.intermediate.Low; var result = this.Intermediate.Low;
this.F = AdjustHalfCarryAdd(this.F, operand, value, result); this.F = AdjustHalfCarryAdd(this.F, operand, value, result);
this.F = AdjustOverflowAdd(this.F, operand, value, result); this.F = AdjustOverflowAdd(this.F, operand, value, result);
this.F = ClearBit(this.F, StatusBits.NF); this.F = ClearBit(this.F, StatusBits.NF);
this.F = SetBit(this.F, StatusBits.CF, this.intermediate.High & (byte)StatusBits.CF); this.F = SetBit(this.F, StatusBits.CF, this.Intermediate.High & (byte)StatusBits.CF);
this.F = AdjustSZXY(this.F, result); this.F = AdjustSZXY(this.F, result);
return result; return result;
@@ -2104,8 +2104,8 @@ namespace EightBit
private void WritePort(byte port) private void WritePort(byte port)
{ {
this.MEMPTR.Word = this.Bus.Address.Word = new Register16(port, this.A).Word; this.MEMPTR.Low = this.Bus.Address.Low = port;
this.Bus.Data = this.A; this.MEMPTR.High = this.Bus.Address.High = this.Bus.Data = this.A;
this.WritePort(); this.WritePort();
++this.MEMPTR.Low; ++this.MEMPTR.Low;
} }
@@ -2122,7 +2122,8 @@ namespace EightBit
private byte ReadPort(byte port) private byte ReadPort(byte port)
{ {
this.MEMPTR.Word = this.Bus.Address.Word = new Register16(port, this.A).Word; this.MEMPTR.Low = this.Bus.Address.Low = port;
this.MEMPTR.High = this.Bus.Address.High = this.A;
++this.MEMPTR.Low; ++this.MEMPTR.Low;
return this.ReadPort(); return this.ReadPort();
} }