The note that volume writes reset waveform is not correct, I misinterpreted my readings (I just had got an oscilloscope at that time and didn't know how to use it properly yet). I recall setting lowest freq (register value 0) and just spammed non changing attenuator value and didn't observe any change in signal, but I probably didn't look at slow enough timebase. That was really long ago, I will do new tests in not too far future, I got more work to do with VDP for now, there's plenty registers which exact points of taking effect aren't yet determined.

EDIT: Waveform coming out the chip is perfect squarewave, any deviations are from any analog circuitry preset (only some bandpass filtering, low end at few tens of Hz, high end at few tens of KHz, depending on particular hardware). You also shouldn't try to replicate it, your sound card output or other devices in the signal path already do that.

PSG has prescaler in it that divides the clock by 16. Ti sold chips with and without the prescaler. PSG integrated into the VDP (SMS, MD and SG-1000 II) always has prescaler present, and LFSR is different compared to real Ti chip (not sure about SG-1000 II). The last part matters for SG-1000 and SG-3000 vs SMS and MD, alternate mode on noise channel has 1/15% duty cycle on one and 1/16% duty cycle on other, causing things to be out of tune if not compensated for.

The value in output, when set, outputs the noise channel's volume, otherwise zero.

When you write to the Tone 2 register, I copy the value into the noise class.

For now, when writing to the Noise register, I'm not modifying the counter at all.

I'm also unsure if my LFSR computation is 100% correct. The docs go into testing parity and things like that, but that seems really overly complex. This implementation of the LFSR is courtesy of Cydrak, but I'm not sure where sie got it from.

Last edited by byuu on Mon Feb 27, 2017 7:28 pm, edited 1 time in total.

Why is there a bitwise NOT in there? All descriptions of the SN76489 noise channel I've seen have had the new bit15 set to bit0 XOR bit3 in "white noise" mode. Has someone made recordings where they concluded that it should in fact be bit0 XOR (NOT bit3) ?

That looks like what I'd expect. Though I haven't made any hardware tests to verify this, so I was curious about that NOT and whether it was based on some recent discovery. If it wasn't then I'd say leave it out for the time being.

I have been testing hardware the entire yesterday and I've found and verified few things.Things tested :*SN76489AN in SC-3000*315-5124 (SMS1 VDP)*315-5246 (SMS2 VDP)*315-5313-x (MD1 VDP)*315-5476/5660/5700/5708/5960 (MD2 ASIC)*315-6123 (Genesis 3 VA2 ASIC)I would love to test out Sega SG-1000 II with 315-5066 chip which has VDP and PSG combined. It will be good to verify if it has vanilla PSG or what all other machines got, and also determine if the RGB output is same as SMS VDPs or different.

Freq of $000 acts as $400 on TI chip (MCLK / 32 / $400), producing lowest possible frequency. Decrement counter and then check for zero logic.On Sega VDPs, freq of $000 acts same as $001, producing (MCLK / 32) output rate, highest possible frequency. Rest works exactly as on TI PSG. Freq of $000 is handled specially, which makes little sense from hardware perspective. I would have liked the extra low freq step, as the chip has very shit lower end freq range to begin with due to being clocked so high.

Do notice the gap between start and first pulse, same thing also happens on hardware. Noise output is not instant, suggesting the way I do the noise register is correct.

Alternate noise mode produces 100/15 duty cycle square wave on TI chips and 100/16 duty cycle squares on Sega VDPs. Noise register is rotated left without any XOR magic and output is inversion of bit 0. The implication of this is that you need a new freq table to have noise in tune with tones on TI PSG, while on Sega VDPs noise is exactly 4 octaves lower allowing freq table to be reused.

Tone phase is not reset by either volume or frequency writes on TI chip or Sega VDPs. You can spam either to the chips and nothing happens as far as phase goes. Change applies immediately to current state. This has implications on PCM playback, only sane way to do it is by using highest possible frequency which then averages into something along the lines of DC level due to lowpass filters on the chip output path. This is also part of the reason why PCM playback is very quiet on actual hardware. If noise started at high level you could get reliable DC offset to exploit and get better results for PCM playback.

It is possible to detect TI PSG, as it has READY output which is connected to !WAIT line on Z80 in SC-3000 and if the chip is not ready, CPU is stalled until it is. You can spam writes to the chip and then determine if you have lagged behind or not. There is no such stall mechanism with Sega VDPs. Chip is able to accept one write every sample, I'm not right now sure if Sega VDP can accept data faster than TI chip or it misses the writes, I will have to do some explicit tests to determine that.

Outputs of TI chip behaves as expected, you have 4x log scaled channels that just get summed together. The output has tendency to oscillate at transitions from low to high and high to low, but that is fixed by placing a 150pF or smaller cap from Audio Out pin (9) to the Audio In / NC pin (7). TI chip is made of BJTs not MOS transistors.Sega VDPs are made of NMOS transistors and require external current sinking resistor and this has some implications on what signals are like. The higher overall output level gets the less the resistor is able to sink current away and the more output flattens out, you do not get equal spacing of summed channels as current is running out. The resistor value used in SMS and MDs is 2.2Kohm, exception is SMS2 which uses an additional resistor to VCC on the output which really destroys 3 top levels of a channel causing totally messed up output :http://www.tmeeco.eu/SMS/PSGbadLevels.jpgthis has 3 channels playing at the same time doing a volume ramp. The pic was taken a long time ago, my current digital scope is unable to show as clear result unfortunately as it has relatively low sample rate and things are full of aliasing artifacts. My other nice analog scope managed to develop dead tube. Normal, unmessed up output looks like this (just 2.2k resistor): http://www.tmeeco.eu/SMS/PSGgoodLevels.jpgThere is still some non linearity but it is much smaller. By using a lower value resistor (under 470ohm) you start getting output that starts reaching the ideal (like TI chip). NES for example uses 100ohm resistors on its audio outputs to get best possible linearity (albeit it still has problems due to varying DC offsets on different channels). TI, SMS1, SMS2 and MD chips all got differing DC offsets and peak-to-peak output levels. I will do accurate measuerements of all the levels in near future once I write out a good test program for that. It should be noted that while MD2 ASIC is CMOS, the PSG output is still NMOS based and requires sink resistor to function, while YM output is full CMOS based and will not function with sinking resistor in place (which are required for YM2612 which is NMOS).

In other words, if the bit is low on the output for a channel, should we just not adjust the total output volume at all, or should we subtract from it by the volume level for said channel?

The former has a significant problem in that it produdes a strictly unsigned waveform. We can try to center the channel. Say the total maximum value for all channels is 0x3fff, then we can subtract 0x2000 to turn the range from 0000 - 3fff into -2000 - +1fff. But this is tricky as well, because total silence now ends up being -0x2000 instead of 0, and when mixing with the YM2612, it can lead to faster audio distortion.

The latter avoids this problem, but is very different in terms of operation. It also means the only way to produce silent output for a channel is to set the volume register to 0xf. And obviously it doubles the range of output, so we'd have to halve the volume levels[], or use +0.5 and -0.5 instead.

The thing is ... I've tried both, and while the latter sounds slightly better to my ears, I'd like to know definitively which one is the correct behavior.

The output of the chip is all "unsigned", going above some DC offset (never below), but there's always a highpass filter on the chip output which will give you "signed" result that swings around some voltage reference given later in the circuit.

Ideally you would implement a highpass filter in software, but you can cheat and make the chip output swing around 0 rather than always above. Technically it would be inaccurate but there's no audible difference and it takes less CPU too.

Games using PCM, such as the "Say-Gah" sample before the titlescreen in some Sonic games, expect the unsigned behavior. Otherwise, they'll be inaudible or nearly so. For both 2A03 and SN76489 family, use unsigned output followed by a software band-pass filter.

To simulate the Game Gear's internal speaker, you could pretend it's the same as a Game Boy Advance's speaker, which I've modeled as a third-order Butterworth highpass with corner frequency 800 Hz.

For general use with TV or headphones, you could use a filter that's more or less transparent in the audible band. Try a 20 Hz corner frequency because that's the canonical lower limit of human hearing.

Or you can use half the PSG's minimum continuous output frequency as the corner frequency so that it's essentially flat in the desired band. For the SN76489 family, the lowest frequency is close to 39375000/11/32768 = 109.2 Hz, so you can set the corner frequency at 54.6 Hz.

HPF cutoff freq is subsonic, like 10Hz or something (10µF caps and relatively weak loading on subsequent stages in the circuit). LPFs are all cutting well into audible range, under 10KHz even on some hardware models (! ). I will experimentally determine the cutoff points later on when I make some freq sweep tests on various hardware.

Anyway this is what happens in the hardware : http://www.tmeeco.eu/SMD/AnalogSoundStuff.pngSimulating the analog effects is going to be a bit ugly on the dynamic range side of things, full scale 16bit output will not fit in 16bit datatype after HPF, due to half of Vpp signal going below GND at that point (not a problem if you use floats).

As far as cheating with PSG output goes, I jsut created a volume table with + values for high states and - values for low states and I sum stuff up. It is dirty but approximates output after the HPF well enough for just music (which is all I need in my music tool) but it should break down for PCM playback stuff. Doing it the proper way will work best there. Bear in mind that most games using PCM on SMS/GG sound very bad (like playing 4bit PCM without taking account the log scale of the chip). Here's one PSG PCM test ROM I made a while ago : http://www.tmeeco.eu/BitShit/SMSPCM.SMSOriginal track used : http://www.tmeeco.eu/BitShit/GreenHillsXGremixLOOP.flac

Who is online

Users browsing this forum: No registered users and 1 guest

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum