Sega CDC Library recreated

I guess I was rather curious as to how the cd block functioned in more depth, so I decided to put my disassembly knowledge to the test and used sega's CDC library as a basis for writing my own library. See attached file.

As you can see it's basically the recreation of the source that sega decided not to release in any form. Hopefully this will help out anyone trying to understand how the cd block works.

I also spent some time going through the bios and noticed there's actually 3 cd block commands that aren't used anywhere else aside from the bios. They are: 0xE0, 0xE1, and 0xE2. When the saturn is turned on, and validates the ip of the said game, it calls 0xE0 and 0xE1 commands before it reads in the first program. Ironically enough, psy-q's "cd block unlocking" function is nothing more than a couple of bios calls that end up calling those two commands(and from the looks of it, potentially 0xE2 as well under the right conditions). Anyways, I tried my best to implement those commands as well(they're under cdc_unk.c).

Aside from CDC_CdInit and CDC_TgetToc, I haven't tested out every single function to verify that they work 100% correctly so please keep that in mind.

Cyber Warrior X
 
One of the 0xEX command (I think it's the 0xE1 one) is used by the ST-V game Sports Fishing 2, and it loops after that ...

Thanks for your work, I'm sure it'll be useful :)
 
ExCyber: Thanks :)

Runik: It could be that it's waiting for a specific hirq bit to be set. Or maybe you're returning the wrong values in the command registers.

Cyber Warrior X
 
*waves* Hi cyber ^^;

real interesting stuffs ya got. if ya want i can send it off to you know who to look at and see if he can do anything with it :p, or better yet you have his addy, you can let him know : )
 
I guess I was rather curious as to how the cd block functioned in more depth, so I decided to put my disassembly knowledge to the test and used sega's CDC library as a basis for writing my own library.

So you plan to write a higher level cd lib ? There are some simple functions that would be very usefull, like cd data transfert to some adress (direct or via dma transfert using a user provided buffer) and audio cd playing.

I have some problems with audio cd playing. I have this function (the comments show structures affected by the macros).

Code:
int track = 3;

CDC_CdInit(0x00,0x00,0x05,0x0f);

 // (&((ply)->start))->ptype = CDC_PTYPE_TNO;  

 CDC_PLY_STYPE(ply) = CDC_PTYPE_TNO;   

 // (&(((ply)->start)))->pbody.trkidx.tno)  = 2;  

 // was :  CDC_PLY_STNO(ply) = 2;     

 CDC_PLY_STNO(ply) = track;     

 // (&((ply)->start))->pbody.trkidx.idx = 1;

 CDC_PLY_SIDX(ply) = 1;

 // (&((ply)->end))->ptype = CDC_PTYPE_TNO;

 CDC_PLY_ETYPE(ply) = CDC_PTYPE_TNO;

 // (&((ply)->end))->pbody.trkidx.tno = 2;

 CDC_PLY_ETNO(ply) = track;

 // (&((ply)->end))->pbody.trkidx.idx = 99;

 CDC_PLY_EIDX(ply) = 99;

 /*

  #define CDC_PM_DFL     0x00  

  #define CDC_PM_REP_NOCHG  0x7f  

  #define CDC_PM_PIC_NOCHG  0x80  

  #define CDC_PM_NOCHG    -1   

  ((ply)->pmode) = 0x00 + 10;

 */

 // CDC_PLY_PMODE(ply) = CDC_PM_DFL+ 10;

 CDC_PLY_PMODE(ply) = 10;

 CDC_CdPlay(ply);

Among the numerous things I don't understand is the cdc_ply_pmode. Do you know if it has something to do with the fact that the track is always looping ?
 
So you plan to write a higher level cd lib ? There are some simple functions that would be very usefull, like cd data transfert to some adress (direct or via dma transfert using a user provided buffer) and audio cd playing.

I haven't really thought about that. Considering this is a drop in replacement, you could essentially use the GFS library. Of course if anyone wants to write one, I'm sure a lot of people would appreciate it.

I have some problems with audio cd playing. I have this function (the comments show structures affected by the macros).

Among the numerous things I don't understand is the cdc_ply_pmode. Do you know if it has something to do with the fact that the track is always looping ?

Most likely, though I'm not entirely sure myself how it works since the information I have is rather vague.

Cyber Warrior X
 
I made some interesting discoveries today which I figured people would like to know:

As I stated in my original post, cd block commands 0xE0, 0xE1, 0xE2 were copyprotection related, but I really didn't understand how each was used. Anyways, I spent some time today writing a test program that allowed me to test each of the commands with different args, etc.

