42 unsigned nonDataCauses;
46 unsigned audioRealTime;
47 unsigned audioNotRealTime;
52 unsigned busyAfterClear;
63 if (!waitCDRomIRQWithTimeout(&
timeout))
return -1;
71 static int xaWaitCause(uint8_t expected,
uint32_t timeoutUs) {
74 if (!waitCDRomIRQWithTimeout(&
timeout))
return 0;
77 return cause == expected;
82 uint8_t msf[3] = {
itob(total / 4500),
itob((total / 75) % 60),
itob(total % 75)};
83 if (xaCommand(
CDL_SETLOC, msf, 3, NULL, NULL) != 3)
return 0;
84 if (xaCommand(
CDL_SEEKL, NULL, 0, NULL, NULL) != 3)
return 0;
85 return xaWaitCause(2, 4000000);
90 static void xaStop() {
93 for (
unsigned i = 0;
i < 64;
i++) {
96 if (!waitCDRomIRQWithTimeout(&
timeout))
return;
99 if (
cause == 2)
return;
103 static void xaReadHead(uint8_t*
head,
unsigned count) {
106 for (
unsigned t = 0;
t < 50000;
t++) {
117 static int xaRead(uint8_t
mode,
int filter, uint8_t file, uint8_t channel,
uint32_t startLBA,
118 uint32_t durationUs,
unsigned stopAfterClear,
struct XAReadStats*
stats) {
120 stats->minLBA = 0xffffffff;
121 if (!resetCDRom())
return 0;
124 uint8_t params[2] = {
file, channel};
125 if (xaCommand(
CDL_SETFILTER, params, 2, NULL, NULL) != 3)
return 0;
127 if (!xaSeekL(startLBA))
return 0;
128 if (xaCommand(
CDL_READS, NULL, 0, NULL, NULL) != 3)
return 0;
132 while ((elapsed < durationUs) && (
stats->events < 2000)) {
134 int got = waitCDRomIRQWithTimeout(&slice);
143 stats->nonDataCauses++;
151 xaReadHead(
head, 16);
153 uint8_t submode =
head[6];
154 if (submode & 0x04) {
155 if (submode & 0x40) {
156 stats->audioRealTime++;
158 stats->audioNotRealTime++;
168 if (lba < startLBA || lba > startLBA + 20000) {
172 if (lba < stats->minLBA)
stats->minLBA = lba;
174 stats->slotMask |= 1 << ((lba - startLBA) % 16);
175 if (payload[3] ==
'D')
stats->form2Seen++;
178 stats->lastLBABusy = lba;
179 if (
stats->busyClear)
stats->busyAfterClear++;
181 if (!
stats->busyClear)
stats->firstLBAClear = lba;
183 if (stopAfterClear && (
stats->busyClear >= stopAfterClear))
break;
188 "XA mode %02x filter %i %i/%i from %i: %i events, %i not data ready, %i unstamped, slots %04x, LBA %i-%i, "
189 "form 2 %i, audio RT %i not RT %i, ADPBUSY set %i clear %i (last set %i, first clear %i)\n",
192 stats->firstLBAClear);
224 struct XAReadStats
stats;
225 int done = xaRead(0xc8, 1, 1, 0, 135000, 1500000, 0, &
stats);
238 int done = xaRead(0xc8, 1, 1, 3, 135000, 1500000, 0, &
stats);
250 struct XAReadStats
stats;
251 int done = xaRead(0x88, 1, 1, 0, 135000, 1500000, 0, &
stats);
263 struct XAReadStats
stats;
264 int done = xaRead(0xc0, 0, 0, 0, 135000, 1500000, 0, &
stats);
282 struct XAReadStats
stats;
283 int done = xaRead(0xe8, 1, 1, 0, 152744, 1500000, 0, &
stats);
298 struct XAReadStats
stats;
299 int done = xaRead(0xc8, 1, 1, 3, 155960, 7000000, 20, &
stats);
313 static int xaPeak(
const uint8_t atv[4],
int demute,
unsigned* signChanges) {
314 if (!cddaAudioSetup(atv, demute))
return -1;
317 uint8_t
filter[2] = {1, 0};
319 if (!xaSeekL(135016))
return -1;
320 if (xaCommand(
CDL_READS, NULL, 0, NULL, NULL) != 3)
return -1;
324 while (elapsed < 600000u) {
326 int ok = waitCDRomIRQWithTimeout(&budget);
334 int peak = cddaCapturePeak(signChanges);
341 static const uint8_t atv[4] = {0x80, 0x00, 0x80, 0x00};
351 static const uint8_t atv[4] = {0x80, 0x80, 0x80, 0x80};
361 static const uint8_t atv[4] = {0x80, 0x00, 0x80, 0x00};
int resetDone
Definition cdlforward.c:60
uint8_t responseSize
Definition cdlgetlocl.c:85
int ok
Definition cdlstop.c:75
uint8_t cause
Definition cdltest.c:207
@ CDL_READS
Definition cdrom.h:69
@ CDL_SETMODE
Definition cdrom.h:56
@ CDL_SEEKL
Definition cdrom.h:63
@ CDL_PAUSE
Definition cdrom.h:51
@ CDL_SETFILTER
Definition cdrom.h:55
@ CDL_GETMODE
Definition cdrom.h:57
@ CDL_SETLOC
Definition cdrom.h:44
#define CDROM_REG0
Definition cdrom.h:31
#define CDROM_REG3
Definition cdrom.h:34
#define CDROM_REG1
Definition cdrom.h:32
#define CDROM_REG2
Definition cdrom.h:33
#define head
Definition alloc.c:111
uint32_t t
Definition cop0.c:79
ramsyscall_printf("=== e01_kseg1_reads_no_fill ===\n")
struct EventInfo * events
Definition globals.h:49
int i
Definition gte-regio.c:297
file
Definition gen-sjis-encode-table.py:51
payload
Definition genjob.py:327
int total
Definition gentable.py:106
constexpr uint8_t itob(uint8_t i)
Definition msf.hh:36
uint32_t timeout
Definition race.c:103
__builtin_memset(sectorData, 0, sizeof(sectorData))
Definition gte-timing.c:164
static void * buffer
Definition syscalls.h:231
static const void size_t count
Definition syscalls.h:146
void uint32_t(classId, spec)
cester_assert_uint_ne(0, fillers)
cester_assert_uint_gt(stats.firstLBAClear, 156744)
int peak
Definition xa.c:343
uint8_t mode
Definition xa.c:203
uint8_t response[16]
Definition xa.c:205
CESTER_TEST(xaRealTimeFilteredWithholdsAudio, test_instance, struct XAReadStats stats;int done=xaRead(0xc8, 1, 1, 0, 135000, 1500000, 0, &stats);cester_assert_true(done);uint32_t fillers=stats.slotMask &0xff00;uint32_t audio=stats.slotMask &0x00ff;cester_assert_uint_ne(0, fillers);cester_assert_uint_eq(0, audio);cester_assert_uint_eq(0, stats.nonDataCauses);cester_assert_uint_eq(0, stats.unstamped);cester_assert_uint_eq(0, stats.busyClear);) CESTER_TEST(xaRealTimeOtherChannelWithholdsAudio
int done
Definition xa.c:238
uint8_t filter[2]
Definition xa.c:204
cester_assert_int_ge(peak, 22400)
test_instance
Definition xa.c:236
struct XAReadStats stats
Definition xa.c:237
cester_assert_int_le(peak, 22900)
uint32_t audio
Definition xa.c:241
cester_assert_int_eq(3, xaCommand(CDL_SETMODE, &mode, 1, NULL, NULL))
cester_assert_uint_ge(stats.lastLBABusy, 156504)
uint32_t fillers
Definition xa.c:240
unsigned changes
Definition xa.c:342
cester_assert_uint_eq(5, size)
uint8_t size
Definition xa.c:206
CESTER_BODY(struct XAReadStats { unsigned events;unsigned nonDataCauses;unsigned unstamped;uint32_t slotMask;unsigned form2Seen;unsigned audioRealTime;unsigned audioNotRealTime;unsigned busySet;unsigned busyClear;uint32_t lastLBABusy;uint32_t firstLBAClear;unsigned busyAfterClear;uint32_t minLBA;uint32_t maxLBA;};static int xaCommand(uint8_t command, const uint8_t *params, unsigned count, uint8_t *response, uint8_t *responseSize) { CDROM_REG0=0;for(unsigned i=0;i< count;i++) CDROM_REG2=params[i];CDROM_REG1=command;uint32_t timeout=2000000;if(!waitCDRomIRQWithTimeout(&timeout)) return -1;uint8_t cause=ackCDRomCause();uint8_t buffer[16];uint8_t size=readResponse(response ? response :buffer);if(responseSize) *responseSize=size;return cause;} static int xaWaitCause(uint8_t expected, uint32_t timeoutUs) { uint8_t response[16];uint32_t timeout=timeoutUs;if(!waitCDRomIRQWithTimeout(&timeout)) return 0;uint8_t cause=ackCDRomCause();readResponse(response);return cause==expected;} static int xaSeekL(uint32_t lba) { uint32_t total=lba+150;uint8_t msf[3]={itob(total/4500), itob((total/75) % 60), itob(total % 75)};if(xaCommand(CDL_SETLOC, msf, 3, NULL, NULL) !=3) return 0;if(xaCommand(CDL_SEEKL, NULL, 0, NULL, NULL) !=3) return 0;return xaWaitCause(2, 4000000);} static void xaStop() { CDROM_REG0=0;CDROM_REG1=CDL_PAUSE;for(unsigned i=0;i< 64;i++) { uint8_t response[16];uint32_t timeout=1000000;if(!waitCDRomIRQWithTimeout(&timeout)) return;uint8_t cause=ackCDRomCause();readResponse(response);if(cause==2) return;} } static void xaReadHead(uint8_t *head, unsigned count) { CDROM_REG0=0;CDROM_REG3=0x80;for(unsigned t=0;t< 50000;t++) { if(CDROM_REG0 &0x40) break;} for(unsigned i=0;i< count;i++) head[i]=CDROM_REG2;CDROM_REG0=0;CDROM_REG3=0;} static int xaRead(uint8_t mode, int filter, uint8_t file, uint8_t channel, uint32_t startLBA, uint32_t durationUs, unsigned stopAfterClear, struct XAReadStats *stats) { __builtin_memset(stats, 0, sizeof(*stats));stats->minLBA=0xffffffff;if(!resetCDRom()) return 0;if(xaCommand(CDL_SETMODE, &mode, 1, NULL, NULL) !=3) return 0;if(filter) { uint8_t params[2]={file, channel};if(xaCommand(CDL_SETFILTER, params, 2, NULL, NULL) !=3) return 0;} if(!xaSeekL(startLBA)) return 0;if(xaCommand(CDL_READS, NULL, 0, NULL, NULL) !=3) return 0;initializeTime();uint32_t elapsed=0;while((elapsed< durationUs) &&(stats->events< 2000)) { uint32_t slice=30000;int got=waitCDRomIRQWithTimeout(&slice);elapsed=slice;if(!got) continue;int busy=(CDROM_REG0 &0x04) !=0;uint8_t cause=ackCDRomCause();uint8_t response[16];readResponse(response);stats->events++;if(cause !=1) { stats->nonDataCauses++;continue;} uint8_t head[16];const uint8_t *payload=head;if(mode &0x20) { xaReadHead(head, 16);payload=head+12;uint8_t submode=head[6];if(submode &0x04) { if(submode &0x40) { stats->audioRealTime++;} else { stats->audioNotRealTime++;} continue;} } else { xaReadHead(head, 4);} uint32_t lba=payload[0]|(payload[1]<< 8)|(payload[2]<< 16);if(lba< startLBA||lba > startLBA+20000) { stats->unstamped++;continue;} if(lba< stats->minLBA) stats->minLBA=lba;if(lba > stats->maxLBA) stats->maxLBA=lba;stats->slotMask|=1<<((lba - startLBA) % 16);if(payload[3]=='D') stats->form2Seen++;if(busy) { stats->busySet++;stats->lastLBABusy=lba;if(stats->busyClear) stats->busyAfterClear++;} else { if(!stats->busyClear) stats->firstLBAClear=lba;stats->busyClear++;if(stopAfterClear &&(stats->busyClear >=stopAfterClear)) break;} } xaStop();ramsyscall_printf("XA mode %02x filter %i %i/%i from %i: %i events, %i not data ready, %i unstamped, slots %04x, LBA %i-%i, " "form 2 %i, audio RT %i not RT %i, ADPBUSY set %i clear %i (last set %i, first clear %i)\n", mode, filter, file, channel, startLBA, stats->events, stats->nonDataCauses, stats->unstamped, stats->slotMask, stats->minLBA, stats->maxLBA, stats->form2Seen, stats->audioRealTime, stats->audioNotRealTime, stats->busySet, stats->busyClear, stats->lastLBABusy, stats->firstLBAClear);return 1;})
Definition xa.c:39