Detatch is now reserved only for removal of hardware (will unhook keyboard shortcuts) whereas listener registration can be performed during reconfiguration. This distinction had to be made because reconfiguration was disconnecting keyboard shortcuts and making a general mess of things. Also, now the correct open/closed apple key behavior is working.

This commit is contained in:
Brendan Robert 2015-02-21 10:52:26 -06:00
parent 9dcbc3422e
commit 7e5ddac0e6
20 changed files with 157 additions and 148 deletions

View File

@ -327,6 +327,8 @@ public class Apple2e extends Computer {
}
private List<RAMListener> 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

View File

@ -321,5 +321,6 @@ public class Speaker extends Device {
public void detach() {
removeListener();
suspend();
super.detach();
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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() {
}

View File

@ -158,8 +158,4 @@ public abstract class CPU extends Device {
@Override
public void attach() {
}
@Override
public void detach() {
}
}

View File

@ -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;
}
}
}

View File

@ -114,5 +114,7 @@ public abstract class Device implements Reconfigurable {
public abstract void attach();
public abstract void detach();
public void detach() {
Keyboard.unregisterAllHandlers(this);
}
}

View File

@ -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);

View File

@ -198,5 +198,6 @@ public class Motherboard extends TimedDevice {
});
miscDevices.clear();
// halt();
super.detach();
}
}

View File

@ -218,6 +218,7 @@ public class SoundMixer extends Device {
}
availableLines.clear();
activeLines.clear();
super.detach();
}
private void initMixer() {

View File

@ -221,6 +221,8 @@ public class CardMockingboard extends Card implements Runnable {
resume();
}
}
///////////////////////////////////////////////////////////
public static int[] VolTable;
int[][] buffers;

View File

@ -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

View File

@ -18,7 +18,6 @@
*/
package jace.hardware;
import jace.Emulator;
import jace.apple2e.MOS65C02;
import jace.config.ConfigurableField;
import jace.config.Name;

View File

@ -180,6 +180,7 @@ public class Joystick extends Device {
@Override
public void detach() {
removeListeners();
super.detach();
}
@Override

View File

@ -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<Card>[] 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};
}

View File

@ -165,11 +165,6 @@ public abstract class R6522 extends Device {
// Start chip
}
@Override
public void detach() {
// Reset
}
@Override
public void reconfigure() {
// Reset