YM2610 registers: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
mNo edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Summary:
Pages detailing the different YM2610 parts:
...


=Timers=
* [[SSG]]
* [[FM]]
* [[ADPCM]]
* [[YM2610 timers]]


See [[YM2610 timers]].
=Reading=


=SSG part=
The only writable registers that can be read back are the SSG ones.
To read register X, write X to Z80 port 4, then read Z80 port 5 (needs clarification).


See [[SSG]] for details on this part's operation.
{| class="regdef"
|'''Z80 port'''
|'''Data'''
|Notes
|-
|$04
|{{8BitRegister|Busy|1|-|5|Timer B flag|1|Timer A flag|1}}
|When a timer expires and IRQ is enabled for that timer, the respective flag is set.
|-
|$05
|{{8BitRegister|SSG register data|8}}
|Attempting to read non-SSG registers will return 0.
|-
|$06
|{{8BitRegister|ADPCM-B end|1|-|1|CH6 end|1|CH5 end|1|CH4 end|1|CH3 end|1|CH2 end|1|CH1 end|1}}
|When a channel has reached the end address and stops, the respective bit is set (unless masked). See [[ADPCM#Status_register|Status register]] for more details.
|-
|$07
|Not implemented
|Always returns $00
|-
|}


=FM part=
=Map=


See [[FM]] for details on this part's operation.
This is a quick reference table to help visualize the whole chip mapping, check the individual sections below for more complete information.


==Common FM registers==
CHx stands for channel x, OPx for operator x.


Color codes:
{| class="regdef"
{| class="regdef"
|'''Address (Z80 port 4)'''
|'''Data (Z80 port 5)'''
|
|-
|-
|$22
  | colspan="3" style="background: #ffe699;" |  
|{{8BitRegister|-|4|On|1|Control|3}}
  | [[SSG]]
| LFO Frequency
|-
|-
|$28
  | colspan="3" style="background: lightskyblue;" |
|{{8BitRegister|Slot|4|-|1|Channel|3|}}
  | [[FM]]
| Key On/Off
|-
  | colspan="3" style="background: #cc99ff;" |  
  | [[YM2610_timers|TIMERS]]
|-
  | width="20" style="background: #e2efda;" |
  | width="20" style="background: #c6e0b4;" |
  | width="20" style="background: #a9d08e;" |
  | [[ADPCM]]
|-
  | colspan="3" style="background: silver;" |  
  | Unused/Test
|}
|}


LFO frequency values are as follows:
*0 – 3.98Hz
*1 – 5.56Hz
*2 – 6.02Hz
*3 – 6.37Hz
*4 – 6.88Hz
*5 – 9.63Hz
*6 – 48.1Hz
*7 – 72.2Hz


==Overall channel registers==
{| class="regdef"
The first value listed in the Address column is for channels 1/3; the second is for channels 2/4.
|-
 
  | width="50" |
{|class="regdef"
  | align="center" colspan="2" | '''Port 0 (Z80 writes to port 4/5)'''
| '''Address (Z80 port 4 or 6)''' || '''Data (Z80 port 5 or 7)''' ||
  | align="center" colspan="2" | '''Port 1 (Z80 writes to port 6/7)'''
|-
  | 0x00
  | width="80" rowspan="2" style="background: #ffe699;" | CHA
  | width="480" align="center" style="background: #ffe699;" | {{8BitRegister|Fine tune|8}}
  | align="center" colspan="2" style="background: #c6e0b4;" | {{8BitRegister|Dump|1|-|1|CH6 ON|1|CH5 ON|1|CH4 ON|1|CH3 ON|1|CH2 ON |1|CH1 ON|1}}
|-
  | 0x01
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|4|Coarse tune|4}}
  | align="center" colspan="2" style="background: #c6e0b4;" | {{8BitRegister|-|2|Master volume|6}}
|-
  | 0x02
  | rowspan="2" style="background: #ffe699;" | CHB
  | align="center" style="background: #ffe699;" | {{8BitRegister|Fine tune|8}}
  | align="center" colspan="2" style="background: silver;" | {{8BitRegister|?|8}}
|-
  | 0x03
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|4|Coarse tune|4}}
  | colspan="2" style="background: silver;" |
|-
  | 0x04
  | rowspan="2" style="background: #ffe699;" | CHC
  | align="center" style="background: #ffe699;" | {{8BitRegister|Fine tune|8}}
  | colspan="2" style="background: silver;" |
|-
  | 0x05
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|4|Coarse tune|4}}
  | colspan="2" style="background: silver;" |
|-
  | 0x06
  | style="background: #ffe699;" | Noise
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|3|Noise tune|5}}
  | colspan="2" style="background: silver;" |
