Dumping Datel unlicensed discs?

Find all your GameCube topics here
rayman
Posts: 6
Joined: Sat Oct 02, 2010 10:41 pm

Dumping Datel unlicensed discs?

Postby rayman » Sun Oct 16, 2016 11:42 pm

My memory is a little hazy on this. Did anyone release a tool that dumps Datel discs accurately? They're known to use some kind of copy protection. I think Crediar said something about it on GBAtemp years ago?

andzlay wrote:I dunno if it is even possible to rip the SDML disc... Never seen it anywhere on the net.

viewtopic.php?f=37&t=432&p=4258

Does CleanRip do the trick? What about Swiss? I have an Ultimate Codes disc and a homebrew-capable GC & Wii. I'd like to dump the disc.

tueidj
Posts: 563
Joined: Fri May 03, 2013 6:57 am

Re: Dumping Datel unlicensed discs?

Postby tueidj » Mon Oct 17, 2016 7:58 am

Cleanrip won't do it. I remember someone wrote some sort of patch that ran the disc and dumped only the parts of it that were accessed/as they were being read, since the rest is full of garbage that throws read errors and isn't important.

GreyRogue
Posts: 25
Joined: Sun Dec 07, 2014 2:57 am

Re: Dumping Datel unlicensed discs?

Postby GreyRogue » Mon Oct 24, 2016 6:22 am

I had been too laz---I mean too busy to finish this for a long time now.
So this post finally got me to finish modding CleanRip to read Datel discs.
https://github.com/greyrogue/cleanrip/c ... 32a69a2930

Notes:
-This will only work if someone has created the disc info (matching checksums and skip sections) for the disc you want to read.
-This is using a CRC of the first 0x100000 bytes to identify the disc. This assumes they are unique in this section. For the vast sample size of 2 discs that I own, this seems possible, as the Disc title, the copyright year, and the file size/offset of the first DOL to load are all in there. If this isn't sufficient, another method will be needed.
-This also assumes that the first 0x100000 bytes can be read without error. Same caution about sample size of 2 applies.
-The code is in pretty sad shape. I did just enough to get it working. It should probably be cleaned up by someone.
-This will dump the first 0x100000 bytes and report the CRC, even without a matching file section. This can be used to start generating the disc info and create an initial/partial image. This can then be run in Dolphin to retrieve the next offset/length needed. This could be a lengthy/repetitive/boring process if there are many sections, but I suspect that other than the Advance Game Port (USA) and the Mega Play discs, most should only need the first 0x100000 and the section containing the main DOL.
-The code I wrote will only work if the skip sections are not entirely inside one 0xXXX10000 block (the Read size in main.h). The logic I used only works correctly if the data to be read is entirely in a skip section, or the skip section crosses the edges of the data to be read. This could be fixed in the code without changing the format of datel.dat by anyone who isn't as laz--busy as me (having problems with me "b" "u" "s" keys apparently.)

I did at one point have a custom build of Nintendont that could read the disc and write the image as it ran. It would be just as easy to just have Nintendont write the offsets/lengths as it goes. I might be able to go dig up that version if I still have it. It should be easy to do it with current Nintnedont with debugging on the DI enabled, but I think the last time I tried to run a Datel image, support for it had been broken. It might be easier to just wait for someone else who understands what all this stuff means to create the disc info for the disc you want.

I'd like some other people to look at what I did (especially the datel.dat file) and comment before this goes to much further. I'd like to limit the number of times I end up needing to dump these discs. It's entirely possible that some of the data being skipped is readable and not equal to the fill value specified. See here for my original posts about how I came up with this stuff:
viewtopic.php?f=23&t=1025&p=28349#p28349
viewtopic.php?f=26&t=2655

User avatar
emu_kidid
Site Admin
Posts: 4228
Joined: Mon Mar 29, 2010 10:06 am
Location: Australia
Contact:

Re: Dumping Datel unlicensed discs?

Postby emu_kidid » Tue Oct 25, 2016 1:43 am

GreyRogue wrote:I had been too laz---I mean too busy to finish this for a long time now.
So this post finally got me to finish modding CleanRip to read Datel discs.
https://github.com/greyrogue/cleanrip/c ... 32a69a2930

*snip*


It definitely needs work to integrate nicely into CleanRip.

