When the noise waveform is combined with others the waveform selector output is written back to the noise generator register causing the infamous lockup, the current implementation however seems flawed as shown by nata's test [1] posted at the lemon64 forum [2]. If you play the example sid, which alternates between $D and $8 waveforms, you notice that the noise component disappears too quickly compared to the real sid.
My rough guess is that the write to the register only happens during LFSR clocking and the attached path in fact gives a result closer to the original. I had a look at the vectorized IC and I see that the output of each bit, which gets connected to the output of the other waveforms when combined waveforms are selected, is also the input for the next bit when the shift register is clocked so likely the write back happens during the shifting phase.
[1] ftp://ftp.untergrund.net/users/nata/sid_test/$D1+$81_wave_test.7z
[2] http://www.lemon64.com/forum/viewtopic.php?t=25442&postdays=0&postorder=asc&start=454
Previous patch did break SounDemoN's Bojojoing. Here's a new version based on the observation that the combined waveforms write back to the shift register also when the test bit is set.
here's a windows compile with that patch v2, if interested.
http://vicebuilds3.bplaced.net/builds/2.4.27.31139/
thanks leandro.
Thank you for the build Querino.
After a more in depth analysis of the circuit I realized that things are a bit more complex so a new patch is in the works.
This is the detail of what really happens:
* during normal operation the output is written back to the same bit, overwriting its value;
* in the shifting cycle the output is written back to the internal latch of the following bit. This will become the bit's value in the next cycle, during which no write-back happens;
* if test (or reset) line is active the output overwrites the internal latch of the following bit at each cycle. When the signal is released the latch status becomes the bit's effective value. Again during this first cycle there is no write-back.
Here is the new patch. Both Bojojoing and nata's test plays fine. I haven't verified the delta_t clock version yet, it probably won't play correctly but at least it should be checked it isn't worst than before.
Edit: patch updated
Last edit: Leandro Nini 2016-07-28
i am not able to apply this one, i get
also i tried to do it manually but also struggled.
Sorry, messed up the patch. Now it should apply cleanly.
it would be great if this behaviour could be backed up by some test program... this would need cycle exact timing i assume?
Well, I guess so. Also it's hard to control the state of the noise register and only eight bits are accessible so really not an easy task. Maybe using nata's program as a base with a check against output sampled from a real machine?
now i can apply the patch.
again here's a windows build with patch v3.
http://vicebuilds3.bplaced.net/builds/2.4.29.31489/
thanks mr. nini.
a disassembled/reworked version of natas test is here: https://sourceforge.net/p/vice-emu/code/HEAD/tree/testprogs/SID/noisewriteback/
still needs some improvement to serve as a proper test...
I think I've found a way to verify the latter point, and a bug in the patch. The trick is explained in the source code.
Unfortunately this already works in VICE so not really helpful here, but it's good to spot regressions.
Well, it seems that some more work is needed...
unfortunately, that test fails on my C64C - i think first of all a (much) longer delay is needed to actually "clear" the LFSR. i have modified the test a bit .... previously on subsequent runs it would always show different values (indicating that the lfsr was not cleared). now it always shows $fe for BOTH values on the real thing (but NOT in VICE! - without your patches that is) (confirmed on both old- and new- SID)
Last edit: gpz 2016-08-13
ok i also asked around on csdb... see https://csdb.dk/forums/?roomid=11&topicid=118693#118733 ... also updated the tests in https://sourceforge.net/p/vice-emu/code/HEAD/tree/testprogs/SID/waveforms/ somewhat. interestingly on my breadbox the result for 8x wave is reproduceable, while on C64C it is not and becomes a bit random after ~50 bytes. also interestingly the result is significantly different from what VICE produces. shrug we might want to try fixing the "pure" 8x wave first, and then proceed with fixing the writeback stuff :)
Interesting...
I see that to reset the noise reg you put the value $ff into the control reg, this might cause some zeros to creep into the lfsr due to combined waveforms, can you please try setting only the test bit?
Anyway here is another patch with some mistakes fixed, unfortunately nata's test is still broken. The crazy thing is that the same change applied to residfp works fine :/
I must be overlooking something...
yay indeed, changed the testprog to use $08 for the control register instead - now the result is much more predictable and it even matches VICE (for some reason it would still fail sometimes on the real C64 - perhaps the wait time is still not long enough)
Very good, that's reassuring!
As for the patch it is definitely broken, just had an issue on my setup. Unless there is something wrong with nata's program, did you check it on a c64? Does it sound different from vsid, more "noisy"?
Anyway I've made another test as a slight variation of the other and this one fails on unpatched VICE.
Edit: forgot that there is an actual recording of the test output so the problem is indeed there. Must dig deeper...
Last edit: Leandro Nini 2016-08-15
Another try...
mmmh now the test program produces $00 for the first number and $12 for the second on my C64... are you sure the delay between the two reads is what you want it to be? when you put $ffff into the freq it would "shift" every cycle, no? :) also consider that with how the code is laid out currently, it will run for a few cycles with freq=$00ff
Is it an 8580? The result is the same as unpatched VICE.
The noise register is clocked after bit 19 of the oscillator goes high so more or less 10 cycles are needed after the test bit is released with frequency at $fff.
By the way, I dissected the noise machinery again and found out that it is a bit different from what I've depicted. The shift is delayed one cycle but is performed in two cycles. In the first the value is transferred to the latch of the following bit, in the second the latched value becomes active. The "no write-back" described above is only for the first half of the cycle so not interesting in our context.
Here is a preliminary patch, it's still missing the write-back to next bit during the first phase of the shifting but already seems to yield a good result.
Need to think of a way to do some useful tests...
Ah, also realized that a shift is performed right after the reset signal is released, so the value at startup is actually $7ffffe.
i tested on 8580 previously, indeed. on 6581 it shows $00 and $14 (@T)
Ok, same results with the new patch.
So, to summarize this is what happens when the lfsr is clocked:
cycle 0: bit 19 of the accumulator goes from low to high, the noise register acts normally, the output may overwrite a bit;
cycle 1: first phase of the shift, the bits are interconnected and the output of each bit is latched into the following. The output may overwrite the latched value.
cycle 2: second phase of the shift, the latched value becomes active in the first half of the clock and from the second half the register returns to normal operation.
When the test or reset lines are active the first phase is executed at every cyle until the signal is released triggering the second phase.
Hope this helps :)
ok then - i have put the (updated to show green on the real thing - and with your patch also in VICE) tests here: https://sourceforge.net/p/vice-emu/code/HEAD/tree/testprogs/SID/noisewriteback/
also wave_v6.diff has been applied in r31615 - thanks!
more elaborated tests would be welcomed of course, can never have enough of those :)
This is a test that verifies that combined waveforms does not affect the status of noise register while test bit is high but zeroes out the following bits on test release.
If my theory is correct this should succeed on a c64, independently from the model, while the last check fails in VICE.
Edit: fixed test
Last edit: Leandro Nini 2016-08-17
it fails unfortunately, result on 8580 is: $fe $fc $20, on 6581 i get $fe $fe $fc
Last edit: gpz 2016-08-17
Uh, weird...
The result on the 6581 seems to confirm that the patch is pretty decent, although I'm not sure why. As for the 8580 maybe it requires a longer time to fully reset?