Welcome to Data Crystal's new home! Data Crystal is now part of the TCRF family (sort of).
The wiki has recently moved; please report any issues in Discord. Pardon the dust.

PSG (TG-16)

From Data Crystal
Jump to navigation Jump to search

(the following is an excerpt from the research notes of David Shadoff, for TGHack)

Register Map

Note: all addresses are segment $FF-relative.

[code]

$0800 - Voice Select (select voice #)
       Mask = $07 (only 3 bits used)
$0801 - Main Volume - not a voice-dependent register
       Most sig.  4 bits = left channel
       Least sig. 4 bits = right channel
       Mask = $FF
$0802 - Frequency (low) -  Least sig. 8 bits of 12-bit frequency counter,
                          for voice selected by 'Voice Select'
       Mask = $FF
$0803 - Frequency (high) - Most sig. 4 bits of 12-bit frequency counter,
                          for voice selected by 'Voice Select'
       Mask = $0F
$0804 - Channel on/dda/volume - voice-dependent register
              bit 7   = 'on'  - (I believe it's a voice-enable flag)
              bit 6   = 'dda' - 'Direct digital-to-analogue'(?)  With this
                                flag set, any value written into the 'wave
                                data' location will directly appear on the
                                channel's output, rather than be stored in
                                the circular wave buffer
              bit 0-4 = voice volume
       Mask = $CF
$0805 - Pan volume ('balance') - voice-dependent register
       Most sig.  4 bits = left channel
       Least sig. 4 bits = right channel
       Mask = $FF
$0806 - Wave data - Samples are inserted into a 32-address circular buffer
                   when this address is written to.  Only 5 dtaa bits are
                   used.  (voice-dependent register)
       Mask = $1F
$0807 - Noise - (voice-dependent register, available only to voices 5 & 6)
                     bit 7   = noise enable
                     bit 0-4 = noise frequency (some experimentation needs
       Mask = $9F              to be done, to understand the range of these
                               values, and their sound)

The LFO is not a per-voice attribute. Unfortunately, I don't know much else about it, or understand how these affect sound:

$0808 - LFO Frequency
       Mask = $FF
$0809 - LFO Control - bit 7   = LFO trigger (?)
                     bit 0&1 = LFO Control (?)
       Mask = $83
       

About the 'frequency' values:

First, I discovered that the values are inverse - a higher value means a lower tone. Second, I had to use the value $1b4 to get a 256Hz tone from the PC-Engine. From this, I worked out that the sound chip has a base clock of 3.58MHz (common in these systems, since this is the NTSC colorburst frequency), and uses the 'frequency' value as a down-counter (or divider). Once the value reaches 0, a 'step' is performed. In this case, the 'step' means advancing to the next sample in the 5-bit, 32-sample waveform for that voice.

So, 3.58Mhz / $1b4 (436 decimal) / 256Hz = 32 samples/cycle

This all starts to make sense when you realize that the PCE put the sound generator inside the CPU -- it's all simple digital stuff, up until the D/A output. [/code]