Regarding the YM3438 on the Mega Drive...
Moderator: BigEvilCorporation
-
- Very interested
- Posts: 53
- Joined: Mon Mar 07, 2011 12:58 am
Regarding the YM3438 on the Mega Drive...
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.
Re: Regarding the YM3438 on the Mega Drive...
oof, not yet another detail to worry about x_xl_oliveira wrote: ↑Sat Sep 15, 2018 9:31 pmSpamming 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.
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".
-
- Very interested
- Posts: 53
- Joined: Mon Mar 07, 2011 12:58 am
Re: Regarding the YM3438 on the Mega Drive...
For sake of being illustrative, this is the ASM macro I was using for the YM2612 access:
This is how it ended after I got YM3438 to work properly:
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.
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
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
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.
-
- Very interested
- Posts: 2442
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
Re: Regarding the YM3438 on the Mega Drive...
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
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
-
- Very interested
- Posts: 53
- Joined: Mon Mar 07, 2011 12:58 am
Re: Regarding the YM3438 on the Mega Drive...
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.
Re: Regarding the YM3438 on the Mega Drive...
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.l_oliveira wrote: ↑Sun Sep 16, 2018 5:07 amApparently, 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.
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".
-
- Very interested
- Posts: 616
- Joined: Thu Nov 30, 2006 6:30 am
-
- Very interested
- Posts: 53
- Joined: Mon Mar 07, 2011 12:58 am
Re: Regarding the YM3438 on the Mega Drive...
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.
-
- Very interested
- Posts: 53
- Joined: Mon Mar 07, 2011 12:58 am
Re: Regarding the YM3438 on the Mega Drive...
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.
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 (16.17 KiB) Viewed 19116 times
-
- Very interested
- Posts: 616
- Joined: Thu Nov 30, 2006 6:30 am
Re: Regarding the YM3438 on the Mega Drive...
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 wrote: ↑Wed Sep 19, 2018 9:11 pmIf it is not done that way, the YM3438 actually fails to work on a lot of games.
-
- Very interested
- Posts: 53
- Joined: Mon Mar 07, 2011 12:58 am
Re: Regarding the YM3438 on the Mega Drive...
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.
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.
-
- Very interested
- Posts: 2442
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
Re: Regarding the YM3438 on the Mega Drive...
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
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen