SSG part
Address (Z80 port 4)
|
Data (Z80 port 5)
|
|
$00
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Fine tune |
|
Channel A
|
$01
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Coarse tune |
|
$02
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Fine tune |
|
Channel B
|
$03
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Coarse tune |
|
$04
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Fine tune |
|
Channel C
|
$05
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Coarse tune |
|
$06
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Noise tune |
|
Noise channel
|
$07
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
/EN noise | /EN A | /EN B | /EN C |
|
|
$08
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Mode | Volume |
|
Channel A
|
$09
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Mode | Volume |
|
Channel B
|
$0A
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Mode | Volume |
|
Channel C
|
$0B
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Volume envelope period fine tune |
|
|
$0C
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Volume envelope period coarse tune |
|
|
$0D
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Volume envelop shape |
|
See diagram.
|
If 'Mode' = 1, the EG is used instead of the 4bit volume value.
f = 8M / (Coarse*256 + Fine) ?
Timers
Address (Z80 port 4)
|
Data (Z80 port 5)
|
$24
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
TA counter load bits 9-2 |
|
$25
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
TA counter load bits 1-0 |
|
$26
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
TB counter load bits 0-7 |
|
$27
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
CSM Mode |
3 slot mode | Reset TB flag | Reset TA flag | Enable TB IRQ | Enable TA IRQ | Load TB | Load TA |
|
- TA = Timer A, TB = Timer B
- Timers will tick until they have reached zero, at which point an IRQ will be generated if enabled. Reading port $04 will show which timer caused it.
- The actual timer counter registers are not directly accessable. They can be reset to zero or initialised from load registers $24-$26
- Writing 0 to the load bits in register $27 will reset the timer counter registers to zero
- Writing 1 to the load bits will copy the respective timer load register to the timer counter. This only works when the timer is at zero.
- When a timer expires, it is automatically reloaded from the load registers and continues.
- Timer flag reset refers to the same flags that are read from port $04
- CSM mode is for automatic key on for operators on the second FM channel when timer A expires?
FM part
ADPCM-A part
'Dump' in register $00 is the key on/off bit. Write 0 to start playing specified channels and write 1 to stop playing.
Address (Z80 port 6)
|
Data (Z80 port 7)
|
$00
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Dump |
- | CH6 ON | CH5 ON | CH4 ON | CH3 ON | CH2 ON | CH1 ON |
|
$01
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
- |
Master volume |
|
$08~$0D (one for each channel)
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
L |
R | - | Channel volume |
|
$10~$15 (one for each channel)
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Sample's start address/256 LSB |
|
$18~$1D (one for each channel)
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Sample's start address/256 MSB |
|
$20~$25 (one for each channel)
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Sample's stop address/256 LSB |
|
$28~$2D (one for each channel)
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Sample's stop address/256 MSB |
|
ADPCM-B part
Reading
The only writable registers that can also be read are from the SSG. All other ports and addresses return different data.
Z80 port #
|
Data
|
Notes
|
$04
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
Busy |
- | Timer B flag | Timer A flag |
|
When a timer expires and IRQ is enabled for the timer, the respective bit is set
|
$05
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
SSG register data |
|
Attempting to read non-SSG registers will fail
|
$06
|
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Def |
ADPCM-B end |
- | CH6 end | CH5 end | CH4 end | CH3 end | CH2 end | CH1 end |
|
When a channel has reached the end address and stops, the respective bit is set
|
$07
|
not implemented
|
Always returns $00
|