|-
  | 0x07
  | align="center" colspan="2" style="background: #ffe699;" | {{8BitRegister|-|2|/EN noise C|1|/EN noise B|1|/EN noise A|1|/EN tone C|1|/EN tone B|1|/EN tone A|1}}
  | colspan="2" style="background: silver;" |
|-
  | 0x08
  | style="background: #ffe699;" | CHA
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|3|Mode|1|Volume|4}}
  | width="480" align="center" style="background: #c6e0b4;" rowspan="6" | {{8BitRegister|L|1|R|1|-|1|Channel volume|5}}
  | width="80" style="background: #c6e0b4;" align="right" | CH1
|-
  | 0x09
  | style="background: #ffe699;" | CHB
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|3|Mode|1|Volume|4}}
  | style="background: #c6e0b4;" align="right" | CH2
|-
  | 0x0a
  | style="background: #ffe699;" | CHC
  | align="center" style="background: #ffe699;" | {{8BitRegister|-|3|Mode|1|Volume|4}}
  | style="background: #c6e0b4;" align="right" | CH3
|-
  | 0x0b
  | align="center" colspan="2" style="background: #ffe699;" | {{8BitRegister|Volume envelope period fine tune|8}}
  | style="background: #c6e0b4;" align="right" | CH4
|-
  | 0x0c
  | align="center" colspan="2" style="background: #ffe699;" | {{8BitRegister|Volume envelope period coarse tune|8}}
  | style="background: #c6e0b4;" align="right" | CH5
|-
  | 0x0d
  | align="center" colspan="2" style="background: #ffe699;" | {{8BitRegister|-|4|Volume envelope shape|4}}
  | style="background: #c6e0b4;" align="right" | CH6
|-
  | 0x0e
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x0f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x10
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Start|1|-|2|Repeat|1|-|3|Reset|1|}}
  | align="center" style="background: #c6e0b4;" rowspan="6" | {{8BitRegister|Sample's start address/256 LSB|8}}
  | style="background: #c6e0b4;" align="right" | CH1
|-
  | 0x11
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|L|1|R|1|-|6|}}
  | style="background: #c6e0b4;" align="right" | CH2
|-
  | 0x12
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Sample's start address/256 LSB|8}}
  | style="background: #c6e0b4;" align="right" | CH3
|-
  | 0x13
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Sample's start address/256 MSB|8}}
  | style="background: #c6e0b4;" align="right" | CH4
|-
  | 0x14
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Sample's stop address/256 LSB|8}}
  | style="background: #c6e0b4;" align="right" | CH5
|-
  | 0x15
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Sample's stop address/256 MSB|8}}
  | style="background: #c6e0b4;" align="right" | CH6
|-
  | 0x16
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x17
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x18
  | colspan="2" style="background: silver;" |
  | align="center" style="background: #c6e0b4;" rowspan="6" | {{8BitRegister|Sample's start address/256 MSB|8}}
  | style="background: #c6e0b4;" align="right" | CH1
|-
  | 0x19
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Delta-N (L)|8}}
  | style="background: #c6e0b4;" align="right" | CH2
|-
  | 0x1a
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|Delta-N (H)|8}}
  | style="background: #c6e0b4;" align="right" | CH3
|-
  | 0x1b
  | align="center" colspan="2" style="background: #e2efda;" | {{8BitRegister|ADPCM-B channel volume|8}}
  | style="background: #c6e0b4;" align="right" | CH4
|-
  | 0x1c
  | align="center" colspan="2" style="background: #a9d08e;" | {{8BitRegister|B|1|-|1|A6|1|A5|1|A4|1|A3|1|A2|1|A1|1|}}
  | style="background: #c6e0b4;" align="right" | CH5
