Reading subcode data on the MegaCD

Ask anything your want about Mega/SegaCD programming.

Moderator: Mask of Destiny

Post Reply
Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Reading subcode data on the MegaCD

Post by Nemesis » Mon Jan 06, 2014 7:48 pm

The MegaCD has bios routines for reading subcode data. The following functions are exposed and documented in CDBIOS.INC:
-BIOS_SCDINIT
-BIOS_SCDSTART
-BIOS_SCDSTOP
-BIOS_SCDSTAT
-BIOS_SCDREAD
-BIOS_SCDPQ
-BIOS_SCDPQL

And there's also BIOS_CDCSETMODE, which seems either related or another way of getting subcode data, but try as I might, I've never been able to get subcode reading working at all. Maybe I'm doing something dumb, but I never seem to be able to get anything out. Has anyone ever attempted to read subcode data on the MegaCD? Anyone got any working example code? Do any games actually use these functions?

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Re: Reading subcode data on the MegaCD

Post by TascoDLX » Tue Jan 07, 2014 1:25 pm

Well, the BIOS uses the subcode functions for CD+G. In fact, the R-W data delivered by the subcode functions is actually deinterleaved CD+G data, though that's not mentioned in the docs. If you want the full subcode data, you have to read it out yourself from the gate array buffer during the SCD-INT-- some of that info is in the docs.

I haven't experimented with subcodes, but I'm more than slightly familiar with the BIOS. When reading subcodes, the BIOS calls CDCSTARTP, which has the same parameters as CDCSETMODE (the flags expected in d1 are the same) except it resets buffering, reconfigures the CDC and all that junk. The BIOS uses d1=0E for its CD+G mode, but I think it also reads out audio data for visualization so that may be part of it as well.

I would imagine a good indicator that subcode readout is working is if SCD-INT (subcpu level 6) gets triggered, then you should be able to read out the subcode buffer. Of course, that data is bit interleaved so you get 98 bytes of pqrstuvw and you'll have to 'extract' whichever channels you want.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Jan 07, 2014 10:33 pm

I finally managed to get something out of the hardware last night while testing this stuff, but I had limited time to work on it, so I wasn't able to verify my results, but still, I managed to initialize subcode reading and get something out of the SCDREAD and SCDPQ functions. I'm still not quite sure of the data that's being returned from these functions though. By my calculations, there should be 12 bytes of subcode data for each of the 8 subcode channels per sector, and these functions only return 32 bytes between them :(. I guess you know about this TascoDLX? Do you know exactly what segment of subcode data is returned by these functions? Can you give me a pointer as to how I'd capture the full subcode data during the subcode interrupt? Is it possible to pull that same data out of the scratch buffer I provide to the bios for the SCDINIT function?

I did manage to get reading the raw 2352 byte sector contents working by calling CDCSETMODE to put it into CD-DA mode, although the LC8950 seems to return the sync block at the end of the sector for some reason rather than the beginning, I'll have to check its register settings over to see what might be causing that, or if that's expected behaviour. I'm also not sure if error correction is enabled or disabled on the LC8950 if I instruct the bios to select CD-DA mode, I'll have to dig through the bios routines more thoroughly. I really want the data to not have CRC and RS error correction applied, so that I really could read out digital audio data. It also seems like CDCSETMODE needs to be set after a call to the ROMREAD functions if you're using them, but before CDCREAD. ROMREAD seems to be resetting the CDC mode, but I couldn't track down exactly where after looking through the code.

As a note, neither subcode reading or CD-DA mode work correctly in any emulators, it's hardware only for this stuff. CD mode 2 should work, it's the returning of the sync pattern block after all the other sector data that fails in emulators, but if you need to read out the full 2352 byte sector, nothing handles that right now.

My goal is to be able to read out, or reliably reconstruct, the full raw 3234 byte CD sector data, including the 2352 data block, subcode data, and ideally the CD error correction bytes and sync data too if possible (although this is less important). I'm happy to hit the LC8950 for this data directly if I have to and bypass the bios entirely, but I've only just started really studying the LC8950 documentation and I'm not sure how to do that just yet.

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Wed Jan 08, 2014 6:25 am

