GenesisPlus DC DL's + Discussion

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.
Locked
Warmtoe
DC Developer
DC Developer
Posts: 453
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Thu May 16, 2002 8:29 am
Location: ice88's house
Has thanked: 0
Been thanked: 0
Contact:

Post by Warmtoe »

BlackAura wrote:The emulator itself is more than fast enough to run at full speed. However, when displaying a frame, the Dreamcast's hardware requires that we wait around for it to be ready for us to start sending data. That means that, at the end of each frame, we need to wait until the graphics hardware is ready. In practice, that means that each frame lasts a multiple of 1/60th of a second.

That wouldn't be a problem, but occasionally a frame takes just over 1/60th of a second. The result is that the frame ends up taking 2/60th of a second, and is sitting around for almost an entire frame doing nothing. With the frameskipping, we can detect that a frame has taken too long, and then not draw a frame and get on with emulating the next frame instead. Hopefully, the next frame will take less that 1/60th of a second, so we'll still be running at full speed (with occasional frameskipping as required), but most importantly the sound system will still be properly synchronised.
Hmmmm... can't the emulator be getting on with something while it's waiting for the next frame? Instead of doing 'pvr_wait_ready()' you can use 'pvr_check_ready()' and if it's not ready, start emulating the next frame? Just thinking out loud.

I did some work on trying to get z80 running faster - did I ever send you that source? I tried to use some of the tricks that Stef did on M68000 on the Z80 - perhaps it's faster? PM me and I'll sort out sending you that source.
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

he already has something that doesnt really need tricks :wink:
Check out the beats of rage community at http://borrevolution.vg-network.com/
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7499
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 10 times
Contact:

Post by Quzar »

*sigh* this was neither the time nor place, anyone who read what was here, sorry.
"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 »

Hmmmm... can't the emulator be getting on with something while it's waiting for the next frame? Instead of doing 'pvr_wait_ready()' you can use 'pvr_check_ready()' and if it's not ready, start emulating the next frame? Just thinking out loud.
The main problem is the graphics emulation. If I start emulating the next frame before drawing the current frame, there's a chance that the game will start changing video registers or modifying video memory. If it does that, we'll end up with garbage when we get around to doing the drawing (presumably triggered by a vblank interrupt or something).
I did some work on trying to get z80 running faster - did I ever send you that source? I tried to use some of the tricks that Stef did on M68000 on the Z80 - perhaps it's faster? PM me and I'll sort out sending you that source.
I remember you were doing some work on it, but I don't remember you sending me anything.

The ideal solution would be to store the display list in a main memory buffer somewhere, then get on with the next frame. When a vblank interrupt is triggered (hence the PVR is ready for another frame) we could send the complete display list over to the PVR using DMA. We'd have to be careful, because the graphics data is also being transferred using DMA (mostly because I couldn't think of a better way to handle it), and there's a possibility that the DMA channel will be in use when a vblank occurs, in which case we'd be completely screwed. We could work around that using a callback function (called when the DMA has completed) but that would just be getting insanely complex.