|-
  | 0x1d
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH6
|-
  | 0x1e
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x1f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x20
  | colspan="2" style="background: silver;" |
  | align="center" style="background: #c6e0b4;" rowspan="6" | {{8BitRegister|Sample's stop address/256 LSB|8}}
  | style="background: #c6e0b4;" align="right" | CH1
|-
  | 0x21
  | align="center" colspan="2" style="background: silver;" | {{8BitRegister|?|8}}
  | style="background: #c6e0b4;" align="right" | CH2
|-
  | 0x22
  | align="center" colspan="2" style="background: lightskyblue;" | {{8BitRegister|-|4|On|1|Control|3}}
  | style="background: #c6e0b4;" align="right" | CH3
|-
  | 0x23
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH4
|-
  | 0x24
  | align="center" colspan="2" style="background: #cc99ff;" | {{8BitRegister|TA counter load bits MSBs|8}}
  | style="background: #c6e0b4;" align="right" | CH5
|-
  | 0x25
  | align="center" colspan="2" style="background: #cc99ff;" | {{8BitRegister|-|6|TA counter load bits LSBs|2}}
  | style="background: #c6e0b4;" align="right" | CH6
|-
  | 0x26
  | align="center" colspan="2" style="background: #cc99ff;" | {{8BitRegister|TB counter load|8}}
  | colspan="2" style="background: silver;" |
|-
  | 0x27
  | align="center" colspan="2" style="background: #cc99ff;" | {{8BitRegister|CSM mode|1|2CH mode|1|Flag reset TB|1|Flag reset TA|1|Enable TB IRQ|1|Enable TA IRQ|1|Load TB|1|Load TA|1}}
  | colspan="2" style="background: silver;" |
|-
  | 0x28
  | align="center" colspan="2" style="background: lightskyblue;" | {{8BitRegister|Slot|4|-|1|Channel|3|}}
  | align="center" style="background: #c6e0b4;" rowspan="6" | {{8BitRegister|Sample's stop address/256 MSB|8}}
  | style="background: #c6e0b4;" align="right" | CH1
|-
  | 0x29
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH2
|-
  | 0x2a
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH3
|-
  | 0x2b
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH4
|-
  | 0x2c
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH5
|-
  | 0x2d
  | colspan="2" style="background: silver;" |
  | style="background: #c6e0b4;" align="right" | CH6
|-
  | 0x2e
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x2f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x30
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x31
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|-|1|DT|3|MUL|4}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x32
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x33
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x34
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x35
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x36
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x37
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x38
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x39
  | style="background: lightskyblue;" | CH1/OP2
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
  | 0x3a
  | style="background: lightskyblue;" | CH2/OP2
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
  | 0x3b
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x3c
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x3d
  | style="background: lightskyblue;" | CH1/OP4
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
  | 0x3e
  | style="background: lightskyblue;" | CH2/OP4
  | style="background: lightskyblue;" align="right" | CH4/OP4
|-
  | 0x3f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x40
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x41
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|-|1|Total Level|7|}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x42
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x43
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x44
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x45
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x46
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x47
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x48
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x49
  | style="background: lightskyblue;" | CH1/OP2
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
  | 0x4a
  | style="background: lightskyblue;" | CH2/OP2
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
  | 0x4b
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x4c
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x4d
  | style="background: lightskyblue;" | CH1/OP4
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
  | 0x4e
  | style="background: lightskyblue;" | CH2/OP4
  | style="background: lightskyblue;" align="right" | CH4/OP4
|-
  | 0x4f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x50
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x51
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|KS|2|-|1|AR|5}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x52
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x53
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x54
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x55
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x56
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x57
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x58
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x59
  | style="background: lightskyblue;" | CH1/OP2
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
  | 0x5a
  | style="background: lightskyblue;" | CH2/OP2
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
  | 0x5b
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x5c
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x5d
  | style="background: lightskyblue;" | CH1/OP4
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
  | 0x5e
  | style="background: lightskyblue;" | CH2/OP4
  | style="background: lightskyblue;" align="right" | CH4/OP4
|-
  | 0x5f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x60
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x61
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|AM|1|-|2|DR|5}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x62
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x63
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x64
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x65
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x66
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x67
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x68
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x69
  | style="background: lightskyblue;" | CH1/OP2
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
  | 0x6a
  | style="background: lightskyblue;" | CH2/OP2
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
  | 0x6b
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x6c
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x6d
  | style="background: lightskyblue;" | CH1/OP4
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
  | 0x6e
  | style="background: lightskyblue;" | CH2/OP4
  | style="background: lightskyblue;" align="right" | CH4/OP4
|-
  | 0x6f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x70
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x71
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|-|3|SR|5}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x72
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x73
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x74
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x75
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x76
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x77
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x78
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x79
  | style="background: lightskyblue;" | CH1/OP2
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
  | 0x7a
  | style="background: lightskyblue;" | CH2/OP2
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
  | 0x7b
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x7c
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x7d
  | style="background: lightskyblue;" | CH1/OP4
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
  | 0x7e
  | style="background: lightskyblue;" | CH2/OP4
  | style="background: lightskyblue;" align="right" | CH4/OP4
|-
  | 0x7f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x80
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x81
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|SL|4|RR|4}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x82
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x83
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x84
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x85
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x86
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x87
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x88
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x89
  | style="background: lightskyblue;" | CH1/OP2
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
  | 0x8a
  | style="background: lightskyblue;" | CH2/OP2
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
  | 0x8b
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x8c
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x8d
  | style="background: lightskyblue;" | CH1/OP4
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
  | 0x8e
  | style="background: lightskyblue;" | CH2/OP4
  | style="background: lightskyblue;" align="right" | CH4/OP4
