Skip to content

Commit

Permalink
[#314] Implement ZX-spectrum bus
Browse files Browse the repository at this point in the history
  • Loading branch information
vbmacher committed Apr 25, 2023
1 parent 8da09dc commit 8669265
Show file tree
Hide file tree
Showing 29 changed files with 595 additions and 127 deletions.
2 changes: 2 additions & 0 deletions application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ dependencies {
providedRuntime project(":plugins:device:vt100-terminal")
providedRuntime project(":plugins:device:simh-pseudo")
providedRuntime project(":plugins:device:ssem-display")
providedRuntime project(":plugins:device:zxspectrum-bus")
providedRuntime project(":plugins:device:zxspectrum-ula")
providedRuntime project(":plugins:device:cassette-player")

Expand Down Expand Up @@ -218,6 +219,7 @@ distributions {
from(output(":plugins:device:vt100-terminal"))
from(output(":plugins:device:simh-pseudo"))
from(output(":plugins:device:ssem-display"))
from(output(":plugins:device:zxspectrum-bus"))
from(output(":plugins:device:zxspectrum-ula"))
from(output(":plugins:device:cassette-player"))
}
Expand Down
49 changes: 36 additions & 13 deletions application/src/main/files/config/ZxSpectrum48K.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ZX Spectrum 48K"

[MEMORY]
schemaPoint = "220,60"
schemaPoint = "80,180"
path = "byte-mem.jar"
name = "byte-mem"
id = "1e13a25d-fb23-4061-853a-5fe996b03281"
Expand All @@ -10,9 +10,11 @@ name = "ZX Spectrum 48K"
[MEMORY.settings]
#memorySize = 49152
banksCount = 0
ROMfrom0 = 0
imageName0 = "/home/vbmacher/tmp/emuStudio/examples/zxspectrum-48k/48.rom" # TODO: change!
imageBank1 = 0
imageBank0 = 0
commonBoundary = 0
ROMto0 = 16383
imageAddress0 = 0

# memorySize = 65536
# ROM areas are stored as pairs ROMfromN and ROMtoN, where N is 0-based counter. There can be multiple rom areas.
Expand All @@ -36,29 +38,44 @@ name = "ZX Spectrum 48K"
type = "COMPILER"

[CPU]
schemaPoint = "220,180"
schemaPoint = "260,300"
path = "z80-cpu.jar"
settings = {}
name = "z80-cpu"
id = "b86d4bc2-632c-46e3-bba1-c088c9177983"
type = "CPU"

[CPU.settings]
frequency_khz = 3500
frequency_khz = 3500

# Uncomment the following for specific settings (and remove settings = {} above)
# [CPU.settings]
# printCode = true
# printCodeUseCache = true
# printCodeFileName = "syserr" # Or custom path to a file
[[DEVICE]]
schemaPoint = "380,180"
schemaPoint = "420,60"
path = "zxspectrum-ula.jar"
settings = {}
name = "zxspectrum-ula"
id = "1436ac2d-982f-4a52-b7c6-ecb6f2a0440d"
type = "DEVICE"

[[DEVICE]]
schemaPoint = "420,180"
path = "cassette-player.jar"
settings = {}
name = "cassette-player"
id = "581cc598-3beb-4a67-b1e3-b4ec1731a9a7"
type = "DEVICE"

[[DEVICE]]
schemaPoint = "260,180"
path = "zxspectrum-bus.jar"
settings = {}
name = "zxspectrum-bus"
id = "c16f6ea4-c26f-4dbf-972b-893c22a0d92c"
type = "DEVICE"

[[connections]]
bidirectional = true
from = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da"
Expand All @@ -68,18 +85,24 @@ name = "ZX Spectrum 48K"
[[connections]]
bidirectional = true
from = "1e13a25d-fb23-4061-853a-5fe996b03281"
to = "b86d4bc2-632c-46e3-bba1-c088c9177983"
to = "c16f6ea4-c26f-4dbf-972b-893c22a0d92c"
points = []

[[connections]]
bidirectional = true
from = "b86d4bc2-632c-46e3-bba1-c088c9177983"
to = "1436ac2d-982f-4a52-b7c6-ecb6f2a0440d"
from = "1436ac2d-982f-4a52-b7c6-ecb6f2a0440d"
to = "c16f6ea4-c26f-4dbf-972b-893c22a0d92c"
points = ["260,60"]

[[connections]]
bidirectional = true
from = "581cc598-3beb-4a67-b1e3-b4ec1731a9a7"
to = "c16f6ea4-c26f-4dbf-972b-893c22a0d92c"
points = []

[[connections]]
bidirectional = true
from = "1e13a25d-fb23-4061-853a-5fe996b03281"
to = "1436ac2d-982f-4a52-b7c6-ecb6f2a0440d"
points = ["360,60"]
from = "c16f6ea4-c26f-4dbf-972b-893c22a0d92c"
to = "b86d4bc2-632c-46e3-bba1-c088c9177983"
points = []

Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ private void verifyPluginContext(Class<? extends Context> contextInterface) thro
throw new InvalidContextException("Given class is not an interface");
}
if (!contextInterface.isAnnotationPresent(PluginContext.class)) {
throw new InvalidContextException("The interface is not annotated with 'PluginContext' annotation");
throw new InvalidContextException("The interface is not annotated with 'PluginContext' annotation: " + contextInterface);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ private static Plugin createPluginInstance(long pluginID, Class<? extends Plugin
PluginSettings pluginSettings) throws InvalidPluginException {
Objects.requireNonNull(mainClass);
Objects.requireNonNull(applicationApi);



try {
Constructor<?> constructor = mainClass.getDeclaredConstructor(PLUGIN_CONSTRUCTOR_PARAMS);
return (Plugin) constructor.newInstance(pluginID, applicationApi, pluginSettings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ public class MemoryStub extends AbstractMemoryContext<RamInstruction> implements
private final RamInstruction[] memory = new RamInstruction[1000];
private final Map<Integer, RamLabel> labels = new HashMap<>();
private final List<RamValue> inputs = new ArrayList<>();
private final MemoryContextAnnotations annotations;

protected MemoryStub(MemoryContextAnnotations annotations) {
super(annotations);
this.annotations = Objects.requireNonNull(annotations);
}

@Override
Expand Down Expand Up @@ -73,6 +74,11 @@ public int getSize() {
return memory.length;
}

@Override
public MemoryContextAnnotations annotations() {
return annotations;
}

@Override
public void setLabels(List<RamLabel> labels) {
this.labels.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ public class MemoryStub extends AbstractMemoryContext<Integer> implements RaspMe
private final Integer[] memory = new Integer[1000];
private final Map<Integer, RaspLabel> labels = new HashMap<>();
private final List<Integer> inputs = new ArrayList<>();
private final MemoryContextAnnotations annotations;

protected MemoryStub(MemoryContextAnnotations annotations) {
super(annotations);
this.annotations = Objects.requireNonNull(annotations);
}

@Override
Expand Down Expand Up @@ -66,6 +67,11 @@ public int getSize() {
return memory.length;
}

@Override
public MemoryContextAnnotations annotations() {
return annotations;
}

@Override
public void setLabels(List<RaspLabel> labels) {
this.labels.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ public class MemoryStub extends AbstractMemoryContext<Integer> implements RaspMe
private final Integer[] memory = new Integer[1000];
private final Map<Integer, RaspLabel> labels = new HashMap<>();
private final List<Integer> inputs = new ArrayList<>();
private final MemoryContextAnnotations annotations;

protected MemoryStub(MemoryContextAnnotations annotations) {
super(annotations);
this.annotations = Objects.requireNonNull(annotations);
}

@Override
Expand Down Expand Up @@ -71,6 +72,11 @@ public int getSize() {
return memory.length;
}

@Override
public MemoryContextAnnotations annotations() {
return annotations;
}

@Override
public void setLabels(List<RaspLabel> labels) {
this.labels.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

import net.emustudio.emulib.plugins.memory.AbstractMemoryContext;
import net.emustudio.emulib.plugins.memory.MemoryContext;
import net.emustudio.emulib.plugins.memory.annotations.Annotation;
import net.emustudio.emulib.plugins.memory.annotations.Annotations;
import net.emustudio.emulib.plugins.memory.annotations.MemoryContextAnnotations;
import net.emustudio.emulib.runtime.helpers.NumberUtils;

import java.util.Arrays;
Expand Down Expand Up @@ -62,7 +64,8 @@ public class TimingEstimator {
0x3F, 0xFF, 0xE0, 0x50
};

private final MemoryContext<Byte> memoryContext = new AbstractMemoryContext<>(new Annotations()) {
private final MemoryContext<Byte> memoryContext = new AbstractMemoryContext<>() {
private final Annotations annotations = new Annotations();

@Override
public Byte read(int position) {
Expand Down Expand Up @@ -98,6 +101,11 @@ public void clear() {
public int getSize() {
return memory.length;
}

@Override
public MemoryContextAnnotations annotations() {
return annotations;
}
};

public long estimateWaitNanos(int instructionsPerSecond) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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.zilogZ80.api.ContextZ80;
import net.emustudio.plugins.cpu.zilogZ80.gui.StatusPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -65,6 +66,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett
super(pluginID, applicationApi, settings);
try {
applicationApi.getContextPool().register(pluginID, context, Context8080.class);
applicationApi.getContextPool().register(pluginID, context, ContextZ80.class);
} catch (InvalidContextException | ContextAlreadyRegisteredException e) {
LOGGER.error("Could not register Z80 CPU context", e);
applicationApi.getDialogs().showError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
*/
package net.emustudio.plugins.cpu.zilogZ80.api;

import net.emustudio.emulib.plugins.annotations.PluginContext;
import net.emustudio.plugins.cpu.intel8080.api.Context8080;

@SuppressWarnings("unused")
@PluginContext
public interface ContextZ80 extends Context8080 {

/**
Expand Down
2 changes: 1 addition & 1 deletion plugins/device/cassette-player/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies {
implementation libs.emuLib
implementation libs.slf4JApi
implementation libs.jcipAnnotations
// cpuLib project(":plugins:cpu:8080-cpu")
deviceLib project(":plugins:device:zxspectrum-bus")

testImplementation libs.junit
testImplementation libs.slf4JSimple
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void initialize() throws PluginInitializationException {
// a cassette player needs a device to which it will write at its own pace
DeviceContext<Byte> lineIn = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class);
if (lineIn.getDataType() != Byte.class) {
throw new PluginInitializationException("Could not find Byte device");
throw new PluginInitializationException("Could not find line-in device");
}
this.cassetteListener = new PlaybackListenerImpl(lineIn);
this.controller = new CassetteController(cassetteListener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

//Machine Pilot pulse Length Sync1 Sync2 Bit 0 Bit 1
//ZX Spectrum 2168 (1) 667 735 855 1710
public class PlaybackListenerImpl implements Loader.PlaybackListener {
private final DeviceContext<Byte> lineIn;
private final DeviceContext<Byte> bus;
private final AtomicReference<CassettePlayerGui> gui = new AtomicReference<>();

public PlaybackListenerImpl(DeviceContext<Byte> lineIn) {
this.lineIn = Objects.requireNonNull(lineIn);
public PlaybackListenerImpl(DeviceContext<Byte> bus) {
this.bus = Objects.requireNonNull(bus);
}

public void setGui(CassettePlayerGui gui) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void interpret(byte[] content, PlaybackListener listener) {
if (flagByte == 255) {
listener.onData(data);
} else {
LOGGER.warn("TAP: Unknwon flag: " + flagByte);
LOGGER.warn("TAP: unknown flag: " + flagByte);
}
}
buffer.get(); // checksum
Expand Down
57 changes: 57 additions & 0 deletions plugins/device/zxspectrum-bus/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/

import org.apache.tools.ant.filters.ReplaceTokens

plugins {
id 'java'
id 'com.adarshr.test-logger' version '3.1.0'
}

dependencies {
implementation libs.emuLib
implementation libs.slf4JApi
implementation libs.jcipAnnotations
cpuLib project(":plugins:cpu:z80-cpu")
cpuLib project(":plugins:cpu:8080-cpu")

testImplementation libs.junit
testImplementation libs.slf4JSimple
testImplementation libs.easyMock
}

jar {
archiveVersion = ''
manifest {
attributes manifestAttributes('')
}
}

processResources {
filesMatching("**/*.properties") {
filter ReplaceTokens, tokens: [
"project.version": project.version,
"today.year" : new Date().format("yyyy")
]
}
}

compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
javadoc.options.encoding = 'UTF-8'
Loading

0 comments on commit 8669265

Please sign in to comment.