Aside from which, what happens if the emulation is running faster than 100%? The emulation code itself would be running as fast as possible (with sound disabled, that's well over 100%), and there would be nothing to slow it down. So we'd have to put a delay of some kind in there again. Which means more waiting, probably on a semaphore or a mutex triggered by the vblank handler.

In addition to all that, that would end up breaking the sound emulation, because there'd be nothing to synchronise it to unless we moved most of the actual work into the vblank handler...

The threaded (interrupt driven) approach would undoubtedly be the best one, but I really don't think I can do it. It's far more complex that the single-threaded approach I have now, even if you include the frameskipping stuff. The threaded method would also need that as well, in case it's not running at full speed. Plus you have to worry about concurrency issues, and all the other nasty stuff you run into when doing multi-threaded programming.

If you can think of a better way (or see any way I could do it without driving myself insane in the attempt), please enlighten me.
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

about the sonic 3 and knuckles save situation, try patching the rom with this:

http://dev.dcemulation.org/SON3KFIX.ZIP

I have a good feeling it will work.
Check out the beats of rage community at http://borrevolution.vg-network.com/
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7499
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 10 times
Contact:

Post by Quzar »

DcSteve wrote:about the sonic 3 and knuckles save situation, try patching the rom with this:

http://dev.dcemulation.org/SON3KFIX.ZIP

I have a good feeling it will work.
that doesnt solve the saving problem though, because the emulator will still only work by name/with battery backed saves like sonic 3 has. all that would do is MAYBE fix that specific rom to be recognized and be able to save, which is relatively useless.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

that makes no sense, the goal is to make it save, and this IS the only way to do that for now, so YES, it probably DOES solve the saving problem for THAT game. But anyway, that is a SRAM fix that should take care of it.
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

Acording to Charles Macdonald-

Some cartridges use a Xicor X24C01 EEPROM chip. The chip is programmed in a serial fashion (it has only two wires), and has 128 8-bit bytes of storage.

Games using EEPROM have the backup data string at offset $1B0 in the
cartridge header area formatted like so:

0001B0: 52 41 E8 40 00 20 00 01 00 20 00 01

The Sega manual describes how the above data should be interpreted.
In this case, it corresponds to a device mapped to odd memory addresses,
occupying the byte at $200001.

The only games he know's of which use an EEPROM chip are:

- Wonderboy 3 / Monster World IV
- Rockman Megaworld
- Megaman: The Wily Wars
Check out the beats of rage community at http://borrevolution.vg-network.com/
Warmtoe
DC Developer
DC Developer
Posts: 453
Joined: Thu May 16, 2002 8:29 am
Location: ice88's house
Has thanked: 0
Been thanked: 0
Contact:

Post by Warmtoe »

BlackAura wrote:The ideal solution would be to store the display list in a main memory buffer somewhere, then get on with the next frame. When a vblank interrupt is triggered (hence the PVR is ready for another frame) we could send the complete display list over to the PVR using DMA. We'd have to be careful, because the graphics data is also being transferred using DMA (mostly because I couldn't think of a better way to handle it), and there's a possibility that the DMA channel will be in use when a vblank occurs, in which case we'd be completely screwed. We could work around that using a callback function (called when the DMA has completed) but that would just be getting insanely complex.
Right - that's just a matter of replacing the current pvr_* calls with 'gp_pvr_*' calls - each of which store the data they were sent in some internal buffer, when the vblank interrupt is triggered, you 'replay' these calls with their real pvr equivalents, the 'gp_pvr_*' functions can continue to run, filling up more of the buffer, when the interrupt fires we play the pvr_ calls until we hit the end of a frame... I'm not sure I understand why it's worth trying to push the complete display list over in a DMA when the vblank interrupt fires (doesn't the interrupt run on a different thread of execution?). - this leaves the DMA available for the textures.
BlackAura wrote:Aside from which, what happens if the emulation is running faster than 100%?
Isn't that always going to be a problem that would have to be coped with?
BlackAura wrote:In addition to all that, that would end up breaking the sound emulation, because there'd be nothing to synchronise it to unless we moved most of the actual work into the vblank handler...
OK - vblank handler it is!!
BlackAura wrote:If you can think of a better way (or see any way I could do it without driving myself insane in the attempt), please enlighten me.
;-) How insane are you feeling?
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

After more research, i found more supplemental info to my above post that may help you in emulating EEPROM.

"Every Genesis game has a 256 byte header at location 100h to 1FFh in the cartridge ROM. The 16 bytes at location 1B0h onward define how the battery backed RAM is implemented. If battery backed RAM is present, bytes 1B0h and 1B1h are set to the ASCII values 'RA', while bytes 1B2h and 1B3h define how the RAM is set up. Bit 6 of 1B2h should be set to 1 to specify that battery backed RAM is being used, while bits 4-3 denote how the RAM should be accessed. (the documentation is sketchy on this, saying a code of 10 is for accessing the RAM at even addresses, and 11 is for odd addresses - or something like that.)

The weird thing is that this Megaman game has bits 4-3 set to '01' which is an invalid code. Furthermore, the remaining bytes in the header define the RAM range, which is usually set from 200001h to 203FFFh. This game has the range set to just one byte, at 200001h.

My answer to all this is that Megaman doesn't use battery backed RAM, but instead uses EEPROM. Why, you ask? Here's my evidence:


EEPROM is programmed serially, meaning there's only one data line. This would account for only needing one byte of space defined for backup RAM.
If EEPROM were used, then it would definetly require a different kind of code as specified in the header - which is probably why the code is set to '01'.
In a disassembly of the game, it manipulated bit 0 of 200001h several times, and it never checks the other bits. Another reference to the way EEPROM is accessed serially.
Finally, this game does not run in the Sega Channel adapter, which does support battery backed RAM, and has worked with every game that backs up data I know of.
I also tried modifying the header to show that the one byte at 200001 should be saved as battery backed RAM, but this didn't help - the game intentionally wrote zero to this location.
I could be wrong, and this is pure speculation based on what I have observed. Besides, it's late, and I need to sleep. :) But I hope this little overview will generate some discussion about how the battery backed RAM (or EEPROM) is implemented in Mega Man, and how it can be emulated. "
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 »

Right - that's just a matter of replacing the current pvr_* calls with 'gp_pvr_*' calls - each of which store the data they were sent in some internal buffer, when the vblank interrupt is triggered, you 'replay' these calls with their real pvr equivalents, the 'gp_pvr_*' functions can continue to run, filling up more of the buffer, when the interrupt fires we play the pvr_ calls until we hit the end of a frame...
Hmm... Good point. Newer KOS versions allow you to have a callback function that's called when DMA completes, so we can just use that to do multiple DMA transfers in one go. Initiate the first one, then do each subsequent one in the callback.
I'm not sure I understand why it's worth trying to push the complete display list over in a DMA when the vblank interrupt fires
Basically, we must generate the display list when we've finished one frame, but before we start emulating the next. That means we can't generate it during the vblank, because we might have already started emulating the next frame. We also can't send the display list directly to the PVR if the PVR isn't ready for it (I've tried - it produces a terrible mess). That means that we have only one choice - generate the display list when we're done with one frame, store it in main memory, and then transfer it over when the PVR is ready for it. The fastest way to transfer something that's already sitting in main memory over to the PVR is using DMA.

That's the reason the graphics are being sent using DMA. To prevent texture screwups, I'm keeping four copies of the graphics data. First, the original copy from the MD's VRAM. Next, the twiddled version, which is stored in main RAM. Then multiple versions in VRAM, a different one for each frame. Each frame, we send to current twiddled texture over to VRAM using DMA, and the generated display list uses the most recently uploaded texture. Sprite corruption problem is gone.
Isn't that always going to be a problem that would have to be coped with?
Yes, but it's easier to deal with if you can use the vblank handler to synchronize things. Otherwise, we have to use thread synchronization stuff (like semaphores and mutexes), we have to keep track of things carefully, and we have to make sure that the entire thing is thread safe, there are no deadlocks, and no other concurrency issues.
How insane are you feeling?
I'm not sure. I'll have to get back to you on that one.
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

ba- another important pm :)
Check out the beats of rage community at http://borrevolution.vg-network.com/
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

after talking with chui, another really good way to sync gp would be to use the mame's method. To see what i am talking about, take a look at the dccastaway source found...

http://chui.dcemu.co.uk/dcastaway.shtml
Check out the beats of rage community at http://borrevolution.vg-network.com/
tr0ll
DCEmu Freak
DCEmu Freak
Posts: 69
Joined: Mon Aug 04, 2003 2:12 pm
Location: Boston, MA
Has thanked: 0
Been thanked: 0
Contact:

Post by tr0ll »

