mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-09-30 18:54:47 +00:00
Self-clocking mockingboard is no longer tied to the main emulator speed
This commit is contained in:
parent
e0bc6a797e
commit
e52d4016dd
@ -27,7 +27,6 @@ import jace.core.RAMEvent;
|
||||
import jace.core.RAMEvent.TYPE;
|
||||
import jace.core.RAMListener;
|
||||
import jace.core.SoundMixer;
|
||||
import static jace.core.Utility.*;
|
||||
import jace.hardware.mockingboard.PSG;
|
||||
import jace.hardware.mockingboard.R6522;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -80,7 +79,7 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
Condition playbackFinished = timerSync.newCondition();
|
||||
@ConfigurableField(name = "Idle sample threshold", description = "Number of samples to wait before suspending sound")
|
||||
private int MAX_IDLE_SAMPLES = SAMPLE_RATE;
|
||||
|
||||
|
||||
@Override
|
||||
public String getDeviceName() {
|
||||
return "Mockingboard";
|
||||
@ -90,7 +89,7 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
super(computer);
|
||||
controllers = new R6522[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
//don't ask...
|
||||
// has to be final to be used inside of anonymous class below
|
||||
final int j = i;
|
||||
controllers[i] = new R6522(computer) {
|
||||
int controller = j;
|
||||
@ -131,6 +130,13 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
public String getShortName() {
|
||||
return "timer" + j;
|
||||
}
|
||||
|
||||
public void doTick() {
|
||||
super.doTick();
|
||||
if (controller == 0) {
|
||||
doSoundTick();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -140,6 +146,18 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
suspend();
|
||||
}
|
||||
RAMListener mainListener = null;
|
||||
|
||||
boolean heatbeatUnclocked = false;
|
||||
long heartbeatReclockTime = 0L;
|
||||
long unclockTime = 5000L;
|
||||
|
||||
private void setUnclocked(boolean unclocked) {
|
||||
heatbeatUnclocked = unclocked;
|
||||
for (R6522 controller : controllers) {
|
||||
controller.setUnclocked(unclocked);
|
||||
}
|
||||
heartbeatReclockTime = System.currentTimeMillis() + unclockTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleFirmwareAccess(int register, TYPE type, int value, RAMEvent e) {
|
||||
@ -152,7 +170,7 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
chip++;
|
||||
}
|
||||
if (chip >= 2) {
|
||||
System.err.println("Could not determine which PSG to communicate to");
|
||||
System.err.println("Could not determine which PSG to communicate to for access to regsiter + " + Integer.toHexString(register));
|
||||
e.setNewValue(computer.getVideo().getFloatingBus());
|
||||
return;
|
||||
}
|
||||
@ -177,13 +195,21 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
for (R6522 c : controllers) {
|
||||
if (c == null || !c.isRunning()) {
|
||||
continue;
|
||||
if (heatbeatUnclocked) {
|
||||
if (System.currentTimeMillis() - heartbeatReclockTime >= unclockTime) {
|
||||
setUnclocked(false);
|
||||
} else {
|
||||
for (R6522 c : controllers) {
|
||||
if (c == null || !c.isRunning()) {
|
||||
continue;
|
||||
}
|
||||
c.doTick();
|
||||
}
|
||||
}
|
||||
c.tick();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void doSoundTick() {
|
||||
if (isRunning() && !pause) {
|
||||
// buildMixerTable();
|
||||
timerSync.lock();
|
||||
@ -194,7 +220,7 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
while (isRunning() && ticksSinceLastPlayback >= ticksBetweenPlayback) {
|
||||
if (!playbackFinished.await(1, TimeUnit.SECONDS)) {
|
||||
// gripe("The mockingboard playback thread has stalled. Disabling mockingboard.");
|
||||
suspend();
|
||||
suspendSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,14 +289,15 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
@Override
|
||||
public void resume() {
|
||||
pause = false;
|
||||
if (!isRunning()) {
|
||||
if (chips == null) {
|
||||
initPSG();
|
||||
for (PSG psg : chips) {
|
||||
psg.setRate(phasorMode ? CLOCK_SPEED * 2 : CLOCK_SPEED, SAMPLE_RATE);
|
||||
psg.reset();
|
||||
}
|
||||
if (chips == null) {
|
||||
initPSG();
|
||||
for (PSG psg : chips) {
|
||||
psg.setRate(phasorMode ? CLOCK_SPEED * 2 : CLOCK_SPEED, SAMPLE_RATE);
|
||||
psg.reset();
|
||||
}
|
||||
}
|
||||
if (!isRunning()) {
|
||||
setUnclocked(true);
|
||||
for (R6522 controller : controllers) {
|
||||
controller.attach();
|
||||
controller.resume();
|
||||
@ -290,6 +317,10 @@ public class CardMockingboard extends Card implements Runnable {
|
||||
controller.suspend();
|
||||
controller.detach();
|
||||
}
|
||||
return suspendSound();
|
||||
}
|
||||
|
||||
public boolean suspendSound() {
|
||||
if (playbackThread == null || !playbackThread.isAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -20,13 +20,15 @@ package jace.hardware.mockingboard;
|
||||
|
||||
import jace.core.Computer;
|
||||
import jace.core.Device;
|
||||
import jace.core.TimedDevice;
|
||||
|
||||
/**
|
||||
* Implementation of 6522 VIA chip
|
||||
*
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
*/
|
||||
public abstract class R6522 extends Device {
|
||||
public abstract class R6522 extends TimedDevice {
|
||||
public static long SPEED = 1020484L; // (NTSC)
|
||||
|
||||
public R6522(Computer computer) {
|
||||
super(computer);
|
||||
@ -34,9 +36,15 @@ public abstract class R6522 extends Device {
|
||||
timer1running = true;
|
||||
timer1latch = 0x1fff;
|
||||
timer1interruptEnabled = false;
|
||||
setSpeedInHz(SPEED);
|
||||
setRun(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long defaultCyclesPerSecond() {
|
||||
return SPEED;
|
||||
}
|
||||
|
||||
// 6522 VIA
|
||||
// http://www.applevault.com/twiki/Main/Mockingboard/6522.pdf
|
||||
// I/O registers
|
||||
@ -133,6 +141,7 @@ public abstract class R6522 extends Device {
|
||||
public int timer2latch = 0;
|
||||
public int timer2counter = 0;
|
||||
public boolean timer2running = false;
|
||||
public boolean unclocked = false;
|
||||
|
||||
@Override
|
||||
protected String getDeviceName() {
|
||||
@ -141,6 +150,16 @@ public abstract class R6522 extends Device {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (!unclocked) {
|
||||
doTick();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUnclocked(boolean unclocked) {
|
||||
this.unclocked = unclocked;
|
||||
}
|
||||
|
||||
public void doTick() {
|
||||
if (timer1running) {
|
||||
timer1counter--;
|
||||
if (timer1counter < 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user