If you can get a build of something that dumps all the offsets as they're used I'm sure we can get some members from here to run it on the complete set of discs (I have a few too). Alternatively we make it so that the disc read errors don't stop the drive via custom drive code patch and support dumping it only on GC (but this is more complicated by far).
Image

rayman
Posts: 6
Joined: Sat Oct 02, 2010 10:41 pm

Re: Dumping Datel unlicensed discs?

Postby rayman » Tue Oct 25, 2016 4:52 am

Thank you for your work, GreyRogue.

GreyRogue
Posts: 25
Joined: Sun Dec 07, 2014 2:57 am

Re: Dumping Datel unlicensed discs?

Postby GreyRogue » Sat Nov 05, 2016 10:12 pm

I did find my old dump as you run code, but it has issues. As expected, changes to the Nintendont code base have broken it, so I'd have to refix it to work with current. Even if I fixed it however, I only ever got it to work partially. My Action Replay works enough to dump the whole thing, but the AGP disc does not. I now remember that I used it to partially dump the disc, then used Dolphin to finish getting the rest of the offset/lengths. I would need to add some more patches to get it working the rest of the way. I also never finished getting the EXI (memory card working). If this is still wanted, I guess I could keep working on it. It's in pretty rough shape now (coding/debugging without a USBgecko was a bit of a mess. I have a Shiruken now, but I've never used it, and would face a learning curve if I wanted to).

My suggestion is still using Dolphin. I modified my dumping code slightly.
https://github.com/greyrogue/cleanrip
It now has a default behavior, and generates a .skp file with the crc100000 and skip offsets. If a crc100000=default setting exists, it will use that for skip information. If not, it will attempt to go through the whole disk, and will skip ahead to the next 0xX0000000 offset when finds an error (I left commented out lines for both 0xXX000000 and 0xXXX00000).

Doing this with both my discs found that from 0x00100000-01F00000, the disc is readable and is filled with 0xA8, which is obviously different than the 0x00 fill value I used everywhere, but I don't believe either disc ever actually reads that range.

Other than that range, using the 0xX0000000 offset produced the same data for my Action Replay, but not the AGP. Switching to 0xXX000000 didn't add anything, but took the dumping time from ~10 minutes to ~20 minutes (88 available retry offsets). Switching to 0xXXX000000 would presumably work for my AGP disc, as all the offsets start with those offsets, but would take several hours and would give the disc motor quite a workout (~1300 available retry offsets). I don't know if there's a faster/less motor intensive way to reset after an error. The code should work though if someone wanted to try it.

My recommendation is to use one of the shorter (0xX0000000 or 0xXX000000) ones to get a starting image, and then use Dolphin to get any missing offsets (note that Dolphin requires the IPL file to work with Datel discs).

As an aside, it would be nice to know if all the Datel discs use GNHE as their identifier. The NHL Hitz 2002 info in the datel.dat file is there to support auto Datel detection, but I wasn't sure if they were all GNHE (or possibly GNHP?).

GreyRogue
Posts: 25
Joined: Sun Dec 07, 2014 2:57 am

Re: Dumping Datel unlicensed discs?

Postby GreyRogue » Sat Nov 05, 2016 10:36 pm

Also, current Nintendont does work well enough to read all of my Action Replay disc (but not my AGP disc). Putting this line back in uncommented in DI.c should generate the offsets/lengths needed for those discs that get far enough (might be almost of them):
//dbgprintf( "DIP:DVDReadA8( 0x%08x, 0x%08x, 0x%08x )\r\n", Offset, Length, Buffer|0x80000000 );
Then just set controls to Native (which still might not work), and don't use emulated memory cards, turn on logging, and run with the "Boot GC Disc in Drive" and run it long enough to get the disc info. It might be unwise to actually use a real memory card as it might corrupt it (or report it as corrupted), so I'd stop before that.

This is another option for reading the discs, though. Current Nintendont works as well as my dump as you run version (aka partially for some discs). It's only when running/testing with an ISO that current Nintendont has broken from old versions.

GreyRogue
Posts: 25
Joined: Sun Dec 07, 2014 2:57 am

Re: Dumping Datel unlicensed discs?

Postby GreyRogue » Thu Nov 10, 2016 4:57 am

Well, that was unexpected.
I decided to try and use the ~1300 retry setting. Both of my discs took about 3 hours each to rip and gave the DVD drive a bit of a work out.
When done, the Action Replay disc was the same as the ones that only did 6 or 88 retries, with the addition of the 0xA8 section mentioned above.
The AGP disc on the other hand worked correctly, dumping all of the known offsets, plus the 0xA8 section.
However, it also found another version of the AGP dol at 0x12900000 (in addition to the known one at 0x12D00000). It is a copy of the version at 0x12D00000, so there's nothing too exciting there. However, there turned out to be an additional 9 gba games similar to the 10 known ones. These are similar quality to the other ten, and are clones of other games.

Absolute Zed - horizontal shmup
Alien Invasion 2 - Space Invaders clone
In The Garden - Centipede clone
Llamaboost - Robotron clone (voice samples are kinda fun)
Puzzle - Bejewelled clone
Q Zone - vertical shmup
Rally Z - Rally X clone
Space Loonies - Bosconian clone
Stick a Brick - Bust a Move clone
I don't know if there's any way to get these to load from disc without cheat codes/or equivalent.

If all Datel discs only use 0xXXX00000 start offsets, maybe this is the best way to determine where valid data is. I've updated the default behavior in my GitHub copy of cleanrip to use this as the default behavior if no matching crc100000 is found, and a default skip pattern isn't specified. I've also updated the datel.dat file for the two discs I have.

GreyRogue
Posts: 25
Joined: Sun Dec 07, 2014 2:57 am

Re: Dumping Datel unlicensed discs?

Postby GreyRogue » Sat Dec 10, 2016 3:47 am

Alright. I got Nintendont working with the Datel AGP disc again (mostly anyway).
This version will report all of the reads it does on the disc (make sure Log is on in the settings). It lists the starting offset, length, and memory location where the data is copied to. This can be used to generate a dat file to use with the modified version of CleanRip I created to generate an ISO. I recommend trying to expand all of the ranges to 0xXXX00000 boundaries. I still think just using the method above is better (1300 default range setup), as there were definitely ranges I can't get the disc to read unmodified. Maybe doing both and comparing is a good idea.
Notes on using the modded Nintendont:
-Must be run on a Wii with Native Controls - ON and Memory Card Emulation - OFF.
-Log must be on to get the Disc access info.
-Select the disc drive as the game to run.
-The disc access info will be in the root of the device under ndebug.log.
-It occasionally locks up (just start over). It works most of the time, but I must have a race condition somewhere with the Fake Disc Interrupts.
-Since I only have two Datel discs, this might not work on other ones.
-For fun, I added access to the nine other GBA games on the AGP disc. Turn Triforce Arcade setting ON (I just borrowed the setting-ignore the name), and the first 9 games will load the other 9 games instead (pictures/titles will be wrong). e.g. Selecting Bounty Hunter will load Absolute Zed instead.

<<<<<<<<<<<<< THIS IS YOUR WARNING.>>>>>>>>>>>>>
-I wouldn't recommend attaching EXI (Memory Card/AGP device). The timing is likely to be wrong, which can cause unexpected behavior. In my case, it wouldn't recognize my Action Replay memory card. Since the disc has already finished loading everything when it complains, I just stopped at that point. For the AGP, it would read games and start some of them, but any save access is likely to fail. This causes many games to hang. The Frogger game I have works fine (except saving). Using either a memory card or actual GBA cart could cause data corruption.
https://github.com/greyrogue/Nintendont ... 20bd75533c

This is all I plan on doing with this, unless someone needs something else.

User avatar
MockyLock
Posts: 319
Joined: Tue Aug 07, 2012 8:12 pm

Re: Dumping Datel unlicensed discs?

Postby MockyLock » Sat Dec 10, 2016 8:14 am

'llo here.
I don't come here so often (I still have issues to connect here from my job computer).
I'm very happy that people worked again on this Datel AGP disc.
Would a disc rip usable with swiss be possible ?

GreyRogue
Posts: 25
Joined: Sun Dec 07, 2014 2:57 am

Re: Dumping Datel unlicensed discs?

Postby GreyRogue » Sat Dec 10, 2016 1:52 pm

It would probably need some game specific patches to run with Swiss to handle the disc interface, as it doesn't use the Nintendo SDK. Here are my notes in case it helps. These are the functions I found that I needed to modify to get it to work. (Memory locations for first dol load (0x80003100), and after it copies the apploader to 0x81300000 (before it loads the next dol) below). Note that there are multiple, non-identical versions of functions that do the same thing. These are a bit out of date, as it does't include the changes I just added to Nintendont (Interrupt mask, etc.). Also watch out for the apploader. In the dol at 0x80003100 is the apploader that gets copied to 0x81300000 after selecting AGP or Cheat Creator. Patches using relative branches (e.g. to 0x80001800 range) will be to the wrong address if patched before the copy.
Spoiler: show
FuncPattern DatelFPatterns[] =
{
{ 0x48, 9, 2, 3, 0, 3, NULL, FCODE_DolEntryMod, "DolEntryMod", "Datel", FGROUP_NONE, 0 },
{ 0xF8, 8, 6, 7, 1, 6, NULL, FCODE_DolEntryMod, "DolEntryMod", "DatelB", FGROUP_NONE, 0 },
{ 0x14, 1, 1, 0, 0, 1, NULL, FCODE_PatchFunc, "GetImmediateBuffer", "Datel", FGROUP_NONE, 0 },
{ 0x20, 2, 2, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDLowStopMotor", "Datel", FGROUP_NONE, 0 },//DVDLowStopMotor
{ 0x58, 3, 6, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDInquiryAsync", "Datel", FGROUP_DVDInquiryAsync, 0 },
// { 0x58, 3, 6, 0, 0, 0, DVDInquiryAsync, DVDInquiryAsync_size, "DVDInquiryAsync", "Datel", FGROUP_DVDInquiryAsync, 0 },
{ 0x6C, 4, 7, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDLowReadDiskID", "Datel", FGROUP_NONE, 0 },
{ 0x60, 3, 7, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDLowRead", "Datel", FGROUP_DVDLowRead, 0 },
{ 0x3C, 3, 4, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDSeekAbsAsyncPrio", "Datel", FGROUP_NONE, 0 },
// { 0x3C, 3, 4, 0, 0, 0, DVDSeekAbsAsyncPrio,DVDSeekAbsAsyncPrio_size, "DVDSeekAbsAsyncPrio", "Datel", FGROUP_NONE, 0 },
{ 0x20, 2, 2, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDEnableInterrupts", "Datel", FGROUP_NONE, 0 },
{ 0xE4, 12, 14, 1, 1, 5, NULL, FCODE_PatchFunc, "DVDEnableInterrupts", "DatelB", FGROUP_NONE, 0 },
{ 0x30, 2, 3, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDEnableInterrupts", "DatelC", FGROUP_NONE, 0 },
{ 0x24, 2, 3, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDGetDriveStatus", "Datel", FGROUP_NONE, 0 },
// { 0x24, 2, 3, 0, 0, 0, DVDGetDriveStatus, sizeof(DVDGetDriveStatus), "DVDGetDriveStatus", "Datel", FGROUP_NONE, 0 },
// { 0x190, 15, 12, 2, 8, 15, NULL, FCODE_PatchFunc, "__DVDInterruptHandler","Datel", FGROUP_NONE, 0 },
{ 0x18, 2, 1, 0, 0, 0, NULL, FCODE_GetCoverStatus, "GetCoverStatus", "Datel", FGROUP_NONE, 0 },
{ 0x34, 1, 2, 0, 0, 3, NULL, FCODE_PatchFunc, "DVDAudioDisable", "Datel", FGROUP_NONE, 0 },
{ 0x6C, 8, 8, 3, 0, 4, NULL, FCODE_PatchFunc, "CallDVDAudioDisable", "Datel", FGROUP_NONE, 0 },
{ 0x3C, 6, 4, 1, 0, 2, NULL, FCODE_PatchFunc, "GetImmBufferAndStore", "Datel", FGROUP_NONE, 0 },
{ 0x80, 10, 8, 4, 0, 2, NULL, FCODE_PatchFunc, "DVDReadHeader", "Datel", FGROUP_NONE, 0 },
{ 0x70, 10, 9, 2, 1, 2, NULL, FCODE_PatchFunc, "DVDWait", "Datel", FGROUP_NONE, 0 },
{ 0x58, 8, 8, 1, 0, 2, NULL, FCODE_PatchFunc, "ClearCoverInterrupt", "Datel", FGROUP_NONE, 0 },
{ 0x48, 2, 1, 0, 0, 3, NULL, FCODE_PatchDiscFunc, "GetAndClearError", "Datel", FGROUP_NONE, 0 },
// { 0x134, 19, 10, 0, 11, 7, NULL, FCODE_PatchDiscFunc, "__DVDInterruptHandler","Datel", FGROUP_NONE, 0 },
{ 0x14, 1, 1, 0, 0, 0, NULL, FCODE_PatchFunc, "GetImmediateBuffer", "Datel", FGROUP_NONE, 0 },
{ 0x98, 7, 7, 0, 1, 1, NULL, FCODE_PatchFunc, "DVDEnableInterrupts", "DatelD", FGROUP_NONE, 0 },
// Same as DVDLowStopMotor, but patch is the same so ok
// { 0x20, 2, 2, 0, 0, 0, NULL, FCODE_PatchFunc, "DVDGetDriveStatus", "Datel", FGROUP_NONE, 0 },
{ 0x98, 9, 8, 2, 1, 6, NULL, FCODE_PatchDiscFunc, "_CallDVDIntHandler", "Datel", FGROUP_NONE, 0 },
{ 0x74, 8, 8, 3, 0, 4, NULL, FCODE_PatchFunc, "CallDVDAudioDisable", "Datel", FGROUP_NONE, 0 },
};

//FuncPattern[0x01300118] : 0xF8, 8, 6, 7, 1, 6
//FuncPattern[0x013006CC] : 0x48, 2, 1, 0, 0, 3
//FuncPattern[0x01300718] : 0x134, 19, 10, 0, 11, 7
//FuncPattern[0x01300888] : 0x14, 1, 1, 0, 0, 0
//FuncPattern[0x01300B28] : 0x98, 7, 7, 0, 1, 1
//FuncPattern[0x01300BE8] : 0x98, 9, 8, 2, 1, 6
//FuncPattern[0x01300CBC] : 0x74, 8, 8, 3, 0, 4
//FuncPattern[0x00003218] : 0x48, 9, 2, 3, 0, 3
//FuncPattern[0x00018CE0] : 0x14, 1, 1, 0, 0, 1
//FuncPattern[0x00018CF8] : 0x20, 2, 2, 0, 0, 0
//FuncPattern[0x00018D1C] : 0x4C, 6, 6, 3, 0, 3
//FuncPattern[0x00018D6C] : 0x58, 3, 6, 0, 0, 0
//FuncPattern[0x00018DC8] : 0x70, 8, 6, 5, 1, 3
//FuncPattern[0x00018E3C] : 0x6C, 4, 7, 0, 0, 0
//FuncPattern[0x00018EAC] : 0x78, 8, 8, 4, 0, 5
//FuncPattern[0x00018F28] : 0x60, 3, 7, 0, 0, 0
//FuncPattern[0x00018F8C] : 0x4C, 6, 6, 3, 0, 3
//FuncPattern[0x00018FDC] : 0x3C, 3, 4, 0, 0, 0
//FuncPattern[0x0001901C] : 0x1C, 2, 2, 1, 0, 2
//FuncPattern[0x0001903C] : 0x20, 2, 2, 0, 0, 0
//FuncPattern[0x00019060] : 0x60, 9, 6, 4, 0, 3
//FuncPattern[0x000190C4] : 0x7C, 10, 6, 4, 0, 2
//FuncPattern[0x00019144] : 0x2C, 3, 3, 3, 0, 2
//FuncPattern[0x00019178] : 0xE4, 12, 14, 1, 1, 5
//FuncPattern[0x00019260] : 0x30, 2, 3, 0, 0, 0
//FuncPattern[0x00019294] : 0x24, 2, 3, 0, 0, 0
//FuncPattern[0x000192BC] : 0x190, 15, 12, 2, 8, 15
//FuncPattern[0x0001947C] : 0x18, 2, 1, 0, 0, 0
//FuncPattern[0x00019498] : 0x34, 1, 2, 0, 0, 3
//FuncPattern[0x000194D0] : 0x6C, 8, 8, 3, 0, 4
//FuncPattern[0x00019540] : 0x34, 5, 3, 1, 1, 2
//FuncPattern[0x00019634] : 0x3C, 6, 4, 1, 0, 2
//FuncPattern[0x00019780] : 0x80, 10, 8, 4, 0, 2
//FuncPattern[0x00019804] : 0x70, 10, 9, 2, 1, 2
//FuncPattern[0x00019878] : 0x58, 8, 8, 1, 0, 2


Return to “GameCube”

Who is online

Users browsing this forum: No registered users and 2 guests