mirror of
https://github.com/badvision/jace.git
synced 2025-02-06 16:30:10 +00:00
You can now boot with -s6.d1 and -s6.d2 again (fixing WUDSN compatibility) -- Configurator now understands Optional[] arrays (for card support)
This commit is contained in:
parent
8fc422e0dd
commit
e643eb0bdf
@ -23,6 +23,7 @@ import jace.config.Configuration;
|
|||||||
import jace.ui.AbstractEmulatorFrame;
|
import jace.ui.AbstractEmulatorFrame;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ public class Emulator {
|
|||||||
computer = new Apple2e();
|
computer = new Apple2e();
|
||||||
Configuration.loadSettings();
|
Configuration.loadSettings();
|
||||||
mainThread = Thread.currentThread();
|
mainThread = Thread.currentThread();
|
||||||
Map<String, String> settings = new HashMap<>();
|
Map<String, String> settings = new LinkedHashMap<>();
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
for (int i = 0; i < args.size(); i++) {
|
for (int i = 0; i < args.size(); i++) {
|
||||||
if (args.get(i).startsWith("-")) {
|
if (args.get(i).startsWith("-")) {
|
||||||
|
@ -30,11 +30,17 @@ import java.io.ObjectInputStream;
|
|||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.GenericArrayType;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -45,7 +51,8 @@ import javax.swing.tree.TreePath;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the configuration state of the emulator components.
|
* Manages the configuration state of the emulator components.
|
||||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
*
|
||||||
|
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||||
*/
|
*/
|
||||||
public class Configuration implements Reconfigurable {
|
public class Configuration implements Reconfigurable {
|
||||||
|
|
||||||
@ -57,7 +64,7 @@ public class Configuration implements Reconfigurable {
|
|||||||
public String getShortName() {
|
public String getShortName() {
|
||||||
return "cfg";
|
return "cfg";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reconfigure() {
|
public void reconfigure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,12 +123,12 @@ public class Configuration implements Reconfigurable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a serializable configuration node as part of a tree.
|
* Represents a serializable configuration node as part of a tree. The root
|
||||||
* The root node should be a single instance (e.g. Computer)
|
* node should be a single instance (e.g. Computer) The child nodes should
|
||||||
* The child nodes should be all object instances that stem from each object
|
* be all object instances that stem from each object The overall goal of
|
||||||
* The overall goal of this class is two-fold:
|
* this class is two-fold: 1) Provide a navigable manner to inspect
|
||||||
* 1) Provide a navigable manner to inspect configuration
|
* configuration 2) Provide a simple persistence mechanism to load/store
|
||||||
* 2) Provide a simple persistence mechanism to load/store configuration
|
* configuration
|
||||||
*/
|
*/
|
||||||
public static class ConfigNode implements Serializable {
|
public static class ConfigNode implements Serializable {
|
||||||
|
|
||||||
@ -147,8 +154,8 @@ public class Configuration implements Reconfigurable {
|
|||||||
|
|
||||||
public ConfigNode(ConfigNode parent, Reconfigurable subject) {
|
public ConfigNode(ConfigNode parent, Reconfigurable subject) {
|
||||||
this.subject = subject;
|
this.subject = subject;
|
||||||
this.settings = new TreeMap<String, Serializable>();
|
this.settings = new TreeMap<>();
|
||||||
this.children = new TreeMap<String, ConfigNode>();
|
this.children = new TreeMap<>();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
if (this.parent != null) {
|
if (this.parent != null) {
|
||||||
this.root = this.parent.root != null ? this.parent.root : this.parent;
|
this.root = this.parent.root != null ? this.parent.root : this.parent;
|
||||||
@ -156,6 +163,7 @@ public class Configuration implements Reconfigurable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFieldValue(String field, Serializable value) {
|
public void setFieldValue(String field, Serializable value) {
|
||||||
|
changed = true;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
if (value.equals(getFieldValue(field))) {
|
if (value.equals(getFieldValue(field))) {
|
||||||
return;
|
return;
|
||||||
@ -165,7 +173,6 @@ public class Configuration implements Reconfigurable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changed = true;
|
|
||||||
setRawFieldValue(field, value);
|
setRawFieldValue(field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,38 +242,66 @@ public class Configuration implements Reconfigurable {
|
|||||||
} else if (o.getClass().isArray()) {
|
} else if (o.getClass().isArray()) {
|
||||||
String fieldName = f.getName();
|
String fieldName = f.getName();
|
||||||
Class type = o.getClass().getComponentType();
|
Class type = o.getClass().getComponentType();
|
||||||
|
// System.out.println("Evaluating " + node.subject.getShortName() + "." + fieldName + "; type is " + type.toGenericString());
|
||||||
|
List<Reconfigurable> children = new ArrayList<>();
|
||||||
if (!Reconfigurable.class.isAssignableFrom(type)) {
|
if (!Reconfigurable.class.isAssignableFrom(type)) {
|
||||||
continue;
|
// System.out.println("Looking at type " + type.getName() + " to see if optional");
|
||||||
|
if (Optional.class.isAssignableFrom(type)) {
|
||||||
|
Type genericTypes = f.getGenericType();
|
||||||
|
// System.out.println("Looking at generic parmeters " + genericTypes.getTypeName() + " for reconfigurable class, type "+genericTypes.getClass().getName());
|
||||||
|
if (genericTypes instanceof GenericArrayType) {
|
||||||
|
GenericArrayType aType = (GenericArrayType) genericTypes;
|
||||||
|
ParameterizedType pType = (ParameterizedType) aType.getGenericComponentType();
|
||||||
|
if (pType.getActualTypeArguments().length != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Type genericType = pType.getActualTypeArguments()[0];
|
||||||
|
// System.out.println("Looking at type " + genericType.getTypeName() + " to see if reconfigurable");
|
||||||
|
if (!Reconfigurable.class.isAssignableFrom((Class) genericType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Optional<Reconfigurable> child : (Optional<Reconfigurable>[]) o) {
|
||||||
|
if (child.isPresent()) {
|
||||||
|
children.add(child.get());
|
||||||
|
} else {
|
||||||
|
children.add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
children = Arrays.asList((Reconfigurable[]) o);
|
||||||
}
|
}
|
||||||
Reconfigurable[] r = (Reconfigurable[]) o;
|
visited.add(o);
|
||||||
visited.add(r);
|
for (int i = 0; i < children.size(); i++) {
|
||||||
for (int i = 0; i < r.length; i++) {
|
Reconfigurable child = children.get(i);
|
||||||
String childName = fieldName + i;
|
String childName = fieldName + i;
|
||||||
if (r[i] == null) {
|
if (child == null) {
|
||||||
node.children.remove(childName);
|
node.children.remove(childName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ConfigNode grandchild = node.children.get(childName);
|
ConfigNode grandchild = node.children.get(childName);
|
||||||
if (grandchild == null || !grandchild.subject.equals(r[i])) {
|
if (grandchild == null || !grandchild.subject.equals(child)) {
|
||||||
grandchild = new ConfigNode(node, r[i]);
|
grandchild = new ConfigNode(node, child);
|
||||||
node.children.put(childName, grandchild);
|
node.children.put(childName, grandchild);
|
||||||
}
|
}
|
||||||
buildTree(grandchild, visited);
|
buildTree(grandchild, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@InvokableAction(
|
@InvokableAction(
|
||||||
name="Save settings",
|
name = "Save settings",
|
||||||
description="Save all configuration settings as defaults",
|
description = "Save all configuration settings as defaults",
|
||||||
category="general",
|
category = "general",
|
||||||
alternatives="save preferences;save defaults"
|
alternatives = "save preferences;save defaults"
|
||||||
)
|
)
|
||||||
public static void saveSettings() {
|
public static void saveSettings() {
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
@ -293,10 +328,10 @@ public class Configuration implements Reconfigurable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@InvokableAction(
|
@InvokableAction(
|
||||||
name="Load settings",
|
name = "Load settings",
|
||||||
description="Load all configuration settings previously saved",
|
description = "Load all configuration settings previously saved",
|
||||||
category="general",
|
category = "general",
|
||||||
alternatives="load preferences;revert settings;revert preferences"
|
alternatives = "load preferences;revert settings;revert preferences"
|
||||||
)
|
)
|
||||||
public static void loadSettings() {
|
public static void loadSettings() {
|
||||||
{
|
{
|
||||||
@ -334,10 +369,12 @@ public class Configuration implements Reconfigurable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply settings from node tree to the object model
|
* Apply settings from node tree to the object model This also calls
|
||||||
* This also calls "reconfigure" on objects in sequence
|
* "reconfigure" on objects in sequence
|
||||||
|
*
|
||||||
* @param node
|
* @param node
|
||||||
* @return True if any settings have changed in the node or any of its descendants
|
* @return True if any settings have changed in the node or any of its
|
||||||
|
* descendants
|
||||||
*/
|
*/
|
||||||
public static boolean applySettings(ConfigNode node) {
|
public static boolean applySettings(ConfigNode node) {
|
||||||
boolean resume = false;
|
boolean resume = false;
|
||||||
@ -363,7 +400,7 @@ public class Configuration implements Reconfigurable {
|
|||||||
if (resume) {
|
if (resume) {
|
||||||
Emulator.computer.resume();
|
Emulator.computer.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasChanged;
|
return hasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,14 +413,14 @@ public class Configuration implements Reconfigurable {
|
|||||||
doApply(oldRoot);
|
doApply(oldRoot);
|
||||||
buildTree(oldRoot, new HashSet());
|
buildTree(oldRoot, new HashSet());
|
||||||
}
|
}
|
||||||
for (String childName : newRoot.children.keySet()) {
|
newRoot.children.keySet().stream().forEach((childName) -> {
|
||||||
// System.out.println("Applying settings for " + childName);
|
// System.out.println("Applying settings for " + childName);
|
||||||
applyConfigTree(newRoot.children.get(childName), oldRoot.children.get(childName));
|
applyConfigTree(newRoot.children.get(childName), oldRoot.children.get(childName));
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doApply(ConfigNode node) {
|
private static void doApply(ConfigNode node) {
|
||||||
List<String> removeList = new ArrayList<String>();
|
List<String> removeList = new ArrayList<>();
|
||||||
for (String f : node.settings.keySet()) {
|
for (String f : node.settings.keySet()) {
|
||||||
try {
|
try {
|
||||||
Field ff = node.subject.getClass().getField(f);
|
Field ff = node.subject.getClass().getField(f);
|
||||||
@ -409,19 +446,15 @@ public class Configuration implements Reconfigurable {
|
|||||||
// System.out.println("Setting "+node.subject.getName()+" property "+ff.getName()+" with value "+String.valueOf(val));
|
// System.out.println("Setting "+node.subject.getName()+" property "+ff.getName()+" with value "+String.valueOf(val));
|
||||||
ff.set(node.subject, val);
|
ff.set(node.subject, val);
|
||||||
} catch (NoSuchFieldException ex) {
|
} catch (NoSuchFieldException ex) {
|
||||||
System.out.println("Setting "+f+" no longer exists, skipping.");
|
System.out.println("Setting " + f + " no longer exists, skipping.");
|
||||||
removeList.add(f);
|
removeList.add(f);
|
||||||
} catch (SecurityException ex) {
|
} catch (SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (String f : removeList) {
|
removeList.stream().forEach((f) -> {
|
||||||
node.settings.remove(f);
|
node.settings.remove(f);
|
||||||
}
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// When settings are applied, this could very well change the object structure
|
// When settings are applied, this could very well change the object structure
|
||||||
@ -431,39 +464,37 @@ public class Configuration implements Reconfigurable {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
node.changed = false;
|
node.changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void applySettings(Map<String, String> settings) {
|
public static void applySettings(Map<String, String> settings) {
|
||||||
for (Map.Entry<String, String> setting : settings.entrySet()) {
|
for (Map.Entry<String, String> setting : settings.entrySet()) {
|
||||||
Map<String, ConfigNode> shortNames = new HashMap<String, ConfigNode>();
|
Map<String, ConfigNode> shortNames = new HashMap<>();
|
||||||
buildNodeMap(BASE, shortNames);
|
buildNodeMap(BASE, shortNames);
|
||||||
|
|
||||||
String settingName = setting.getKey();
|
String settingName = setting.getKey();
|
||||||
String value = setting.getValue();
|
String value = setting.getValue();
|
||||||
String[] parts = settingName.split("\\.");
|
String[] parts = settingName.split("\\.");
|
||||||
if (parts.length != 2) {
|
if (parts.length != 2) {
|
||||||
System.err.println("Unable to parse settting, should be in the form of DEVICE.PROPERTYNAME "+settingName);
|
System.err.println("Unable to parse settting, should be in the form of DEVICE.PROPERTYNAME " + settingName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String deviceName = parts[0];
|
String deviceName = parts[0];
|
||||||
String fieldName = parts[1];
|
String fieldName = parts[1];
|
||||||
ConfigNode n = shortNames.get(deviceName.toLowerCase());
|
ConfigNode n = shortNames.get(deviceName.toLowerCase());
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
System.err.println("Unable to find device named "+deviceName+", try one of these: "+Utility.join(shortNames.keySet(), ", "));
|
System.err.println("Unable to find device named " + deviceName + ", try one of these: " + Utility.join(shortNames.keySet(), ", "));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
List<String> shortFieldNames = new ArrayList<String>();
|
List<String> shortFieldNames = new ArrayList<>();
|
||||||
for (String longName : n.getAllSettingNames()) {
|
for (String longName : n.getAllSettingNames()) {
|
||||||
ConfigurableField f = null;
|
ConfigurableField f = null;
|
||||||
try {
|
try {
|
||||||
f = n.subject.getClass().getField(longName).getAnnotation(ConfigurableField.class);
|
f = n.subject.getClass().getField(longName).getAnnotation(ConfigurableField.class);
|
||||||
} catch (NoSuchFieldException ex) {
|
} catch (NoSuchFieldException | SecurityException ex) {
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} catch (SecurityException ex) {
|
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
String shortName = (f != null && !f.shortName().equals("")) ? f.shortName() : longName;
|
String shortName = (f != null && !f.shortName().equals("")) ? f.shortName() : longName;
|
||||||
@ -473,41 +504,42 @@ public class Configuration implements Reconfigurable {
|
|||||||
found = true;
|
found = true;
|
||||||
n.setFieldValue(longName, value);
|
n.setFieldValue(longName, value);
|
||||||
applySettings(n);
|
applySettings(n);
|
||||||
n.subject.reconfigure();
|
// n.subject.reconfigure();
|
||||||
buildTree();
|
buildTree();
|
||||||
System.out.println("Set property "+n.subject.getName()+"."+longName+" to "+value);
|
System.out.println("Set property " + n.subject.getName() + "." + longName + " to " + value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
System.err.println("Unable to find property "+fieldName+" for device "+deviceName+". Try one of these :"+Utility.join(shortFieldNames, ", "));
|
System.err.println("Unable to find property " + fieldName + " for device " + deviceName + ". Try one of these :" + Utility.join(shortFieldNames, ", "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildNodeMap(ConfigNode n, Map<String, ConfigNode> shortNames) {
|
private static void buildNodeMap(ConfigNode n, Map<String, ConfigNode> shortNames) {
|
||||||
|
// System.out.println("Encountered " + n.subject.getShortName().toLowerCase());
|
||||||
shortNames.put(n.subject.getShortName().toLowerCase(), n);
|
shortNames.put(n.subject.getShortName().toLowerCase(), n);
|
||||||
for (Map.Entry<String, ConfigNode> c : n.children.entrySet()) {
|
n.children.entrySet().stream().forEach((c) -> {
|
||||||
buildNodeMap(c.getValue(), shortNames);
|
buildNodeMap(c.getValue(), shortNames);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printTree(ConfigNode n, String prefix, int i) {
|
private static void printTree(ConfigNode n, String prefix, int i) {
|
||||||
for (String setting : n.getAllSettingNames()) {
|
n.getAllSettingNames().stream().forEach((setting) -> {
|
||||||
for (int j=0; j < i; j++) System.out.print(" ");
|
for (int j = 0; j < i; j++) {
|
||||||
|
System.out.print(" ");
|
||||||
|
}
|
||||||
ConfigurableField f = null;
|
ConfigurableField f = null;
|
||||||
try {
|
try {
|
||||||
f = n.subject.getClass().getField(setting).getAnnotation(ConfigurableField.class);
|
f = n.subject.getClass().getField(setting).getAnnotation(ConfigurableField.class);
|
||||||
} catch (NoSuchFieldException ex) {
|
} catch (NoSuchFieldException | SecurityException ex) {
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} catch (SecurityException ex) {
|
|
||||||
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
String sn = (f != null && !f.shortName().equals("")) ? f.shortName() : setting;
|
String sn = (f != null && !f.shortName().equals("")) ? f.shortName() : setting;
|
||||||
System.out.println(prefix+">>"+setting+" ("+n.subject.getShortName()+"."+sn+")");
|
System.out.println(prefix + ">>" + setting + " (" + n.subject.getShortName() + "." + sn + ")");
|
||||||
}
|
});
|
||||||
for (Map.Entry<String, ConfigNode> c : n.children.entrySet()) {
|
n.children.entrySet().stream().forEach((c) -> {
|
||||||
printTree(c.getValue(), prefix+"."+c.getKey(), i+1);
|
printTree(c.getValue(), prefix + "." + c.getKey(), i + 1);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public abstract class RAM implements Reconfigurable {
|
|||||||
public List<RAMListener> listeners;
|
public List<RAMListener> listeners;
|
||||||
public List<RAMListener>[] listenerMap;
|
public List<RAMListener>[] listenerMap;
|
||||||
public List<RAMListener>[] ioListenerMap;
|
public List<RAMListener>[] ioListenerMap;
|
||||||
protected Optional<Card>[] cards;
|
public Optional<Card>[] cards;
|
||||||
// card 0 = 80 column card firmware / system rom
|
// card 0 = 80 column card firmware / system rom
|
||||||
public int activeSlot = 0;
|
public int activeSlot = 0;
|
||||||
protected final Computer computer;
|
protected final Computer computer;
|
||||||
|
@ -29,6 +29,7 @@ import jace.core.RAMEvent.TYPE;
|
|||||||
import jace.core.Utility;
|
import jace.core.Utility;
|
||||||
import jace.library.MediaConsumer;
|
import jace.library.MediaConsumer;
|
||||||
import jace.library.MediaConsumerParent;
|
import jace.library.MediaConsumerParent;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -39,10 +40,9 @@ import java.util.logging.Logger;
|
|||||||
* side of the Disk ][ controller interface as well as the on-board "boot0" ROM.
|
* side of the Disk ][ controller interface as well as the on-board "boot0" ROM.
|
||||||
* The behavior of the actual drive stepping, reading disk images, and so on is
|
* The behavior of the actual drive stepping, reading disk images, and so on is
|
||||||
* performed by DiskIIDrive and FloppyDisk, respectively. This class only serves
|
* performed by DiskIIDrive and FloppyDisk, respectively. This class only serves
|
||||||
* as the I/O interface portion.
|
* as the I/O interface portion. Created on April 21, 2007
|
||||||
* Created on April 21, 2007
|
|
||||||
*
|
*
|
||||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||||
*/
|
*/
|
||||||
@Name("Disk ][ Controller")
|
@Name("Disk ][ Controller")
|
||||||
public class CardDiskII extends Card implements Reconfigurable, MediaConsumerParent {
|
public class CardDiskII extends Card implements Reconfigurable, MediaConsumerParent {
|
||||||
@ -54,6 +54,10 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
|
|||||||
static public int DEFAULT_VOLUME_NUMBER = 0x0FE;
|
static public int DEFAULT_VOLUME_NUMBER = 0x0FE;
|
||||||
@ConfigurableField(category = "Disk", defaultValue = "true", name = "Speed boost", description = "If enabled, emulator will run at max speed during disk access")
|
@ConfigurableField(category = "Disk", defaultValue = "true", name = "Speed boost", description = "If enabled, emulator will run at max speed during disk access")
|
||||||
static public boolean USE_MAX_SPEED = true;
|
static public boolean USE_MAX_SPEED = true;
|
||||||
|
@ConfigurableField(category = "Disk", defaultValue = "", shortName = "d1", name = "Drive 1 disk image", description = "Path of disk 1")
|
||||||
|
public String disk1;
|
||||||
|
@ConfigurableField(category = "Disk", defaultValue = "", shortName = "d2", name = "Drive 2 disk image", description = "Path of disk 1")
|
||||||
|
public String disk2;
|
||||||
|
|
||||||
public CardDiskII(Computer computer) {
|
public CardDiskII(Computer computer) {
|
||||||
super(computer);
|
super(computer);
|
||||||
@ -143,8 +147,7 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
|
|||||||
currentDrive.setReadMode();
|
currentDrive.setReadMode();
|
||||||
if (currentDrive.disk != null && currentDrive.disk.writeProtected) {
|
if (currentDrive.disk != null && currentDrive.disk.writeProtected) {
|
||||||
e.setNewValue(0x080);
|
e.setNewValue(0x080);
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
// e.setNewValue((byte) (Math.random() * 256.0));
|
// e.setNewValue((byte) (Math.random() * 256.0));
|
||||||
e.setNewValue(0);
|
e.setNewValue(0);
|
||||||
}
|
}
|
||||||
@ -191,6 +194,19 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
|
|||||||
@Override
|
@Override
|
||||||
public void reconfigure() {
|
public void reconfigure() {
|
||||||
super.reconfigure();
|
super.reconfigure();
|
||||||
|
try {
|
||||||
|
if (disk1 != null && !disk1.isEmpty()) {
|
||||||
|
drive1.insertDisk(new File(disk1));
|
||||||
|
disk1 = null;
|
||||||
|
}
|
||||||
|
if (disk2 != null && !disk2.isEmpty()) {
|
||||||
|
drive2.insertDisk(new File(disk2));
|
||||||
|
disk2 = null;
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(CardDiskII.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tweakTiming() {
|
private void tweakTiming() {
|
||||||
@ -212,10 +228,10 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
|
|||||||
public void setSlot(int slot) {
|
public void setSlot(int slot) {
|
||||||
super.setSlot(slot);
|
super.setSlot(slot);
|
||||||
drive1.getIcon().setDescription("S" + slot + "D1");
|
drive1.getIcon().setDescription("S" + slot + "D1");
|
||||||
drive2.getIcon().setDescription("S" + slot + "D2");
|
drive2.getIcon().setDescription("S" + slot + "D2");
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaConsumer[] getConsumers() {
|
public MediaConsumer[] getConsumers() {
|
||||||
return new MediaConsumer[] {drive1, drive2};
|
return new MediaConsumer[]{drive1, drive2};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ import javax.swing.JPanel;
|
|||||||
*/
|
*/
|
||||||
public class MediaLibrary implements Reconfigurable {
|
public class MediaLibrary implements Reconfigurable {
|
||||||
|
|
||||||
public static MediaLibrary instance;
|
private static MediaLibrary instance;
|
||||||
|
|
||||||
public static MediaLibrary getInstance() {
|
public static MediaLibrary getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user