Regarding the YM3438 on the Mega Drive...

For anything related to sound (YM2612, PSG, Z80, PCM...)

Moderator: BigEvilCorporation

Post Reply
l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Regarding the YM3438 on the Mega Drive...

Post by l_oliveira » 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.
YM3438.jpg
YM3438.jpg (91.92 KiB) Viewed 16088 times

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Regarding the YM3438 on the Mega Drive...

Post by Sik » Sun Sep 16, 2018 1:11 am

l_oliveira wrote:
Sat Sep 15, 2018 9:31 pm
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.
oof, not yet another detail to worry about x_x

Just to make it clear: is this really a problem for a 3.58MHz Z80, or just for the faster R800 from the newer MSX models?
Sik is pronounced as "seek", not as "sick".

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Re: Regarding the YM3438 on the Mega Drive...

Post by l_oliveira » Sun Sep 16, 2018 5:07 am

For sake of being illustrative, this is the ASM macro I was using for the YM2612 access:

Code: Select all

OPN2: MACRO
	super: Driver Driver_PrintInfoImpl
	
	; e = register
	; d = value
	SafeWriteRegister:
		ld a,e
		cp 21h
		ret z  ; block TEST register
		cp 27h
		jr z,TimerControl  ; mask timer control
		cp 2AH
		jr z,pcm2612  ; do not wait busy flag if DAC/PCM write
	; a = register
	; d = value
	WriteRegister: PROC
		out (OPN2_FM1_ADDRESS),a
		in a,(OPN2_STATUS)
		in a,(OPN2_STATUS)
		or (hl)
		ld a,d
		out (OPN2_FM1_DATA),a
	Wait:
		in a,(OPN2_STATUS)
		rla
		jr c,Wait
		ret
		ENDP
		TimerControl:
		ld a,d
		and 11000000b
		ld d,a
		ld a,e
		jr WriteRegister
		
pcm2612:
		out (OPN2_FM1_ADDRESS),a
		cp (ix)
		ld a,d
		out (OPN2_FM1_DATA),a
		ret

	; e = register
	; d = value
	SafeWriteRegister2:
		ld a,e
	; a = register
	; d = value
	WriteRegister2: PROC
		out (OPN2_FM2_ADDRESS),a
		in a,(OPN2_STATUS)
		in a,(OPN2_STATUS)
		or (hl)
		ld a,d
		out (OPN2_FM2_DATA),a
	Wait:
		in a,(OPN2_STATUS)
		rla
		jr c,Wait
		ret
		ENDP
	ENDM
This is how it ended after I got YM3438 to work properly:

Code: Select all

OPN2: MACRO
	super: Driver Driver_PrintInfoImpl
	
	; e = register
	; d = value
	SafeWriteRegister:
		ld a,e
		cp 21h
		ret z  ; block TEST register
		cp 27h
		jr z,TimerControl  ; mask timer control
		cp 2AH
		jr z,pcm2612  ; do not wait busy flag if DAC/PCM write
	; a = register
	; d = value
	WriteRegister: PROC
		out (OPN2_FM1_ADDRESS),a
		cp (ix)
		ld a,d
		out (OPN2_FM1_DATA),a
	Wait:
		cp (ix) ; Delay slot required by YM3438
		in a,(OPN2_STATUS)
		rla
		jr c,Wait
		ret
		ENDP
		TimerControl:
		ld a,d
		and 11000000b
		ld d,a
		ld a,e
		jr WriteRegister
pcm2612:
		out (OPN2_FM1_ADDRESS),a
		cp (ix)
		ld a,d
		out (OPN2_FM1_DATA),a
		ret

	; e = register
	; d = value
	SafeWriteRegister2:
		ld a,e
	; a = register
	; d = value
	WriteRegister2: PROC
		out (OPN2_FM2_ADDRESS),a
		cp (ix)
		ld a,d
		out (OPN2_FM2_DATA),a
	Wait:
		cp (ix) ; Delay slot required by YM3438
		in a,(OPN2_STATUS)
		rla
		jr c,Wait
		ret
		ENDP
	ENDM
ValleyBell and SuperCTR mentioned (at VGMRIPS IRC) that SMPS and GEMS like to busyloop read the busy flag of the YM2612, and GEMS even do check for busy flag after writing addresses (we know that is not really necessary) which on the YM3438 means it will glitch out bad.

On the MSX case, as the code on the top had two instances of reading the status register twice to waste cycles, it was glitching the YM3438 chip even on Z80 mode. Removing that double status read between address and data writes and running on Z80 mode was enough to make the chip work. For working on R800 mode I had to insert the cp (ix) instruction on the busy loops. But then the worst offender were the way I was making the CPU wait for the address write to settle. Apparently, just like on YM2612 reads on any of the four possible addresses result on the status register so while the datasheet mentions you should only read the status with A0 = 0 and A1 = 0, they actually don't matter.

