mirror of https://github.com/badvision/jace.git
Mass storage supports command-line settings now. For example -s7.d1 myDisk.2mg will insert the 800k or hard drive image into Slot 7, Drive 1.
This commit is contained in:
parent
b4ee1fafd8
commit
7668e723ec
|
@ -598,7 +598,7 @@ public class Configuration implements Reconfigurable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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, ", "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
|
@ -51,152 +52,10 @@ import javafx.scene.paint.Color;
|
||||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||||
*/
|
*/
|
||||||
public class Utility {
|
public class Utility {
|
||||||
|
|
||||||
//--------------- Introspection utilities
|
|
||||||
/*
|
|
||||||
private static Set<Class> findClasses(String pckgname, Class clazz) {
|
|
||||||
Set<Class> output = new HashSet<>();
|
|
||||||
// Code from JWhich
|
|
||||||
// ======
|
|
||||||
// Translate the package name into an absolute path
|
|
||||||
String name = pckgname;
|
|
||||||
if (!name.startsWith("/")) {
|
|
||||||
name = "/" + name;
|
|
||||||
}
|
|
||||||
name = name.replace('.', '/');
|
|
||||||
|
|
||||||
// Get a File object for the package
|
|
||||||
URL url = Utility.class.getResource(name);
|
|
||||||
if (url == null || url.getFile().contains("jre/lib")) {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
if (url.getProtocol().equalsIgnoreCase("jar")) {
|
|
||||||
return findClassesInJar(url, clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
File directory = new File(url.getFile());
|
|
||||||
// New code
|
|
||||||
// ======
|
|
||||||
if (directory.exists()) {
|
|
||||||
// Get the list of the files contained in the package
|
|
||||||
for (String filename : directory.list()) {
|
|
||||||
char firstLetter = filename.charAt(0);
|
|
||||||
if (firstLetter < 'A' || (firstLetter > 'Z' && firstLetter < 'a') || firstLetter > 'z') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// we are only interested in .class files
|
|
||||||
if (filename.endsWith(".class")) {
|
|
||||||
// removes the .class extension
|
|
||||||
String classname = filename.substring(0, filename.length() - 6);
|
|
||||||
try {
|
|
||||||
// Try to create an instance of the object
|
|
||||||
String className = pckgname + "." + classname;
|
|
||||||
Class c = Class.forName(className);
|
|
||||||
if (clazz.isAssignableFrom(c)) {
|
|
||||||
output.add(c);
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
System.err.println(ex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// System.out.println("Skipping non class: " + filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<Class> findClassesInJar(URL jarLocation, Class clazz) {
|
|
||||||
Set<Class> output = new HashSet<>();
|
|
||||||
JarFile jarFile = null;
|
|
||||||
try {
|
|
||||||
JarURLConnection conn = (JarURLConnection) jarLocation.openConnection();
|
|
||||||
jarFile = conn.getJarFile();
|
|
||||||
Enumeration<JarEntry> entries = jarFile.entries();
|
|
||||||
String last = "";
|
|
||||||
while (entries.hasMoreElements()) {
|
|
||||||
JarEntry jarEntry = entries.nextElement();
|
|
||||||
if (jarEntry.getName().equals(last)) {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
last = jarEntry.getName();
|
|
||||||
if (jarEntry.getName().endsWith(".class")) {
|
|
||||||
String className = jarEntry.getName();
|
|
||||||
className = className.substring(0, className.length() - 6);
|
|
||||||
className = className.replaceAll("/", "\\.");
|
|
||||||
if (className.startsWith("com.sun")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (className.startsWith("java")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (className.startsWith("javax")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (className.startsWith("com.oracle")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// removes the .class extension
|
|
||||||
try {
|
|
||||||
// Try to create an instance of the object
|
|
||||||
// System.out.println("Class: " + className);
|
|
||||||
Class c = Class.forName(className);
|
|
||||||
if (clazz.isAssignableFrom(c)) {
|
|
||||||
output.add(c);
|
|
||||||
}
|
|
||||||
} catch (ClassNotFoundException cnfex) {
|
|
||||||
System.err.println(cnfex);
|
|
||||||
} catch (Throwable cnfex) {
|
|
||||||
// System.err.println(cnfex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// System.out.println("Skipping non class: " + jarEntry.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(Utility.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (jarFile != null) {
|
|
||||||
jarFile.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(Utility.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
private static final Map<Class, Collection<Class>> classCache = new HashMap<>();
|
|
||||||
*/
|
|
||||||
static Reflections reflections = new Reflections("jace");
|
static Reflections reflections = new Reflections("jace");
|
||||||
public static Set<Class> findAllSubclasses(Class clazz) {
|
public static Set<Class> findAllSubclasses(Class clazz) {
|
||||||
return reflections.getSubTypesOf(clazz);
|
return reflections.getSubTypesOf(clazz);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
public static List<Class> findAllSubclasses(Class clazz) {
|
|
||||||
if (classCache.containsKey(clazz)) {
|
|
||||||
return (List<Class>) classCache.get(clazz);
|
|
||||||
}
|
|
||||||
TreeMap<String, Class> allClasses = new TreeMap<>();
|
|
||||||
List<Class> values = new ArrayList(allClasses.values());
|
|
||||||
classCache.put(clazz, values);
|
|
||||||
for (Package p : Package.getPackages()) {
|
|
||||||
if (p.getName().startsWith("java")
|
|
||||||
|| p.getName().startsWith("com.sun")
|
|
||||||
|| p.getName().startsWith("sun")
|
|
||||||
|| p.getName().startsWith("com.oracle")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
findClasses(p.getName(), clazz)
|
|
||||||
.stream()
|
|
||||||
.filter((c) -> !(Modifier.isAbstract(c.getModifiers())))
|
|
||||||
.forEach((c) -> {
|
|
||||||
allClasses.put(c.getSimpleName(), c);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//------------------------------ String comparators
|
//------------------------------ String comparators
|
||||||
/**
|
/**
|
||||||
|
@ -271,14 +130,8 @@ public class Utility {
|
||||||
return score * adjustment * adjustment;
|
return score * adjustment * adjustment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String join(Collection c, String d) {
|
public static String join(Collection<String> c, String d) {
|
||||||
String result = "";
|
return c.stream().collect(Collectors.joining(d));
|
||||||
boolean isFirst = true;
|
|
||||||
for (Object o : c) {
|
|
||||||
result += (isFirst ? "" : d) + o.toString();
|
|
||||||
isFirst = false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isHeadless = false;
|
private static boolean isHeadless = false;
|
||||||
|
|
|
@ -20,6 +20,7 @@ package jace.hardware.massStorage;
|
||||||
|
|
||||||
import jace.EmulatorUILogic;
|
import jace.EmulatorUILogic;
|
||||||
import jace.apple2e.MOS65C02;
|
import jace.apple2e.MOS65C02;
|
||||||
|
import jace.config.ConfigurableField;
|
||||||
import jace.config.Name;
|
import jace.config.Name;
|
||||||
import jace.core.Card;
|
import jace.core.Card;
|
||||||
import jace.core.Computer;
|
import jace.core.Computer;
|
||||||
|
@ -28,8 +29,11 @@ import jace.core.RAMEvent.TYPE;
|
||||||
import jace.core.Utility;
|
import jace.core.Utility;
|
||||||
import jace.hardware.ProdosDriver;
|
import jace.hardware.ProdosDriver;
|
||||||
import jace.hardware.SmartportDriver;
|
import jace.hardware.SmartportDriver;
|
||||||
|
import jace.library.MediaCache;
|
||||||
import jace.library.MediaConsumer;
|
import jace.library.MediaConsumer;
|
||||||
import jace.library.MediaConsumerParent;
|
import jace.library.MediaConsumerParent;
|
||||||
|
import jace.library.MediaEntry;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -43,6 +47,10 @@ import java.util.logging.Logger;
|
||||||
@Name("Mass Storage Device")
|
@Name("Mass Storage Device")
|
||||||
public class CardMassStorage extends Card implements MediaConsumerParent {
|
public class CardMassStorage extends Card implements MediaConsumerParent {
|
||||||
|
|
||||||
|
@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 2")
|
||||||
|
public String disk2;
|
||||||
MassStorageDrive drive1;
|
MassStorageDrive drive1;
|
||||||
MassStorageDrive drive2;
|
MassStorageDrive drive2;
|
||||||
|
|
||||||
|
@ -59,8 +67,8 @@ public class CardMassStorage extends Card implements MediaConsumerParent {
|
||||||
@Override
|
@Override
|
||||||
public void setSlot(int slot) {
|
public void setSlot(int slot) {
|
||||||
super.setSlot(slot);
|
super.setSlot(slot);
|
||||||
drive1.getIcon().ifPresent(icon->icon.setText("S" + getSlot() + "D1"));
|
drive1.getIcon().ifPresent(icon -> icon.setText("S" + getSlot() + "D1"));
|
||||||
drive2.getIcon().ifPresent(icon->icon.setText("S" + getSlot() + "D2"));
|
drive2.getIcon().ifPresent(icon -> icon.setText("S" + getSlot() + "D2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -128,10 +136,28 @@ public class CardMassStorage extends Card implements MediaConsumerParent {
|
||||||
@Override
|
@Override
|
||||||
public void reconfigure() {
|
public void reconfigure() {
|
||||||
unregisterListeners();
|
unregisterListeners();
|
||||||
|
if (disk1 != null && !disk1.isEmpty()) {
|
||||||
|
try {
|
||||||
|
MediaEntry entry = MediaCache.getMediaFromFile(new File(disk1));
|
||||||
|
drive1.insertMedia(entry, entry.files.get(0));
|
||||||
|
disk1 = null;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(CardMassStorage.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disk2 != null && !disk2.isEmpty()) {
|
||||||
|
try {
|
||||||
|
MediaEntry entry = MediaCache.getMediaFromFile(new File(disk2));
|
||||||
|
drive2.insertMedia(entry, entry.files.get(0));
|
||||||
|
disk2 = null;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(CardMassStorage.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (computer.getCpu() != null) {
|
if (computer.getCpu() != null) {
|
||||||
int pc = computer.getCpu().getProgramCounter();
|
int pc = computer.getCpu().getProgramCounter();
|
||||||
if (drive1.getCurrentDisk() != null && getSlot() == 7 && (pc >= 0x0c65e && pc <= 0x0c66F)) {
|
if (drive1.getCurrentDisk() != null && getSlot() == 7 && (pc >= 0x0c65e && pc <= 0x0c66F)) {
|
||||||
// If the computer is in a loop trying to boot from cards 6, fast-boot from here instead
|
// If the computer is in a loop trying to boot from cards 6, fast-boot from here instead
|
||||||
// This is a convenience to boot a hard-drive if the emulator has started waiting for a currentDisk
|
// This is a convenience to boot a hard-drive if the emulator has started waiting for a currentDisk
|
||||||
currentDrive = drive1;
|
currentDrive = drive1;
|
||||||
EmulatorUILogic.simulateCtrlAppleReset();
|
EmulatorUILogic.simulateCtrlAppleReset();
|
||||||
|
|
Loading…
Reference in New Issue