From f01e3e0430c2363ecfda02966c88509b340bb839 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Fri, 6 Sep 2019 22:50:21 +0100 Subject: [PATCH] Tighten up the sequence associated with changing pin levels + fix persistent HALT/PC bug Signed-off-by: Adrian Conlon --- EightBit/Device.cs | 18 ++++--- EightBit/IntelProcessor.cs | 44 ++++++++++------ EightBit/Processor.cs | 36 ++++++++----- M6502/M6502.cs | 76 ++++++++++++++++----------- MC6809/MC6809.cs | 104 ++++++++++++++++++++++++------------- MC6850/MC6850.cs | 12 ++--- Z80/Z80.cs | 77 +++++++++++++++------------ 7 files changed, 229 insertions(+), 138 deletions(-) diff --git a/EightBit/Device.cs b/EightBit/Device.cs index 5da0c17..04c96dc 100644 --- a/EightBit/Device.cs +++ b/EightBit/Device.cs @@ -28,16 +28,22 @@ namespace EightBit public virtual void RaisePOWER() { - this.OnRaisingPOWER(); - this.POWER.Raise(); - this.OnRaisedPOWER(); + if (this.POWER.Lowered()) + { + this.OnRaisingPOWER(); + this.POWER.Raise(); + this.OnRaisedPOWER(); + } } public virtual void LowerPOWER() { - this.OnLoweringPOWER(); - this.POWER.Lower(); - this.OnLoweredPOWER(); + if (this.POWER.Raised()) + { + this.OnLoweringPOWER(); + this.POWER.Lower(); + this.OnLoweredPOWER(); + } } protected virtual void OnRaisingPOWER() => this.RaisingPOWER?.Invoke(this, EventArgs.Empty); diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index e252148..c238a88 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -64,25 +64,24 @@ namespace EightBit public IntelOpCodeDecoded GetDecodedOpCode(byte opCode) => this.decodedOpCodes[opCode]; - public override void RaisePOWER() - { - base.RaisePOWER(); - this.RaiseHALT(); - this.SP.Word = this.AF.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16; - } - public virtual void RaiseHALT() { - this.OnRaisingHALT(); - this.HALT.Raise(); - this.OnRaisedHALT(); + if (this.HALT.Lowered()) + { + this.OnRaisingHALT(); + this.HALT.Raise(); + this.OnRaisedHALT(); + } } public virtual void LowerHALT() { - this.OnLoweringHALT(); - this.HALT.Lower(); - this.OnLoweredHALT(); + if (this.HALT.Raised()) + { + this.OnLoweringHALT(); + this.HALT.Lower(); + this.OnLoweredHALT(); + } } protected static int BuildHalfCarryIndex(byte before, byte value, int calculation) => ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3); @@ -99,13 +98,28 @@ namespace EightBit return HalfCarryTableSub[index & (int)Mask.Mask3]; } + protected override void OnRaisedPOWER() + { + this.RaiseHALT(); + this.SP.Word = this.AF.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16; + base.OnRaisedPOWER(); + } + protected virtual void OnRaisingHALT() => this.RaisingHALT?.Invoke(this, EventArgs.Empty); - protected virtual void OnRaisedHALT() => this.RaisedHALT?.Invoke(this, EventArgs.Empty); + protected virtual void OnRaisedHALT() + { + ++this.PC.Word; // Release the PC from HALT instruction + 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 virtual void OnLoweredHALT() + { + --this.PC.Word; // Keep the PC on the HALT instruction (i.e. executing NOP) + this.LoweredHALT?.Invoke(this, EventArgs.Empty); + } protected override void HandleRESET() { diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index 7ef5fcf..54b6f45 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -78,30 +78,42 @@ namespace EightBit public virtual void RaiseRESET() { - this.OnRaisingRESET(); - this.RESET.Raise(); - this.OnRaisedRESET(); + if (this.RESET.Lowered()) + { + this.OnRaisingRESET(); + this.RESET.Raise(); + this.OnRaisedRESET(); + } } public virtual void LowerRESET() { - this.OnLoweringRESET(); - this.RESET.Lower(); - this.OnLoweredRESET(); + if (this.RESET.Raised()) + { + this.OnLoweringRESET(); + this.RESET.Lower(); + this.OnLoweredRESET(); + } } public virtual void RaiseINT() { - this.OnRaisingINT(); - this.INT.Raise(); - this.OnRaisedINT(); + if (this.INT.Lowered()) + { + this.OnRaisingINT(); + this.INT.Raise(); + this.OnRaisedINT(); + } } public virtual void LowerINT() { - this.OnLoweringINT(); - this.INT.Lower(); - this.OnLoweredINT(); + if (this.INT.Raised()) + { + this.OnLoweringINT(); + this.INT.Lower(); + this.OnLoweredINT(); + } } protected virtual void OnRaisingRESET() => this.RaisingRESET?.Invoke(this, EventArgs.Empty); diff --git a/M6502/M6502.cs b/M6502/M6502.cs index 1ba066f..09bea47 100644 --- a/M6502/M6502.cs +++ b/M6502/M6502.cs @@ -95,57 +95,64 @@ namespace EightBit private int Carry => this.P & (byte)StatusBits.CF; - public override void RaisePOWER() - { - base.RaisePOWER(); - this.X = (byte)Bits.Bit7; - this.Y = 0; - this.A = 0; - this.P = (byte)StatusBits.RF; - this.S = (byte)Mask.Mask8; - this.LowerSYNC(); - } - public virtual void RaiseNMI() { - this.OnRaisingNMI(); - this.NMI.Raise(); - this.OnRaisedNMI(); + if (this.NMI.Lowered()) + { + this.OnRaisingNMI(); + this.NMI.Raise(); + this.OnRaisedNMI(); + } } public virtual void LowerNMI() { - this.OnLoweringNMI(); - this.NMI.Lower(); - this.OnLoweredNMI(); + if (this.NMI.Raised()) + { + this.OnLoweringNMI(); + this.NMI.Lower(); + this.OnLoweredNMI(); + } } public virtual void RaiseSO() { - this.OnRaisingSO(); - this.SO.Raise(); - this.OnRaisedSO(); + if (this.SO.Lowered()) + { + this.OnRaisingSO(); + this.SO.Raise(); + this.OnRaisedSO(); + } } public virtual void LowerSO() { - this.OnLoweringSO(); - this.SO.Lower(); - this.OnLoweredSO(); + if (this.SO.Raised()) + { + this.OnLoweringSO(); + this.SO.Lower(); + this.OnLoweredSO(); + } } public virtual void RaiseRDY() { - this.OnRaisingRDY(); - this.RDY.Raise(); - this.OnRaisedRDY(); + if (this.RDY.Lowered()) + { + this.OnRaisingRDY(); + this.RDY.Raise(); + this.OnRaisedRDY(); + } } public virtual void LowerRDY() { - this.OnLoweringRDY(); - this.RDY.Lower(); - this.OnLoweredRDY(); + if (this.RDY.Raised()) + { + this.OnLoweringRDY(); + this.RDY.Lower(); + this.OnLoweredRDY(); + } } public override int Execute() @@ -502,6 +509,17 @@ namespace EightBit protected virtual void OnLoweredRDY() => this.LoweredRDY?.Invoke(this, EventArgs.Empty); + protected override void OnRaisedPOWER() + { + this.X = (byte)Bits.Bit7; + this.Y = 0; + this.A = 0; + this.P = (byte)StatusBits.RF; + this.S = (byte)Mask.Mask8; + this.LowerSYNC(); + base.OnRaisedPOWER(); + } + protected override byte Pop() => this.BusRead(++this.S, 1); protected override void Push(byte value) => this.BusWrite(this.S--, 1, value); diff --git a/MC6809/MC6809.cs b/MC6809/MC6809.cs index 27afc37..4463ad2 100644 --- a/MC6809/MC6809.cs +++ b/MC6809/MC6809.cs @@ -221,81 +221,111 @@ return this.Cycles; } - public override void RaisePOWER() - { - base.RaisePOWER(); - this.LowerBA(); - this.LowerBS(); - } - public void RaiseNMI() { - this.OnRaisingNMI(); - this.NMI.Raise(); - this.OnRaisedNMI(); + if (this.NMI.Lowered()) + { + this.OnRaisingNMI(); + this.NMI.Raise(); + this.OnRaisedNMI(); + } } public void LowerNMI() { - this.OnLoweringNMI(); - this.NMI.Lower(); - this.OnLoweredNMI(); + if (this.NMI.Raised()) + { + this.OnLoweringNMI(); + this.NMI.Lower(); + this.OnLoweredNMI(); + } } public void RaiseFIRQ() { - this.OnRaisingFIRQ(); - this.FIRQ.Raise(); - this.OnRaisedFIRQ(); + if (this.FIRQ.Lowered()) + { + this.OnRaisingFIRQ(); + this.FIRQ.Raise(); + this.OnRaisedFIRQ(); + } } public void LowerFIRQ() { - this.OnLoweringFIRQ(); - this.FIRQ.Lower(); - this.OnLoweredFIRQ(); + if (this.FIRQ.Raised()) + { + this.OnLoweringFIRQ(); + this.FIRQ.Lower(); + this.OnLoweredFIRQ(); + } } public void RaiseHALT() { - this.OnRaisingHALT(); - this.HALT.Raise(); - this.OnRaisedHALT(); + if (this.HALT.Lowered()) + { + this.OnRaisingHALT(); + this.HALT.Raise(); + this.OnRaisedHALT(); + } } public void LowerHALT() { - this.OnLoweringHALT(); - this.HALT.Lower(); - this.OnLoweredHALT(); + if (this.HALT.Raised()) + { + this.OnLoweringHALT(); + this.HALT.Lower(); + this.OnLoweredHALT(); + } } public void RaiseBA() { - this.OnRaisingBA(); - this.BA.Raise(); - this.OnRaisedBA(); + if (this.BA.Lowered()) + { + this.OnRaisingBA(); + this.BA.Raise(); + this.OnRaisedBA(); + } } public void LowerBA() { - this.OnLoweringBA(); - this.BA.Lower(); - this.OnLoweredBA(); + if (this.BA.Raised()) + { + this.OnLoweringBA(); + this.BA.Lower(); + this.OnLoweredBA(); + } } public void RaiseBS() { - this.OnRaisingBS(); - this.BS.Raise(); - this.OnRaisedBS(); + if (this.BS.Lowered()) + { + this.OnRaisingBS(); + this.BS.Raise(); + this.OnRaisedBS(); + } } public void LowerBS() { - this.OnLoweringBS(); - this.BS.Lower(); - this.OnLoweredBS(); + if (this.BS.Raised()) + { + this.OnLoweringBS(); + this.BS.Lower(); + this.OnLoweredBS(); + } + } + + protected override void OnRaisedPOWER() + { + this.LowerBA(); + this.LowerBS(); + base.OnRaisedPOWER(); } protected override void HandleRESET() diff --git a/MC6850/MC6850.cs b/MC6850/MC6850.cs index d081985..619fbe9 100644 --- a/MC6850/MC6850.cs +++ b/MC6850/MC6850.cs @@ -337,12 +337,6 @@ namespace EightBit } } - public override void RaisePOWER() - { - base.RaisePOWER(); - this.startup = StartupCondition.ColdStart; - } - public void MarkTransmitComplete() { this.statusTDRE = this.CTS.Lowered(); @@ -383,6 +377,12 @@ namespace EightBit return returned; } + protected override void OnRaisedPOWER() + { + this.startup = StartupCondition.ColdStart; + base.OnRaisedPOWER(); + } + protected override void OnTicked() { base.OnTicked(); diff --git a/Z80/Z80.cs b/Z80/Z80.cs index fda5382..4c06afd 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -108,53 +108,44 @@ namespace EightBit public void ExxAF() => this.accumulatorFlagsSet ^= 1; - public override void RaisePOWER() - { - base.RaisePOWER(); - - this.RaiseM1(); - - this.DisableInterrupts(); - this.IM = 0; - - this.REFRESH = new RefreshRegister(0); - this.IV = (byte)Mask.Mask8; - - this.ExxAF(); - this.AF.Word = (ushort)Mask.Mask16; - - this.Exx(); - this.IX.Word = this.IY.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16; - - this.prefixCB = this.prefixDD = this.prefixED = false; - } - public virtual void RaiseNMI() { - this.OnRaisingNMI(); - this.NMI.Raise(); - this.OnRaisedNMI(); + if (this.NMI.Lowered()) + { + this.OnRaisingNMI(); + this.NMI.Raise(); + this.OnRaisedNMI(); + } } public virtual void LowerNMI() { - this.OnLoweringNMI(); - this.NMI.Lower(); - this.OnLoweredNMI(); + if (this.NMI.Raised()) + { + this.OnLoweringNMI(); + this.NMI.Lower(); + this.OnLoweredNMI(); + } } public virtual void RaiseM1() { - this.OnRaisingM1(); - this.M1.Raise(); - this.OnRaisedM1(); + if (this.M1.Lowered()) + { + this.OnRaisingM1(); + this.M1.Raise(); + this.OnRaisedM1(); + } } public virtual void LowerM1() { - this.OnLoweringM1(); - this.M1.Lower(); - this.OnLoweredM1(); + if (this.M1.Raised()) + { + this.OnLoweringM1(); + this.M1.Lower(); + this.OnLoweredM1(); + } } public override int Execute() @@ -228,6 +219,26 @@ namespace EightBit return this.Cycles; } + protected override void OnRaisedPOWER() + { + this.RaiseM1(); + + this.DisableInterrupts(); + this.IM = 0; + + this.REFRESH = new RefreshRegister(0); + this.IV = (byte)Mask.Mask8; + + this.AF.Word = this.IX.Word = this.IY.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16; + + this.ExxAF(); + this.Exx(); + + this.prefixCB = this.prefixDD = this.prefixED = false; + + base.OnRaisedPOWER(); + } + protected virtual void OnExecutingInstruction() => this.ExecutingInstruction?.Invoke(this, EventArgs.Empty); protected virtual void OnExecutedInstruction() => this.ExecutedInstruction?.Invoke(this, EventArgs.Empty);