A lesson learned out of this: Avoid spamming reads.

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Re: Regarding the YM3438 on the Mega Drive...

Post by TmEE co.(TM) » Sun Sep 16, 2018 6:03 am

I have not got any sort of issues on YM3438 with doing continuous reads on MD and over LPT port. Neither have clock that is equal or higher than the YM though.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Re: Regarding the YM3438 on the Mega Drive...

Post by l_oliveira » Sun Sep 16, 2018 2:57 pm

I don't think it's even possible to reach a high enough read rate that would cause the YM3438 to glitch on a PC printer port.

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Regarding the YM3438 on the Mega Drive...

Post by Sik » Sun Sep 16, 2018 4:06 pm

l_oliveira wrote:
Sun Sep 16, 2018 5:07 am
Apparently, just like on YM2612 reads on any of the four possible addresses result on the status register so while the datasheet mentions you should only read the status with A0 = 0 and A1 = 0, they actually don't matter.
Not in the version that got integrated into the ASIC in later Mega Drive models, if I recall correctly reading from the wrong address can give the wrong values (there's one game that glitches out as a result). Sega had to warn about this in an addenum.

This reminds me, the Mega Drive never had a discrete YM3438 (somebody pointed it out to me last night after I had posted >.>). We know that the integrated version is not exactly like the YM2612 but it's also not exactly a YM3438 either. Not sure what Yamaha actually did here.
Sik is pronounced as "seek", not as "sick".

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Re: Regarding the YM3438 on the Mega Drive...

Post by Mask of Destiny » Sun Sep 16, 2018 4:34 pm

Sik wrote:
Sun Sep 16, 2018 4:06 pm
This reminds me, the Mega Drive never had a discrete YM3438 (somebody pointed it out to me last night after I had posted >.>).
The Teradrive has an actual YM3438.

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Re: Regarding the YM3438 on the Mega Drive...

Post by l_oliveira » Sun Sep 16, 2018 6:02 pm

Sik wrote:
Sun Sep 16, 2018 4:06 pm
We know that the integrated version is not exactly like the YM2612 but it's also not exactly a YM3438 either. Not sure what Yamaha actually did here.
Very likely they had it changed from the original YM3438 design so it doesn't break when the games spam reads on the status register.

I actually stick to reading the status on the first address on all my code to avoid headaches.

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Re: Regarding the YM3438 on the Mega Drive...

Post by l_oliveira » Wed Sep 19, 2018 9:11 pm

I forgot to mention this:
Consider that people using YM3438 on Mega Drive are actually cheating by piggybacking the YM3438 with the original YM2612 and tying the /RD pin to +5V so the original YM2612 is the one spammed with reads by the system.

If it is not done that way, the YM3438 actually fails to work on a lot of games.
Attachments
YM3438 on MD.jpeg
YM3438 on MD.jpeg (16.17 KiB) Viewed 15966 times

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Re: Regarding the YM3438 on the Mega Drive...

Post by Mask of Destiny » Wed Sep 19, 2018 11:25 pm

l_oliveira wrote:
Wed Sep 19, 2018 9:11 pm
If it is not done that way, the YM3438 actually fails to work on a lot of games.
Which games? I haven't heard of widespread compatibility issues with the Teradrive (which as I previously mentioned has a discrete YM3438), but I'd happy to test some if you know specific games that have problems.

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Re: Regarding the YM3438 on the Mega Drive...

Post by l_oliveira » Thu Sep 20, 2018 2:51 am

I actually re-installed the YM3438 mod I had made many years ago in one of my MD consoles. I now remember why I undo it. The noise floor was very high and it annoyed me a lot. Anyway, not a single one of my games did fail with it. But I only own Japanese cartridges.

One game I know that have problems with the YM3438 is Hellfire (The Japanese version, even).

I wanted to test games using the GEMS sound engine but I don't have any with it here to try.

Edit:

http://www.sega-16.com/forum/showthread ... st-results

The post has some possible candidates for games with issues:
-Sonic Spinball.
-Earth worm jim.
-Super fantasy zone.

I'm almost sure Sonic Spinball use GEMS as sound engine.

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Re: Regarding the YM3438 on the Mega Drive...

Post by TmEE co.(TM) » Thu Sep 20, 2018 4:37 am

Hellfire reads status from the wrong ports and has music slowed down by half, same happens on a stock MD2 also. With proper analog parts, 3438 is much cleaner and waaaaay less noisy than 2612. The output pulses are much wider and amplitude greater, SNR is greatly increased.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Post Reply