Yamaha FM-Sound Synthesizer Unit documentation Ver:1.0
Made By: NYYRIKKI
 
General
  This document contains short description about programming FM sound Synthesizer (YM2151) of the FM sound synthesizer unit(II), that was made by Yamaha for CX5M MSX computer, but that was also available for other MSX computers trough Yamaha Unit Connector UCN-01. This unit includes also D/A converter (YM3012), so 8 audio tone signals can be obtained at the R and L channels. The YM2151 has 8-note capability and it is also equipped with a noise generator, vibrato oscillator, amplitude modulation circuit, tonal effect generator and timer circuitry. 2 sets of timers are used and when a timer overflows an interrupt request takes place. This unit has also YM2148 chip, that has a MIDI function, keyboard scan function and it supports MODE 2 IRQ for CPU, but this document does not tell, how to use these features. Addresses, that are needed for accessing this chip can be anyway founded from address table.
   
How to find the FM-Sound Synthesizer Unit
  Because Yamaha made a Unit Connector, that can be inserted to any expansion slot, it is not sure, that this Unit is always connected to slot #3. That means, that you have to find this with your own routine. The standard way to do that is to search text "MCHFM0" from address #80 in every slot. Here is a simple routine to do that, activate this slot, run your FM-program part and exit to previous routine.

  LD HL,BBEGIN
LD DE,BEGIN
LD BC,END-BEGIN
LDIR
JP BEGIN
 
BBEGIN
  ORG #4000  
BEGIN
  DI ; Interrupts must be disabled, other ways we can't
; switch slots in #0000-#3FFF area.
  LD (TOHL),SP ; We have to be sure, that SP is in area #4000-#BFFF
  LD HL,0  
TOHL  
  EQU $-2  
  LD SP,#8000
