diff --git a/src/main/java/jace/apple2e/Apple2e.java b/src/main/java/jace/apple2e/Apple2e.java index b828d71..3a6aed1 100644 --- a/src/main/java/jace/apple2e/Apple2e.java +++ b/src/main/java/jace/apple2e/Apple2e.java @@ -327,6 +327,8 @@ public class Apple2e extends Computer { } private List hints = new ArrayList<>(); + Thread twinkleEffect; + private void enableHints() { if (hints.isEmpty()) { hints.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) { @@ -340,64 +342,66 @@ public class Apple2e extends Computer { if (getCpu().getProgramCounter() != getScopeStart()) { return; } - Thread t = new Thread(() -> { - try { - // Give the floppy drive time to start - Thread.sleep(1000); - if (getCpu().getProgramCounter() >> 8 != 0x0c6) { - return; - } + if (twinkleEffect == null || !twinkleEffect.isAlive()) { + twinkleEffect = new Thread(() -> { + try { + // Give the floppy drive time to start + Thread.sleep(1000); + if (getCpu().getProgramCounter() >> 8 != 0x0c6) { + return; + } - int row = 2; - for (String s : new String[]{ - " Welcome to", - " _ __ ___ ____ ", - " | | / /\\ / / ` | |_ ", - " \\_|_| /_/--\\ \\_\\_, |_|__ ", - "", - " Java Apple Computer Emulator", - "", - " Presented by BLuRry", - " http://goo.gl/SnzqG", - "", - "Press F1 to insert disk in Slot 6, D1", - "Press F2 to insert disk in Slot 6, D2", - "Press F3 to insert HDV or 2MG in slot 7", - "Press F4 to open configuration", - "Press F5 to run raw binary program", - "Press F8 to correct the aspect ratio", - "Press F9 to toggle fullscreen", - "Press F10 to open/close the debugger", - "", - " If metacheat is enabled:", - "Press HOME to activate memory heatmap", - "Press END to activate metacheat search" - }) { - int addr = 0x0401 + VideoDHGR.calculateTextOffset(row++); - for (char c : s.toCharArray()) { - getMemory().write(addr++, (byte) (c | 0x080), false, true); - } - } - while (getCpu().getProgramCounter() >> 8 == 0x0c6) { - int x = (int) (Math.random() * 26.0) + 7; - int y = (int) (Math.random() * 4.0) + 3; - int addr = 0x0400 + VideoDHGR.calculateTextOffset(y) + x; - byte old = getMemory().readRaw(addr); - for (char c : "+xX*+".toCharArray()) { - if (getCpu().getProgramCounter() >> 8 != 0x0c6) { - break; + int row = 2; + for (String s : new String[]{ + " Welcome to", + " _ __ ___ ____ ", + " | | / /\\ / / ` | |_ ", + " \\_|_| /_/--\\ \\_\\_, |_|__ ", + "", + " Java Apple Computer Emulator", + "", + " Presented by BLuRry", + " http://goo.gl/SnzqG", + "", + "Press F1 to insert disk in Slot 6, D1", + "Press F2 to insert disk in Slot 6, D2", + "Press F3 to insert HDV or 2MG in slot 7", + "Press F4 to open configuration", + "Press F5 to run raw binary program", + "Press F8 to correct the aspect ratio", + "Press F9 to toggle fullscreen", + "Press F10 to open/close the debugger", + "", + " If metacheat is enabled:", + "Press HOME to activate memory heatmap", + "Press END to activate metacheat search" + }) { + int addr = 0x0401 + VideoDHGR.calculateTextOffset(row++); + for (char c : s.toCharArray()) { + getMemory().write(addr++, (byte) (c | 0x080), false, true); } - getMemory().write(addr, (byte) (c | 0x080), true, true); - Thread.sleep(100); } - getMemory().write(addr, old, true, true); + while (getCpu().getProgramCounter() >> 8 == 0x0c6) { + int x = (int) (Math.random() * 26.0) + 7; + int y = (int) (Math.random() * 4.0) + 3; + int addr = 0x0400 + VideoDHGR.calculateTextOffset(y) + x; + byte old = getMemory().readRaw(addr); + for (char c : "+xX*+".toCharArray()) { + if (getCpu().getProgramCounter() >> 8 != 0x0c6) { + break; + } + getMemory().write(addr, (byte) (c | 0x080), true, true); + Thread.sleep(100); + } + getMemory().write(addr, old, true, true); + } + } catch (InterruptedException ex) { + Logger.getLogger(Apple2e.class.getName()).log(Level.SEVERE, null, ex); } - } catch (InterruptedException ex) { - Logger.getLogger(Apple2e.class.getName()).log(Level.SEVERE, null, ex); - } - }); - t.setName("Startup Animation"); - t.start(); + }); + twinkleEffect.setName("Startup Animation"); + twinkleEffect.start(); + } } }); // Latch to the PRODOS SYNTAX CHECK parser diff --git a/src/main/java/jace/apple2e/Speaker.java b/src/main/java/jace/apple2e/Speaker.java index 9625de0..b9a3abc 100644 --- a/src/main/java/jace/apple2e/Speaker.java +++ b/src/main/java/jace/apple2e/Speaker.java @@ -321,5 +321,6 @@ public class Speaker extends Device { public void detach() { removeListener(); suspend(); + super.detach(); } } diff --git a/src/main/java/jace/apple2e/VideoDHGR.java b/src/main/java/jace/apple2e/VideoDHGR.java index 8abbe12..7778e67 100644 --- a/src/main/java/jace/apple2e/VideoDHGR.java +++ b/src/main/java/jace/apple2e/VideoDHGR.java @@ -734,11 +734,6 @@ public class VideoDHGR extends Video { // Do nothing } - @Override - public void detach() { - // Do nothing - } - @Override public void hblankStart(WritableImage screen, int y, boolean isDirty) { // Do nothing diff --git a/src/main/java/jace/apple2e/VideoNTSC.java b/src/main/java/jace/apple2e/VideoNTSC.java index 55fd1f5..ddd01dd 100644 --- a/src/main/java/jace/apple2e/VideoNTSC.java +++ b/src/main/java/jace/apple2e/VideoNTSC.java @@ -328,10 +328,8 @@ public class VideoNTSC extends VideoDHGR { @Override public void reconfigure() { - detach(); activePalette = useTextPalette ? textPalette : solidPalette; super.reconfigure(); - attach(); } // The following section captures changes to the RGB mode // The details of this are in Brodener's patent application #4631692 @@ -456,10 +454,10 @@ public class VideoNTSC extends VideoDHGR { @Override public void detach() { - super.detach(); rgbStateListeners.stream().forEach((l) -> { computer.getMemory().removeListener(l); }); + super.detach(); } @Override diff --git a/src/main/java/jace/cheat/Cheats.java b/src/main/java/jace/cheat/Cheats.java index c922d66..592024e 100644 --- a/src/main/java/jace/cheat/Cheats.java +++ b/src/main/java/jace/cheat/Cheats.java @@ -41,18 +41,30 @@ public abstract class Cheats extends Device { computer.getMemory().addListener(l); } + @Override + public void attach() { + registerListeners(); + } + @Override public void detach() { + unregisterListeners(); + super.detach(); + } + + abstract void registerListeners(); + + protected void unregisterListeners() { listeners.stream().forEach((l) -> { computer.getMemory().removeListener(l); }); - listeners.clear(); + listeners.clear(); } @Override public void reconfigure() { - detach(); - attach(); + unregisterListeners(); + registerListeners(); } @Override diff --git a/src/main/java/jace/cheat/MetaCheats.java b/src/main/java/jace/cheat/MetaCheats.java index 0798833..b389fe2 100644 --- a/src/main/java/jace/cheat/MetaCheats.java +++ b/src/main/java/jace/cheat/MetaCheats.java @@ -165,7 +165,7 @@ public class MetaCheats extends Cheats { @Override - public void attach() { + public void registerListeners() { this.addCheat(new RAMListener(RAMEvent.TYPE.READ, RAMEvent.SCOPE.ANY, RAMEvent.VALUE.ANY) { @Override protected void doConfig() { @@ -205,12 +205,6 @@ public class MetaCheats extends Cheats { }); } - @Override - public void detach() { - super.detach(); - Keyboard.unregisterAllHandlers(this); - } - public void addByteCheat(int addr, int val) { holdBytes.put(addr, val); redrawCheats(); diff --git a/src/main/java/jace/cheat/PrinceOfPersiaCheats.java b/src/main/java/jace/cheat/PrinceOfPersiaCheats.java index 639e37f..a5504fb 100644 --- a/src/main/java/jace/cheat/PrinceOfPersiaCheats.java +++ b/src/main/java/jace/cheat/PrinceOfPersiaCheats.java @@ -99,9 +99,9 @@ public class PrinceOfPersiaCheats extends Cheats implements MouseListener { public static int InEditor = 0x0202; public static int MinLeft = 0x0300; public static int hasSword = 0x030a; - public static int mobtables = 0x0b600; - public static int trloc = mobtables; - public static int trscrn = trloc + 0x020; + public static final int mobtables = 0x0b600; + public static final int trloc = mobtables; + public static final int trscrn = trloc + 0x020; public static int trdirec = trscrn + 0x020; // Blueprint (map level data)0 public static int BlueSpec = 0x0b9d0; @@ -164,7 +164,7 @@ public class PrinceOfPersiaCheats extends Cheats implements MouseListener { } @Override - public void attach() { + public void registerListeners() { if (velocityHack) { addCheat(new RAMListener(RAMEvent.TYPE.READ_DATA, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) { @Override @@ -269,8 +269,8 @@ public class PrinceOfPersiaCheats extends Cheats implements MouseListener { } @Override - public void detach() { - super.detach(); + public void unregisterListeners() { + super.unregisterListeners(); if (Emulator.getScreen() != null) { Emulator.getScreen().removeMouseListener(this); } @@ -411,11 +411,8 @@ public class PrinceOfPersiaCheats extends Cheats implements MouseListener { if (blockType == gate || blockType == exit2 || blockType == exit) { // If the object in question can be opened (exit or gate) add it to the transitional animation buffer //System.out.print("Triggering screen " + currentScrn + " at pos " + clickedLoc); - boolean addTransition = false; - if (numTransition == 0) { - addTransition = true; - } else { - addTransition = true; + boolean addTransition = true; + if (numTransition > 0) { for (int i = 1; i <= numTransition; i++) { byte scrn = auxMem.readByte(trscrn + i); byte loc = auxMem.readByte(trloc + i); diff --git a/src/main/java/jace/config/Configuration.java b/src/main/java/jace/config/Configuration.java index 778fdb8..f1f9330 100644 --- a/src/main/java/jace/config/Configuration.java +++ b/src/main/java/jace/config/Configuration.java @@ -68,6 +68,7 @@ public class Configuration implements Reconfigurable { return null; } + @Override public String getName() { return "Configuration"; } @@ -77,6 +78,7 @@ public class Configuration implements Reconfigurable { return "cfg"; } + @Override public void reconfigure() { } diff --git a/src/main/java/jace/core/CPU.java b/src/main/java/jace/core/CPU.java index 543a399..83e7f5f 100644 --- a/src/main/java/jace/core/CPU.java +++ b/src/main/java/jace/core/CPU.java @@ -158,8 +158,4 @@ public abstract class CPU extends Device { @Override public void attach() { } - - @Override - public void detach() { - } } \ No newline at end of file diff --git a/src/main/java/jace/core/Card.java b/src/main/java/jace/core/Card.java index e2ec510..b84961b 100644 --- a/src/main/java/jace/core/Card.java +++ b/src/main/java/jace/core/Card.java @@ -65,6 +65,57 @@ public abstract class Card extends Device { @Override public void attach() { + registerListeners(); + } + + @Override + public void detach() { + suspend(); + unregisterListeners(); + super.detach(); + } + + abstract protected void handleIOAccess(int register, RAMEvent.TYPE type, int value, RAMEvent e); + + abstract protected void handleFirmwareAccess(int register, RAMEvent.TYPE type, int value, RAMEvent e); + + abstract protected void handleC8FirmwareAccess(int register, RAMEvent.TYPE type, int value, RAMEvent e); + + public int getSlot() { + return slot; + } + + public void setSlot(int slot) { + this.slot = slot; + } + + public PagedMemory getCxRom() { + return cxRom; + } + + public PagedMemory getC8Rom() { + return c8Rom; + } + + @Override + public void reconfigure() { + boolean restart = suspend(); + unregisterListeners(); + if (restart) { + resume(); + } + registerListeners(); + } + + public void notifyVBLStateChanged(boolean state) { + // Do nothing unless overridden + } + + public boolean suspendWithCPU() { + return false; + } + + protected void registerListeners() { ioListener = new RAMListener( RAMEvent.TYPE.ANY, RAMEvent.SCOPE.RANGE, @@ -106,11 +157,13 @@ public abstract class Card extends Device { RAMEvent.TYPE.ANY, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) { + @Override protected void doConfig() { setScopeStart(slot * 256 + 0x00c800); setScopeEnd(slot * 256 + 0x00cfff); } + @Override protected void doEvent(RAMEvent e) { if (SoftSwitches.CXROM.getState() || computer.getMemory().getActiveSlot() != getSlot() @@ -126,51 +179,9 @@ public abstract class Card extends Device { computer.getMemory().addListener(c8firmwareListener); } - @Override - public void detach() { - suspend(); + protected void unregisterListeners() { computer.getMemory().removeListener(ioListener); computer.getMemory().removeListener(firmwareListener); computer.getMemory().removeListener(c8firmwareListener); - } - - abstract protected void handleIOAccess(int register, RAMEvent.TYPE type, int value, RAMEvent e); - - abstract protected void handleFirmwareAccess(int register, RAMEvent.TYPE type, int value, RAMEvent e); - - abstract protected void handleC8FirmwareAccess(int register, RAMEvent.TYPE type, int value, RAMEvent e); - - public int getSlot() { - return slot; - } - - public void setSlot(int slot) { - this.slot = slot; - } - - public PagedMemory getCxRom() { - return cxRom; - } - - public PagedMemory getC8Rom() { - return c8Rom; - } - - @Override - public void reconfigure() { - boolean restart = suspend(); - detach(); - if (restart) { - resume(); - } - attach(); - } - - public void notifyVBLStateChanged(boolean state) { - // Do nothing unless overridden - } - - public boolean suspendWithCPU() { - return false; - } + } } \ No newline at end of file diff --git a/src/main/java/jace/core/Device.java b/src/main/java/jace/core/Device.java index f362a96..808502e 100644 --- a/src/main/java/jace/core/Device.java +++ b/src/main/java/jace/core/Device.java @@ -114,5 +114,7 @@ public abstract class Device implements Reconfigurable { public abstract void attach(); - public abstract void detach(); + public void detach() { + Keyboard.unregisterAllHandlers(this); + } } diff --git a/src/main/java/jace/core/Keyboard.java b/src/main/java/jace/core/Keyboard.java index 81b285f..a2bd7b3 100644 --- a/src/main/java/jace/core/Keyboard.java +++ b/src/main/java/jace/core/Keyboard.java @@ -98,11 +98,11 @@ public class Keyboard implements Reconfigurable { if (!action.notifyOnRelease()) { return false; } - System.out.println("Key up: "+method.toString()); +// System.out.println("Key up: "+method.toString()); Object returnValue = null; try { if (method.getParameterCount() > 0) { - returnValue = method.invoke(isStatic ? null : owner, true); + returnValue = method.invoke(isStatic ? null : owner, false); } else { returnValue = method.invoke(isStatic ? null : owner); } @@ -117,7 +117,7 @@ public class Keyboard implements Reconfigurable { @Override public boolean handleKeyDown(KeyEvent e) { - System.out.println("Key down: "+method.toString()); +// System.out.println("Key down: "+method.toString()); Object returnValue = null; try { if (method.getParameterCount() > 0) { @@ -263,7 +263,7 @@ public class Keyboard implements Reconfigurable { computer.resume(); } - @InvokableAction(name = "Closed Apple Key", alternatives = "CA", category = "Keyboard", notifyOnRelease = true, defaultKeyMapping = "Meta", consumeKeyEvent = false) + @InvokableAction(name = "Closed Apple Key", alternatives = "CA", category = "Keyboard", notifyOnRelease = true, defaultKeyMapping = {"Shortcut","Meta","Command"}, consumeKeyEvent = false) public void solidApple(boolean pressed) { computer.pause(); SoftSwitches.PB1.getSwitch().setState(pressed); diff --git a/src/main/java/jace/core/Motherboard.java b/src/main/java/jace/core/Motherboard.java index 8943c58..40ce6e3 100644 --- a/src/main/java/jace/core/Motherboard.java +++ b/src/main/java/jace/core/Motherboard.java @@ -198,5 +198,6 @@ public class Motherboard extends TimedDevice { }); miscDevices.clear(); // halt(); + super.detach(); } } diff --git a/src/main/java/jace/core/SoundMixer.java b/src/main/java/jace/core/SoundMixer.java index 0d1f843..a186d14 100644 --- a/src/main/java/jace/core/SoundMixer.java +++ b/src/main/java/jace/core/SoundMixer.java @@ -218,6 +218,7 @@ public class SoundMixer extends Device { } availableLines.clear(); activeLines.clear(); + super.detach(); } private void initMixer() { diff --git a/src/main/java/jace/hardware/CardMockingboard.java b/src/main/java/jace/hardware/CardMockingboard.java index 19ac8a1..29770e2 100644 --- a/src/main/java/jace/hardware/CardMockingboard.java +++ b/src/main/java/jace/hardware/CardMockingboard.java @@ -221,6 +221,8 @@ public class CardMockingboard extends Card implements Runnable { resume(); } } + + /////////////////////////////////////////////////////////// public static int[] VolTable; int[][] buffers; diff --git a/src/main/java/jace/hardware/CardSSC.java b/src/main/java/jace/hardware/CardSSC.java index 2de66e8..a4251eb 100644 --- a/src/main/java/jace/hardware/CardSSC.java +++ b/src/main/java/jace/hardware/CardSSC.java @@ -18,7 +18,6 @@ */ package jace.hardware; -import jace.Emulator; import jace.config.ConfigurableField; import jace.config.Name; import jace.config.Reconfigurable; @@ -415,6 +414,7 @@ public class CardSSC extends Card implements Reconfigurable, Runnable { /** * Detach from server socket port and ensure that the card's resources are * no longer in use + * @return */ @Override public boolean suspend() { @@ -458,7 +458,6 @@ public class CardSSC extends Card implements Reconfigurable, Runnable { } catch (IOException ex) { suspend(); Logger.getLogger(CardSSC.class.getName()).log(Level.SEVERE, null, ex); - ex.printStackTrace(); } } } @@ -484,7 +483,6 @@ public class CardSSC extends Card implements Reconfigurable, Runnable { @Override protected void handleFirmwareAccess(int register, TYPE type, int value, RAMEvent e) { // Do nothing -- the card rom does everything - return; } @Override diff --git a/src/main/java/jace/hardware/CardThunderclock.java b/src/main/java/jace/hardware/CardThunderclock.java index 236eda8..22d35e0 100644 --- a/src/main/java/jace/hardware/CardThunderclock.java +++ b/src/main/java/jace/hardware/CardThunderclock.java @@ -18,7 +18,6 @@ */ package jace.hardware; -import jace.Emulator; import jace.apple2e.MOS65C02; import jace.config.ConfigurableField; import jace.config.Name; diff --git a/src/main/java/jace/hardware/Joystick.java b/src/main/java/jace/hardware/Joystick.java index 09000cc..64d02a6 100644 --- a/src/main/java/jace/hardware/Joystick.java +++ b/src/main/java/jace/hardware/Joystick.java @@ -180,6 +180,7 @@ public class Joystick extends Device { @Override public void detach() { removeListeners(); + super.detach(); } @Override diff --git a/src/main/java/jace/hardware/massStorage/CardMassStorage.java b/src/main/java/jace/hardware/massStorage/CardMassStorage.java index 4deec3d..e2405af 100644 --- a/src/main/java/jace/hardware/massStorage/CardMassStorage.java +++ b/src/main/java/jace/hardware/massStorage/CardMassStorage.java @@ -128,8 +128,7 @@ public class CardMassStorage extends Card implements MediaConsumerParent { @Override public void reconfigure() { try { - detach(); - + unregisterListeners(); int pc = computer.getCpu().getProgramCounter(); if (drive1.getCurrentDisk() != null && getSlot() == 7 && (pc == 0x0c65e || pc == 0x0c661)) { // If the computer is in a loop trying to boot from cards 6, fast-boot from here instead @@ -139,7 +138,7 @@ public class CardMassStorage extends Card implements MediaConsumerParent { Optional[] cards = computer.getMemory().getAllCards(); cards[6].ifPresent(card->computer.getMotherboard().cancelSpeedRequest(card)); } - attach(); + registerListeners(); } catch (IOException ex) { Logger.getLogger(CardMassStorage.class.getName()).log(Level.SEVERE, null, ex); } @@ -255,6 +254,7 @@ public class CardMassStorage extends Card implements MediaConsumerParent { } }; + @Override public MediaConsumer[] getConsumers() { return new MediaConsumer[]{drive1, drive2}; } diff --git a/src/main/java/jace/hardware/mockingboard/R6522.java b/src/main/java/jace/hardware/mockingboard/R6522.java index 58f514f..32b8e1c 100644 --- a/src/main/java/jace/hardware/mockingboard/R6522.java +++ b/src/main/java/jace/hardware/mockingboard/R6522.java @@ -165,11 +165,6 @@ public abstract class R6522 extends Device { // Start chip } - @Override - public void detach() { - // Reset - } - @Override public void reconfigure() { // Reset