Secrets of the YM2154
After a break, I returned to the PSR-70 reverse engineering project: the YM2154, a.k.a. RYP4 is still an unknown territory. The time has come to reveal its secrets.
RYP4 is used a bit more widely than OPQ. Besides PSR-60/70 it is used at least in PSR-80 and RX-11/15/21 drum machines. This time I did remember to check for service manuals, and found one for RX-11: https://elektrotanya.com/yamaha_rx11_sm.pdf/download.html. This contains a full schematic and other useful information.
Tracing register writes
Because I had good results with OPQ by tracing what the PSR-70 firmware is writing to the chip registers, this would be a good starting point also for RYP4. The chip has 128 registers which reside in Z80 I/O address space at addresses 80H...FFH.
Looking at the disassembly listing reveals quickly that there is no single function which would take care of all the register writes, like OPQ had. There are many IN and OUT instructions accessing the RYP4 registers. In addition, there are several places where Z80 indirect I/O instructions (like OUT (C),A or IN A,(C)) are used, and they seem to be accessing the RYP4 register area. Tracing of all this is not that easy.
I modified the PSR-70 firmware by replacing most of the OUT instructions by one of the six available RST instructions (RST 0 is reset and RST 7 is interrupt, so they are not available). RST is handy here because it is in fact a one-byte CALL. Rest of the OUTs I replaced with a normal CALL instruction, which takes 3 bytes so it is more tricky to fit in the code to replace a two-byte OUT instruction.
I used the same serial output routines as with OPQ to output the register numbers and values from midi port. And got again output like this:
01=00 02=80 03=00 04=3F 07=01 03=40 10=60 11=60 12=60 13=60 14=60 15=60 18=60 19=60 1A=60 1B=60 …
Also the previously written Python analyzer was useful here:
And now we should again start recognizing some patterns. At least it looks quite clear that in each 8 register group (except the first one) only first 6 registers are written. This page says that there are 12 sound channels, two groups of 6 channels. Maybe these are parameter writes to each of the 6 channels… the speculating starts again.
Testing with drumtest
Next step would be to start the “what happens if I modify this register” type of testing. The soundtest2 program used with OPQ for the same purpose was quite easy to modify to work with RYP4, the basic functionality needed is similar. The result was drumtest program which can be found in my Github.
Using drumtest I started to test how the RYP4 reacts to different register values. Being only a PCM sample player, the RYP4 is significantly simpler circuit than OPQ, so it did not take that much time to achieve the basic understanding.
RYP4 can play 12 samples simultaneously, one on each channel. For each channel you can select a sample, set volume and pan and trigger the sample. It’s not any more complicated than that. The chip contains also some additional I/O: a timer, an A/D converter and a couple of general purpose outputs.
RX-11 uses the RYP4 quite differently than PSR-70 and it took me a while to understand why the schematics deviate so much. Especially the A/D arrangement is totally different:
- PSR-70 uses A/D converter YM3012 which interfaces via serial bus to RYP4 and outputs two stereo channels.
- RX-11 uses YM3010 which uses parallel interface to RYP4 and a whole bunch of standard ICs (4000-series logic and op amps). All this makes it possible to get all 12 sample channels out separately, for external mixing. This is not possible with serial A/D.
I don’t have the RX-11 at hand, so studying of it has been a bit of “academic research” (not to blame any academic researchers, but I would like more hands-on approach) and my guesses may be wrong. In the end, all reverse engineering is just guessing, only the certainty level of the guesses varies.
I won’t present the reverse engineering results in detail here, they are documented in the RYP4 Programmer's Guide detailed enough, I hope.
Additional tests and some corrections
After I published the project and OPQ results here in the blog, a couple of people contacted me, offering help and suggesting things I could still test with the PSR-70. This introduced some new tests which I did not originally plan to do.
My basic goal has been to understand how the OPQ and RYP4 are controlled from the programmer’s point of view. For that goal I don’t need to understand the inner workings of the chips or, for example, how the RYP4 and serial sample ROMs are communicating. I just do the register writes so that they produce sounds I want.
One thing I was asked for was to read the contents of the YM2190x sample ROMs. That is not so straightforward thing to do because RYP4 communicates with the ROMs using a Yamaha-specific serial bus. You don’t just desolder the chips and insert them into a ROM reader.
In the RX-11 service manual there is a bit vague timing diagram about the bus signals. Using that I connected the logic analyzer probes on the bus, started trace and played all the percussion sounds with the PSR-70 keyboard. The result looked like this in the Sigrok:
I sent the analyzer data file to the person who asked this and he did an amazing job: he made a software which took the analyzer data and converted it to binary image of the ROM, and also to corresponding wav-file. I could not do that; I tried to analyze the data but ran into troubles in interpreting it: the timing picture in the RX-11 manual is obviously wrong, and I could not figure out how it should be. I’m still not sure how the data is interpreted, but as said, it was not one of my goals in the first place.
The resulting ROM images are in my Github. The corresponding wav-files sound very realistic compared to real PSR-70, so I believe the data is correct. The wav-files sound quite cacophonic if played as such, they just contain all samples after each other, without pauses. That’s how it is in the original ROMs also. The main job of the RYP4 is to make some sense in this: to play suitably selected snippets of the ROM when asked.
Another feedback I got was that my original guess about the RYP4 internal timer bit width seems to be wrong. I had guessed it would be 14 bits wide, because it seemed logical, I did not test it that much. I was suggested that it most probably is 11 bits. I re-tested this and it really seems to be like that. Also the internal clock rate for the timer makes now much more sense; with this assumption it would be same as the sample rate clock. Thanks for pointing this out.
The Programmer’s Guide
After all this, the RYP4 Programmer’s Guide is now in version 1.1, found in my Github. It may still contain wrong guesses, feel free to comment on those or anything else.
This project is getting near the end, I still have a couple of ideas to test with the OPQ side, maybe I return with those a bit later.
Hi, cool project! I have an old Yamaha PSR-70 that I got for my 12th birthday in 1986. I tested it today and when powering off it doesn't keep the Custom patterns. I downloaded a service manual looking for info on an internal battery, but couldn't find the info. Do you know if there is one? And what type? All the best, Anders from Sweden
ReplyDeleteI did not observe any battery there. In the service manual schematic, area H1, there is a block of components marked "Back Up". It contains a 0.1F capacitor, which must be the backup power for the static RAMs. It is not odd if a supercap looses its capacity in 40 years.
DeleteIn the service manual page 7, near the center of the main board layout figure, there is a large circle marked "SC" which must the supercap. I think you should replace that.