/**
* This file is a part of JaC64 - a Java C64 Emulator
* Main Developer: Joakim Eriksson (JaC64.com Dreamfabric.com)
* Contact: joakime@sics.se
* Web: http://www.jac64.com/
* http://www.dreamfabric.com/c64
* ---------------------------------------------------
*/
package com.dreamfabric.jac64;
import resid.ISIDDefs;
import resid.SID;
import resid.ISIDDefs.sampling_method;
/**
* SIDChip - implements all neccessary control and set-up for the SID
* chip emulation.
* @author Joakim
*/
public class RESIDChip extends ExtChip {
static final int SAMPLE_RATE = 44000;
static final int DL_BUFFER_SIZE = 44000;
int BUFFER_SIZE = 256;
byte[] buffer = new byte[BUFFER_SIZE * 2];
SID sid;
int CPUFrq = 985248;
int clocksPerSample = CPUFrq / SAMPLE_RATE;
int clocksPerSampleRest = 0;
long nextSample = 0;
long lastCycles = 0;
private int nextRest = 0;
private int pos = 0;
private AudioDriver driver;
private boolean removeSample = false;
TimeEvent sampleEvent = new TimeEvent(0, "resid event") {
public void execute(long cycles) {
nextSample += clocksPerSample;
nextRest += clocksPerSampleRest;
if (nextRest > 1000) {
nextRest -= 1000;
nextSample++;
}
// Clock resid!
while(lastCycles < cycles) {
sid.clock();
lastCycles++;
}
// and take the sample!
int sample = sid.output();
buffer[pos++] = (byte) (sample & 0xff);
buffer[pos++] = (byte) ((sample >> 8));
if (pos == buffer.length) {
writeSamples();
}
time = nextSample;
if (!removeSample)
cpu.scheduler.addEvent(this);
}
};
public RESIDChip(MOS6510Core cpu, AudioDriver audio) {
init(cpu);
// Assume 44 Khz sample rate for now... later this must be handled...
driver = audio;
sid = new SID();
lastCycles = cpu.cycles;
nextSample = cpu.cycles;
sid.set_sampling_parameters(CPUFrq, sampling_method.SAMPLE_FAST, SAMPLE_RATE, -1, 0.97);
clocksPerSampleRest = (int) ((CPUFrq * 1000L) / SAMPLE_RATE);
clocksPerSampleRest -= clocksPerSample * 1000;
System.out.println("ClocksPer Sample: " + clocksPerSample + "." + clocksPerSampleRest);
sampleEvent.time = cpu.cycles + 5;
cpu.scheduler.addEvent(sampleEvent);
}
public void clock(long cycles) { }
private void writeSamples() {
driver.write(buffer);
pos = 0;
}
public int performRead(int address, long cycles) {
return sid.read(address - CPU.IO_OFFSET - 0xd400);
}
public void performWrite(int address, int data, long cycles) {
sid.write(address - CPU.IO_OFFSET - 0xd400, data);
}
public void reset() {
nextSample = cpu.cycles + 10;
lastCycles = cpu.cycles;
cpu.scheduler.addEvent(sampleEvent, nextSample);
sid.reset();
}
public void stop() {
// Called from any thread!
removeSample = true;
}
public void setChipVersion(int version) {
if (version == C64Screen.RESID_6581)
sid.set_chip_model(ISIDDefs.chip_model.MOS6581);
else
sid.set_chip_model(ISIDDefs.chip_model.MOS8580);
}
}