Skip to content

Commit

Permalink
[#314] update to different cycle update style (emuLib changes)
Browse files Browse the repository at this point in the history
  • Loading branch information
vbmacher committed May 18, 2023
1 parent be02862 commit 1097cf7
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 214 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package net.emustudio.plugins.cpu.intel8080;

import net.emustudio.emulib.plugins.cpu.AbstractCPUContext;
import net.emustudio.plugins.cpu.intel8080.api.Context8080;
import net.jcip.annotations.ThreadSafe;
import org.slf4j.Logger;
Expand All @@ -27,7 +28,7 @@
import java.util.concurrent.ConcurrentMap;

@ThreadSafe
public class Context8080Impl implements Context8080 {
public class Context8080Impl extends AbstractCPUContext implements Context8080 {
public final static int DEFAULT_FREQUENCY_KHZ = 2000;
private final static Logger LOGGER = LoggerFactory.getLogger(Context8080Impl.class);
private final static byte NO_DATA = (byte) 0xFF; // ha! from survey.mac in cpm2.dsk: "inactive port could return 0xFF or echo port#"
Expand Down Expand Up @@ -89,6 +90,11 @@ public boolean isInterruptSupported() {
return true;
}

@Override
public boolean passedCyclesSupported() {
return true;
}

/**
* Signals raw interrupt to the CPU.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
import net.emustudio.emulib.plugins.annotations.PluginRoot;
import net.emustudio.emulib.plugins.cpu.AbstractCPU;
import net.emustudio.emulib.plugins.cpu.Disassembler;
import net.emustudio.emulib.plugins.cpu.FrequencyCalculator;
import net.emustudio.emulib.runtime.ApplicationApi;
import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException;
import net.emustudio.emulib.runtime.InvalidContextException;
import net.emustudio.emulib.runtime.settings.PluginSettings;
import net.emustudio.plugins.cpu.intel8080.api.Context8080;
import net.emustudio.plugins.cpu.intel8080.api.FrequencyUpdater;
import net.emustudio.plugins.cpu.intel8080.gui.StatusPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -37,11 +37,6 @@
import java.util.MissingResourceException;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@PluginRoot(
type = PLUGIN_TYPE.CPU,
Expand All @@ -51,16 +46,15 @@
public class CpuImpl extends AbstractCPU {
private final static Logger LOGGER = LoggerFactory.getLogger(CpuImpl.class);

private final ScheduledExecutorService frequencyScheduler = Executors.newSingleThreadScheduledExecutor();
private final AtomicReference<Future<?>> frequencyUpdaterFuture = new AtomicReference<>();

private final Context8080Impl context = new Context8080Impl();
private final InitializerFor8080 initializer;

private EmulatorEngine engine;
private StatusPanel statusPanel;
private Disassembler disassembler;

private FrequencyCalculator frequencyCalculator;

public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) {
super(pluginID, applicationApi, settings);

Expand Down Expand Up @@ -100,10 +94,13 @@ public void initialize() throws PluginInitializationException {
context.setCpu(engine);
disassembler = initializer.getDisassembler();
statusPanel = new StatusPanel(this, context, initializer.shouldDumpInstructions());
frequencyCalculator = new FrequencyCalculator(engine::fireFrequencyChanged);
}

@Override
protected void destroyInternal() {
frequencyCalculator.stop();
frequencyCalculator.close();
context.clearDevices();
initializer.destroy();
}
Expand All @@ -115,19 +112,19 @@ public EmulatorEngine getEngine() {
@Override
public void resetInternal(int startPos) {
engine.reset(startPos);
stopFrequencyUpdater();
frequencyCalculator.stop();
}

@Override
public void pause() {
super.pause();
stopFrequencyUpdater();
frequencyCalculator.stop();
}

@Override
public void stop() {
super.stop();
stopFrequencyUpdater();
frequencyCalculator.stop();
}

@Override
Expand All @@ -140,36 +137,13 @@ public JPanel getStatusPanel() {
return statusPanel;
}

private void stopFrequencyUpdater() {
Future<?> tmpFuture;

do {
tmpFuture = frequencyUpdaterFuture.get();
if (tmpFuture != null) {
tmpFuture.cancel(false);
}
} while (!frequencyUpdaterFuture.compareAndSet(tmpFuture, null));
}

private void startFrequencyUpdater() {
Future<?> tmpFuture;
Future<?> newFuture = frequencyScheduler.scheduleAtFixedRate(new FrequencyUpdater(engine), 0, 1, TimeUnit.SECONDS);

do {
tmpFuture = frequencyUpdaterFuture.get();
if (tmpFuture != null) {
tmpFuture.cancel(false);
}
} while (!frequencyUpdaterFuture.compareAndSet(tmpFuture, newFuture));
}

@Override
public RunState call() {
try {
startFrequencyUpdater();
frequencyCalculator.start();
return engine.run(this);
} finally {
stopFrequencyUpdater();
frequencyCalculator.stop();
}
}

Expand All @@ -196,6 +170,7 @@ private Optional<ResourceBundle> getResourceBundle() {
try {
return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.cpu.intel8080.version"));
} catch (MissingResourceException e) {
e.printStackTrace();
return Optional.empty();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ public class EmulatorEngine implements CpuEngine {
private short b2 = 0;
private short b3 = 0;
private int lastOpcode;
private long executedCycles = 0;

private volatile DispatchListener dispatchListener;

Expand All @@ -84,13 +83,6 @@ public void setDispatchListener(DispatchListener dispatchListener) {
this.dispatchListener = dispatchListener;
}

@Override
public long getAndResetGlobalExecutedCycles() {
long tmpExecutedCycles = executedCycles;
executedCycles = 0;
return tmpExecutedCycles;
}

public void addFrequencyChangedListener(FrequencyChangedListener listener) {
frequencyChangedListeners.add(listener);
}
Expand Down Expand Up @@ -125,7 +117,7 @@ public CPU.RunState step() throws Exception {

public CPU.RunState run(CPU cpu) {
long startTime, endTime;
int cycles_executed;
int cyclesExecuted;
int checkTimeSlice = 100;
int cycles_to_execute = checkTimeSlice * context.getCPUFrequency();
int cycles;
Expand All @@ -134,12 +126,12 @@ public CPU.RunState run(CPU cpu) {
currentRunState = CPU.RunState.STATE_RUNNING;
while (!Thread.currentThread().isInterrupted() && (currentRunState == CPU.RunState.STATE_RUNNING)) {
startTime = System.nanoTime();
cycles_executed = 0;
while ((cycles_executed < cycles_to_execute) && !Thread.currentThread().isInterrupted() && (currentRunState == CPU.RunState.STATE_RUNNING)) {
cyclesExecuted = 0;
while ((cyclesExecuted < cycles_to_execute) && !Thread.currentThread().isInterrupted() && (currentRunState == CPU.RunState.STATE_RUNNING)) {
try {
cycles = dispatch();
cycles_executed += cycles;
executedCycles += cycles;
cyclesExecuted += cycles;
context.passedCycles(cycles);
if (cpu.isBreakpointSet(PC)) {
throw new Breakpoint();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@

public interface CpuEngine {

long getAndResetGlobalExecutedCycles();

void fireFrequencyChanged(float newFrequency);

void setDispatchListener(DispatchListener dispatchListener);

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package net.emustudio.plugins.cpu.intel8080;

import net.emustudio.emulib.plugins.PluginInitializationException;
import net.emustudio.emulib.plugins.memory.MemoryContext;
import net.emustudio.emulib.runtime.ApplicationApi;
import net.emustudio.emulib.runtime.ContextPool;
import net.emustudio.emulib.runtime.settings.PluginSettings;
Expand All @@ -31,15 +33,21 @@
public class CpuImplTest {
private CpuImpl cpu;

@SuppressWarnings("unchecked")
@Before
public void setup() {
public void setup() throws PluginInitializationException {
ContextPool contextPool = createNiceMock(ContextPool.class);
MemoryContext<Byte> memory = createMock(MemoryContext.class);
expect(memory.getCellTypeClass()).andReturn(Byte.class).anyTimes();
replay(memory);
expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memory).anyTimes();
replay(contextPool);
ApplicationApi applicationApi = createNiceMock(ApplicationApi.class);
expect(applicationApi.getContextPool()).andReturn(contextPool).anyTimes();
replay(applicationApi);

this.cpu = new CpuImpl(0, applicationApi, PluginSettings.UNAVAILABLE);
this.cpu.initialize();
}

@After
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,19 @@ public byte readFromDevice() {
Byte value = tmp.readData();
return (value == null) ? 0 : value;
}

@Override
public boolean passedCyclesSupported() {
return false;
}

@Override
public void addPassedCyclesListener(PassedCyclesListener passedCyclesListener) {

}

@Override
public void removePassedCyclesListener(PassedCyclesListener passedCyclesListener) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,19 @@ public void destroy() {
Optional.ofNullable(storageTape).ifPresent(AbstractTapeContext::clear);
Optional.ofNullable(outputTape).ifPresent(AbstractTapeContext::clear);
}

@Override
public boolean passedCyclesSupported() {
return false;
}

@Override
public void addPassedCyclesListener(PassedCyclesListener passedCyclesListener) {

}

@Override
public void removePassedCyclesListener(PassedCyclesListener passedCyclesListener) {

}
}
Loading

0 comments on commit 1097cf7

Please sign in to comment.