|-
  | 0x8f
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x90
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|-
  | 0x91
  | style="background: lightskyblue;" | CH1/OP1
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="14" | {{8BitRegister|-|4|SSG-EG|4}}
  | style="background: lightskyblue;" align="right" | CH3/OP1
|-
  | 0x92
  | style="background: lightskyblue;" | CH2/OP1
  | style="background: lightskyblue;" align="right" | CH4/OP1
|-
  | 0x93
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x94
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x95
  | style="background: lightskyblue;" | CH1/OP3
  | style="background: lightskyblue;" align="right" | CH3/OP3
|-
  | 0x96
  | style="background: lightskyblue;" | CH2/OP3
  | style="background: lightskyblue;" align="right" | CH4/OP3
|-
  | 0x97
  | style="background: silver;" |
  | style="background: silver;" |
|-
  | 0x98
  | style="background: silver;" |
  | style="background: silver;" |  
|-
|-
| $A1,$A2
  | 0x99
| {{8BitRegister|F-Num 1|8}}
  | style="background: lightskyblue;" | CH1/OP2
| F-Numbers and Block (1/2)
  | style="background: lightskyblue;" align="right" | CH3/OP2
|-
|-
| $A5,$A6
  | 0x9a
| {{8BitRegister|-|2|Block|3|F-Num 2|3}}
  | style="background: lightskyblue;" | CH2/OP2
| F-Numbers and Block (2/2)<br/>(must set this first)
  | style="background: lightskyblue;" align="right" | CH4/OP2
|-
|-
| $A9,$AA
  | 0x9b
| {{8BitRegister|2CH * F-Num 1|8}}
  | style="background: silver;" |  
| 2CH - 2 Slot F-Numbers/Block (1/2)
  | style="background: silver;" |  
|-
|-
| $AD,$AE
  | 0x9c
| {{8BitRegister|-|2|2CH * Block|3|2CH * F-Num 2|3}}
  | style="background: silver;" |  
| 2CH - 2 Slot F-Numbers/Block (1/2)<br/>(must set this first)
  | style="background: silver;" |  
|-
|-
| $B1,$B2
  | 0x9d
| {{8BitRegister|-|2|FB|3|ALGO|3}}
  | style="background: lightskyblue;" | CH1/OP4
| Feedback (FB) and Algorithm (ALGO)
  | style="background: lightskyblue;" align="right" | CH3/OP4
|-
|-
| $B5,B6
  | 0x9e
| {{8BitRegister|L|1|R|1|AMS|2|-|1|PMS|3}}
  | style="background: lightskyblue;" | CH2/OP4
| Left (L)/Right (R) output, AM Sense (AMS), and PM Sense (PMS)
  | style="background: lightskyblue;" align="right" | CH4/OP4
|}
 
==Channel registers==
Depending on which channel you want to write to, the ports used are different:
* Channels 1 & 2: Ports 4/5
* Channels 3 & 4: Ports 6/7
 
===Per-operator registers===
The ranges given for the address represent all of the parameter values. Each channel's operators are laid out as follows:
 
{|class="wikitable"
! Operator || 1 || 2 || 3 || 4
|-
|-
! Channels 1, 3
  | 0x9f
| $x1 || $x5 || $x9 || $xD
  | colspan="2" style="background: silver;" |  
  | colspan="2" style="background: silver;" |  
|-
|-
! Channels 2, 4
  | 0xa0
| $x2 || $x6 || $xA || $xE
  | colspan="2" style="background: silver;" |  
|}
  | colspan="2" style="background: silver;" |  
 
