Deciphering CD_ReadAudio
Jeffrey Lee (213) 6048 posts |
The StrongHelp manual and wiki currently state that the R3 parameter to CD_ReadAudio is “pointer to destination buffer (multiple of 256)”. To me the description makes it sound like the buffer pointer should be 256 byte aligned (which sounds like a plausible restriction some old drives/drivers may enforce), but Jim Lesurf’s comments from this thread suggest that it’s actually the buffer length that has to be a multiple of 256 bytes. Does this mean that any value of R2 where (R2*2352) MOD 256 != 0 doesn’t work reliably? Or do some drives return more data than requested (overwriting memory up to the next 256 byte multiple)? Or does R2 itself need to be a multiple of 256? I’m not seeing any obvious “multiple of 256” limitation in the ATAPIDriver sources – but I haven’t traced through the code to see exactly what it’s doing, so maybe there’s a bug or hidden limitation in the ATAPI layer (and neither have I tried any test code yet). But while looking at the ATAPIDriver sources I did spot the previously undocumented requirement that R4 must be a flags word with the bottom byte zero, which could easily explain some of the problems people have been having. |
Jon Abbott (1421) 2651 posts |
R2 is the number of blocks you want, which are 2352 bytes in length for audio, there’s no restrictions on this value. R3 as far I’m aware has no restrictions however the “multiple of 256” could be for DMA transfers perhaps? I would have thought it should be “multiples of 2352” if it were related to R2. |
nemo (145) 2552 posts |
I read it the same as Jim – buffer is a multiple of 256 bytes long. |
Jeffrey Lee (213) 6048 posts |
The source code says “reason code for CD_Identify”. Ignoring the obvious copy-paste error from the Identify function (the next function above ReadAudio), it looks to be correct, since ReadAudio is the 31st entry in ATAPI’s jump table, and CDFSDriver subtracts one plus five plus one (= 7) from 38 (= 31) |
nemo (145) 2552 posts |
Sorry to doubt you. I was looking at the SCSI driver which doesn’t check R4 before calling SCSI_Op, whereas ATAPI does, as you say. However, now I check ATAPI I’m not reading that as a bitfield but as a check that R4 is a multiple of 256. It appears to be utterly bogus. Perhaps they meant to check R2? (The length is the register before the buffer, whereas conventionally it’s the register after) |
Steffen Huber (91) 1953 posts |
I know of no drives returning more than 2352 bytes/sector when instructed to read audio. There are drives that can be put into “read raw” mode which return everything including the subcode, but who would use such a mode to read audio? My recommendation would be not to try to make sense of CDFS or CDFS softloadable drivers. They are a big mess. What happended to the sources of CDFS3, by the way? |
Jeffrey Lee (213) 6048 posts |
The ROOL CDFSSoftSCSI was produced by looking at the various scraps of documentation, sample code, and bits of the ATAPI driver – I guess the R4 check slipped past me since it wasn’t in the StrongHelp docs and didn’t trip up my BASIC test program.
Potentially locked in a vault somewhere in ROOL’s HQ – ModuleDB does contain entries for the various components. Of course, there’s no guarantee that it’s better than current CDFS! Some analysis of the many CD modules in RISC OS 3.6 reveals the following:
|
Steffen Huber (91) 1953 posts |
Just be aware that CDFSSoftATAPI is full of strange code that uses raw mode (“Read CD” command) for various things, which regularly fails on DVD drives when reading DVDs (but mostly works for CDs), and anyway “Read CD” command is no longer part of MMC since MMC2 IIRC (but keeps working for most drives for CDs!). I once did a bit of hacking to reduce it to “plain simple Read Data commands” and suddenly all those non-working DVD drives became functional. However, to produce a proper fix, you need to have a look at Mode 2 Form 1, Mode 2 Form 2(XA), PhotoCD…that was far beyond my assembler skills. |
Steffen Huber (91) 1953 posts |
Yes, those were special drivers for not-really-SCSI2-compliant SCSI CD drives when CDFS became available and 3rd party SCSI podule vendors hat not yet started producing their generic drivers. Back in the time, there were three ways to do audio read: use “Read CDDA” command (this was the one Sony supported), setting the block size to 2352 via mode select and use “Read Data” (I think Toshiba and Plextor CD-ROMs and Philips CD writers worked that way), and a third method that escaped my mind. I think the Chinon driver was comparably “clean” so could be patched to work with other generic SCSI2 compatible CD-ROMs. But no audio extraction support IIRC. |
Sprow (202) 1158 posts |
Not the case since ATAPI 1.43. And yes, it did work with a Kodak PhotoCD. |
nemo (145) 2552 posts |
Just to be clear:
TEQ R11, #ReadAudio MOVEQ R4, R2
|
Jeffrey Lee (213) 6048 posts |
For that to make sense, you’d have to completely ignore the comments surrounding it which indicate that R4 is meant to be a flags word. r4 = flags, bits 0 to 7 = read PCM, bits 8 to 31 RESERVED ;--------------------------------------------- ; Check that flag bits are set to to read PCM ;--------------------------------------------- TST r4, # &ff BNE invalidparameter |
nemo (145) 2552 posts |
Comments? Luxury. Digging deeper… The definitive implementations would be AudioFS and cdparanoia, and both of those explicitly set R4 to 0 (coincidentally so in the latter case, but conscientiously in the former). Matthew Astley’s demos do the same, explicitly. However, Jim Lesurf’s example code sets R4 to &D7A00 (3450<<8), which suggests there’s more going on than that comment explains. |
Jeffrey Lee (213) 6048 posts |
That’s under the mistaken assumption that R4 should be the byte size of the buffer. Both ATAPI and Sony drivers calculate the byte size of the buffer themselves, so passing in the byte size shouldn’t be required. char dbuffer[883200]; /* 5 second’s worth of bytes */ ... rin.r[4]=883200; Although oddly 883200 is 375*2352 rounded up to a multiple of 512, rather than a multiple of 256. |
nemo (145) 2552 posts |
I took it to be 5 (seconds) × 2 (16bit) × 2 (stereo) × 44,100 = 883200.
So the conclusion seems to be that R4 doesn’t do anything in any implementation anyone can find, is sometimes checked to have b0-7 clear, and is either set to zero or an incorrect value by actual (example) code. And apart from a comment in what used to be closed source code, no one has seen any documentation that defines what it’s for? Jim’s PDF aside, everything seems to be using 0. I vote for ‘reserved, must be 0’. |
Jeffrey Lee (213) 6048 posts |
Pretty much! Jim’s assumption that R4 should be the byte buffer size of the buffer is perhaps based around what the StrongHelp docs say for CD_ReadData (“R4 = length of buffer”), but that also contradicts the comments in the OS sources (“R4 = number of bytes from each block wanted” (although the actual use in the OS sources suggests that R4 is merely the size of each block (or the number of bytes to return if you’re only reading one block), since all that happens is that the drivers multiply R4 by R2 to work out the length to pass to SCSI_Op/ATAPI_Op)). So CD_ReadData is probably also a victim of the lack of widely-available official documentation. |
Jon Abbott (1421) 2651 posts |
I believe that’s correct, but possibly somewhat misleading. I read it to mean the data type to read, 0=PCM to return 2352 per block, the other standards Mode 1 – 2048, Mode 2 form 1 – 2048, Mode 2 form 2 – 2324 etc were probably never implemented as that’s the only one listed.
That’s almost correct, I believe it should use bits 0..7 in R4 as a lookup reference for the amount of data in each block and multiply that by R2. eg. 0 (PCM) = 2352 |
Jeffrey Lee (213) 6048 posts |
Most of what I said in my previous post was about CD_ReadData, not CD_ReadAudio. They both use R4 for different things (and both have incorrect StrongHelp documentation) |
Steffen Huber (91) 1953 posts |
I knew you fixed a few things, but didn’t remember the details :-) Going by the commit comment: well done! Once I finish that damn CDVDBurn update, I will have a closer look at the current state of CDFSSoftATAPI. Do you happen to know if the current version still works on Risc PC internal IDE? |
Jeffrey Lee (213) 6048 posts |
It should do; the latest version of the module is in the IOMD 5.24 ROM. |
Steffen Huber (91) 1953 posts |
Maybe it is now a good time to resurrect one of my Risc PCs and try softloading the latest CDFSSoftATAPI to check compatibility with one of the newer DVD writers. Just need to find one which consumes not too much power @12V. |
jim lesurf (2082) 1438 posts |
FWIW I can’t really say I understand this beyond having written up the old info on these calls and having used CD_ReadAudio in my CD ripping programme and the CD_HealthCheck programme. All I had to go on were some text files that gave some info but which seem to be rather ‘unofficial’. The Audio ‘channel bit stream’ on an Audio CD is in ‘frames’, but how that relates (if at all here) I’m not sure beyond the need at a low level to get the cross check bits that are interleaved around the data. CDparanoia does (apparently) look at this, but I’ve never worked out how! However I seem to be able to get the same outcome from decent-condition disks using CDparanoia and my own ‘ripframes’ that uses the CD_ calls. Albeit sometimes offset by a sample or two in alignment, depending on the drive used. |
Theo Markettos (89) 919 posts |
I should warn not to trust the CDFS parts of the StrongHelp manuals too much. I wrote them based on some reverse engineering since Acorn never released documentation for that part of the stack. Of course we can now look at the source, which is probably a better idea given there are unlikely to be competing implementations… |
Jeffrey Lee (213) 6048 posts |
OK – good to get confirmation that it shouldn’t be trusted! |