From 87de500621c366c893edf7db348a59f55714a970 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 18 May 2023 12:46:43 +0200 Subject: [PATCH] [#314] 8080,z80: fix frequency counting --- .../plugins/cpu/intel8080/CpuImpl.java | 9 +++- .../plugins/cpu/intel8080/EmulatorEngine.java | 15 ------- .../plugins/cpu/intel8080/api/CpuEngine.java | 2 - .../api/FrequencyChangedListener.java | 33 -------------- .../cpu/intel8080/gui/StatusPanel.java | 2 +- .../plugins/cpu/zilogZ80/CpuImpl.java | 12 +++--- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 43 +++++++------------ .../plugins/cpu/zilogZ80/gui/StatusPanel.java | 2 +- 8 files changed, 31 insertions(+), 87 deletions(-) delete mode 100644 plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/FrequencyChangedListener.java diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java index d96d16a4e..9135a308c 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java @@ -53,7 +53,7 @@ public class CpuImpl extends AbstractCPU { private StatusPanel statusPanel; private Disassembler disassembler; - private FrequencyCalculator frequencyCalculator; + private final FrequencyCalculator frequencyCalculator = new FrequencyCalculator(); public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -93,12 +93,17 @@ public void initialize() throws PluginInitializationException { engine = initializer.getEngine(); context.setCpu(engine); disassembler = initializer.getDisassembler(); + context.addPassedCyclesListener(frequencyCalculator); statusPanel = new StatusPanel(this, context, initializer.shouldDumpInstructions()); - frequencyCalculator = new FrequencyCalculator(engine::fireFrequencyChanged); + } + + public FrequencyCalculator getFrequencyCalculator() { + return frequencyCalculator; } @Override protected void destroyInternal() { + context.removePassedCyclesListener(frequencyCalculator); frequencyCalculator.stop(); frequencyCalculator.close(); context.clearDevices(); diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index adb6c8ce2..3d7c89058 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -23,16 +23,13 @@ import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.cpu.intel8080.api.CpuEngine; import net.emustudio.plugins.cpu.intel8080.api.DispatchListener; -import net.emustudio.plugins.cpu.intel8080.api.FrequencyChangedListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.lang.invoke.MethodHandle; import java.util.Arrays; -import java.util.List; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import static net.emustudio.plugins.cpu.intel8080.DispatchTables.DISPATCH_TABLE; @@ -58,7 +55,6 @@ public class EmulatorEngine implements CpuEngine { ); private final MemoryContext memory; private final Context8080Impl context; - private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); public boolean INTE = false; // enabling / disabling of interrupts public int PC = 0; // program counter public int SP = 0; // stack pointer @@ -83,17 +79,6 @@ public void setDispatchListener(DispatchListener dispatchListener) { this.dispatchListener = dispatchListener; } - public void addFrequencyChangedListener(FrequencyChangedListener listener) { - frequencyChangedListeners.add(listener); - } - - @Override - public void fireFrequencyChanged(float newFrequency) { - for (FrequencyChangedListener listener : frequencyChangedListeners) { - listener.frequencyChanged(newFrequency); - } - } - public void reset(int startPos) { Arrays.fill(regs, 0); SP = 0; diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/CpuEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/CpuEngine.java index 81240e48b..15ded8899 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/CpuEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/CpuEngine.java @@ -20,7 +20,5 @@ public interface CpuEngine { - void fireFrequencyChanged(float newFrequency); - void setDispatchListener(DispatchListener dispatchListener); } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/FrequencyChangedListener.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/FrequencyChangedListener.java deleted file mode 100644 index cbe0867df..000000000 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/FrequencyChangedListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2023 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.cpu.intel8080.api; - -/** - * Listener of frequency changes - */ -@FunctionalInterface -public interface FrequencyChangedListener { - - /** - * Handle frequency changes of the CPU. - * - * @param newFrequency new Frequency in kHz - */ - void frequencyChanged(float newFrequency); -} diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java index 66856e64e..45a596d11 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java @@ -86,7 +86,7 @@ public void internalStateChanged() { } }); - cpu.getEngine().addFrequencyChangedListener(newFrequency -> lblFrequency.setText(String.format("%.2f kHz", newFrequency))); + cpu.getFrequencyCalculator().addListener(f -> lblFrequency.setText(String.format("%.2f kHz", f))); spnFrequency.addChangeListener(e -> { int i = (Integer) spnFrequency.getModel().getValue(); try { diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java index 1dc6c8d94..8da629c02 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java @@ -54,7 +54,7 @@ public class CpuImpl extends AbstractCPU { private Disassembler disassembler; private EmulatorEngine engine; - private FrequencyCalculator frequencyCalculator; + private final FrequencyCalculator frequencyCalculator = new FrequencyCalculator(); public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -68,9 +68,6 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett ); } context.setCPUFrequency(settings.getInt("frequency_khz", ContextZ80Impl.DEFAULT_FREQUENCY_KHZ)); - - context.setCPUFrequency(settings.getInt("frequency_khz", ContextZ80Impl.DEFAULT_FREQUENCY_KHZ)); - initializer = new InitializerZ80( this, pluginID, applicationApi.getContextPool(), settings, context ); @@ -96,7 +93,7 @@ public void initialize() throws PluginInitializationException { disassembler = initializer.getDisassembler(); engine = initializer.getEngine(); context.setEngine(engine); - frequencyCalculator = new FrequencyCalculator(engine::fireFrequencyChanged); + context.addPassedCyclesListener(frequencyCalculator); statusPanel = new StatusPanel(this, context, initializer.shouldDumpInstructions()); } @@ -149,6 +146,7 @@ public Disassembler getDisassembler() { @Override protected void destroyInternal() { + context.removePassedCyclesListener(frequencyCalculator); frequencyCalculator.stop(); frequencyCalculator.close(); context.clearDevices(); @@ -178,4 +176,8 @@ private Optional getResourceBundle() { return Optional.empty(); } } + + public FrequencyCalculator getFrequencyCalculator() { + return frequencyCalculator; + } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 42b906250..bbb570290 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -25,7 +25,6 @@ import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.cpu.intel8080.api.CpuEngine; import net.emustudio.plugins.cpu.intel8080.api.DispatchListener; -import net.emustudio.plugins.cpu.intel8080.api.FrequencyChangedListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,7 +65,6 @@ public class EmulatorEngine implements CpuEngine { private final ContextZ80Impl context; private final TimedEventsProcessor tep; private final MemoryContext memory; - private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); private final AtomicLong cyclesExecutedPerTimeSlice = new AtomicLong(0); public final int[] regs = new int[8]; @@ -141,17 +139,6 @@ public void addExecutedCyclesPerTimeSlice(long tstates) { cyclesExecutedPerTimeSlice.addAndGet(tstates); } - public void addFrequencyChangedListener(FrequencyChangedListener listener) { - frequencyChangedListeners.add(listener); - } - - @Override - public void fireFrequencyChanged(float newFrequency) { - for (FrequencyChangedListener listener : frequencyChangedListeners) { - listener.frequencyChanged(newFrequency); - } - } - public void requestMaskableInterrupt(byte[] data) { if (currentRunState == RunState.STATE_RUNNING) { pendingInterrupts.add(data); @@ -338,11 +325,11 @@ private void doInterrupt() throws Throwable { if (dataBus != null && dataBus.length > 0) { lastOpcode = dataBus[0] & 0xFF; // TODO: if dataBus had more bytes, they're ignored (except call). if (lastOpcode == 0xCD) { /* CALL */ - advanceCycles(4+7); // fetch + advanceCycles(4 + 7); // fetch SP = (SP - 2) & 0xFFFF; - memory.write(SP, (byte)(PC & 0xFF)); + memory.write(SP, (byte) (PC & 0xFF)); advanceCycles(3); - memory.write((SP + 1) & 0xFFFF, (byte)(PC >>> 8)); + memory.write((SP + 1) & 0xFFFF, (byte) (PC >>> 8)); PC = ((dataBus[2] & 0xFF) << 8) | (dataBus[1] & 0xFF); memptr = PC; @@ -918,18 +905,18 @@ void I_PUSH_AF() { void I_PUSH_IX() { // pc:5,sp-1:3,sp-2:3 SP = (SP - 2) & 0xFFFF; - memory.write((SP + 1) & 0xFFFF, (byte)(IX >>> 8)); + memory.write((SP + 1) & 0xFFFF, (byte) (IX >>> 8)); advanceCycles(3); - memory.write(SP, (byte)(IX & 0xFF)); + memory.write(SP, (byte) (IX & 0xFF)); advanceCycles(3); } void I_PUSH_IY() { // pc:5,sp-1:3,sp-2:3 SP = (SP - 2) & 0xFFFF; - memory.write((SP + 1) & 0xFFFF, (byte)(IY & 0xFF)); + memory.write((SP + 1) & 0xFFFF, (byte) (IY & 0xFF)); advanceCycles(3); - memory.write(SP, (byte)(IY >>> 8)); + memory.write(SP, (byte) (IY >>> 8)); advanceCycles(3); } @@ -2827,10 +2814,10 @@ void I_LD_REF_NN_XY(int xy) { PC = (PC + 2) & 0xFFFF; advanceCycles(3); - memory.write(address, (byte)(xy & 0xFF)); + memory.write(address, (byte) (xy & 0xFF)); advanceCycles(3); memptr = (address + 1) & 0xFFFF; - memory.write(memptr, (byte)(xy >>> 8)); + memory.write(memptr, (byte) (xy >>> 8)); advanceCycles(3); } @@ -3833,7 +3820,7 @@ void I_SET_N_R() { void I_LD_IX_NN() { IX = memory.read(PC) & 0xFF; advanceCycles(3); - IX = ((memory.read((PC +1) & 0xFFFF) << 8) | IX) & 0xFFFF; + IX = ((memory.read((PC + 1) & 0xFFFF) << 8) | IX) & 0xFFFF; PC = (PC + 2) & 0xFFFF; advanceCycles(3); } @@ -3841,7 +3828,7 @@ void I_LD_IX_NN() { void I_LD_IY_NN() { IY = memory.read(PC) & 0xFF; advanceCycles(3); - IY = ((memory.read((PC +1) & 0xFFFF) << 8) | IY) & 0xFFFF; + IY = ((memory.read((PC + 1) & 0xFFFF) << 8) | IY) & 0xFFFF; PC = (PC + 2) & 0xFFFF; advanceCycles(3); } @@ -3904,9 +3891,9 @@ void I_EX_REF_SP_IX() { IX = tmp; memptr = IX; - memory.write(SP, (byte)(tmp1 & 0xFF)); + memory.write(SP, (byte) (tmp1 & 0xFF)); advanceCycles(3); - memory.write((SP + 1) & 0xFFFF, (byte)(tmp1 >>> 8)); + memory.write((SP + 1) & 0xFFFF, (byte) (tmp1 >>> 8)); advanceCycles(6); } @@ -3920,9 +3907,9 @@ void I_EX_REF_SP_IY() { IY = tmp; memptr = IY; - memory.write(SP, (byte)(tmp1 & 0xFF)); + memory.write(SP, (byte) (tmp1 & 0xFF)); advanceCycles(3); - memory.write((SP + 1) & 0xFFFF, (byte)(tmp1 >>> 8)); + memory.write((SP + 1) & 0xFFFF, (byte) (tmp1 >>> 8)); advanceCycles(6); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java index d69ac47ab..02c9a5edb 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java @@ -101,7 +101,7 @@ public void internalStateChanged() { } }); - cpu.getEngine().addFrequencyChangedListener(newFrequency -> lblFrequency.setText(String.format("%.2f kHz", newFrequency))); + cpu.getFrequencyCalculator().addListener(f -> lblFrequency.setText(String.format("%.2f kHz", f))); spnFrequency.addChangeListener(e -> { int i = (Integer) spnFrequency.getModel().getValue(); try {