PUSH HL
IN A,(#A8)
PUSH AF
AND %00111100
LD D,A
LD B,3

 
SEARCHM ; Loop to search from main-slots.
  LD A,B
RRCA
RRCA
OR B
OR D
OUT (#A8),A
PUSH BC
LD A,(#FFFF)
CPL
PUSH AF
AND %11111100
LD E,A
LD B,3

 
SEARCHS ; Inner loop for sub slot search.
  LD A,B
OR E
LD (#FFFF),A

EXX
LD B,6
LD HL,IDTXT-1
LD DE,#80-1
 
SEID  
  INC HL
INC DE
LD A,(DE)
CP (HL)
JR NZ,NOMATCH
DJNZ SEID

 
; It was found, so we will call a main program (you have to make that one),
; and after that we will select a slot, that was selected before running
; this part and we will exit with C flag as zero.

  CALL FM_PROGGRAM

POP AF
LD (#FFFF),A
POP AF
POP AF
OUT (#A8),A
POP HL
LD SP,HL
XOR A
RET

 
IDTXT  
  DEFB "MCHFM0"

 
NOMATCH  
  EXX
DJNZ SEARCHS
POP AF
LD (#FFFF),A
POP BC
DJNZ SEARCHM

 
; We didn't find it, and we will set C flag to detect an error

  POP AF
OUT (#A8),A
POP HL
LD SP,HL
SCF
RET
 
 
Address Table
 
#3FF0 (R) FM Status register
#3FF0 (W) FM Address register
#3FF1 (R/W) FM Data register
#3FF2 (R/W) Yamaha external keyboard (YK-01 or YK-10) I/O address.
#3FF3 (W) MIDI IRQ vector address
#3FF4 (W) External IRQ vector address
#3FF5 (R/W) MIDI UART Data read and write buffer
#3FF6 (R) MIDI UART Status Register
#3FF6 (W) MIDI UART Command Register

Using the FM-Chip (Ready for write, timer overflows)
 
Status register
7 6 5 4 3 2 1 0
BUSY           Timer
B
Timer
A

Writeable registers

Register #00 (Not used)


Register #01 (Test & LFO reset)
7 6 5 4 3 2 1 0
            LFO
R
 


Register #02 - #07 (Not used)


Register #08 (Key on)
7 6 5 4 3 2 1 0
  MOD1 CAR1 MOD2 CAR2 Channel
Number


Register #09 - #0E (Not used)


REGISTER : #0F (NOISE ENABLE, NOISE FREQUENCY)
7 6 5 4 3 2 1 0
NE     Noise Frequency


Register #10 (Not used)


Register #11 (Clock A1)
7 6 5 4 3 2 1 0
B9 B8 B7 B6 B5 B4 B3 B2


Register #12 (Clock A2)
7 6 5 4 3 2 1 0
            B1 B0


Register #13 (Clock B)
7 6 5 4 3 2 1 0
B7 B6 B5 B4 B3 B2 B1 B0


Register #14 (Clock Functions)
7 6 5 4 3 2 1 0
CSM   F RESET IRQ EN LOAD


Register #15 - #17 (Not used)


Register #18 (Low Frequency)
7 6 5 4 3 2 1 0
LOW OSCILLATION FREQUENCY


Register #19 (Phase and Amplitude modulation)
7 6 5 4 3 2 1 0
F PHS OR AMP MODULATION DEPTH
(F=0: Amplitude, F=1: Phase)


Register #1A (Not used)


Register #1B (Control output & wave form select)
7 6 5 4 3 2 1 0
CT2 CT1         Wave Form

WF= 0 WF=1 WF=2 WF=3
SAW SQUARE TRIANGLE NOISE


Register #1C-1F (Not used)


Register #20 (Channel control)
7 6 5 4 3 2 1 0
RGT LFT FB CONNECT


Register #28-2F (Key code)
7 6 5 4 3 2 1 0
  Octave Note
Register = #28 + Channel number (0-7)


Register #30-37 (Key Fraction)
7 6 5 4 3 2 1 0
Key Fraction    
Register = #30 + Channel number (0-7)


Register #38-3F (Phase & amplitude modulation sensitivity)
7 6 5 4 3 2 1 0
  PMS     AMS
Register = #38 + Channel number (0-7)


Register #40-5F (Detune & phase multiply)
7 6 5 4 3 2 1 0
  Detune(1) Phase multiply
Register = #40 + 8 * DEV* + Channel number (0-7)


Register #60-7F (Total level)
7 6 5 4 3 2 1 0
  Total level
Register = #60 + 8 * DEV* + Channel number (0-7)


Register #80-9F (EG Attack)
7 6 5 4 3 2 1 0
KeyScl   Attack rate
Register = #80 + 8 * DEV* + Channel number (0-7)


Register #A0-BF (EG Decay 1)
7 6 5 4 3 2 1 0
ASE     First decay rate
Register = #A0 + 8 * DEV* + Channel number (0-7)
ASE = Amplitude modulation Sensitivity Enable (1=enable)


Register #C0-DF (EG Decay 2)
7 6 5 4 3 2 1 0
Detune(2)     Second decay rate
Register = #C0 + 8 * DEV* + Channel number (0-7)


Register #E0-FF (EG Decay level, Release rate)
7 6 5 4 3 2 1 0
First decay level Release rate
Register = #C0 + 8 * DEV* + Channel number (0-7)


*
If you change value of MODULATOR1 then DEV=0
If you change value of MODULATOR2 then DEV=1
If you change value of CARRIER1 then DEV=2
If you change value of CARRIER2 then DEV=3

How to handle external Yamaha keyboard
  Yamaha keyboards are easy to use. They have been divided to 8 separate rows, that each have 6 keys. When you want to read some key, you first have to select a row to read. This is done by sending this row number to #3FF2 in format:

7 6 5 4 3 2 1 0
ROW7 ROW6 ROW5 ROW4 ROW3 ROW2 ROW1 ROW0

This means, that you can calculate current row by using formula:

[to #3FF2] = 2 ^ [ROW NUMBER 0-7]

After this you need to wait a little while. Unfortunately I don't know how little, but something like one microsecond. Then you can read this address, and you will get a value in following format:

7 6 5 4 3 2 1 0
  KEY5 KEY4 KEY3   KEY2 KEY1 KEY0
1=Not pressed
0=Pressed

Current key number from bottom to up can be calculated by using formula:

KEYNUMBER + ROW * 6

Please note, that YK-01 does not have few bottom keys at all.

Rest that I want to say
  I want to thank "Greg_" about helping me to collect this information, I mean, that this information is not a offical documentation, but I have just collected it from different sources and rest is just generated by testing.

Here are the Yamaha part-numbers for the most important chips, that are in FM-Sound Synthesizer Unit:

YM2151 (IC101): #IT-21-51-00 (FM-chip)
YM3012 (IC102): #IT-30-12-00 (Stereo D/A converter)
YM2148 (IC103): #IT-21-46-00 (Midi handling)
YM22702 (IC104): #IT-22-70-20 (ROM)


Greetings: NYYRIKKI