{|class="regdef"
| '''Address (Z80 port 4 or 6)''' || '''Data (Z80 port 5 or 7)''' || &nbsp;
|-
|-
| $31-$3E
  | 0xa1
| {{8BitRegister|-|1|DT|3|MUL|4}}
  | style="background: lightskyblue;" | CH1
| Detune (DT) and Multiple (MUL)
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="2" | {{8BitRegister|F-Num 1|8}}
  | style="background: lightskyblue;" align="right" | CH3
|-
|-
| $41-$4E
  | 0xa2
| {{8BitRegister|-|1|Total Level|7|}}
  | style="background: lightskyblue;" | CH2 /OP4
| Total Level (Volume)
  | style="background: lightskyblue;" align="right" | CH4
|-
|-
| $51-$5E
  | 0xa3
| {{8BitRegister|KS|2|-|1|AR|5}}
  | colspan="2" style="background: silver;" |  
| Key Scale (KS) and Attack Rate (AR)
  | colspan="2" style="background: silver;" |  
|-
|-
| $61-$6E
  | 0xa4
| {{8BitRegister|AM|1|-|2|DR|5}}
  | colspan="2" style="background: silver;" |  
| AM On (AM) and Decay Rate (DR)
  | colspan="2" style="background: silver;" |  
|-
|-
| $71-$7E
  | 0xa5
| {{8BitRegister|-|3|SR|5}}
  | style="background: lightskyblue;" | CH1
| Sustain Rate (SR)
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="2" | {{8BitRegister|-|2|Block|3|F-Num 2|3}}
  | style="background: lightskyblue;" align="right" | CH3
|-
|-
| $81-$8E
  | 0xa6
| {{8BitRegister|SL|4|RR|4}}
  | style="background: lightskyblue;" | CH2 / OP4
| Sustain Level (SL) and Release Rate (RR)
  | style="background: lightskyblue;" align="right" | CH4
|-
|-
| $91-$9E
  | 0xa7
| {{8BitRegister|-|4|SSG-EG|4}}
  | colspan="2" style="background: silver;" |  
| SSG-EG
  | colspan="2" style="background: silver;" |  
|}
 
=ADPCM part=
 
See [[ADPCM]] for details on this part's operation.
 
{| class="regdef"
|'''Address (Z80 port 4)'''
|'''Data (Z80 port 5)'''
|Value on [[reset]]
|-
|-
|$1C
  | 0xa8
|{{8BitRegister|B|1|-|1|A6|1|A5|1|A4|1|A3|1|A2|1|A1|1|}}
  | style="background: lightskyblue;" | OP3
|$00
  | align="center" style="background: lightskyblue;" rowspan="3" | {{8BitRegister|2CH * F-Num 1|8}}
|}
  | colspan="2" style="background: silver;" |  
 
* Write to flag control to reset/mask channel end flags
** Write 1 to reset and/or mask selected flag
** Write 0 to unmask selected flag
** Masking a flag will prevent it from being raised when a channel reaches its end address. This means you have to write 1 to clear the flag, then 0 to keep it active.
** Flags must be manually cleared, playing a new sample on the channel won't clear it.
 
==ADPCM-A part==
 
See [[ADPCM]] for details on this part's operation.
 
