diff --git a/html/src/main/java/emu/joric/gwt/GwtAYPSG.java b/html/src/main/java/emu/joric/gwt/GwtAYPSG.java index a7c98b5..9623fb7 100644 --- a/html/src/main/java/emu/joric/gwt/GwtAYPSG.java +++ b/html/src/main/java/emu/joric/gwt/GwtAYPSG.java @@ -340,7 +340,12 @@ public void writeRegister(int address, int value) { int val = (((registers[(address << 1) + 1] & 0x0f) << 8) | registers[address << 1]) * updateStep; int last = period[address]; period[address] = val = ((val < 0x8000) ? 0x8000 : val); - int newCount = count[address] - (val - last); + // Adjust the time remaining to the next flip-flop toggle so that the + // time already elapsed since the last toggle is preserved, i.e. the + // period write moves only the target, as on the real chip. If the + // elapsed time already exceeds the new period, the clamp below makes + // the overdue toggle happen straight away. + int newCount = count[address] + (val - last); count[address] = newCount < 1 ? 1 : newCount; break; } @@ -348,10 +353,15 @@ public void writeRegister(int address, int value) { // Noise period. case 0x06: { int val = (value & 0x1f) * updateStep; + // A noise period of 0 behaves the same as a noise period of 1: the + // data sheet notes that the lowest period value is 1 for both tone + // and noise, and this behaviour has been verified using original + // Oric-1 hardware. + val = (val == 0 ? updateStep : val); val *= 2; int last = period[NOISE]; - period[NOISE] = val = val == 0 ? updateStep : val; - int newCount = count[NOISE] - (val - last); + period[NOISE] = val; + int newCount = count[NOISE] + (val - last); count[NOISE] = newCount < 1 ? 1 : newCount; break; } @@ -386,7 +396,7 @@ public void writeRegister(int address, int value) { int val = (((registers[0x0C] << 8) | registers[0x0B]) * updateStep) << 1; int last = period[ENVELOPE]; period[ENVELOPE] = val; - int newCount = count[ENVELOPE] - (val - last); + int newCount = count[ENVELOPE] + (val - last); count[ENVELOPE] = newCount < 1 ? 1 : newCount; break; }