Difference between revisions of "PSG (TG-16)"

From Data Crystal
Jump to: navigation, search
m
(reformatting)
Line 6: Line 6:
  
 
[code]
 
[code]
$0800 - Voice Select (select voice #)
+
{|
        Mask = $07 (only 3 bits used)
+
|-
 +
|$0800
 +
|Voice Select
 +
|select voice #
 +
|$07 (only 3 bits used)
 +
|-
 +
|$0801
 +
|Main Volume
 +
|
  
$0801 - Main Volume - not a voice-dependent register
+
Most sig.  4 bits = left channel
        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,
+
Least sig. 4 bits = right channel
                          for voice selected by 'Voice Select'
 
        Mask = $FF
 
  
$0803 - Frequency (high) - Most sig. 4 bits of 12-bit frequency counter,
+
not a voice-dependent register
                          for voice selected by 'Voice Select'
+
|$FF
        Mask = $0F
+
|-
 +
|$0802
 +
|Frequency (low)
 +
|Least sig. 8 bits of 12-bit frequency counter, for voice selected by 'Voice Select'
 +
|$FF
 +
|-
 +
|$0803
 +
|Frequency (high)
 +
|Most sig. 4 bits of 12-bit frequency counter, for voice selected by 'Voice Select'
 +
|$0F
 +
|-
 +
|$0804
 +
|Channel on/dda/volume
 +
|
 +
bit 7  = voice enabled
  
$0804 - Channel on/dda/volume - voice-dependent register
+
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 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
+
bit 0-4 = voice volume
        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
+
voice-dependent register
                    when this address is written to.  Only 5 dtaa bits are
+
|$CF
                    used.  (voice-dependent register)
+
|-
        Mask = $1F
+
|$0805
 +
|Pan volume ('balance')
 +
|
  
  $0807 - Noise - (voice-dependent register, available only to voices 5 & 6)
+
Most sig. 4 bits = left channel
                      bit 7  = noise enable
+
 
                      bit 0-4 = noise frequency (some experimentation needs
+
Least sig. 4 bits = right channel
        Mask = $9F             to be done, to understand the range of these
+
 
                                values, and their sound)
+
voice-dependent register
 +
|$FF
 +
|-
 +
|$0806
 +
|Wave data
 +
|Samples are inserted into a 32-address circular buffer when this address is written to.  Only 5 data bits are used.  (voice-dependent register)
 +
|$1F
 +
|-
 +
|$0807
 +
|Noise
 +
|(available only to voices 5 & 6)
 +
 
 +
bit 7  = noise enable
 +
 
 +
bit 0-4 = noise frequency (for more details, see patent)
 +
 
 +
voice-dependent register
 +
|$9F
 +
|}
  
 
The LFO is not a per-voice attribute.
 
The LFO is not a per-voice attribute.

Revision as of 00:45, 3 March 2016

(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 # $07 (only 3 bits used)
$0801 Main Volume

Most sig. 4 bits = left channel

Least sig. 4 bits = right channel

not a voice-dependent register

$FF
$0802 Frequency (low) Least sig. 8 bits of 12-bit frequency counter, for voice selected by 'Voice Select' $FF
$0803 Frequency (high) Most sig. 4 bits of 12-bit frequency counter, for voice selected by 'Voice Select' $0F
$0804 Channel on/dda/volume

bit 7 = voice enabled

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

voice-dependent register

$CF
$0805 Pan volume ('balance')

Most sig. 4 bits = left channel

Least sig. 4 bits = right channel

voice-dependent register

$FF
$0806 Wave data Samples are inserted into a 32-address circular buffer when this address is written to. Only 5 data bits are used. (voice-dependent register) $1F
$0807 Noise (available only to voices 5 & 6)

bit 7 = noise enable

bit 0-4 = noise frequency (for more details, see patent)

voice-dependent register

$9F

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

Address Name Mask Description
$0808 LFO Frequency $FF
$0809 LFO Control $83 bit 7 = LFO trigger (?)

bit 0&1 = LFO Control (?)

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]