32#define CDDA_MARKER 0x0101
33#define CDDA_SPU_DELAY (*(volatile uint32_t *)0xbf801014)
36 static uint16_t s_cddaCapture[0x400];
39 const uint16_t tsa = spuAddr >> 3;
40 const uint16_t
mode = isRead ? 0x30 : 0x20;
44 for (
volatile int i = 0;
i < 60;
i++);
51 for (
unsigned t = 0;
t < 4000000u;
t++) {
58 for (
volatile int i = 0;
i < 60;
i++);
62 static int cddaSimpleCmd(uint8_t
cmd) {
67 int ok = waitCDRomIRQWithTimeout(&
timeout);
73 static void cddaWaitPauseComplete() {
76 while (elapsed < 5000000u) {
78 int ok = waitCDRomIRQWithTimeout(&budget);
84 if (
cause == 2)
return;
90 static int cddaAudioSetup(
const uint8_t atv[4],
int demute) {
91 if (!resetCDRom())
return 0;
95 for (
volatile int i = 0;
i < 20000;
i++);
102 for (
volatile int i = 0;
i < 20000;
i++);
104 if (!cddaSpuDma(0x000, s_cddaCapture, 0x800, 0))
return 0;
125 static int cddaBufferPeak(
unsigned *signChanges) {
129 for (
int i = 0;
i < 0x200;
i++) {
130 int v = (int16_t)s_cddaCapture[
i];
131 int a = v < 0 ? -v : v;
133 int sign = v >= 0 ? 1 : -1;
144 static int cddaCapturePeak(
unsigned *signChanges) {
146 for (
unsigned attempt = 0; attempt < 8; attempt++) {
149 while (updateTime() < 250000u);
151 if (!cddaSpuDma(0x000, s_cddaCapture, 0x800, 1))
return -1;
152 peak = cddaBufferPeak(signChanges);
154 if (attempt)
ramsyscall_printf(
"capture was empty %u time(s) before audio\n", attempt);
163 static int cddaPeak(
const uint8_t atv[4],
int demute,
unsigned *signChanges) {
164 if (!cddaAudioSetup(atv, demute))
return -1;
165 if (!setMode(0))
return -1;
169 if (!cddaSimpleCmd(
CDL_PLAY))
return -1;
172 while (updateTime() < 1500000u);
174 int peak = cddaCapturePeak(signChanges);
178 cddaWaitPauseComplete();
193 static const uint8_t atv[4] = {0x80, 0x00, 0x80, 0x00};
203 static const uint8_t atv[4] = {0x40, 0x00, 0x40, 0x00};
213 static const uint8_t atv[4] = {0x80, 0x80, 0x80, 0x80};
223 static const uint8_t atv[4] = {0x80, 0x00, 0x80, 0x00};
int peak
Definition cdda.c:195
CESTER_TEST(cddaLevelHalf, test_instances, static const uint8_t atv[4]={0x40, 0x00, 0x40, 0x00};unsigned changes=0;int peak=cddaPeak(atv, 1, &changes);ramsyscall_printf("CD-DA level at half ATV: peak %i, %u sign changes\n", peak, changes);cester_assert_int_ge(peak, 11300);cester_assert_int_le(peak, 11800);cester_assert_uint_ge(changes, 4);) CESTER_TEST(cddaLevelClipped
#define CDDA_MARKER
Definition cdda.c:32
cester_assert_uint_ge(changes, 4)
test_instances
Definition cdda.c:212
cester_assert_int_le(peak, 23400)
cester_assert_int_ge(peak, 22800)
#define CDDA_SPU_DELAY
Definition cdda.c:33
unsigned changes
Definition cdda.c:194
CESTER_BODY(static uint16_t s_cddaCapture;static int cddaSpuDma(uint32_t spuAddr, void *buf, uint32_t bytes, int isRead) { const uint16_t tsa=spuAddr > > 3;const uint16_t mode=isRead ? 0x30 :0x20;SPU_RAM_DTA=tsa;for(int i=0;i< 0xf01 &&SPU_RAM_DTA !=tsa;i++);SPU_CTRL=(SPU_CTRL &~0x30)|mode;for(volatile int i=0;i< 60;i++);for(int i=0;i< 0xf01 &&(SPU_STATUS &0x30) !=mode;i++);CDDA_SPU_DELAY=(CDDA_SPU_DELAY &0xf0ffffff)|(isRead ? 0x22000000 :0x20000000);DMA_CTRL[DMA_SPU].MADR=(uint32_t) buf &0x1fffffff;DMA_CTRL[DMA_SPU].BCR=((bytes > > 6)<< 16)|0x10;DMA_CTRL[DMA_SPU].CHCR=isRead ? 0x01000200 :0x01000201;int ok=0;for(unsigned t=0;t< 4000000u;t++) { if((DMA_CTRL[DMA_SPU].CHCR &0x01000000)==0) { ok=1;break;} } SPU_CTRL=SPU_CTRL &~0x30;for(volatile int i=0;i< 60;i++);return ok;} static int cddaSimpleCmd(uint8_t cmd) { uint8_t response[16];CDROM_REG0=0;CDROM_REG1=cmd;uint32_t timeout=2000000;int ok=waitCDRomIRQWithTimeout(&timeout);ackCDRomCause();readResponse(response);return ok;} static void cddaWaitPauseComplete() { initializeTime();uint32_t elapsed=0;while(elapsed< 5000000u) { uint32_t budget=200000u;int ok=waitCDRomIRQWithTimeout(&budget);elapsed=budget;if(!ok) continue;uint8_t cause=ackCDRomCause();uint8_t response[16];readResponse(response);if(cause==2) return;} } static int cddaAudioSetup(const uint8_t atv[4], int demute) { if(!resetCDRom()) return 0;DPCR|=0x000b0000;SPU_CTRL=0;for(volatile int i=0;i< 20000;i++);SPU_VOL_MAIN_LEFT=0;SPU_VOL_MAIN_RIGHT=0;SPU_KEY_OFF_LOW=0xffff;SPU_KEY_OFF_HIGH=0xffff;SPU_RAM_DTC=4;SPU_CTRL=0x8001;for(volatile int i=0;i< 20000;i++);for(int i=0;i< 0x400;i++) s_cddaCapture[i]=CDDA_MARKER;if(!cddaSpuDma(0x000, s_cddaCapture, 0x800, 0)) return 0;if(!cddaSimpleCmd(demute ? CDL_DEMUTE :CDL_MUTE)) return 0;CDROM_REG0=2;CDROM_REG2=atv[0];CDROM_REG3=atv[1];CDROM_REG0=3;CDROM_REG1=atv[2];CDROM_REG2=atv[3];CDROM_REG0=3;CDROM_REG3=0x20;CDROM_REG0=0;SPU_VOL_CD_LEFT=0x7fff;SPU_VOL_CD_RIGHT=0x7fff;SPU_CTRL=SPU_CTRL|0x8001;return 1;} static int cddaBufferPeak(unsigned *signChanges) { int peak=0;unsigned changes=0;int prev=0;for(int i=0;i< 0x200;i++) { int v=(int16_t) s_cddaCapture[i];int a=v< 0 ? -v :v;if(a > peak) peak=a;int sign=v >=0 ? 1 :-1;if(i &&sign !=prev) changes++;prev=sign;} *signChanges=changes;return peak;} static int cddaCapturePeak(unsigned *signChanges) { int peak=0;for(unsigned attempt=0;attempt< 8;attempt++) { if(attempt) { initializeTime();while(updateTime()< 250000u);} if(!cddaSpuDma(0x000, s_cddaCapture, 0x800, 1)) return -1;peak=cddaBufferPeak(signChanges);if(peak) { if(attempt) ramsyscall_printf("capture was empty %u time(s) before audio\n", attempt);break;} } return peak;} static int cddaPeak(const uint8_t atv[4], int demute, unsigned *signChanges) { if(!cddaAudioSetup(atv, demute)) return -1;if(!setMode(0)) return -1;CDROM_REG0=0;CDROM_REG2=0x02;if(!cddaSimpleCmd(CDL_PLAY)) return -1;initializeTime();while(updateTime()< 1500000u);int peak=cddaCapturePeak(signChanges);CDROM_REG0=0;CDROM_REG1=CDL_PAUSE;cddaWaitPauseComplete();CDROM_REG0=0;CDROM_REG2=0x00;CDROM_REG2=0x02;CDROM_REG2=0x16;if(cddaSimpleCmd(CDL_SETLOC) &&cddaSimpleCmd(CDL_SEEKL)) cddaWaitPauseComplete();return peak;}[0x400])
Definition cdda.c:35
uint8_t response[16]
Definition cdlgetlocl.c:84
DMA_CTRL[DMA_CDROM] CHCR
Definition cdlreadn.c:185
int ok
Definition cdlstop.c:75
uint8_t cause
Definition cdltest.c:207
@ CDL_PLAY
Definition cdrom.h:45
@ CDL_MUTE
Definition cdrom.h:53
@ CDL_DEMUTE
Definition cdrom.h:54
@ CDL_SEEKL
Definition cdrom.h:63
@ CDL_PAUSE
Definition cdrom.h:51
@ 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 SPU_VOL_CD_RIGHT
Definition spu.h:108
#define SPU_VOL_CD_LEFT
Definition spu.h:107
#define SPU_STATUS
Definition spu.h:106
#define SPU_VOL_MAIN_LEFT
Definition spu.h:84
#define SPU_KEY_OFF_LOW
Definition spu.h:90
#define SPU_KEY_OFF_HIGH
Definition spu.h:91
#define SPU_CTRL
Definition spu.h:104
#define SPU_VOL_MAIN_RIGHT
Definition spu.h:85
#define SPU_RAM_DTC
Definition spu.h:105
#define SPU_RAM_DTA
Definition spu.h:103
uint32_t t
Definition cop0.c:79
ramsyscall_printf("=== e01_kseg1_reads_no_fill ===\n")
#define DMA_CTRL
Definition dma.h:36
@ DMA_SPU
Definition dma.h:43
int i
Definition gte-regio.c:297
#define DPCR
Definition hwregs.h:49
uint16_t cmd[MON_CMD_WORDS]
Definition monitor.c:69
int a
Definition mktest.py:134
uint32_t timeout
Definition race.c:103
static const void * buf
Definition syscalls.h:61
return((size_t(*)(int, const void *, size_t)) 0xa0)(fd
static void uint32_t mode
Definition syscalls.h:231
void uint32_t(classId, spec)
cester_assert_int_eq(3, xaCommand(CDL_SETMODE, &mode, 1, NULL, NULL))