Best Genesis/Mega Drive emulator for DC?

This forum is for discussion pertaining to homebrew and indie software for the Dreamcast, such as homebrew games, emulators/interpreters, and other homebrew software/applications. Porting requests and developmental ideas are not to be made here; you can make those here. If you need any help burning discs for homebrew software, this is the place to ask as well.
Post Reply
User avatar
Juan
DCEmu Commie
DCEmu Commie
Posts: 3398
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Sun Jun 15, 2003 11:47 pm
Location: Montevideo
Has thanked: 39 times
Been thanked: 3 times

Post by Juan »

Monster World IV works on FAME (at least the translated version); but it hangs later in the game (the ice temple).
User avatar
Segata Sanshiro
Psychotic DCEmu
Psychotic DCEmu
Posts: 686
Joined: Thu Oct 23, 2003 3:23 pm
Location: the future
Has thanked: 0
Been thanked: 0
Contact:

Post by Segata Sanshiro »

Oye gracias Juan! Me doy cuenta que ese emulador, aparte de ser el mejor se cuelga en tremenda cantidad de juegos.
eke-eke
DC Developer
DC Developer
Posts: 16
Joined: Mon May 01, 2006 4:15 am
Has thanked: 0
Been thanked: 0

Post by eke-eke »

I've got no problems with Wonderboy 6

But Wonderboy 5 use a custom SRAM technique (internal EEPROM), different than others roms so the genesis plus code need to be modified to disable sram reading/writing at initial rom detection (when detecting sram.custom)

i made the change in genesis plus gamecube's port and it worked well
but there will be no sram support for this game until you code a specific driver for the eeprom access (it has been made in kega for example)
TechnoWolf
Insane DCEmu
Insane DCEmu
Posts: 126
Joined: Wed Jan 10, 2007 11:56 am
Has thanked: 0
Been thanked: 0

TROUBLE WITH GPWT

Post by TechnoWolf »

Anyone having trouble with GPWT to run should try my new A-Z Tutorial under "Sega Genesis GPWT Newbie-Proof A-Z EASY Tutorial"
Be sure to use UNZIPPED ROMS!!!! :)
User avatar
Christuserloeser
Moderator
Moderator
Posts: 5948
Joined: Thu Aug 28, 2003 12:16 am
Location: DCEvolution.net
Has thanked: 10 times
Been thanked: 0
Contact:

Post by Christuserloeser »

eke-eke wrote:I've got no problems with Wonderboy 6

But Wonderboy 5 use a custom SRAM technique (internal EEPROM), different than others roms so the genesis plus code need to be modified to disable sram reading/writing at initial rom detection (when detecting sram.custom)

i made the change in genesis plus gamecube's port and it worked well
but there will be no sram support for this game until you code a specific driver for the eeprom access (it has been made in kega for example)
Thanks a lot for sharing the info eke-eke :)
TechnoWolf wrote:Be sure to use UNZIPPED ROMS!!!! :)
It's not a problem to use zipped ROMs ;)
Insane homebrew collector.
eke-eke
DC Developer
DC Developer
Posts: 16
Joined: Mon May 01, 2006 4:15 am
Has thanked: 0
Been thanked: 0

Post by eke-eke »

By the way, i finally discover why some games (Castle of Illusion, Quackshot ) didn't have in-game FM music. This occurs in each Genesis Plus port apparently (i was working on the Gamecube's port made by Softdev, see http://www.tehskeen.com/ ).


The problem was in the sound.c code, where it seems that Charles Mc Donald made a mistake in handling FM Timers A & B and inverted the status of the 2 timers, which are used in the "fm_status" returned when the program read the FM registers.

So the Z80 program (which was in charge of producing music) was kept in a loop, reading the bad timer and didn't send data to produce music. The correction I made solved this problem :wink:


For Genesis Plus ports devellopers, here are the (minor) changes I made in sound.c:

- in function fm_update_timers:
/* Set overflow flag (if flag setting is enabled) */
if(timer.enable)
{
fm_status |= (1 << i);
}


becomes

/* Set overflow flag (if flag setting is enabled) */
if(timer.enable)
{
fm_status |= (1 << (1-i));
}


- in function fm_write:

/* RESET */
if(data & 0x10) fm_status &= ~1;
if(data & 0x20) fm_status &= ~2;


become

/* RESET */
if(data & 0x10) fm_status &= ~2;
if(data & 0x20) fm_status &= ~1;



