mirror of
https://github.com/badvision/jace.git
synced 2024-11-28 10:52:33 +00:00
Lambda simplification and code cleanup
This commit is contained in:
parent
5c0855d966
commit
e7f731900a
@ -29,22 +29,6 @@ public class JaceApplication extends Application {
|
||||
JaceUIController controller;
|
||||
|
||||
static boolean romStarted = false;
|
||||
static RAMListener startListener = new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0FA62);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
romStarted = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRelevant(RAMEvent e) {
|
||||
return super.isRelevant(e);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
@ -95,12 +79,16 @@ public class JaceApplication extends Application {
|
||||
* Start the computer and make sure it runs through the expected rom routine for cold boot
|
||||
*/
|
||||
private void bootWatchdog() {
|
||||
Emulator.computer.getMemory().addListener(startListener);
|
||||
romStarted = false;
|
||||
RAMListener startListener = Emulator.computer.getMemory().
|
||||
observe(RAMEvent.TYPE.EXECUTE, 0x0FA62, (e)-> {
|
||||
romStarted = true;
|
||||
});
|
||||
Emulator.computer.coldStart();
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
if (!romStarted) {
|
||||
System.out.println("Boot not detected, performing a cold start");
|
||||
Logger.getLogger(getClass().getName()).log(Level.WARNING,"Boot not detected, performing a cold start");
|
||||
Emulator.computer.coldStart();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
|
@ -425,19 +425,11 @@ public class Apple2e extends Computer {
|
||||
|
||||
private void enableHints() {
|
||||
if (hints.isEmpty()) {
|
||||
hints.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0FB63);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
animationTimer.schedule(drawHints, 1, TimeUnit.SECONDS);
|
||||
animationSchedule =
|
||||
hints.add(getMemory().observe(RAMEvent.TYPE.EXECUTE, 0x0FB63, (e)->{
|
||||
animationTimer.schedule(drawHints, 1, TimeUnit.SECONDS);
|
||||
animationSchedule =
|
||||
animationTimer.scheduleAtFixedRate(doAnimation, 1250, 100, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
});
|
||||
}));
|
||||
// Latch to the PRODOS SYNTAX CHECK parser
|
||||
/*
|
||||
hints.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@ -458,9 +450,6 @@ public class Apple2e extends Computer {
|
||||
});
|
||||
*/
|
||||
}
|
||||
hints.stream().forEach((hint) -> {
|
||||
getMemory().addListener(hint);
|
||||
});
|
||||
}
|
||||
|
||||
private void disableHints() {
|
||||
@ -473,8 +462,4 @@ public class Apple2e extends Computer {
|
||||
public String getShortName() {
|
||||
return "computer";
|
||||
}
|
||||
|
||||
private void attachMiscDevices() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
}
|
@ -26,17 +26,17 @@ import jace.core.RAMEvent;
|
||||
import jace.core.RAMListener;
|
||||
import jace.core.SoundMixer;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.SourceDataLine;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javafx.stage.FileChooser;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.SourceDataLine;
|
||||
|
||||
/**
|
||||
* Apple // Speaker Emulation Created on May 9, 2007, 9:55 PM
|
||||
@ -58,8 +58,8 @@ public class Speaker extends Device {
|
||||
out = null;
|
||||
fileOutputActive = false;
|
||||
} else {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
File f = fileChooser.showSaveDialog(null);
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
File f = fileChooser.showSaveDialog(null);
|
||||
if (f == null) {
|
||||
return;
|
||||
}
|
||||
@ -93,7 +93,7 @@ public class Speaker extends Device {
|
||||
/**
|
||||
* Number of samples in buffer
|
||||
*/
|
||||
static int BUFFER_SIZE = (int) (((float) SoundMixer.RATE) * 0.4);
|
||||
static int BUFFER_SIZE = (int) (SoundMixer.RATE * 0.4);
|
||||
// Number of samples available in output stream before playback happens (avoid extra blocking)
|
||||
// static int MIN_PLAYBACK_BUFFER = BUFFER_SIZE / 2;
|
||||
static int MIN_PLAYBACK_BUFFER = 64;
|
||||
@ -129,35 +129,13 @@ public class Speaker extends Device {
|
||||
byte[] secondaryBuffer;
|
||||
int bufferPos = 0;
|
||||
Timer playbackTimer;
|
||||
private double TICKS_PER_SAMPLE = ((double) Motherboard.SPEED) / ((double) SoundMixer.RATE);
|
||||
private double TICKS_PER_SAMPLE_FLOOR = Math.floor(TICKS_PER_SAMPLE);
|
||||
private final RAMListener listener
|
||||
= new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
|
||||
|
||||
@Override
|
||||
public boolean isRelevant(RAMEvent e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0C030);
|
||||
setScopeEnd(0x0C03F);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
if (e.getType() == RAMEvent.TYPE.WRITE) {
|
||||
level += 2;
|
||||
} else {
|
||||
speakerBit = !speakerBit;
|
||||
}
|
||||
resetIdle();
|
||||
}
|
||||
};
|
||||
private final double TICKS_PER_SAMPLE = ((double) Motherboard.SPEED) / SoundMixer.RATE;
|
||||
private final double TICKS_PER_SAMPLE_FLOOR = Math.floor(TICKS_PER_SAMPLE);
|
||||
private RAMListener listener = null;
|
||||
|
||||
/**
|
||||
* Creates a new instance of Speaker
|
||||
*
|
||||
* @param computer
|
||||
*/
|
||||
public Speaker(Computer computer) {
|
||||
@ -186,11 +164,12 @@ public class Speaker extends Device {
|
||||
*/
|
||||
@Override
|
||||
public void resume() {
|
||||
if (sdl != null && isRunning()) return;
|
||||
System.out.println("Resuming speaker sound");
|
||||
if (sdl != null && isRunning()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (sdl == null || !sdl.isOpen()) {
|
||||
sdl = computer.mixer.getLine(this);
|
||||
sdl = computer.mixer.getLine(this);
|
||||
}
|
||||
sdl.start();
|
||||
setRun(true);
|
||||
@ -199,14 +178,14 @@ public class Speaker extends Device {
|
||||
level = 0;
|
||||
bufferPos = 0;
|
||||
playbackTimer = new Timer();
|
||||
playbackTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
playbackTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
playCurrentBuffer();
|
||||
}
|
||||
}, 10, 30);
|
||||
} catch (LineUnavailableException ex) {
|
||||
System.out.println("ERROR: Could not output sound: " + ex.getMessage());
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "ERROR: Could not output sound", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,11 +254,20 @@ public class Speaker extends Device {
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleSpeaker(RAMEvent e) {
|
||||
if (e.getType() == RAMEvent.TYPE.WRITE) {
|
||||
level += 2;
|
||||
} else {
|
||||
speakerBit = !speakerBit;
|
||||
}
|
||||
resetIdle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a memory event listener for C03x for capturing speaker events
|
||||
*/
|
||||
private void configureListener() {
|
||||
computer.getMemory().addListener(listener);
|
||||
listener = computer.getMemory().observe(RAMEvent.TYPE.ANY, 0x0c030, 0x0c03f, this::toggleSpeaker);
|
||||
}
|
||||
|
||||
private void removeListener() {
|
||||
|
@ -22,8 +22,10 @@ import jace.core.Computer;
|
||||
import jace.core.Font;
|
||||
import jace.core.Palette;
|
||||
import jace.core.RAMEvent;
|
||||
import jace.core.RAMListener;
|
||||
import jace.core.Video;
|
||||
import static jace.core.Video.hiresOffset;
|
||||
import static jace.core.Video.hiresRowLookup;
|
||||
import static jace.core.Video.textRowLookup;
|
||||
import jace.core.VideoWriter;
|
||||
import java.util.logging.Logger;
|
||||
import javafx.scene.image.PixelWriter;
|
||||
@ -69,6 +71,7 @@ public class VideoDHGR extends Video {
|
||||
|
||||
/**
|
||||
* Creates a new instance of VideoDHGR
|
||||
*
|
||||
* @param computer
|
||||
*/
|
||||
public VideoDHGR(Computer computer) {
|
||||
@ -681,47 +684,31 @@ public class VideoDHGR extends Video {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerTextDirtyFlag(RAMEvent e) {
|
||||
int row = textRowLookup[e.getAddress() & 0x03ff];
|
||||
if (row > 23) {
|
||||
return;
|
||||
}
|
||||
VideoWriter tmark = (e.getAddress() < 0x0800) ? textPage1 : textPage2;
|
||||
row <<= 3;
|
||||
int yy = row + 8;
|
||||
for (int y = row; y < yy; y++) {
|
||||
tmark.markDirty(y);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerHiresDirtyFlag(RAMEvent e) {
|
||||
int row = hiresRowLookup[e.getAddress() & 0x01fff];
|
||||
if (row < 0 || row >= 192) {
|
||||
return;
|
||||
}
|
||||
VideoWriter mark = (e.getAddress() < 0x04000) ? hiresPage1 : hiresPage2;
|
||||
mark.markDirty(row);
|
||||
}
|
||||
|
||||
private void registerDirtyFlagChecks() {
|
||||
((RAM128k) computer.getMemory()).addListener(new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0400);
|
||||
setScopeEnd(0x0bff);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
int row = textRowLookup[e.getAddress() & 0x03ff];
|
||||
// int row = identifyTextRow(e.getAddress() & 0x03ff);
|
||||
if (row > 23) {
|
||||
return;
|
||||
}
|
||||
VideoWriter tmark = (e.getAddress() < 0x0800) ? textPage1 : textPage2;
|
||||
row <<= 3;
|
||||
int yy = row + 8;
|
||||
for (int y = row; y < yy; y++) {
|
||||
tmark.markDirty(y);
|
||||
}
|
||||
}
|
||||
});
|
||||
((RAM128k) computer.getMemory()).addListener(new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x2000);
|
||||
setScopeEnd(0x5fff);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
int row = hiresRowLookup[e.getAddress() & 0x01fff];
|
||||
// int row = identifyHiresRow(e.getAddress() & 0x03fff);
|
||||
if (row < 0 || row >= 192) {
|
||||
return;
|
||||
}
|
||||
VideoWriter mark = (e.getAddress() < 0x04000) ? hiresPage1 : hiresPage2;
|
||||
mark.markDirty(row);
|
||||
}
|
||||
});
|
||||
computer.getMemory().observe(RAMEvent.TYPE.WRITE, 0x0400, 0x0bff, this::registerTextDirtyFlag);
|
||||
computer.getMemory().observe(RAMEvent.TYPE.WRITE, 0x02000, 0x05fff, this::registerHiresDirtyFlag);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,11 +18,12 @@
|
||||
*/
|
||||
package jace.apple2e;
|
||||
|
||||
import static jace.apple2e.VideoDHGR.BLACK;
|
||||
import jace.config.ConfigurableField;
|
||||
import jace.core.Computer;
|
||||
import jace.core.RAM;
|
||||
import jace.core.RAMEvent;
|
||||
import jace.core.RAMListener;
|
||||
import jace.core.Video;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@ -64,7 +65,7 @@ public class VideoNTSC extends VideoDHGR {
|
||||
|
||||
public VideoNTSC(Computer computer) {
|
||||
super(computer);
|
||||
createStateListeners();
|
||||
registerStateListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -269,7 +270,7 @@ public class VideoNTSC extends VideoDHGR {
|
||||
col = ((col & 8) >> 3) | ((col << 1) & 0x0f);
|
||||
}
|
||||
double y1 = YIQ_VALUES[col][0];
|
||||
double y2 = ((double) level / (double) maxLevel);
|
||||
double y2 = (level / (double) maxLevel);
|
||||
SOLID_PALETTE[offset][pattern] = yiqToRgb(y1, YIQ_VALUES[col][1] * MAX_I, YIQ_VALUES[col][2] * MAX_Q);
|
||||
TEXT_PALETTE[offset][pattern] = yiqToRgb(y2, YIQ_VALUES[col][1] * MAX_I, YIQ_VALUES[col][2] * MAX_Q);
|
||||
}
|
||||
@ -325,113 +326,61 @@ public class VideoNTSC extends VideoDHGR {
|
||||
}
|
||||
boolean f1 = true;
|
||||
boolean f2 = true;
|
||||
boolean an3 = true;
|
||||
boolean an3 = false;
|
||||
|
||||
public void rgbStateChange() {
|
||||
|
||||
public void rgbStateChange(ModeStateChanges state) {
|
||||
switch (state) {
|
||||
case CLEAR_80:
|
||||
break;
|
||||
case CLEAR_AN3:
|
||||
an3 = false;
|
||||
break;
|
||||
case SET_80:
|
||||
break;
|
||||
case SET_AN3:
|
||||
if (!an3) {
|
||||
f2 = f1;
|
||||
f1 = SoftSwitches._80COL.getState();
|
||||
}
|
||||
an3 = true;
|
||||
break;
|
||||
}
|
||||
// This is the more technically correct implementation except for two issues:
|
||||
// 1) 160-column mode isn't implemented so it's not worth bothering to capture that state
|
||||
// 2) A lot of programs are clueless about RGB modes so it's good to default to normal color mode
|
||||
// graphicsMode = f1 ? (f2 ? rgbMode.color : rgbMode.mix) : (f2 ? rgbMode._160col : rgbMode.bw);
|
||||
graphicsMode = f1 ? (f2 ? rgbMode.COLOR : rgbMode.MIX) : (f2 ? rgbMode.COLOR : rgbMode.BW);
|
||||
// System.out.println(state + ": "+ graphicsMode);
|
||||
}
|
||||
// These catch changes to the RGB mode to toggle between color, BW and mixed
|
||||
Set<RAMListener> rgbStateListeners = new HashSet<>();
|
||||
|
||||
private void createStateListeners() {
|
||||
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0c05e);
|
||||
private void registerStateListeners() {
|
||||
if (!rgbStateListeners.isEmpty() || computer.getVideo() != this) {
|
||||
return;
|
||||
}
|
||||
RAM memory = computer.getMemory();
|
||||
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.ANY, 0x0c05e, (e) -> {
|
||||
an3 = false;
|
||||
rgbStateChange();
|
||||
}));
|
||||
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.ANY, 0x0c05f, (e) -> {
|
||||
if (!an3) {
|
||||
f2 = f1;
|
||||
f1 = SoftSwitches._80COL.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
Video v = computer.getVideo();
|
||||
if (v instanceof VideoNTSC) {
|
||||
((VideoNTSC) v).rgbStateChange(ModeStateChanges.CLEAR_AN3);
|
||||
}
|
||||
}
|
||||
});
|
||||
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0c05f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
Video v = computer.getVideo();
|
||||
if (v instanceof VideoNTSC) {
|
||||
((VideoNTSC) v).rgbStateChange(ModeStateChanges.SET_AN3);
|
||||
}
|
||||
}
|
||||
});
|
||||
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0fa62);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
Video v = computer.getVideo();
|
||||
if (v instanceof VideoNTSC) {
|
||||
// When reset hook is called, reset the graphics mode
|
||||
// This is useful in case a program is running that
|
||||
// is totally clueless how to set the RGB state correctly.
|
||||
((VideoNTSC) v).f1 = true;
|
||||
((VideoNTSC) v).f2 = true;
|
||||
((VideoNTSC) v).an3 = false;
|
||||
((VideoNTSC) v).graphicsMode = rgbMode.COLOR;
|
||||
}
|
||||
}
|
||||
});
|
||||
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0c00d);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
Video v = computer.getVideo();
|
||||
if (v instanceof VideoNTSC) {
|
||||
((VideoNTSC) v).rgbStateChange(ModeStateChanges.SET_80);
|
||||
}
|
||||
}
|
||||
});
|
||||
an3 = true;
|
||||
rgbStateChange();
|
||||
}));
|
||||
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.EXECUTE, 0x0fa62, (e) -> {
|
||||
// When reset hook is called, reset the graphics mode
|
||||
// This is useful in case a program is running that
|
||||
// is totally clueless how to set the RGB state correctly.
|
||||
f1 = true;
|
||||
f2 = true;
|
||||
an3 = false;
|
||||
graphicsMode = rgbMode.COLOR;
|
||||
rgbStateChange();
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void detach() {
|
||||
rgbStateListeners.stream().forEach((l) -> {
|
||||
computer.getMemory().removeListener(l);
|
||||
});
|
||||
rgbStateListeners.clear();
|
||||
super.detach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach() {
|
||||
super.attach();
|
||||
rgbStateListeners.stream().forEach((l) -> {
|
||||
computer.getMemory().addListener(l);
|
||||
});
|
||||
registerStateListeners();
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import jace.apple2e.SoftSwitches;
|
||||
* synchronization.
|
||||
* Created on February 1, 2007, 5:35 PM
|
||||
*
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
*/
|
||||
public abstract class Card extends Device {
|
||||
|
||||
@ -44,6 +44,7 @@ public abstract class Card extends Device {
|
||||
|
||||
/**
|
||||
* Creates a new instance of Card
|
||||
*
|
||||
* @param computer
|
||||
*/
|
||||
public Card(Computer computer) {
|
||||
@ -117,72 +118,32 @@ public abstract class Card extends Device {
|
||||
}
|
||||
|
||||
protected void registerListeners() {
|
||||
ioListener = new RAMListener(
|
||||
RAMEvent.TYPE.ANY,
|
||||
RAMEvent.SCOPE.RANGE,
|
||||
RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(slot * 16 + 0x00c080);
|
||||
setScopeEnd(slot * 16 + 0x00c08F);
|
||||
}
|
||||
RAM memory = computer.getMemory();
|
||||
int baseIO = 0x0c080 + slot * 16;
|
||||
int baseRom = 0x0c000 + slot * 256;
|
||||
ioListener = memory.observe(RAMEvent.TYPE.ANY, baseIO, baseIO + 15, (e) -> {
|
||||
int address = e.getAddress() & 0x0f;
|
||||
handleIOAccess(address, e.getType(), e.getNewValue(), e);
|
||||
});
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
int address = e.getAddress() & 0x0f;
|
||||
handleIOAccess(address, e.getType(), e.getNewValue(), e);
|
||||
}
|
||||
};
|
||||
|
||||
firmwareListener = new RAMListener(
|
||||
RAMEvent.TYPE.ANY,
|
||||
RAMEvent.SCOPE.RANGE,
|
||||
RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(slot * 256 + 0x00c000);
|
||||
setScopeEnd(slot * 256 + 0x00c0ff);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
computer.getMemory().setActiveCard(slot);
|
||||
if (SoftSwitches.CXROM.getState()) {
|
||||
return;
|
||||
}
|
||||
firmwareListener = memory.observe(RAMEvent.TYPE.ANY, baseRom, baseRom + 255, (e) -> {
|
||||
computer.getMemory().setActiveCard(slot);
|
||||
if (SoftSwitches.CXROM.isOff()) {
|
||||
handleFirmwareAccess(e.getAddress() & 0x0ff, e.getType(), e.getNewValue(), e);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
c8firmwareListener = new RAMListener(
|
||||
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()
|
||||
|| SoftSwitches.INTC8ROM.getState()) {
|
||||
return;
|
||||
}
|
||||
c8firmwareListener = memory.observe(RAMEvent.TYPE.ANY, 0xc800, 0xcfff, (e) -> {
|
||||
if (SoftSwitches.CXROM.isOff() && SoftSwitches.INTC8ROM.isOff()
|
||||
&& computer.getMemory().getActiveSlot() == slot) {
|
||||
handleC8FirmwareAccess(e.getAddress() - 0x0c800, e.getType(), e.getNewValue(), e);
|
||||
}
|
||||
};
|
||||
|
||||
computer.getMemory().addListener(ioListener);
|
||||
computer.getMemory().addListener(firmwareListener);
|
||||
computer.getMemory().addListener(c8firmwareListener);
|
||||
});
|
||||
}
|
||||
|
||||
protected void unregisterListeners() {
|
||||
computer.getMemory().removeListener(ioListener);
|
||||
computer.getMemory().removeListener(firmwareListener);
|
||||
computer.getMemory().removeListener(c8firmwareListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,30 +105,28 @@ public abstract class RAM implements Reconfigurable {
|
||||
|
||||
abstract public void configureActiveMemory();
|
||||
|
||||
public byte write(int address, byte b, boolean generateEvent, boolean requireSynchronization) {
|
||||
public void write(int address, byte b, boolean generateEvent, boolean requireSynchronization) {
|
||||
byte[] page = activeWrite.getMemoryPage(address);
|
||||
byte old = 0;
|
||||
if (page == null) {
|
||||
if (generateEvent) {
|
||||
callListener(RAMEvent.TYPE.WRITE, address, old, b, requireSynchronization);
|
||||
callListener(RAMEvent.TYPE.WRITE, address, 0, b, requireSynchronization);
|
||||
}
|
||||
} else {
|
||||
int offset = address & 0x0FF;
|
||||
old = page[offset];
|
||||
byte old = page[offset];
|
||||
if (generateEvent) {
|
||||
b = callListener(RAMEvent.TYPE.WRITE, address, old, b, requireSynchronization);
|
||||
page[offset] = callListener(RAMEvent.TYPE.WRITE, address, old, b, requireSynchronization);
|
||||
} else {
|
||||
page[offset] = b;
|
||||
}
|
||||
page[offset] = b;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
public void writeWord(int address, int w, boolean generateEvent, boolean requireSynchronization) {
|
||||
int lsb = write(address, (byte) (w & 0x0ff), generateEvent, requireSynchronization);
|
||||
int msb = write(address + 1, (byte) (w >> 8), generateEvent, requireSynchronization);
|
||||
// int oldValue = msb << 8 + lsb;
|
||||
write(address, (byte) (w & 0x0ff), generateEvent, requireSynchronization);
|
||||
write(address + 1, (byte) (w >> 8), generateEvent, requireSynchronization);
|
||||
}
|
||||
|
||||
|
||||
public byte readRaw(int address) {
|
||||
// if (address >= 65536) return 0;
|
||||
return activeRead.getMemoryPage(address)[address & 0x0FF];
|
||||
@ -236,7 +234,7 @@ public abstract class RAM implements Reconfigurable {
|
||||
}
|
||||
|
||||
public RAMListener observe(RAMEvent.TYPE type, int addressStart, int addressEnd, RAMEvent.RAMEventHandler handler) {
|
||||
return addListener(new RAMListener(type, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
return addListener(new RAMListener(type, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(addressStart);
|
||||
@ -251,7 +249,7 @@ public abstract class RAM implements Reconfigurable {
|
||||
}
|
||||
|
||||
public RAMListener observe(RAMEvent.TYPE type, int addressStart, int addressEnd, boolean auxFlag, RAMEvent.RAMEventHandler handler) {
|
||||
return addListener(new RAMListener(type, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
return addListener(new RAMListener(type, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(addressStart);
|
||||
@ -334,40 +332,6 @@ public abstract class RAM implements Reconfigurable {
|
||||
|
||||
abstract protected void loadRom(String path) throws IOException;
|
||||
|
||||
public void dump() {
|
||||
for (int i = 0; i < 0x0FFFF; i += 16) {
|
||||
System.out.print(Integer.toString(i, 16));
|
||||
System.out.print(":");
|
||||
String part1 = "";
|
||||
String part2 = "";
|
||||
for (int j = 0; j < 16; j++) {
|
||||
int a = i + j;
|
||||
int br = 0x0FF & activeRead.getMemory()[i >> 8][i & 0x0ff];
|
||||
String s1 = Integer.toString(br, 16);
|
||||
System.out.print(' ');
|
||||
if (s1.length() == 1) {
|
||||
System.out.print('0');
|
||||
}
|
||||
System.out.print(s1);
|
||||
|
||||
/*
|
||||
try {
|
||||
int bw = 0;
|
||||
bw = 0x0FF & activeWrite.getMemory().get(a/256)[a%256];
|
||||
String s2 = (br == bw) ? "**" : Integer.toString(bw,16);
|
||||
System.out.print(' ');
|
||||
if (s2.length()==1) System.out.print('0');
|
||||
System.out.print(s2);
|
||||
} catch (NullPointerException ex) {
|
||||
System.out.print(" --");
|
||||
}
|
||||
*/
|
||||
}
|
||||
System.out.println();
|
||||
// System.out.println(Integer.toString(i, 16)+":"+part1+" -> "+part2);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public void attach();
|
||||
|
||||
abstract public void detach();
|
||||
|
@ -117,8 +117,11 @@ public class CardRamworks extends RAM128k {
|
||||
public void reconfigure() {
|
||||
boolean resume = computer.pause();
|
||||
maxBank = memorySize / 64;
|
||||
if (maxBank < 1) maxBank = 1;
|
||||
if (maxBank > 128) maxBank = 128;
|
||||
if (maxBank < 1) {
|
||||
maxBank = 1;
|
||||
} else if (maxBank > 128) {
|
||||
maxBank = 128;
|
||||
}
|
||||
for (int i = memory.size(); i < maxBank; i++) {
|
||||
memory.add(null);
|
||||
}
|
||||
@ -127,23 +130,14 @@ public class CardRamworks extends RAM128k {
|
||||
computer.resume();
|
||||
}
|
||||
}
|
||||
RAMListener bankSelectListener = new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(BANK_SELECT);
|
||||
setScopeEnd(BANK_SELECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
currentBank = e.getNewValue();
|
||||
configureActiveMemory();
|
||||
}
|
||||
};
|
||||
|
||||
private RAMListener bankSelectListener;
|
||||
@Override
|
||||
public void attach() {
|
||||
addListener(bankSelectListener);
|
||||
bankSelectListener = computer.getMemory().observe(RAMEvent.TYPE.WRITE, BANK_SELECT, (e) -> {
|
||||
currentBank = e.getNewValue();
|
||||
configureActiveMemory();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,6 +46,7 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
@Stateful
|
||||
public class Joystick extends Device {
|
||||
|
||||
@ConfigurableField(name = "Center Mouse", shortName = "center", description = "Moves mouse back to the center of the screen, can get annoying.")
|
||||
public boolean centerMouse = false;
|
||||
@ConfigurableField(name = "Use keyboard", shortName = "useKeys", description = "Arrow keys will control joystick instead of the mouse.")
|
||||
@ -91,8 +92,8 @@ public class Joystick extends Device {
|
||||
|
||||
private void readJoystick() {
|
||||
if (useKeyboard) {
|
||||
joyX = (leftPressed ? -128 : 0) + (rightPressed ? 255:128);
|
||||
joyY = (upPressed ? -128 : 0) + (downPressed ? 255:128);
|
||||
joyX = (leftPressed ? -128 : 0) + (rightPressed ? 255 : 128);
|
||||
joyY = (upPressed ? -128 : 0) + (downPressed ? 255 : 128);
|
||||
} else {
|
||||
Point l = MouseInfo.getPointerInfo().getLocation();
|
||||
if (l.x < lastMouseLocation.x) {
|
||||
@ -187,29 +188,12 @@ public class Joystick extends Device {
|
||||
y = 0;
|
||||
registerListeners();
|
||||
}
|
||||
|
||||
RAMListener listener = new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
|
||||
@Override
|
||||
protected void doConfig() {
|
||||
setScopeStart(0x0C070);
|
||||
setScopeEnd(0x0C07f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEvent(RAMEvent e) {
|
||||
readJoystick();
|
||||
xSwitch.setState(true);
|
||||
x = 10 + joyX * 11;
|
||||
ySwitch.setState(true);
|
||||
y = 10 + joyY * 11;
|
||||
e.setNewValue(computer.getVideo().getFloatingBus());
|
||||
resume();
|
||||
}
|
||||
};
|
||||
|
||||
@InvokableAction(name = "Left", category = "joystick", defaultKeyMapping = "left", notifyOnRelease = true)
|
||||
public boolean joystickLeft(boolean pressed) {
|
||||
if (!useKeyboard) return false;
|
||||
if (!useKeyboard) {
|
||||
return false;
|
||||
}
|
||||
leftPressed = pressed;
|
||||
if (pressed) {
|
||||
rightPressed = false;
|
||||
@ -220,7 +204,9 @@ public class Joystick extends Device {
|
||||
;
|
||||
@InvokableAction(name = "Right", category = "joystick", defaultKeyMapping = "right", notifyOnRelease = true)
|
||||
public boolean joystickRight(boolean pressed) {
|
||||
if (!useKeyboard) return false;
|
||||
if (!useKeyboard) {
|
||||
return false;
|
||||
}
|
||||
rightPressed = pressed;
|
||||
if (pressed) {
|
||||
leftPressed = false;
|
||||
@ -231,7 +217,9 @@ public class Joystick extends Device {
|
||||
;
|
||||
@InvokableAction(name = "Up", category = "joystick", defaultKeyMapping = "up", notifyOnRelease = true)
|
||||
public boolean joystickUp(boolean pressed) {
|
||||
if (!useKeyboard) return false;
|
||||
if (!useKeyboard) {
|
||||
return false;
|
||||
}
|
||||
upPressed = pressed;
|
||||
if (pressed) {
|
||||
downPressed = false;
|
||||
@ -242,7 +230,9 @@ public class Joystick extends Device {
|
||||
;
|
||||
@InvokableAction(name = "Down", category = "joystick", defaultKeyMapping = "down", notifyOnRelease = true)
|
||||
public boolean joystickDown(boolean pressed) {
|
||||
if (!useKeyboard) return false;
|
||||
if (!useKeyboard) {
|
||||
return false;
|
||||
}
|
||||
downPressed = pressed;
|
||||
if (pressed) {
|
||||
upPressed = false;
|
||||
@ -250,12 +240,23 @@ public class Joystick extends Device {
|
||||
return hogKeyboard;
|
||||
}
|
||||
|
||||
public void initJoystickRead(RAMEvent e) {
|
||||
readJoystick();
|
||||
xSwitch.setState(true);
|
||||
x = 10 + joyX * 11;
|
||||
ySwitch.setState(true);
|
||||
y = 10 + joyY * 11;
|
||||
e.setNewValue(computer.getVideo().getFloatingBus());
|
||||
resume();
|
||||
}
|
||||
|
||||
RAMListener listener;
|
||||
|
||||
private void registerListeners() {
|
||||
computer.getMemory().addListener(listener);
|
||||
listener = computer.getMemory().observe(RAMEvent.TYPE.ANY, 0x0c070, 0x0c07f, this::initJoystickRead);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
computer.getMemory().removeListener(listener);
|
||||
// Keyboard.unregisterAllHandlers(this);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user