{| class="regdef"
|'''Address (Z80 port 6)'''
|'''Data (Z80 port 7)'''
|Value on [[reset]]
|
|-
|-
|$00
  | 0xa9
|{{8BitRegister|Dump|1|-|1|CH6 ON|1|CH5 ON|1|CH4 ON|1|CH3 ON|1|CH2 ON |1|CH1 ON|1}}
  | style="background: lightskyblue;" | OP1
|$00
  | colspan="2" style="background: silver;" |  
|'Dump' is the key on/off bit.  Write 0 to start playing specified channels and write 1 to stop playing.
|-
|-
|$01
  | 0xaa
|{{8BitRegister|-|2|Master volume|6}}
  | style="background: lightskyblue;" | OP2
|$00
  | colspan="2" style="background: silver;" |  
|Actually an attenuator, 0 is the loudest.
|-
|-
|$08~$0D (one for each channel)
  | 0xab
|{{8BitRegister|L|1|R|1|-|1|Channel volume|5}}
  | colspan="2" style="background: silver;" |  
|$00
  | colspan="2" style="background: silver;" |  
|Actually an attenuator, 0 is the loudest. L/R routes the output to the left and/or right channels.
|-
|-
|$10~$15 (one for each channel)
  | 0xac
|{{8BitRegister|Sample's start address/256 LSB|8}}
  | style="background: lightskyblue;" | OP3
|$00
  | align="center" style="background: lightskyblue;" rowspan="3" | {{8BitRegister|-|2|2CH * Block|3|2CH * F-Num 2|3}}
|rowspan="4"|All ADPCM addresses must match a 256-byte boundary (bits 0~7 = 0)
  | colspan="2" style="background: silver;" |  
|-
|-
|$18~$1D (one for each channel)
  | 0xad
|{{8BitRegister|Sample's start address/256 MSB|8}}
  | style="background: lightskyblue;" | OP1
|$00
  | colspan="2" style="background: silver;" |  
|-
|-
|$20~$25 (one for each channel)
  | 0xae
|{{8BitRegister|Sample's stop address/256 LSB|8}}
  | style="background: lightskyblue;" | OP2
|$00
  | colspan="2" style="background: silver;" |  
|-
|-
|$28~$2D (one for each channel)
  | 0xaf
|{{8BitRegister|Sample's stop address/256 MSB|8}}
  | colspan="2" style="background: silver;" |  
|$00
  | colspan="2" style="background: silver;" |  
|}
 
==ADPCM-B part==
 
See [[ADPCM]] for details on this part's operation.
 
{| class="regdef"
|'''Address (Z80 port 4)'''
|'''Data (Z80 port 5)'''
|Value on [[reset]]
|
|-
|-
|$10
  | 0xb0
|{{8BitRegister|Start|1|-|2|Repeat|1|-|3|Reset|1|}}
  | colspan="2" style="background: silver;" |  
|$00
  | colspan="2" style="background: silver;" |  
|Repeat: loop when end address is reached. Reset: clears Start and Repeat.
|-
|-
|$11
  | 0xb1
|{{8BitRegister|L|1|R|1|-|6|}}
  | style="background: lightskyblue;" | CH1
|$00
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="2" | {{8BitRegister|-|2|FB|3|ALGO|3}}
|Left/Right channel output
  | style="background: lightskyblue;" align="right" | CH3
|-
|-
|$12
  | 0xb2
|{{8BitRegister|Sample's start address/256 LSB|8}}
  | style="background: lightskyblue;" | CH2
|?
  | style="background: lightskyblue;" align="right" | CH4
|rowspan="4"|All ADPCM addresses must match a 256-byte boundary (bits 0~7 = 0)
|-
|-
|$13
  | 0xb3
|{{8BitRegister|Sample's start address/256 MSB|8}}
  | colspan="2" style="background: silver;" |  
|?
  | colspan="2" style="background: silver;" |  
|-
|-
|$14
  | 0xb4
|{{8BitRegister|Sample's stop address/256 LSB|8}}
  | colspan="2" style="background: silver;" |  
|?
  | colspan="2" style="background: silver;" |  
|-
|-
|$15
  | 0xb5
|{{8BitRegister|Sample's stop address/256 MSB|8}}
  | style="background: lightskyblue;" | CH1
|?
  | align="center" style="background: lightskyblue;" colspan="2" rowspan="2" | {{8BitRegister|L|1|R|1|AMS|2|-|1|PMS|3}}
  | style="background: lightskyblue;" align="right" | CH3
|-
|-
|$19
  | 0xb6
|{{8BitRegister|Delta-N (L)|8}}
  | style="background: lightskyblue;" | CH2
|?
  | style="background: lightskyblue;" align="right" | CH4
|rowspan="2"|Playback rate is f = 8M / 12 / 12 / (65535 / Delta-N) = 55555 * (Delta-N / 65535) Hz
|-
|-
|$1A
  | 0xb7
|{{8BitRegister|Delta-N (H)|8}}
  | colspan="2" style="background: silver;" |  
|?
  | colspan="2" style="background: silver;" |  
|-
|-
|$1B
  | 0xb8
|{{8BitRegister|ADPCM-B channel volume|8}}
  | colspan="2" style="background: silver;" |  
|?
  | colspan="2" style="background: silver;" |  
|Loudest is $FF
|}
 
=Reading=
 
The only writable registers that can also be read are from the SSG.  All other ports and addresses return different data.
 
{| class="regdef"
|'''Z80 port #'''
|'''Data'''
|Notes
|-
|-
|$04
  | 0xb9
|{{8BitRegister|Busy|1|-|5|Timer B flag|1|Timer A flag|1}}
  | colspan="2" style="background: silver;" |  
|When a timer expires and IRQ is enabled for the timer, the respective bit is set
  | colspan="2" style="background: silver;" |  
|-
|-
|$05
  | '''...'''
|{{8BitRegister|SSG register data|8}}
  | colspan="4" align="center" style="background: silver;" | '''...'''
|Attempting to read non-SSG registers will fail
|-
|-
|$06
  | 0xfd
|{{8BitRegister|ADPCM-B end|1|-|1|CH6 end|1|CH5 end|1|CH4 end|1|CH3 end|1|CH2 end|1|CH1 end|1}}
  | colspan="2" style="background: silver;" |  
|When a channel has reached the end address and stops, the respective bit is set, unless masked
  | colspan="2" style="background: silver;" |  
|-
|-
|$07
  | 0xfe
|not implemented
  | colspan="2" style="background: silver;" |  
|Always returns $00
  | colspan="2" style="background: silver;" |  
|-
|-
  | 0xff
  | colspan="2" style="background: silver;" |
  | colspan="2" style="background: silver;" |
|}
|}


[[Category:Code]]
[[Category:Code]]
[[Category:Audio system]]
[[Category:Audio system]]

Latest revision as of 00:34, 8 August 2021

Pages detailing the different YM2610 parts:

Reading

The only writable registers that can be read back are the SSG ones. To read register X, write X to Z80 port 4, then read Z80 port 5 (needs clarification).

Z80 port Data Notes
$04
Bit 7 6 5 4 3 2 1 0
Def Busy -Timer B flagTimer A flag
When a timer expires and IRQ is enabled for that timer, the respective flag is set.
$05
Bit 7 6 5 4 3 2 1 0
Def SSG register data
Attempting to read non-SSG registers will return 0.
$06
Bit 7 6 5 4 3 2 1 0
Def ADPCM-B end -CH6 endCH5 endCH4 endCH3 endCH2 endCH1 end
When a channel has reached the end address and stops, the respective bit is set (unless masked). See Status register for more details.
$07 Not implemented Always returns $00

Map

This is a quick reference table to help visualize the whole chip mapping, check the individual sections below for more complete information.

CHx stands for channel x, OPx for operator x.

Color codes:

SSG
FM
TIMERS
ADPCM
Unused/Test


Port 0 (Z80 writes to port 4/5) Port 1 (Z80 writes to port 6/7)
0x00 CHA
Bit 7 6 5 4 3 2 1 0
Def Fine tune
Bit 7 6 5 4 3 2 1 0
Def Dump -CH6 ONCH5 ONCH4 ONCH3 ONCH2 ON CH1 ON
0x01
Bit 7 6 5 4 3 2 1 0
Def - Coarse tune
Bit 7 6 5 4 3 2 1 0
Def - Master volume
0x02 CHB
Bit 7 6 5 4 3 2 1 0
Def Fine tune
Bit 7 6 5 4 3 2 1 0
Def ?
0x03
Bit 7 6 5 4 3 2 1 0
Def - Coarse tune
0x04 CHC
Bit 7 6 5 4 3 2 1 0
Def Fine tune
0x05
Bit 7 6 5 4 3 2 1 0
Def - Coarse tune
0x06 Noise
Bit 7 6 5 4 3 2 1 0
Def - Noise tune
0x07
Bit 7 6 5 4 3 2 1 0
Def - /EN noise C/EN noise B/EN noise A/EN tone C/EN tone B/EN tone A
0x08 CHA
Bit 7 6 5 4 3 2 1 0
Def - ModeVolume
Bit 7 6 5 4 3 2 1 0
Def L R-Channel volume
CH1
0x09 CHB
Bit 7 6 5 4 3 2 1 0
Def - ModeVolume
CH2
0x0a CHC
Bit 7 6 5 4 3 2 1 0
Def - ModeVolume
CH3
0x0b
Bit 7 6 5 4 3 2 1 0
Def Volume envelope period fine tune
CH4
0x0c
Bit 7 6 5 4 3 2 1 0
Def Volume envelope period coarse tune
CH5
0x0d
Bit 7 6 5 4 3 2 1 0
Def - Volume envelope shape
CH6
0x0e
0x0f
0x10
Bit 7 6 5 4 3 2 1 0
Def Start -Repeat-Reset
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 LSB
CH1
0x11
Bit 7 6 5 4 3 2 1 0
Def L R-
CH2
0x12
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 LSB
CH3
0x13
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 MSB
CH4
0x14
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 LSB
CH5
0x15
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 MSB
CH6
0x16
0x17
0x18
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 MSB
CH1
0x19
Bit 7 6 5 4 3 2 1 0
Def Delta-N (L)
CH2
0x1a
Bit 7 6 5 4 3 2 1 0
Def Delta-N (H)
CH3
0x1b
Bit 7 6 5 4 3 2 1 0
Def ADPCM-B channel volume
CH4
0x1c
Bit 7 6 5 4 3 2 1 0
Def B -A6A5A4A3A2A1
CH5
0x1d CH6
0x1e
0x1f
0x20
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 LSB
CH1
0x21
Bit 7 6 5 4 3 2 1 0
Def ?
CH2
0x22
Bit 7 6 5 4 3 2 1 0
Def - OnControl
CH3
0x23 CH4
0x24
Bit 7 6 5 4 3 2 1 0
Def TA counter load bits MSBs
CH5
0x25
Bit 7 6 5 4 3 2 1 0
Def - TA counter load bits LSBs
CH6
0x26
Bit 7 6 5 4 3 2 1 0
Def TB counter load
0x27
Bit 7 6 5 4 3 2 1 0
Def CSM mode 2CH modeFlag reset TBFlag reset TAEnable TB IRQEnable TA IRQLoad TBLoad TA
0x28
Bit 7 6 5 4 3 2 1 0
Def Slot -Channel
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 MSB
CH1
0x29 CH2
0x2a CH3
0x2b CH4
0x2c CH5
0x2d CH6
0x2e
0x2f
0x30
0x31 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def - DTMUL
CH3/OP1
0x32 CH2/OP1 CH4/OP1
0x33
0x34
0x35 CH1/OP3 CH3/OP3
0x36 CH2/OP3 CH4/OP3
0x37
0x38
0x39 CH1/OP2 CH3/OP2
0x3a CH2/OP2 CH4/OP2
0x3b
0x3c
0x3d CH1/OP4 CH3/OP4
0x3e CH2/OP4 CH4/OP4
0x3f
0x40
0x41 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def - Total Level
CH3/OP1
0x42 CH2/OP1 CH4/OP1
0x43
0x44
0x45 CH1/OP3 CH3/OP3
0x46 CH2/OP3 CH4/OP3
0x47
0x48
0x49 CH1/OP2 CH3/OP2
0x4a CH2/OP2 CH4/OP2
0x4b
0x4c
0x4d CH1/OP4 CH3/OP4
0x4e CH2/OP4 CH4/OP4
0x4f
0x50
0x51 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def KS -AR
CH3/OP1
0x52 CH2/OP1 CH4/OP1
0x53
0x54
0x55 CH1/OP3 CH3/OP3
0x56 CH2/OP3 CH4/OP3
0x57
0x58
0x59 CH1/OP2 CH3/OP2
0x5a CH2/OP2 CH4/OP2
0x5b
0x5c
0x5d CH1/OP4 CH3/OP4
0x5e CH2/OP4 CH4/OP4
0x5f
0x60
0x61 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def AM -DR
CH3/OP1
0x62 CH2/OP1 CH4/OP1
0x63
0x64
0x65 CH1/OP3 CH3/OP3
0x66 CH2/OP3 CH4/OP3
0x67
0x68
0x69 CH1/OP2 CH3/OP2
0x6a CH2/OP2 CH4/OP2
0x6b
0x6c
0x6d CH1/OP4 CH3/OP4
0x6e CH2/OP4 CH4/OP4
0x6f
0x70
0x71 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def - SR
CH3/OP1
0x72 CH2/OP1 CH4/OP1
0x73
0x74
0x75 CH1/OP3 CH3/OP3
0x76 CH2/OP3 CH4/OP3
0x77
0x78
0x79 CH1/OP2 CH3/OP2
0x7a CH2/OP2 CH4/OP2
0x7b
0x7c
0x7d CH1/OP4 CH3/OP4
0x7e CH2/OP4 CH4/OP4
0x7f
0x80
0x81 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def SL RR
CH3/OP1
0x82 CH2/OP1 CH4/OP1
0x83
0x84
0x85 CH1/OP3 CH3/OP3
0x86 CH2/OP3 CH4/OP3
0x87
0x88
0x89 CH1/OP2 CH3/OP2
0x8a CH2/OP2 CH4/OP2
0x8b
0x8c
0x8d CH1/OP4 CH3/OP4
0x8e CH2/OP4 CH4/OP4
0x8f
0x90
0x91 CH1/OP1
Bit 7 6 5 4 3 2 1 0
Def - SSG-EG
CH3/OP1
0x92 CH2/OP1 CH4/OP1
0x93
0x94
0x95 CH1/OP3 CH3/OP3
0x96 CH2/OP3 CH4/OP3
0x97
0x98
0x99 CH1/OP2 CH3/OP2
0x9a CH2/OP2 CH4/OP2
0x9b
0x9c
0x9d CH1/OP4 CH3/OP4
0x9e CH2/OP4 CH4/OP4
0x9f
0xa0
0xa1 CH1
Bit 7 6 5 4 3 2 1 0
Def F-Num 1
CH3
0xa2 CH2 /OP4 CH4
0xa3
0xa4
0xa5 CH1
Bit 7 6 5 4 3 2 1 0
Def - BlockF-Num 2
CH3
0xa6 CH2 / OP4 CH4
0xa7
0xa8 OP3
Bit 7 6 5 4 3 2 1 0
Def 2CH * F-Num 1
0xa9 OP1
0xaa OP2
0xab
0xac OP3
Bit 7 6 5 4 3 2 1 0
Def - 2CH * Block2CH * F-Num 2
0xad OP1
0xae OP2
0xaf
0xb0
0xb1 CH1
Bit 7 6 5 4 3 2 1 0
Def - FBALGO
CH3
0xb2 CH2 CH4
0xb3
0xb4
0xb5 CH1
Bit 7 6 5 4 3 2 1 0
Def L RAMS-PMS
CH3
0xb6 CH2 CH4
0xb7
0xb8
0xb9
... ...
0xfd
0xfe
0xff