Nemesis wrote:I finally managed to get something out of the hardware last night while testing this stuff, but I had limited time to work on it, so I wasn't able to verify my results, but still, I managed to initialize subcode reading and get something out of the SCDREAD and SCDPQ functions. I'm still not quite sure of the data that's being returned from these functions though. By my calculations, there should be 12 bytes of subcode data for each of the 8 subcode channels per sector, and these functions only return 32 bytes between them :(. I guess you know about this TascoDLX? Do you know exactly what segment of subcode data is returned by these functions?
If you're looking for R-W channels, you don't want to know. Like I said, SCDREAD returns CD+G data which is interleaved among 3 sectors, so it's unlikely to make sense except for CD+G. As for Q channel, it's pretty much as you'd expect if you're familiar with ECMA-130 (the Sega docs have the format slightly wrong). The P channel flag is inserted into the ZERO field of Q-mode 1 (7th byte overall). Also, I believe reading of Q-modes 2 & 3 is broken because the P-channel flag overwrites other data. It appears to be a bug in the v2 BIOS but I don't about any other versions.
Nemesis wrote:Can you give me a pointer as to how I'd capture the full subcode data during the subcode interrupt? Is it possible to pull that same data out of the scratch buffer I provide to the bios for the SCDINIT function?
I would ignore the scratch buffer. You could probably just look what the BIOS SCD-INT handler does. The gate array subcode buffer is at $FF8100 thru $FF817F. You only have to copy out the first 98 bytes. You can adjust the buffer pointer via the reg at $FF8068, but you should probably keep it at zero. The only other thing is that you will need to deinterleave the data yourself. Each byte of subcode data will be PQRSTUVW. So, if you want Q-channel, you take bit 6 of the 1st byte, bit 6 of the 2nd byte, bit 6 of the 3rd byte, etc.
Nemesis wrote:I did manage to get reading the raw 2352 byte sector contents working by calling CDCSETMODE to put it into CD-DA mode, although the LC8950 seems to return the sync block at the end of the sector for some reason rather than the beginning, I'll have to check its register settings over to see what might be causing that, or if that's expected behaviour. I'm also not sure if error correction is enabled or disabled on the LC8950 if I instruct the bios to select CD-DA mode, I'll have to dig through the bios routines more thoroughly. I really want the data to not have CRC and RS error correction applied, so that I really could read out digital audio data. It also seems like CDCSETMODE needs to be set after a call to the ROMREAD functions if you're using them, but before CDCREAD. ROMREAD seems to be resetting the CDC mode, but I couldn't track down exactly where after looking through the code.
Calling CDCSETMODE doesn't change the CDC settings. It only changes how much data is fetched from the CDC, so that's treading into undocumented behavior. I would use CDCSTARTP to be sure. If you're doing ROMREAD, you would wait until the BIOS status word is 0101, then call CDCSTARTP. In theory, that should work fine.
Nemesis wrote:As a note, neither subcode reading or CD-DA mode work correctly in any emulators, it's hardware only for this stuff. CD mode 2 should work, it's the returning of the sync pattern block after all the other sector data that fails in emulators, but if you need to read out the full 2352 byte sector, nothing handles that right now.
I know subcodes work in Fusion because CD+G works in Fusion. Not sure what you mean by CD-DA mode. If you're talking about the CDC, there's a raw mode which includes 288 bytes of ECC/EDC data, and there's Mode 2 which gives you the entire 2352. I think you'd use Mode 2 to get CD-DA data, though I'd imagine you would normally disable error correction when dealing with CD-DA. (Is any of this documented? I have no idea!)
Nemesis wrote:My goal is to be able to read out, or reliably reconstruct, the full raw 3234 byte CD sector data, including the 2352 data block, subcode data, and ideally the CD error correction bytes and sync data too if possible (although this is less important). I'm happy to hit the LC8950 for this data directly if I have to and bypass the bios entirely, but I've only just started really studying the LC8950 documentation and I'm not sure how to do that just yet.
I'd say the most you'll be able to read out will be 2352+98. The remainder is mostly frame parity stuff which is strictly defined, so you could reconstruct it (although I can't imagine why). Also I'm not sure that data doesn't get consumed by the CD-DSP anyway. I think the LC receives scrambled sectors and subcode data separately.

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

Post by Eke » Wed Jan 08, 2014 6:08 pm

This is what I kind of figured from analysing the available Mega CD schematics and L8951x user manual:

- CDC (L8951x ) only get (serially) 2352-bytes sector data from the CD DSP: subcode data is sent to Mega CD ASIC only

- the same data is sent to Mega CD ASIC which passes it to CD Audio DAC only if this is CD-DA (using D/M signal from CD DSP or CDD custom processor, not sure anymore).

- 2352-bytes sector is scrambled in case of Mode 1 or Mode 2 data (this is part of of CD-ROM specification) and unscrambled in case of CD-DA tracks: descrambling can be disabled through one of the L8951x CTRL register.

- Mode 1 or Mode 2 decoding and error correction is also configurable through L8951x CTRL registers: you can get the raw 2352 bytes block by disabling EDC and enabling writes to RAM Buffer

- when written to RAM buffer, the pointer registers points to the start of the 2048 or 2236 data block, i.e after the 16-byte header of the current block: the header of the next block is likely read at that time too (I remember there are functions in later L8951x models to tell infos on the next coming block)

Also I am not sure what you are refering to with the 3234 raw frame but EFM demodulation and lower level CIRC error correction are done internally by the CD DSP (could not found CXD1167Q datasheet but KS9210 chip seems pin compatible). The DSP can only be controlled from the 4-bit custom microprocessor (CDD), which afaik use a custom ROM program which cannot be changed (neither dumped ?) and is not controllable from 68k beside the high-level CDD commands

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jan 15, 2014 4:29 am

Thanks a lot for your help guys. I'm investigating this so that I can dump as much data off the MegaLD disks as possible as part of that dumping project, because there'll probably never be a chance to redump most of these disks. I think between what you've both said I understand enough to attempt a new dumping process. I'll post some code if I get something that works, it could be useful to have around for reference.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Apr 29, 2014 4:45 pm

Ok, I could really use some help here again. To recap, at this stage I have two goals:
1. Read 2352-byte CD sector data out (CD-DA mode)
2. Read subcode data for each sector

Here's my current working CD sector reading routines. This is the code I use for reading a block of normal 2048-byte CD sectors:

Code: Select all

;----------------------------------------------------------------------------------------
;Reads the specified number of sectors from a disk
;Input:
;-a5 - Pointer to params struct
;struct Params
;{
;  long startSectorNumber - Logical sector number to start read from
;  long sectorCopyCount - Number of sectors to transfer
;  long dataDestination - Destination address to write sector data to
;  long headerDestination - Destination address to write header data to
;}
;----------------------------------------------------------------------------------------
ReadCDData:
	BIOS_CDCSTOP		;Ensure that no other CD data transfer is currently occurring

	move.b	#$03, $FF8004	;Set the CDC device destination to subcpu read. Required before calling BIOS_CDCREAD below.

	movea.l	a5, a0		;Set the initial sector number and count of sectors to transfer
	BIOS_ROMREADN		;Start the read operation

	ReadCDDataReadLoop:

	move.w  #$8000,d5
	ReadCDDataCheck_CDCSTAT:
	BIOS_CDCSTAT		;Check if more data is ready to read
	bcc ReadCDDataCheckExit_CDCSTAT
	dbf d5,ReadCDDataCheck_CDCSTAT
	bra ReadCDDataFailed
	ReadCDDataCheckExit_CDCSTAT:

	move.w  #$8000,d5
	ReadCDDataCheck_CDCREAD:
	BIOS_CDCREAD	;Prepare for a data read from the CDC buffer
	bcc ReadCDDataCheckExit_CDCREAD
	dbf d5,ReadCDDataCheck_CDCREAD
	bra ReadCDDataFailed
	ReadCDDataCheckExit_CDCREAD:

	move.w  #$8000,d5
	ReadCDDataCheck_CDCTRN:
	movea.l	8(a5), a0	;Set the destination for the sector data (should be 0x800 bytes)
	lea	12(a5), a1		;Set the destination for the header data (4 bytes)
	BIOS_CDCTRN
	bcc ReadCDDataCheckExit_CDCTRN
	dbf d5,ReadCDDataCheck_CDCTRN
	bra ReadCDDataFailed
	ReadCDDataCheckExit_CDCTRN:

	;Acknowledge the read has been completed
	BIOS_CDCACK

	;Update the target address, starting sector, and remaining sector count, and
	;repeat the loop if more sectors are remaining.
	addi.l	#$800, 8(a5)
	addq.l	#1, (a5)
	subq.l	#1, 4(a5)
	bne	ReadCDDataReadLoop

	ReadCDDataFailed:
	rts
And here's the code I use for reading 2353-byte CD-DA sector data:

Code: Select all

;----------------------------------------------------------------------------------------
;Reads the specified number of sectors from a disk in raw mode
;Input:
;-a5 - Pointer to params struct
;struct Params
;{
;  long startSectorNumber - Logical sector number to start read from
;  long sectorCopyCount - Number of sectors to transfer. Each raw sector is 2352 (0x930) bytes
;  long rawDestination - Destination address to write raw sector data to
;}
;----------------------------------------------------------------------------------------
ReadCDDataRaw:
	BIOS_CDCSTOP		;Ensure that no other CD data transfer is currently occurring

	move.b	#$03, $FF8004	;Set the CDC device destination to subcpu read. Required before calling BIOS_CDCREAD below.

	movea.l	a5, a0		;Set the initial sector number and count of sectors to transfer
	BIOS_ROMREADN		;Start the read operation

	ReadCDDataRawReadLoop:

	move.w  #$8000,d5
	ReadCDDataRawCheck_CDCSTAT:
	BIOS_CDCSTAT		;Check if more data is ready to read
	bcc ReadCDDataRawCheckExit_CDCSTAT
	dbf d5,ReadCDDataRawCheck_CDCSTAT
	bra ReadCDDataRawFailed
	ReadCDDataRawCheckExit_CDCSTAT:

	;Set the CDC read mode to CD-DA mode, to obtain the full 2352 bytes of sector data.
	move.w	#$0002, d1
	BIOS_CDCSETMODE

	move.w  #$8000,d5
	ReadCDDataRawCheck_CDCREAD:
	BIOS_CDCREAD	;Prepare for a data read from the CDC buffer
	bcc ReadCDDataRawCheckExit_CDCREAD
	dbf d5,ReadCDDataRawCheck_CDCREAD
	bra ReadCDDataRawFailed
	ReadCDDataRawCheckExit_CDCREAD:

	;Read the address to write the next raw sector data to
	movea.l	8(a5), a0

	;Set the header target location to be the same as the sector target location. This is
	;safe, since the CDCTRN function writes data to the header target before writing data
	;to the sector data target.
	movea.l	a0, a1

	;Read the sector
	move.w  #$8000,d5
	ReadCDDataRawCheck_CDCTRN:
	BIOS_CDCTRN
	bcc ReadCDDataRawCheckExit_CDCTRN
	dbf d5,ReadCDDataRawCheck_CDCTRN
	bra ReadCDDataRawFailed
	ReadCDDataRawCheckExit_CDCTRN:

	;Acknowledge the read has been completed
	BIOS_CDCACK

	;Update the target address, starting sector, and remaining sector count, and
	;repeat the loop if more sectors are remaining.
	addi.l	#$930, 8(a5)
	addq.l	#1, (a5)
	subq.l	#1, 4(a5)
	bne	ReadCDDataRawReadLoop

	ReadCDDataRawFailed:
	rts
All this is written based on the manual and hardware experimentation. Now the first routine is fairly standard. The second one is where things go a bit off the rails. There's no documentation on exactly when you should call the CDCSETMODE routine. I found the only time I could get it to do anything useful was if I called it for each sector, after CDCSTAT reported that a sector was available. I have no idea if this is how this routine is supposed to be used, but I found if I called it here, I did get returned 2352 bytes of sector data when I called CDCTRN afterwards. That said, the output from CDCTRN isn't entirely correct. I seem to get returned the current sector from the sector header, after the sync data, then for the last 12 bytes of the 2352 bytes of returned sector data, I get returned what appears to be the sync data of the following sector. The sync data being messed up isn't a huge problem, since the sync data is known and needs to be present in order for the drive to be able to locate the sector at all, so I can just insert what I know the sync data should be for the first sector and chop off the trailing 12 bytes, but I'm wondering if there's something else I should be doing in order to read 2352 byte sector data which will avoid this problem.

I'm also completely unsure about the state of the actual hardware error correction in my attempts. Even though I'm reading out 2352 bytes of data, is the hardware still thinking it's reading mode 1 CD data, and will it therefore attempt to use EDC/ECC data to perform error correction on the data if I actually attempt to read mode 2 CD sectors?

There's also the whole issue of reading out subcode data. The BIOS routines don't seem to expose the full subcode data out, so in order to capture the data, I need to snag them from the subcode buffer directly from the hardware. How and when can I do this though? There's a level 6 interrupt fired when the subcode data is buffered I believe, but when does this actually occur in relation to my read calls? What's a real example in code of how and when I can read the subcode data out?


I get the feeling I need to perform reading at a lower level to get the results I want. I'm currently using ROMREADN, which is a high-level bios CD reading routine, but so far it's the only way I've been able to successfully read data. Do I need to go a level deeper? CDBIOS.INC states that ROMREAD calls CDCSTART to begin a read operation, and TascoDLX indicated I should use CDCSTARTP, which accepts the CDC mode as a parameter, but I couldn't find any examples of how and where to actually use this lower level function to read CD data, and all my attempts to figure out how to use it through experimentation have failed.

I also basically don't understand the way the BIOS reads, buffers, and sends sector data to my code, which doesn't help matters. What do CDCSTAT, CDCREAD, and CDCTRN actually do, in a nutshell, and where is the actual data at each stage of the process? It seems to me that the data has already been buffered somewhere by the BIOS by the time CDCSTAT returns "true", is that correct?


So, at this stage, I have a few questions:
1. What is the "correct" sequence of BIOS calls to read CD-DA data using the ROMREAD bios functions?
2. What is a working sequence of BIOS calls to read CD data without using ROMREAD?
3. How, where, and when can the raw subcode buffer be read in this process?

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Wed Apr 30, 2014 4:04 am

I only skimmed your post. I'll come back to it, but this part...
Nemesis wrote:I also basically don't understand the way the BIOS reads, buffers, and sends sector data to my code, which doesn't help matters. What do CDCSTAT, CDCREAD, and CDCTRN actually do, in a nutshell, and where is the actual data at each stage of the process? It seems to me that the data has already been buffered somewhere by the BIOS by the time CDCSTAT returns "true", is that correct?
CDC manages its own buffer memory. When the SUB receives L5 INT, this is the CDC telling the SUB, "I decoded another sector; it's in my buffer". The SUB only receives a pointer to the sector data within that buffer (note, the SUB can't access this buffer directly). The SUB puts this info in its queue.

CDCSTAT is the SUB asking, "Is there anything in my queue?"

CDCREAD negotiates a transfer of sector data w/ the CDC. (FYI, based on the v2 BIOS, this call only ever fails if the SUB's queue is empty.)

CDCTRN is only called by the SUB if it previously told the CDC, "I'll handle the transfer" -- i.e., it wrote 03 to reg @FF8004 ("SUB CPU READ" mode) prior to CDCREAD. Other transfer modes are DMA that the CDC handles.

CDCACK, naturally, is the SUB telling the CDC, "Transfer done. Thanks!"

I believe that setting the CDC control regs to determine what data is read (2352 raw vs. 2048 cooked) must be done prior to decode. Basically the SUB would clear its queue when changing this.

If I may speculate, it's possible what you'll wind up doing is calling MSCPLAY on the data sector, then calling CDCSTARTP to get the data flowing. I'll have to look at the bios again, but that may be what was originally intended.

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Thu May 01, 2014 7:51 am

Nemesis wrote:There's no documentation on exactly when you should call the CDCSETMODE routine. I found the only time I could get it to do anything useful was if I called it for each sector, after CDCSTAT reported that a sector was available.
Not to quote myself, but... "Calling CDCSETMODE doesn't change the CDC settings. It only changes how much data is fetched from the CDC, so that's treading into undocumented behavior." It seems to return all the data, so that's somewhat impressive. But like you said, it's almost certainly error-corrected.

I stand by my suggestion of calling MSCPLAY (or any variant) on the data track, then calling CDCSTARTP. Or calling MSCSEEK, then CDCSTARTP, then MSCPAUSEOFF. Or anything to that effect. Also, use CDBSTAT loops when necessary.
Nemesis wrote:There's also the whole issue of reading out subcode data. The BIOS routines don't seem to expose the full subcode data out, so in order to capture the data, I need to snag them from the subcode buffer directly from the hardware. How and when can I do this though? There's a level 6 interrupt fired when the subcode data is buffered I believe, but when does this actually occur in relation to my read calls? What's a real example in code of how and when I can read the subcode data out?
Here's how I understand the subcode buffer to work:

Buffer
- located @ FF8100 (in gate array)
- mirrored @ FF8180
- 64 words [128 bytes]
- circular buffer

Top address
- byte @ FF8069
- offset into the buffer
- points to the current subcode set [98 bytes]
- bit 7 is a flag that indicates overrun

How the overrun flag works:

The buffer has room for one set of subcodes (49 words [98 bytes]) plus 15 words [30 bytes] from the next set. The 16th word of the next set will overwrite the 1st word of the last set, at which point the overrun flag is raised -- there is no longer a complete set of subcodes in the buffer, so the top address is invalid. The overrun flag is not lowered until the last word of the next set of subcodes is written.

Level 6 INT is triggered once per set/sector (or should be, at least).

Here's my underwhelming pseudo-code for reading subcodes:

Code: Select all

proc L6INT_HANDLER : array_out[]
  
  <byte> buffer_offset := read_byte(0xFF8069)

  if buffer_offset > 0x7F then
    exit :ERROR::OVERRUN
  endif
  
  <ptr> source_addr := 0xFF8100 + buffer_offset  (*NOTE: subcode buffer is mirrored @ 0xFF8180*)

  for n := 0 thru 97 do (*NOTE: the last 2 bytes are sync and can be ignored*)
    array_out[n] := read_byte(source_addr + n)
  endfor

endproc
No guarantees though. This is a little less safe than what the bios does, but if you want to do some checking, you can extract the Q channel in order to figure out sector addresses and do CRC checks.

Also, you probably shouldn't bother trying to match subcodes with their corresponding sector data. If possible, just read it out as a separate stream and sort it out later.

Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake » Wed May 21, 2014 5:11 am

I've been out of the loop forever and this is all from memory but hopefully it's useful...
Nemesis wrote:Do any games actually use these functions?
No.
Nemesis wrote:these functions only return 32 bytes between them
It's because of the odd way this stuff is interleaved. So, to get it all, you'd have to call either one when data is ready, and repeat as needed. Or, just rip it out of the registers.
Nemesis wrote:the LC8950 seems to return the sync block at the end of the sector for some reason
*edit* Yeah, that's the sync for the next sector (not yet error corrected etc) you're seeing. The CDC tells you which parts of the buffer are valid, and you're reading beyond that area. Nothing to stop you doing that it seems, but it isn't very friendly ;)
Nemesis wrote:I really want the data to not have CRC and RS error correction applied
No you don't ;) But if you really do, you should be reading it as Mode 2. That should get you the entire sector, minus the header, and without the level 2 correction being performed.
But, trust me, you don't need that. Better to let the hardware do it's job.
Nemesis wrote:so that I really could read out digital audio data.
I assumed this was common knowledge but I guess not. The digital audio data ends up in the CDC buffer when you're simply playing audio... Just read it out. Done.
Nemesis wrote:As a note, neither subcode reading or CD-DA mode work correctly in any emulators
Subcode definitely works in Kega as does 'proper' CDDA mode. But reading into the next sector looks different because there's no error correction going on.
Nemesis wrote:the full raw 3234 byte CD sector data
I don't know of any hardware (outside of maybe some pro duplication hardware) that'll get you more that 2448 bytes. But, that's all you need.

That 2448 bytes is 16 header, 2048 data, 4 checksum, 284 RS-ECC, 96 subcode.

What's more, if you know its a mode 1 track, all you need is the 2048 bytes. Everything else gets recreated by any burner.

If there's any subcode data other than the stuff that gets recreated automatically, it will be in audio tracks. But it's EXTREMELY unlikely there'll be anything there. Very good reason for that - there's no error correction and it's unreliable. Even with a pristine CD+G disc (like the one I found when I was implementing this stuff 11 years ago), I couldn't get my expensive Yamaha burner to produce two identical binary dumps. This is ok for CD+G, the odd wrong pixel doesn't matter - or for it's other uses (its really just informational and errors are acceptable.) But that means it's unlikely to get used for anything important, and especially so for such discs as the ones you're looking at.

But if you DO want to check this out, I'd recommend finding a disc with known CD+G on it, rip it with something that can do it, and make sure the rip at least works. Then look at the data the SegaCD is returning. You'll notice it's interleaved very differently/ordered differently to the image you ripped, so you'll have to do some correction of your own. But, like I say, chances of anything important being in there is almost zero.

... and if you want to hit the hardware I'll try and offer advice. Need to refresh my memory anyway ;)
Last edited by Snake on Sat May 24, 2014 8:40 am, edited 3 times in total.

Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake » Wed May 21, 2014 5:30 am

Thinking about this a little more...

Maybe you need to use the ROMREAD stuff to get the audio. (*edit* or just play it as audio and call CDCREADP as TascoDLX said above...) At a hardware level, there is only one way to read the disc - the PLAY command. Maybe the only difference in the BIOS calls is to enable (or not) the CDC buffer.

But either way, trying to read a data track (as you've been doing in your tests) isn't going to work the same way here - the system knows what type of track is being read. If it's an audio track, it gets sent to the DAC, but also the CDC buffer (and the subcode stuff goes to the relevant registers obviously) - and it won't try to perform any error correction or strip the header because it knows it's audio. So there shouldn't be a problem.

Incidentally, the BIOS CD player uses this to do it's 'volume bars'.

*edit* SETCDCMODE with 4 probably gets you the raw sector, too, if you want to play with that. But no hacks should be needed, as I say, if you're actually playing an audio track, reading the raw data is supported.

Huge
Very interested
Posts: 197
Joined: Sat Dec 13, 2008 11:50 pm

Post by Huge » Fri May 23, 2014 8:49 pm

Snake wrote:Everything else gets recreated by any burner.
Nemesis wants to do this to rip Mega Laserdiscs - what burners can and cannot burn do not matter here.

Also I think this depends on burners, both hardware and software. The subcodes used for CD+G are burnable for sure, at the very least. Not sure about ECC in mode 1 data.
If there's any subcode data other than the stuff that gets recreated automatically, it will be in audio tracks. But it's EXTREMELY unlikely there'll be anything there. Very good reason for that - there's no error correction and it's unreliable. Even with a pristine CD+G disc (like the one I found when I was implementing this stuff 11 years ago), I couldn't get my expensive Yamaha burner to produce two identical binary dumps. This is ok for CD+G, the odd wrong pixel doesn't matter - or for it's other uses (its really just informational and errors are acceptable.) But that means it's unlikely to get used for anything important, and especially so for such discs as the ones you're looking at.
I've actually managed to dump a disc with 0 subcode errors, but it was literally one in 300 very good quality discs, and it only had 9207 sectors (~20mb raw data, plus ~800k subcode). I also had near mint discs end up with more subcode errors than discs with a billion deep scratches.
Due to the lack of error correction, discs almost always had subcode errors out of the factory, even.

Only way to dump subcodes error free would be ripping 5-10 separate discs, ALL with the same ringcode (!), and then comparing the subcode rips to get the median data. But it's arguable if that would be "correct" due to factory errors.
But if you DO want to check this out, I'd recommend finding a disc with known CD+G on it, rip it with something that can do it, and make sure the rip at least works. Then look at the data the SegaCD is returning. You'll notice it's interleaved very differently/ordered differently to the image you ripped, so you'll have to do some correction of your own.
I can offer a rip of one such disc, the rock paintings cd+g demo, if you need it. And yes, the subcodes are correctly ripped. In as much as they are possible to be ripped. Well, if you burn a copy with CloneCD, it displays fine on a Saturn! I didn't test it on a Sega CD yet, but I may be able to do it tomorrow as I have a functional unit incoming.

Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake » Sat May 24, 2014 7:32 am

Huge wrote:Nemesis wants to do this to rip Mega Laserdiscs - what burners can and cannot burn do not matter here.
Well, it's also easy to generate the data that's actually readable (i.e. the L2 error correction stuff, and the PQ (i think?) subcodes) in software. The rest doesn't matter because it can't be read - I was just pointing out there that if you burned an image of the disc, all the extra unreadable stuff would be generated by the burner. So, the fact it can't be ripped isn't important.

I really can't see, however, there being anything more than just standard mode 1 data tracks on these things. Nothing else was used on SegaCD (in fact I don't think the software provided to create discs supported anything else). In which case it's best to let the CDC handle error correction for you. If the read functions return no errors, you can be sure you've got the data correct, and if you really want to add headers/ecc/edc you can regenerate all that after ripping. I would think that's far better than trying to rip the whole thing RAW, then finding errors in it, and having to rip it again.

Audio can be pulled raw as I said before - if there is even any audio on these games? I would have thought there wouldn't be much, if any at all, since most of the time they'd be playing audio+video from the LD section.

Question: is the cable communication fast enough to send an entire sector in real time? That would be the ideal. Maybe it'd be worth extending the cable to use both ports if not.

Post Reply