Skip to content

Commit

Permalink
Move video redraw out of FastTimer and instead to a dedicated thread …
Browse files Browse the repository at this point in the history
…synced with VDP via REG_SCANLINE

from #3
  • Loading branch information
eswartz committed Jul 5, 2015
1 parent ddd2ad7 commit c403c13
Show file tree
Hide file tree
Showing 16 changed files with 334 additions and 335 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import java.io.File;
import java.io.IOException;

import ejs.base.timer.FastTimer;

import v9t9.common.hardware.IVdpChip;
import v9t9.common.video.IVdpCanvas;
import v9t9.common.video.IVdpCanvasRenderer;
Expand All @@ -36,7 +34,7 @@ public interface IVideoRenderListener {

/** Force redraw of screen from changes from VdpHandler#update,
* incorporating any resolution changes, blank/unblank state, etc. */
void redraw();
void queueRedraw();

/** Synchronize so that screen updates are visible */
void sync();
Expand All @@ -45,6 +43,8 @@ public interface IVideoRenderListener {
long getLastUpdateTime();

boolean isIdle();

boolean isVisible();

void saveScreenShot(File file, boolean plainBitmap) throws IOException;

Expand All @@ -59,13 +59,6 @@ public interface IVideoRenderListener {

IVdpCanvasRenderer getCanvasHandler();

/**
* A renderer should provide a timer for video update
* activities
* @return
*/
FastTimer getFastTimer();

IMonitorEffectSupport getMonitorEffectSupport();

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,10 @@ public interface IVdpChip extends IPersistable, IRegisterAccess {
SettingSchema settingDumpVdpAccess = new SettingSchema(
ISettingsHandler.TRANSIENT, "DumpVdpAccess", Boolean.FALSE);

/** Update video canvas periodically */
//boolean update();

//VdpMmio getVdpMmio();
//void setVdpMmio(VdpMmio mmio);

IMemoryDomain getVideoMemory();

IMachine getMachine();

/** 60Hz timer. Use this or syncVdpInterrupt / addCpuCycles */
void tick();

Expand Down
89 changes: 89 additions & 0 deletions v9t9/v9t9-java/v9t9-common/src/v9t9/common/video/VideoThread.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
*
*/
package v9t9.common.video;

import java.io.PrintWriter;

import ejs.base.properties.IProperty;
import ejs.base.settings.Logging;
import v9t9.common.client.ISettingsHandler;
import v9t9.common.client.IVideoRenderer;
import v9t9.common.cpu.ICpu;
import v9t9.common.hardware.IVdpChip;

/**
* @author ejs
*
*/
public class VideoThread extends Thread {

private IVideoRenderer videoRenderer;
private Object sync;
private IProperty dumpVdpAccess;
private IProperty dumpFullInstructions;

public VideoThread(IVideoRenderer videoRenderer) {
setName("Video Thread");
this.videoRenderer = videoRenderer;
sync = new Object();

ISettingsHandler settings = videoRenderer.getVdpHandler().getMachine().getSettings();
dumpVdpAccess = settings.get(IVdpChip.settingDumpVdpAccess);
dumpFullInstructions = settings.get(ICpu.settingDumpFullInstructions);
}

/**
* Invoke Object#notifyAll() on this object to trigger
* a redraw.
* @return
*/
public Object getSync() {
return sync;
}

@Override
public void run() {
synchronized (sync) {
while (!isInterrupted()) {
try {
// attempt update at least once a second even if the
// CPU and/or video threads are somehow frozen
sync.wait(1000);

// got notify
synchronized (videoRenderer.getVdpHandler()) {
synchronized (videoRenderer) {
synchronized (videoRenderer.getCanvasHandler()) {
synchronized (videoRenderer.getCanvas()) {
updateVideo();
}
}
}
}
} catch (InterruptedException e) {
break;
}
}

}

System.out.println("Exiting video thread");
}

private void log(String msg) {
if (dumpVdpAccess.getBoolean()) {
PrintWriter pw = Logging.getLog(dumpFullInstructions);
if (pw != null)
pw.println("[VideoThread] " + msg);
}
}

public void updateVideo() {
if (videoRenderer.isIdle() && videoRenderer.isVisible()) {
log("updating VDP canvas");
videoRenderer.getCanvasHandler().update();
videoRenderer.queueRedraw();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ public void propertyChanged(IProperty setting) {

machine.getDemoManager().registerActorProvider(new VdpDataDemoActor.Provider());
machine.getDemoManager().registerActorProvider(new VdpRegisterDemoActor.Provider());
}

/* (non-Javadoc)
* @see v9t9.common.hardware.IVdpChip#getMachine()
*/
@Override
public IMachine getMachine() {
return machine;
}

public void initRegisters() {
Expand Down Expand Up @@ -270,7 +278,9 @@ public void tick() {
onScanline(row);
}

doTick();
doTick();

onScanline(-1);
}
}

Expand All @@ -287,55 +297,62 @@ public void syncVdpInterrupt(IMachine machine) {

if (vdpInterruptFrac < 0)
vdpInterruptFrac = 0;

if (vdpScanlineFrac < 0)
vdpScanlineFrac = 0;

while (vdpScanlineFrac >= vdpScanlineLimit) {
vdpScanlineFrac -= vdpScanlineLimit;

if (vdpScanline >= scanlineCount)
vdpScanline -= scanlineCount;

onScanline(vdpScanline);

vdpScanline++;
}

if (vdpInterruptFrac >= vdpInterruptLimit) {
vdpInterruptFrac -= vdpInterruptLimit;

doTick();
}

if (vdpScanlineFrac < 0)
vdpScanlineFrac = 0;

boolean shouldTick = false;
if (vdpInterruptFrac >= vdpInterruptLimit) {
vdpInterruptFrac -= vdpInterruptLimit;

log("INT: interrupt tick");
shouldTick = true;
}
else {
while (vdpScanlineFrac >= vdpScanlineLimit) {
vdpScanlineFrac -= vdpScanlineLimit;

onScanline(vdpScanline + 1);
}

if (vdpScanline >= scanlineCount) {
log("INT: scanline tick");
//shouldTick = true;
vdpScanline -= scanlineCount;
}
}


if (shouldTick) {
doTick();
onScanline(-1);
}
}

/**
*/
protected void onScanline(int vdpScanline) {
fireRegisterChanged(REG_SCANLINE, vdpScanline);
setRegister(REG_SCANLINE, vdpScanline);
}

/**
*
*/
protected void doTick() {
if (true /*|| machine.getExecutor().nVdpInterrupts < settingVdpInterruptRate.getInt()*/) {
if (throttleInterrupts.getBoolean()) {
if (throttleCount-- < 0) {
throttleCount = 6;
} else {
return;
}
}

// a real interrupt only occurs if wanted, but always marked
setRegister(REG_ST, vdpStatus | VDP_INTERRUPT);
if ((vdpregs[1] & R1_INT) != 0) {
triggerInterrupt();
}
if (throttleInterrupts.getBoolean()) {
if (throttleCount-- < 0) {
throttleCount = 6;
} else {
return;
}
}
//System.out.print('!');

// a real interrupt only occurs if wanted, but always marked
setRegister(REG_ST, vdpStatus | VDP_INTERRUPT);

if ((vdpregs[1] & R1_INT) != 0) {
triggerInterrupt();
}
}

/**
Expand Down Expand Up @@ -481,7 +498,9 @@ public int getRegisterNumber(String id) {
}

protected String getRegisterName(int reg) {
switch (reg) {
switch (reg) {
case REG_SCANLINE:
return "Scanline";
case REG_ST:
return "Status";
}
Expand Down Expand Up @@ -587,14 +606,19 @@ protected String caten(String... vals) {
public int setRegister(int reg, int value) {
int old;
if (reg == REG_ST) {
old = vdpStatus & 0xff;
old = vdpStatus & 0xff;
value &= 0xff;
vdpStatus = (byte) value;
}
else {
else if (reg == REG_SCANLINE) {
old = vdpScanline;
vdpScanline = value;
} else {
if (reg >= vdpregs.length)
return 0;

old = vdpregs[reg] & 0xff;
old = vdpregs[reg] & 0xff;
value &= 0xff;
vdpregs[reg] = (byte) value;

doSetVdpReg(reg, (byte) old, (byte) value);
Expand All @@ -604,9 +628,9 @@ public int setRegister(int reg, int value) {
}

if (dumpFullInstructions.getBoolean() && dumpVdpAccess.getBoolean())
log("register " + (reg < 0 ? "ST" : ""+reg) + " " + HexUtils.toHex2(old) + " -> " + HexUtils.toHex2(value));
log("register " + getRegisterName(reg) + " " + HexUtils.toHex2(old) + " -> " + HexUtils.toHex2(value));

fireRegisterChanged(reg, value & 0xff);
fireRegisterChanged(reg, value);
return old;
}

Expand All @@ -616,12 +640,13 @@ public int setRegister(int reg, int value) {
* @param val
*/
protected void doSetVdpReg(int reg, byte old, byte val) {
// /* if interrupts enabled, and interrupt was pending, trigger it */
// if ((val & R1_INT) != 0
// && (old & R1_INT) == 0)
// {
// triggerInterrupt();
// }
/* if interrupts enabled, and interrupt was pending, trigger it */
if ((val & R1_INT) != 0
&& (old & R1_INT) == 0
&& (vdpStatus & VDP_INTERRUPT) != 0)
{
triggerInterrupt();
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.eclipse.swt.graphics.ImageData;
import org.ejs.gui.images.AwtImageUtils;


import v9t9.common.video.ICanvas;
import v9t9.gui.client.swt.svg.SVGException;
import v9t9.gui.client.swt.svg.SVGSalamanderLoader;
Expand Down
Loading

0 comments on commit c403c13

Please sign in to comment.