I found the correct timer handling thanks to the YM2612 Programmer Guide which can be found here: http://www.smspower.org/maxim/docs/ym2612/index.html

Hope this will help to improve your awesome Dreamcast port :wink:
eke-eke
DC Developer
DC Developer
Posts: 16
Joined: Mon May 01, 2006 4:15 am
Has thanked: 0
Been thanked: 0

Post by eke-eke »

eke-eke wrote:By the way, i finally discover why some games (Castle of Illusion, Quackshot ) didn't have in-game FM music. This occurs in each Genesis Plus port apparently (i was working on the Gamecube's port made by Softdev, see http://www.tehskeen.com/ ).


The problem was in the sound.c code, where it seems that Charles Mc Donald made a mistake in handling FM Timers A & B and inverted the status of the 2 timers, which are used in the "fm_status" returned when the program read the FM registers.

So the Z80 program (which was in charge of producing music) was kept in a loop, reading the bad timer and didn't send data to produce music. The correction I made solved this problem :wink:


For Genesis Plus ports devellopers, here are the (minor) changes I made in sound.c:

- in function fm_update_timers:
/* Set overflow flag (if flag setting is enabled) */
if(timer.enable)
{
fm_status |= (1 << i);
}


becomes

/* Set overflow flag (if flag setting is enabled) */
if(timer.enable)
{
fm_status |= (1 << (1-i));
}


- in function fm_write:

/* RESET */
if(data & 0x10) fm_status &= ~1;
if(data & 0x20) fm_status &= ~2;


becomes

/* RESET */
if(data & 0x10) fm_status &= ~2;
if(data & 0x20) fm_status &= ~1;



I found the correct timer handling thanks to the YM2612 Programmer Guide which can be found here: http://www.smspower.org/maxim/docs/ym2612/index.html

Hope this will help to improve your awesome Dreamcast port :wink:
User avatar
Juan
DCEmu Commie
DCEmu Commie
Posts: 3398
Joined: Sun Jun 15, 2003 11:47 pm
Location: Montevideo
Has thanked: 39 times
Been thanked: 3 times

Post by Juan »

Nice. Try to contact the authors directly.
User avatar
Christuserloeser
Moderator
Moderator
Posts: 5948
Joined: Thu Aug 28, 2003 12:16 am
Location: DCEvolution.net
Has thanked: 10 times
Been thanked: 0
Contact:

Post by Christuserloeser »

I can't thank you enough for this eke-eke :kiss)
Insane homebrew collector.
eke-eke
DC Developer
DC Developer
Posts: 16
Joined: Mon May 01, 2006 4:15 am
Has thanked: 0
Been thanked: 0

Post by eke-eke »

In fact, i'm not pretty sure about what I did since in all emulator source code I've read, the FM read register is handled the same as Charles Mc Donald did

That is:

Code: Select all

bit 0 = Timer A overflow
bit 1 = Timer B overflow
Perhaps it's rather an error in the documentation and the change I've made only works because of particular case

by the way, i managed to solve this problem in another way:
1/ don't call the function "fm_update_timers" in system.c
2/ in sound.c, make function "fm_read" return YM2612Read(0,address)
3 in fm.h, set FM_INTERNAL_TIMER to 1
This way, we let the mame FM core (fm.c) handle the timers and the FM status returned on read

The result here is that, with games which previously don't have FM sound (Mickey, Quackshot, Wonderboy 3...):

- I see the FM out sound buffer be filled with data (no 0x00 as before)
- some games that previously hang (Undead Line for example) now run fine


I must discuss that with Charles McDonald or whoever have some interess in this but i'm pretty sure that the problems we had with those games came from FM timer not being handled properly.

