Just few days ago, VIC-20's noise generator (36877) has been reverse enginereed by Lance Ewing, who directly inspected the die shot of the 6561.
He found the noise generator is made out of a 16 bit LFSR with feedback taps 3,12,14 and 15. There are also some very specific connections that makes it unique. You can read all the details on this thread on the Denial forum:
http://sleepingelephant.com/ipw-web/bulletin/bb/viewtopic.php?f=11&t=8733&start=210#p104360
Below is the VHDL code that I derived and used for checking against a real machine. I guess it can be easily converted into C++.
if audio_div_8 then
if noise_sg_cnt = "1111111" then
noise_sg_cnt <= r_noise_freq + "1";
if noise_LFSR(0)='1' then
noise_sg_sreg <= noise_sg_sreg(6 downto 0) & (not noise_sg_sreg(7) and r_noise_enabled);
end if;
noise_LFSR(15 downto 1) <= noise_LFSR(14 downto 0);
noise_LFSR(0) <= ((noise_LFSR(3) xor noise_LFSR(12)) xnor (noise_LFSR(14) xor noise_LFSR(15))) nand r_noise_enabled;
else
noise_sg_cnt <= noise_sg_cnt + "1";
end if;
end if;
noise_sg <= noise_sg_sreg(0);
Remarks to the above code:
line 3 is counter reload
line 5 is 8-bit shift register shift
line 7 is LFSR shift
line 8 is LSFR feedback (notice the XNOR and NAND)
line 10 is frequency counter increment
Test against the real machine (a PAL VIC-20) has been done "by ear", in particular listening to the repeating noise patterns that occur when you do POKE 36877,250 to 254. (SUch patterns are caused by the 16-bit LFSR looping over its 65535 sequences).
it is not possible to read back the status of the oscillator output from the VIC like you can do from the SID, i guess?
no, it's not possible there is no register that reflects the output of the noise generator. Also the noise gen is 1-bit (it's a square wave whose frequency is altered according to the random sequence)
too bad... that means its really hard to test for correctness :(
btw, is there some specific game or demo where i can hear a clear difference between current implementation and the fixed one?
test implementation is in r36241 - please reopen when there is a problem with it :)
The pitch of the new noise generator emulation (testing in SDL2VICE-3.3-win64-r36786) is an octave too high when compared to older version of xvic as well as my real NTSC VIC-20.
Yes, I think you are right. I haven't tested on a real VIC-20 yet, but the the old and the new VICE version sound different, one octave apart.
This suggests that the speed of CR-D (36877) needs to be fixed, halving down its speed. But that would not be consistent with what Lance Ewing found in its reverse engineering work. This is what he says:
So, from the above, there should be 4 different speeds for all the 4 different voices. My only guess it's that perhaps the CR-D speed is halved down somewhere when interacting with the LFSR. We have to check again.
temporary fix in r36994 - leaving the ticket open, it should be confirmed and eventually fixed properly
This does fix the pitch issue, but the noise sounds too "perfect". The thing I always remember with the VIC sound generator was that there was always a bit of randomness with the timbre of the sounds. This is only really noticeable when more than one voice is being generated at the same time, or with the noise voice. Up until r36241, this randomness was present in VICE, but now the noise register sounds too mechanical. Here is a short program to illustrate:
10 POKE 36878,15
20 FOR X=1 TO 100
30 POKE 36877,160
40 FOR Y=1 TO 50
50 NEXT Y
60 POKE 36877,0
70 FOR Y=1 TO 50
80 NEXT Y
90 NEXT X
100 POKE 36878,0
With versions below r36241, you can hear the randomness with each short noise burst, but with r36241 and up, every burst sounds exactly the same.
that was noticed before with the "datapop" demo, but I was unable to recreate it. But with your program the effect is very noticeable and replicable. I suspect it's something due to the filling of the 8-bit shift register, the same that in the other voices allows the creation of "viznut" waveforms. I will investigate in the coming days as I finally managed to sample from my real VIC-20. I will also check the correctness of the noise generation when "running free" without being interrupted and resumed.
Any news?
Sorry for the delay in getting back to this. I had a chance to test out WinVICE 3.5 recently, and the noise generator randomness now behaves exactly like my real VIC-20.
There is another minor issue that I will record sound samples of VICE and my real VIC-20 to demonstrate, but it probably should have a new issue opened up for it as I don't think it involves the noise generator, but has to do more with randomness of the three other tone generators when they play together.
so we can close this?
I believe so, unless anyone else has any objections.
there is still a minor difference between the emulated code and the real VIC-20 that I was not able to reproduce and fix. I tried several times to address that but I failed, so I had to give up. But I would leave this open, in case of a new idea or a new finding.