Williams Arcade Classics sound

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
fox68k
Interested
Posts: 13
Joined: Wed Apr 01, 2009 1:22 pm

Williams Arcade Classics sound

Post by fox68k » Fri Aug 06, 2010 6:26 pm

Hi Eke,

i have found out Defender (included in this pack) does not have sound at the beginning of the game play on Regen and Genesis Plus GX 1.3.0. After a little while, it suddenly comes up (on Regen only, but i suspect it could be happening as well on latter versions of GPGX).
Unfortunately, i cannot test 1.4.0 as it does not seem to have sound output. I am using your FM core (and Regen as well?) and it does not work as expected either. So I wonder whether this is an issue caused by it.

Could you give your emulator a go and let me know?

Thanks!

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sat Aug 07, 2010 7:43 am

Yes, the version i uploaded had sound accidentally disabled, i re-uploaded it some time ago, please give it a try.

This kind of issue could be related to wrong initialized FM registers or Z80 being locked when it should not (wait for interrupt or a value in RAM written by the main CPU). If it works in Gens, it should be easy to spot the difference...

EDIT: I just checked and this bug still occurs in latest build. Also happens with Defender II). Now, if I do a soft-reset AFTER the sound starts appearing, next time I start the game, sound starts immediately. I suspect it has something to do with Z80 initialisation, maybe the banking access to 68k area.

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sun Aug 08, 2010 11:29 am

I did some debugging and it seems there is a counter in Z80 RAM at address $0008, this address is loaded once by 68k (with value from ROM $22c) then decremented by Z80 program everytime it is reseted.

When it reaches 0, Z80 starts controlling FM channels (and music starts). It seems like this counter is decremented everytime the Z80 is reseted by 68k which happen quite constantly once the game starts (68k changes a few values in z80 RAM then reset it). Maybe it is not resetted as often as it should, I have yet to figure why this counter is decrementing too slowly, it seems it is decremented faster when keys are pressed (?)

A quick fix is to patch ROM $22c with $00. Patching with $08 also seems to work (it makes Z80 clearing address $0008 on startup).

Another strange thing its that Z80 try to access the banked memory without having setup the bank register. This is the reason why the game does not start in Gens: it writes to address $FFFF, Gens initialize the bank register to $FF8000 and interprets that as a write to 68k RAM $FFFFFF, which locks the CPU (maybe screwing the stack ?)

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sun Aug 08, 2010 12:16 pm

Ok I fixed it: IY register should not be reseted when Z80 is reseted, it was actually reset to $FFFF everytime 68k was resetting Z80, which lead to address $0008 not being cleared when it should.

I'm not sure how Z80 registers are initialized on power-on (MAME core sets everything to zero on init except IX and IY which are set to $FFFF). On reset, apparently only PC, I, R registers should be cleared.

Some documentation also says that on reset, IFF1 and IFF2 should be cleared, IM set to Mode 0 while AF & SP registers are set to $FFFF. I guess it depends on the CPU implementation, it would be interesting to make some test on various Mega Drive models, after power-on, soft-reset or reset from 68k.

Charles MacDonald
Very interested
Posts: 292
Joined: Sat Apr 21, 2007 1:14 am

Post by Charles MacDonald » Sun Aug 08, 2010 10:46 pm

I've done some tests on the SMS with several different Z80s swapped in (NMOS and CMOS parts from different manufacturers) and on a GameGear which has a CMOS Z80, this is what I found when the Z80 /RESET pin is asserted:

- I, R, PC reset to zero.
- IM 0 selected and interrupts are disabled (like DI).

All other registers (SP, AF, AF', IX, etc.) retain their values.

From memory MAME resets IX and IY to $FFFF for some game that relies on the behavior, but it's much more likely to be a programming bug than anything else. On a NMOS Z80, the non-resetting register bits tend to become '1' when power is turned off and then on again. However they do not all go to '1' after a fixed amount of time, it's jut a general tendency. Perhaps the game needed to have the power cycled a few times to make it run in an arcade. :D

Also out (c), 0 works that way for NMOS parts, on a CMOS Z80 it is out (c), $FF instead. Maybe that could affect the later Genesis consoles where the Z80 is integrated into a custom part and is not a stand-alone chip.

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Mon Aug 09, 2010 4:52 pm

Thanks a lot, I was sure someone like you already did that kind of tests :D

Any idea about the state of registers on a cold start ? Are they random for the most part like after a quick power off/on or are they cleared ?

Anyway, I think that a good way to emulate this is to clear only the registers you mentionned on Z80 reset and initilialize others to random value in Z80 init function.

I also noticed MAME core would not clear /HALT state on Z80 reset but clears /NMI and /IRQ (which could remain asserted by external device during reset). It seems they didn't consider the case where z80 could be reseted while external hardware are still running.

Charles MacDonald
Very interested
Posts: 292
Joined: Sat Apr 21, 2007 1:14 am

Post by Charles MacDonald » Tue Aug 10, 2010 1:37 am

Any idea about the state of registers on a cold start ? Are they random for the most part like after a quick power off/on or are they cleared ?
From memory out of about 10 tests the values were mostly random, with more bits set than not (e.g. I never had it start with most of the registers containing zero bits). However I think a much larger number of tests should be done to look for behavior and trends, and I may be able to do that in a month or so.
I also noticed MAME core would not clear /HALT state on Z80 reset but clears /NMI and /IRQ (which could remain asserted by external device during reset). It seems they didn't consider the case where z80 could be reseted while external hardware are still running.
Aha! Yes it is a bug. The one-time init function clears the HALT state but the reset function forgets to also do this.

On the Genesis you can definitely do a DI; HALT sequence and still recover from a 68K-triggered reset without being 'stuck' in the HALT state.

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Tue Aug 10, 2010 4:02 pm

For the record, here is the thread on SMS Power which is discussing about this same question

http://www.smspower.org/forums/viewtopi ... sc&start=0

It seems like the state of most registers is indeed completely random on Master System but not so much on Mega Drive with PBC where SP/HL are set to some fixed value while others are $FFFF (your Game Gear seemed to act differently with all registers set to $00 on cold start ?).
I will try to run Flubba's test program directly on my MD with Everdrive to see if MS compatibilitty mode can have some effect on registers (I can't figure how it could though ?)
EDIT: no good, Everdrive OS is apparently initializing z80 RAM & registers on startup
EDIT2: it would indeed seem that PBC includes some hardware that would execute some code on reset (at most, 8 bytes, which can make 4 instructions and which would explain the difference between the R register on startup with PBC). See this thread (6th post): http://www.smspower.org/forums/viewtopic.php?t=9277


About the topic, Defender z80 program is actually doing this every time it is reseted:

Code: Select all

 LD(IY + 8h) 0h
 LD(IY + 4h) 0h
 LD(IY + 5h) 0h
 LD(IY + 6h) 0h
 LD(IY + 7h) 0h
 LD(IY + 0h) 0h
but IY is only set to zero later. The result is that the first time Z80 is resetted, writes to random memory occurs (and if IY=$FFFFF on startup, it writes to banked memory without having set the bank register, which initial value is by the way also unkown).

(and as a reminder, Z80 RAM address $0008 need to be cleared by the former routine for sound to be output)

Post Reply