Regarding the YM3438 on the Mega Drive...
Posted: Sat Sep 15, 2018 9:31 pm
Researching on a hardware design to play Mega Drive VGM data on my beloved MSX platform I have been slowly progressing from just the YM2612 to YM2612 + PCM then YM2612 + PCM + PSG. Even after achieving solid results with the YM2612 chip, I never managed to get the YM3438 to work properly on this setup due to bizarre readouts and atrocious results on music playback. Last Thursday I had the blink of inspiration needed and managed to pull the line of this yarn out.
There's two annoyingly small details about this chip and it's status register. At least one of these have to do with why it doesn't work properly with Mega Drive games. Because of that I decided to post this information here.
First detail:
The YM3438 does not drive the whole bus when the status register is read. What does that mean to a programmer? It means any values read back by the program are uncertain besides the bits that are specified by the datasheet.
Only bits 0, 1 and 7 are defined. Depending on the computer bus you may get zeroes or ones from any of the other bits. On a MSX computer due to the bus having a weak pull-up the "open" bits will always read back as "1"s. The YM2612 drive all eight bits when the status register is read and unused bits will always return "0"s. If an unmasked compare is used against the register read back, it will work properly only with the YM2612.
This was causing me trouble with detecting the presence of a YM3438.
Second detail:
Spamming reads on the status register causes the YM3438 go out of whack. This is why I was getting atrocious sounds out of my YM3438 chip. The YM2612 does not care if you spam the status register with reads. Too fast writes will disturb it but reads it doesn't care.
The processor on the MSX computer I am using is a 16bit clone of a Z80 processor. It's eight times faster than a regular Z80 running at 3.57Mhz so, to get the writes working properly without overwhelming the chip with too fast writes I have a busy loop which polls the state of the busy flag before letting the program go on with processing the next frame (it's a vgm player, I can afford to waste cycles this way). I had to insert at least one time wasting instruction on the busy loop to prevent the chip from glitching.
The lucky shot which took me to the solution was when I decided to look into the value I was getting back from the status register by reading the I/O port using a BASIC program:
124 01111100 (what I got)
0 00000000 (what I expected)
I thought "What if the "1"s are just open bus? the bits for the flags do match the datasheet..." and so I decided to mask these bits out on the chip detection routine. Once that was done the chip started producing (atrocious) music. From that to adjusting the register writing code to remove unnecessary reads into the status register only took half an hour and the problem was solved.
So, I would like to hear the thoughts of the folks here on this stuff. I have the YM3438 working solid now on my hardware but these faults were so bizarre I spent almost two years clueless about what was going on before this train of thought engaged.
There's two annoyingly small details about this chip and it's status register. At least one of these have to do with why it doesn't work properly with Mega Drive games. Because of that I decided to post this information here.
First detail:
The YM3438 does not drive the whole bus when the status register is read. What does that mean to a programmer? It means any values read back by the program are uncertain besides the bits that are specified by the datasheet.
Only bits 0, 1 and 7 are defined. Depending on the computer bus you may get zeroes or ones from any of the other bits. On a MSX computer due to the bus having a weak pull-up the "open" bits will always read back as "1"s. The YM2612 drive all eight bits when the status register is read and unused bits will always return "0"s. If an unmasked compare is used against the register read back, it will work properly only with the YM2612.
This was causing me trouble with detecting the presence of a YM3438.
Second detail:
Spamming reads on the status register causes the YM3438 go out of whack. This is why I was getting atrocious sounds out of my YM3438 chip. The YM2612 does not care if you spam the status register with reads. Too fast writes will disturb it but reads it doesn't care.
The processor on the MSX computer I am using is a 16bit clone of a Z80 processor. It's eight times faster than a regular Z80 running at 3.57Mhz so, to get the writes working properly without overwhelming the chip with too fast writes I have a busy loop which polls the state of the busy flag before letting the program go on with processing the next frame (it's a vgm player, I can afford to waste cycles this way). I had to insert at least one time wasting instruction on the busy loop to prevent the chip from glitching.
The lucky shot which took me to the solution was when I decided to look into the value I was getting back from the status register by reading the I/O port using a BASIC program:
124 01111100 (what I got)
0 00000000 (what I expected)
I thought "What if the "1"s are just open bus? the bits for the flags do match the datasheet..." and so I decided to mask these bits out on the chip detection routine. Once that was done the chip started producing (atrocious) music. From that to adjusting the register writing code to remove unnecessary reads into the status register only took half an hour and the problem was solved.
So, I would like to hear the thoughts of the folks here on this stuff. I have the YM3438 working solid now on my hardware but these faults were so bizarre I spent almost two years clueless about what was going on before this train of thought engaged.