... fun its like i never left :)
R.I.P. Dimebag Darrell :(
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

hey troll, been a long time, to bring you up to the current situation of this emu- Gameplay is full speed with loopy or skippy sound (pvr3-prv5 releases), sprite curruption has been fixed (unreleased build), SRAM saves are working (unreleased build).
User avatar
Clessy
DCEmu Super Poster
DCEmu Super Poster
Posts: 1327
Joined: Wed Oct 13, 2004 11:12 am
Has thanked: 0
Been thanked: 0

Post by Clessy »

I always thought crt0's gen-emu was gonna turn out to be the Perfect Genesis emu for DC. I remember those screenies of it back in the day. Ahh those where good times.
SE! SE! SE! Believe the hype!
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 »

Edited due to most-likely being a useless hint anyway... :oops:
Insane homebrew collector.
DcSteve
Modder Of Rage
Modder Of Rage
Posts: 805
Joined: Mon Mar 18, 2002 12:41 pm
Location: Midwest
Has thanked: 0
Been thanked: 0
Contact:

Post by DcSteve »

out of curiosity, is the water layer such as the water in level 1 of sonic 3 fixed?

also- here is some advice on how save states can be done according to my chat with a knowledable programmer who calls himself devster. I put in olny the useful info

<DevSter> each time you write to the cratridge space, make it think its a save state
<DevSter> 0x000000-0x3FFFFF is the cartridge space
<DevSter> whenever a game wants to save a progress, it has to write the data somewhere in memory
<DevSter> this space is inside 0x000000-0x3FFFFF
<DevSter> a game will not write to this space unless it wants to save a state
<DevSter> if the game writes to rom, its not a save state
<DevSter> it's just bad programming =P
<DcSteve> is it easy to "make it think its a save state"
<DevSter> not when it writes to rom
<DevSter> because if your try to read it back, whacha gonna do then =P
<DcSteve> what does he need to do to save state in that situation
<DevSter> just ignore any writes to the rom
<DevSter> a rom won't take up the entire cartridge space 0x000000-0x3FFFFF
<DevSter> so there's room for an external ram
<DevSter> the writes to the external ram are the ones you want
<DevSter> and to read back the values written, you just have to keep track of what was written and where it was written
<DcSteve> how do you "keep track"
<DevSter> you can also use the aid of the header =)
<DcSteve> which is used for sram saves
<DevSter> to keep track of it, just save the lowest address written
<DevSter> you could also use bitwise and to get a clean address
<DcSteve> and thats it, now i doubt u may know, but do u have an idea on how this loads from the vmu
<DcSteve> or "memory card"
<DevSter> u mean loading in general? like how the game will read the save state?
<DevSter> or just vmu?
<DcSteve> how the game will read the savestate is good
<DevSter> well, you just start pumping in data from the save state that was saved into the lowest address that you saved
<DevSter> if you know how it saves, you know exactly how it will be read

hope this helps
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 »

Too late - already worked it out. Here's what I'm doing:

Assume that the battery-backed RAM starts at 0x200001 and is 64kb in length. This is the default save setup.

If the game's header says otherwise, then use that information.

If the game enables the battery-backed RAM switch, but doesn't have any RAM, enable the default save setup. This could be replaced by information in the ROM database, and will at some point when I get around to implementing it.

When saving, strip out unnecessary information (odd/even addresses, start/end address). Add a header to the save containing information about how to load it, and how the save is set up. Then gzip compress it, and add a VMU header. Saves should be two blocks at most, but the VMU saving code is not yet implemented (it works on a PC, but not a Dreamcast yet)

When loading a game, check if a save file exists. If it does, load the save. Use the setup information to set up the save ram as it was before the save.

There's only one problem - when do I save? I want to make it as transparent as possible, so I added code to detect when the game has written to save ram. I can do this, and it turns out that most games don't write to the save very often. Usually at the end of a level, or when you start a new game, and quite often if you start the game without a save. However, saving to a VMU takes a couple of seconds, and I don't really want to freeze the emulator, so I need to figure out if I can do the VMU saving in the background, and keep the emulation going...

As for the graphics... Detection code is there, but drawing code isn't. Drawing code will be there in scanline drawing mode, and tristrip drawing mode, but might not be present in tile drawing mode (the mode that's used in the preview versions). Tristrip mode is more accurate, and should fix most graphics glitches. Scanline more should fix the rest, but will probably be slower.
Midgey34
Insane DCEmu
Insane DCEmu
Posts: 261
Joined: Sat Feb 08, 2003 1:02 pm
Has thanked: 0
Been thanked: 0

Post by Midgey34 »

Sounds good BA, keep up the good work. Finally no more 18 block Shining Force saves for Sega's Samsh Pack. Good luck on completing GP.
Remember, the quickest way to a girl's bed is through her parents. Have sex with them and you're in.
Locked