Calling command 0xE0 with CR2(or arg R4 when refering to my cdcrep library) set to 0 actually causes the laser pickup to go to the outside of the disc, authenticates the disc as a saturn disc(as far as I can tell) then moves the pickup back inside. Calling 0xE0 with CR2 set to 1 appears to initiate a video cd check(at least that's my theory based on the returned hirq value)

Calling 0xE1 seems to return the status of the saturn/vcd authentication. Once again you use CR2(or arg R4) to specify which status you want returned. If the saturn disc check passed, CR2 is set to 4 on return. If the vcd check passed, CR2 is set to 2 on return.

0xE2 seems to be related to the vcd check as well. From what I understood from running the bios through a debugger, after it's called it retrieves 2 sectors from somewhere and stores them in the cd buffer.

Anyways, post your thoughts.

Cyber Warrior X
 
Originally posted by CyberWarriorX@Sep 1, 2004 @ 11:27 PM

Calling command 0xE0 with CR2(or arg R4 when refering to my cdcrep library) set to 0 actually causes the laser pickup to go to the outside of the disc, authenticates the disc as a saturn disc(as far as I can tell) then moves the pickup back inside. Calling 0xE0 with CR2 set to 1 appears to initiate a video cd check(at least that's my theory based on the returned hirq value)

After sending command 0xe0 with CR2=0 what is the cdblock response?

Sport fishing 2 after 0xe0 command loops reading cdblock register

Thanks

ANY
 
Initially after executing the command registers are set to 0xFFFF. Then obviously due to periodic response they are set to the default status report. The drive status portion of CR1 is set to BUSY, then after the copyprotection ring is read and the laser pickup starts moving back, it's set to SEEK. After it's all finished it's returned to PAUSE status and the hirq flags CSCT and EFLS are set. What I did initially for yabause though was just return the default status report and set the CSCT and EFLS hirq flags and it works fine.

I know you'll eventually ask about 0xE0 with CR2=1, so I'll tell you how that one works too. Like the other one, it returns with all the command registers set to 0xFFFF, then pretty much immediately returns a default status report with PAUSE set. At which point it sets the MPED hirq flag.

Cyber Warrior X
 
You're still on Sports Fishing 2 Any ? :p

I have the same problem with Saturnin ...

I'll try this to see what happens :)
 
Well, I finally figured out what the last 0xEx series command is for. 0xE2 actually initiates a transfer of the mpeg card's mask rom to the cd buffer, which can then be retrieved using Get Sector/Get then Delete Sector, etc. I also wrote a program(attached to this post) using a bios function that does all that. The arguments for the bios function are as follows: offset in rom(in sectors), size of read(in sectors), output buffer. The function returns the size of data in bytes on success, and < 0 on failure.

I'm sorry if anyone has problems with the program as it is a bit buggy(especially the par stuff). I put it together in a couple hours and I figured it'd be more useful to people as a resource for information rather than as tool.

Cyber Warrior X
 

Attachments

  • mpgromdump.zip
    39.9 KB · Views: 186
  • mpgromdump.zip
    39.9 KB · Views: 201
New CDCREP release:

New in 1.00rc1

--------------

-Moved cdcmd_struct to sega_cdc.h, as well as added CDSUB_UpdStatus and CDSUB_UpdCdstat to allow people to test custom commands

-Fixed a bug in CDC_AbortFile

-Fixed a status bug in doCmdRsp

-Changed some code to use the defines from sega_cdc.h: It just makes it easier to understand.

-General code cleanups

-Changed CDC_E0 to CDC_AuthDev, CDC_E1 to CDC_GetDevAuthStat, and CDC_E2 to CDC_MpGetRom.

-Added some notes on CDC_GetHwInfo, CDC_AuthDev, CDC_GetDevAuthStat, and CDC_MpGetRom

-Fixed a bug in CDC_GetDevAuthStat

Special thanks to Dave Midknight for spotting the CDC_AbortFile bug!

Oh yeah, if anyone is interested in writing or has written some programs I could include as sample programs, let me know.

Cyber Warrior X
 

Attachments

  • cdcrepv100rc1.zip
    30.8 KB · Views: 154
  • cdcrepv100rc1.zip
    30.8 KB · Views: 146
  • cdcrepv100rc1.zip
    30.8 KB · Views: 156
If you find out how to run own code on the CD block's SH1, please let me know.

Is the SH1 somewhat hardwired to a program rom? If that's the case, could it be replaced by a bigger one, a writeable flashrom for example?

When I remember the Scavenger games Scorcher and Amok, they don't need CD access for sound, so the SH1 would be unused in such cases...
 
Originally posted by ExCyber@Thu, 2004-12-02 @ 09:52 PM

Its part number indicates that it is a ROM MCU, i.e. the program ROM it boots from is internal.

[post=124943]Quoted post[/post]​


Ah, what a pitty! It's really just used as a controller....

Thanks for the info!
 
Cyber Warrior X,

have you noticed that the CDC replacement is bigger than the original one? I tried compiling with -Os but it's still significantly bigger in size. Is there a chance to make it smaller?
 
Has anyone ever tried using the cdc replacement? I tried it today with my minimal CD browser, but it didn't work. The cdroot directory content wasn't read.

I would like to use it, it's the last piece to get 100% self-compiled code.
 
Back
Top