Please note that I've only made test on the original DOS version (easier to compile & test) and that I can't produce any sound with this one (need DOSBOX or something like that, but I'm not good with those manipulation). I only check with debugging marks that the FM sound buffer at exit were filled with data other than 0x00 (which were not the case before) but I can't say if there is bug or not in music playback

i'll be glad if you could test my change on the DC port with those particular games



:wink:
User avatar
Christuserloeser
Moderator
Moderator
Posts: 5948
Joined: Thu Aug 28, 2003 12:16 am
Location: DCEvolution.net
Has thanked: 10 times
Been thanked: 0
Contact:

Post by Christuserloeser »

VDMSound is a nice tool and very easy to use:
http://www.borgeneration.com/tools.shtml

Also I've pmed BlackAura but he's very busy atm. Maybe you could try to compile the Dreamcast version yourself? Fackue compiled a nice package that should help you setting up a DC dev enviroment in Windows:
viewtopic.php?t=88526

GenesisPlusDC latest public version including Source code:
http://www.dcevolution.net/dsdevelopmen ... source.rar

Included MR logo:
Image
Insane homebrew collector.
User avatar
Christuserloeser
Moderator
Moderator
Posts: 5948
Joined: Thu Aug 28, 2003 12:16 am
Location: DCEvolution.net
Has thanked: 10 times
Been thanked: 0
Contact:

Post by Christuserloeser »

Christuserloeser wrote:Also I've pmed BlackAura but he's very busy atm.
Hm, I think I'm gonna pm Warmtoe to see if he could implement your code changes and the new versions of FAME and FAZE :)
Insane homebrew collector.
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Post by Quzar »

I've been working on the DC port for quite a bit. I made these changes and sound still seems to be broken, at least in mickey (the only one of those games I have). Before making the changes, the sound simply isn't there, but afterwards it only works from time to time.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
BlackAura
DC Developer
DC Developer
Posts: 9951
Joined: Sun Dec 30, 2001 9:02 am
Has thanked: 0
Been thanked: 1 time

Post by BlackAura »

I think there's something else going on with the sound code. Most likely bugs in CZ80. As I recall, a few games that used to work with MAME's Z80 stopped working when we switched to CZ80.
User avatar
Christuserloeser
Moderator
Moderator
Posts: 5948
Joined: Thu Aug 28, 2003 12:16 am
Location: DCEvolution.net
Has thanked: 10 times
Been thanked: 0
Contact:

Post by Christuserloeser »

I'll post my notes regarding things that I'd love to see implemented next:
  • Updating to the newest FAME + FAZE versions

    - Both have been released with the latest MAME4All update: http://chui.dcemu.co.uk/releases/mame4a ... rc.tar.bz2
    BlackAura wrote:I also need to add a Z80 CPU switcher in - CZ80 is currently hard-coded in. It might be wise to put the old MAME Z80 emulator back, since CZ80 seems to cause rather a lot of games to stop working.
    Maybe the Z80 emulator could simply be 'bundled' with the CPU options at first (so one wouldn't need to rewrite the menu):
    - C68k + MAMEZ80
    - FAME + FAZE
  • 24khz sound emulation

    FAZE/FAME should hopefully free enough CPU resources... I am having wet dreams over this... It however might probably be a good idea to keep the current low sample rate for the software renderer.

    I hope this could be of help to increase the perfomance:
    http://haze.mameworld.info/2006/08/11/hazemd-002a/ - It's a rewrite of the MAME/MESS drivers for MD/G emulation, source code is included. From what I've read it also has a completely rewritten sound driver. Might be really interesting to see if it's any better or faster than the current FM emulator in GenesisPlusDC.

    I also found some interesting notes from BA and Stef D in this old thread here about optimizations in sound emulation, and regarding using an older MAME FM emulator (Stef mentioned MAME v0.35 or v0.36) instead of the one from Gens or newer MAME versions:
    viewtopic.php?t=61992&postdays=0&postorder=asc&start=20

    So I hope that - in combination with the new FAZE/FAME cores - either one of the older MAME sound divers or the rewritten one by Haze actually would allow 24 khz emulation. 24khz actually does sound significantly better than 22khz. If you keep in mind that at 44/48khz all drums and hihats sound off (too high pitched) - in about any existing MD/G emulator out there!, this would be pretty accurate and much better than anyone could ask for.
  • Auto-Frameskip for software renderer

    ...so it attempts to keep 60Hz/50Hz, depending on the region setting in GPDC.

    This would enable games like Sailor Moon to be playable.
  • Auto-Single-Game-Boot-Feature

    ...so it skips the menu and goes straight to the game.
  • 4 player support

    ...for Mega Bomberman, Double Dribble, etc.
Insane homebrew collector.
User avatar
fox68k
DC Developer
DC Developer
Posts: 49
Joined: Tue Aug 03, 2004 11:01 am
Has thanked: 0
Been thanked: 0
Contact:

Post by fox68k »

Christuserloeser wrote:I'll post my notes regarding things that I'd love to see implemented next:
Keep in mind that the FAME source found in MAME4ALL is not suitable for GP. It should be generated properly to match GP requirements.

I would like to update the FAME package with the lastest generation sources. However, the new C version is keeping me from a new release since there it should be reviewed to support the full range of working options.
Anyway, i can post here the generation source along with some notes to help devs out.

Greetings.
- fox68k -
eke-eke
DC Developer
DC Developer
Posts: 16
Joined: Mon May 01, 2006 4:15 am
Has thanked: 0
Been thanked: 0

Post by eke-eke »

Quzar wrote:I've been working on the DC port for quite a bit. I made these changes and sound still seems to be broken, at least in mickey (the only one of those games I have). Before making the changes, the sound simply isn't there, but afterwards it only works from time to time.
Finally, I managed to understand why this strange thing happened. In fact, debugging the Z80, I've noticed that it was kept in a loop, reading the FM Register.

Technically, on read, the emulator returns the FM status, which contains, in his 2 first bits, the status of the 2 FM timers , TimerA & Timer B (a bit set to 1 means that the Timer has overflowed). It seems also that those games made a lot of use of this to synchronise the Z80 and that the order of the bit in returned status is correct (apparently a mistake in documentation).

These timers are updated externally by Genesis Plus (at each frame to be precise, that means each 64us) and can be controlled by the Z80 or 68000 programm with FM writes.

So, Genesis Plus need to interprate this special write (YM2612 0x27 register, see Techncal Doc) in order to manage correctly the Timers and also the FM Status returned on Read. The available command are:

- Start or Stop TimerA or Timer B
- Enable or Disable Timer Overflow to set the FM status TimerA or TimerB flag
- Reset the FM status TimerA or TimerB flag

At this point, I made a test, letting the FM core (the MAME's one) managing the Timers and the FM status himself (set FM_INTERNAL_TIMER to 1 in fm.h and directly read status with YM2612Read) and noticed that sound playback was finally here, but unfortunately, the tempo was not good and some new games had problem with music playback that weren't before.

In fact, this was due to the way the FM core update the Timers value, which was not correct because it has no idea about the real emulator timings.

So, I came back to external timer, managed by Genesis Plus himself and finally found were the probleme was:

In fact, when it recognizes a FM register writing which want to start or stop a timer, Genesis Plus acted like this:

in funtion "fm_write", in sound.c
case 0x27: /* Timer Control */
/* LOAD */
timer[0].running = (data >> 0) & 1;
if(timer[0].running) timer[0].count = 0;
timer[1].running = (data >> 1) & 1;
if(timer[1].running) timer[1].count = 0;
This is not correct because the timers count have to be reinitialized (set to 0) ONLY if the timer was not already started. Doing like this made the timers reset infinitely each time this register is writing with the LOAD bit set to 1 (which, in those games, the Z80 program effectively do each time it want to access this register and don't want to stop the timer)

So, I only changed the code like this:
case 0x27: /* Timer Control */
/* LOAD */
if(!timer[0].running && (data & 1 )) timer[0].count = 0;
timer[0].running = (data & 1);

if(!timer[1].running && (data & 2 )) timer[1].count = 0;
timer[1].running = (data & 2);

And with only this small modifiaction, now we have sound (please forget all the previous changes I gave in my last posts) !

By the way, It makes some other games which previously hangs (games were 68000 is waiting for the Z80, looping forever) to work fine (Undead Line for example).


Please note, that I also made some other modifications in sound.c that don't have so much repercussion but I thought it would be more correct like that:

- in function "fm_update_timers", don't stop the Timers when associated counter overflows.

- in function "sound_reset", add Timers and FM Status initialization:
void sound_reset(void)
{
if(snd.enabled)
{
YM2612ResetChip(0);

/* reset timers status */
timer[0].running = 0;
timer[1].running = 0;
timer[0].enable = 0;
timer[1].enable = 0;
timer[0].count = 0;
timer[1].count = 0;
timer[0].base = 0;
timer[1].base = 0;

/* reset FM status */
fm_status = 0;
}
}
I also replace in gen_reset() and system_reset() the call to YM2612Init() by the function above.

I only made test on the Gamecube's Port but thanks to the link you gave in this topic, I will try to compile a DC version and see what happens
:wink:

PS: GenPlus for Gamecube uses the last MAME Z80 and YM2612 cores for emulation, so there can be some difference, as BlackAura said
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Post by Quzar »

after all those changes it seems to work right now =). I guess that means my thing is now in alpha4 =P. The only thing I see as being off is the speed of the music, which seems to be extremely fast (although I havn't played CoI in a long time, only the second mickey game).

Thanks a bundle for sharing these findings with us.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
eke-eke
DC Developer
DC Developer
Posts: 16
Joined: Mon May 01, 2006 4:15 am
Has thanked: 0
Been thanked: 0

Post by eke-eke »

I think this is due to the sample rate used in the DC port (12000 ?), which is also used to init the genesis audio and the sound buffers. The Timer increment (64us at each scanline) only works for high sample rate (22500 and higher), I think.

As these timers are used by the Z80 program to synchronise his FM data writing, fast tempo means Z80 running too fast because of FM timers decrement to quickly.


To be more precise, if RATE is the sample rate of music playback, passed also to the audio_init() function, and if genesis is in 60Hz mode(by default in GP):

- we have to produce RATE samples per seconds and there are 60 frames per seconds => RATE/60 samples per frame, which actually determine the length of the sound buffers (sound buffer are updated after each frame)

- in 60Hz mode, we have 262 scanlines per frame, that means RATE/15720 average samples per scanlines (+/- 1)
So, if N < 15720, there are some scanlines where no samples have to te produced and some others where 1 sample is produced. The formula used in GenPlus to determine the total numbers of samples achieved at a specific scanlines is : (i * RATE)/15720 where i is the number of the scanline (between 0 and 261)

- FM sound buffers are the same size of the output sound buffers and are updated totally at the end of each frame but ALSO partially, each time the Z80 (or the 68000) access the FM register. The number of samples updated corresponds to the number of samples needed between the actual scanline and the previous one.

So, for example in our case, between 2 scanlines, we could have the timers incrementing by 64us and eventually one of the timer, readed by the Z80, finished his count. This unlock the Z80 which produce some new data BUT, as I said before, no samples needed to be updated between those 2 scanlines


=> the solution is to synchronise timers with sample rate rather than frame rate (or cpu clock), that means calculate the timer increment (added at each scanline) according to the number of the samples produced in this particular scanline.

- sound_tbl is the table which contains the number of achieved sample for each 262 scanline, in audio_init (see system.c), sound_tbl is initialized like this:
sound_tbl = ((i*RATE) / 15720) ---> {0, 0, 1, 2, 3, 3,... , 199} in our case

- the number of samples to be produced for scanline i is:
if i < 261: N = sound_tbl[i+1] - sound_tbl ---> 0 or 1 in our case
else N = (RATE/60) - sound_tbl ---> 1 in our case (last line)

- one sample must be produced each 1/RATE seconds = 1000000/RATE usec

So, in conclusion, the timer has to be incremented by:
inc = (N *1000000)/RATE microseconds


We only have to modified the "FM_Timer_Update" function to give in entry the increment and calculate it at the end of each scanline, before calling the function .



I hope I was clear enough and that I didn't made too much mistakes, but here's the idea and that's how it is implemented in Gens also I think
:wink:
User avatar
Christuserloeser
Moderator
Moderator
Posts: 5948
Joined: Thu Aug 28, 2003 12:16 am
Location: DCEvolution.net
Has thanked: 10 times
Been thanked: 0
Contact:

Post by Christuserloeser »

fox68k wrote:
Christuserloeser wrote:I'll post my notes regarding things that I'd love to see implemented next:
Keep in mind that the FAME source found in MAME4ALL is not suitable for GP. It should be generated properly to match GP requirements.

I would like to update the FAME package with the lastest generation sources. However, the new C version is keeping me from a new release since there it should be reviewed to support the full range of working options.
Anyway, i can post here the generation source along with some notes to help devs out.
That would be great, Fox :!:

Hm, I got a question regarding FAZE then: Do you think it would be save to implement FAZE from the MAME4ALL source into GenesisPlusDC ?

Thanks for all your work on FAME and FAZE!

eke-eke wrote:=> the solution is to synchronise timers with sample rate rather than frame rate (or cpu clock), that means calculate the timer increment (added at each scanline) according to the number of the samples produced in this particular scanline.
Woohoo ! This sounds very promising and I can't wait to see ...er hear it implemented. Thanks a lot for contributing to GenesisPlusDC! :)
Insane homebrew collector.
Post Reply