//
// Copyright (c) Adrian Conlon. All rights reserved.
//
namespace EightBit
{
using System;
public abstract class IntelProcessor : LittleEndianProcessor
{
private readonly IntelOpCodeDecoded[] decodedOpCodes = new IntelOpCodeDecoded[0x100];
private PinLevel haltLine;
protected IntelProcessor(Bus bus)
: base(bus)
{
this.SP = (ushort)Mask.Mask16;
this.MEMPTR = (ushort)Mask.Mask16;
for (int i = 0; i < 0x100; ++i)
{
this.decodedOpCodes[i] = new IntelOpCodeDecoded((byte)i);
}
}
public event EventHandler RaisingHALT;
public event EventHandler RaisedHALT;
public event EventHandler LoweringHALT;
public event EventHandler LoweredHALT;
public ushort SP { get; set; }
public ushort MEMPTR { get; set; }
public abstract ushort AF { get; set; }
public byte A { get => Chip.HighByte(this.AF); set => this.AF = (ushort)(Chip.LowerPart(this.AF) | Chip.PromoteByte(value)); }
public byte F { get => Chip.LowByte(this.AF); set => this.AF = (ushort)(Chip.HigherPart(this.AF) | value); }
public abstract ushort BC { get; set; }
public byte B { get => Chip.HighByte(this.BC); set => this.BC = (ushort)(Chip.LowerPart(this.BC) | Chip.PromoteByte(value)); }
public byte C { get => Chip.LowByte(this.BC); set => this.BC = (ushort)(Chip.HigherPart(this.BC) | value); }
public abstract ushort DE { get; set; }
public byte D { get => Chip.HighByte(this.DE); set => this.DE = (ushort)(Chip.LowerPart(this.DE) | Chip.PromoteByte(value)); }
public byte E { get => Chip.LowByte(this.DE); set => this.DE = (ushort)(Chip.HigherPart(this.DE) | value); }
public abstract ushort HL { get; set; }
public byte H { get => Chip.HighByte(this.HL); set => this.HL = (ushort)(Chip.LowerPart(this.HL) | Chip.PromoteByte(value)); }
public byte L { get => Chip.LowByte(this.HL); set => this.HL = (ushort)(Chip.HigherPart(this.HL) | value); }
protected bool Halted => this.HALT().Lowered();
public ref PinLevel HALT() => ref this.haltLine;
public override void RaisePOWER()
{
base.RaisePOWER();
this.RaiseHALT();
this.SP = this.AF = this.BC = this.DE = this.HL = (ushort)Mask.Mask16;
}
public virtual void RaiseHALT()
{
this.OnRaisingHALT();
this.HALT().Raise();
this.OnRaisedHALT();
}
public virtual void LowerHALT()
{
this.OnLoweringHALT();
this.HALT().Lower();
this.OnLoweredHALT();
}
protected virtual void OnRaisingHALT() => this.RaisingHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedHALT() => this.RaisedHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringHALT() => this.LoweringHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredHALT() => this.LoweredHALT?.Invoke(this, EventArgs.Empty);
protected override void HandleRESET()
{
base.HandleRESET();
this.PC = 0;
}
protected sealed override void Push(byte value) => this.Bus.Write(--this.SP, value);
protected sealed override byte Pop() => this.Bus.Read(this.SP++);
protected sealed override ushort GetWord()
{
var returned = base.GetWord();
this.MEMPTR = this.Bus.Address;
return returned;
}
protected sealed override void SetWord(ushort value)
{
base.SetWord(value);
this.MEMPTR = this.Bus.Address;
}
////
protected void Restart(byte address)
{
this.MEMPTR = address;
this.Call(this.MEMPTR);
}
protected bool CallConditional(bool condition)
{
this.MEMPTR = this.FetchWord();
if (condition)
{
this.Call(this.MEMPTR);
}
return condition;
}
protected bool JumpConditional(bool condition)
{
this.MEMPTR = this.FetchWord();
if (condition)
{
this.Jump(this.MEMPTR);
}
return condition;
}
protected bool ReturnConditional(bool condition)
{
if (condition)
{
this.Return();
}
return condition;
}
protected void JumpRelative(sbyte offset)
{
this.MEMPTR = (ushort)(this.PC + offset);
this.Jump(this.MEMPTR);
}
protected bool JumpRelativeConditional(bool condition)
{
var offset = (sbyte)this.FetchByte();
if (condition)
{
this.JumpRelative(offset);
}
return condition;
}
protected override sealed void Return()
{
base.Return();
this.MEMPTR = this.PC;
}
protected void Halt()
{
--this.PC;
this.LowerHALT();
}
protected void Proceed()
{
++this.PC;
this.RaiseHALT();
}
}
}