5#define ATTACK(step, shift, exp) (\
6 (((step) & 3) << 8) | \
7 (((shift) & 31) << 10) | \
10 (((shift) & 15) << 4))
11#define SUSTAIN(step, shift, level, direction, exp) (\
12 (((step) & 3) << 22) | \
13 (((shift) & 31) << 24) | \
14 (((level) & 15) << 0) | \
15 (!!(direction) << 30) | \
17#define RELEASE(shift, exp) (\
18 (((shift) & 31) << 16) | \
36static void spu_adsr_capture(
53 spu_wait_status_bit11_flip();
57 ramsyscall_printf(
"spu_adsr_capture: drain stalled at envx=%04x after %u ticks\n",
61 spu_wait_status_bit11_flip();
70 spu_wait_status_bit11_flip();
71 SPU_VOICES[1].adsrLo = (uint16_t)(adsr & 0xFFFF);
82 ramsyscall_printf(
"spu_adsr_capture: envelope never left zero for adsr=%08x\n", adsr);
89 for (
unsigned i = 1;
i < n_samples;
i++) {
90 spu_wait_status_bit11_flip();
99static void spu_adsr_capture_with_keyoff(
105 spu_adsr_capture(adsr, envx_out, keyoff_at + 1);
106 for (
unsigned i = keyoff_at + 1;
i < n_samples;
i++) {
107 spu_wait_status_bit11_flip();
158 (got) <= (uint16_t)((nominal) +
ENVX_MARGIN(step)))
166 spu_adsr_capture(
ATTACK(2, 12, 0) | base, envx, 4);
172 spu_adsr_capture(
ATTACK(3, 12, 0) | base, envx, 4);
178 spu_adsr_capture(
ATTACK(2, 24, 0) | base, envx, 48);
179 for (
i = 0;
i < 17;
i++)
181 for (
i = 17;
i < 33;
i++)
183 for (
i = 33;
i < 48;
i++)
186 spu_adsr_capture(
ATTACK(3, 24, 0) | base, envx, 48);
187 for (
i = 0;
i < 17;
i++)
189 for (
i = 17;
i < 33;
i++)
191 for (
i = 33;
i < 48;
i++)
201 spu_adsr_capture(
ATTACK(0, 0, 0) | base, envx, 1);
204 spu_adsr_capture(
ATTACK(1, 0, 0) | base, envx, 1);
207 spu_adsr_capture(
ATTACK(0, 11, 0) | base, envx, 4);
213 spu_adsr_capture(
ATTACK(1, 11, 0) | base, envx, 4);
219 spu_adsr_capture(
ATTACK(0, 12, 0) | base, envx, 32);
240 spu_adsr_capture(
ATTACK(1, 12, 0) | base, envx, 4);
246 spu_adsr_capture(
ATTACK(0, 23, 0) | base, envx, 48);
247 for (
i = 0;
i < 9;
i++)
249 for (
i = 9;
i < 17;
i++)
251 for (
i = 17;
i < 25;
i++)
253 for (
i = 25;
i < 33;
i++)
255 for (
i = 33;
i < 41;
i++)
257 for (
i = 41;
i < 48;
i++)
260 spu_adsr_capture(
ATTACK(1, 23, 0) | base, envx, 48);
261 for (
i = 0;
i < 9;
i++)
263 for (
i = 9;
i < 17;
i++)
265 for (
i = 17;
i < 25;
i++)
267 for (
i = 25;
i < 33;
i++)
269 for (
i = 33;
i < 41;
i++)
271 for (
i = 41;
i < 48;
i++)
274 spu_adsr_capture(
ATTACK(0, 24, 0) | base, envx, 48);
275 for (
i = 0;
i < 17;
i++)
277 for (
i = 17;
i < 33;
i++)
279 for (
i = 33;
i < 48;
i++)
282 spu_adsr_capture(
ATTACK(1, 24, 0) | base, envx, 48);
283 for (
i = 0;
i < 17;
i++)
285 for (
i = 17;
i < 33;
i++)
287 for (
i = 33;
i < 48;
i++)
298 spu_adsr_capture(
ATTACK(0, 12, 1) | base, envx, 32);
350 for (
unsigned i = 10;
i < 16;
i++)
413 for (
unsigned i = 10;
i < 16;
i++)
419 for (
unsigned i = 3;
i < 16;
i++)
425 for (
unsigned i = 2;
i < 16;
i++)
431 for (
unsigned i = 1;
i < 16;
i++)
437 for (
unsigned i = 1;
i < 16;
i++)
451 for (
unsigned i = 3;
i < 8;
i++)
462 for (
unsigned i = 5;
i < 8;
i++)
478 for (
unsigned i = 10;
i < 16;
i++)
520 for (
unsigned i = 4;
i < 8;
i++)
535 for (
unsigned i = 9;
i < 16;
i++)
639 spu_adsr_capture_with_keyoff(
662 for (
unsigned i = 19;
i < 24;
i++)
665 spu_adsr_capture_with_keyoff(
681 spu_adsr_capture_with_keyoff(
698 spu_adsr_capture_with_keyoff(
CESTER_TEST(cdlGetLocL, test_instances, int resetDone=resetCDRom();if(!resetDone) { cester_assert_true(resetDone);return;} initializeTime();CDROM_REG0=0;CDROM_REG1=CDL_GETLOCL;uint32_t ackTime=waitCDRomIRQ();uint8_t cause1=ackCDRomCause();uint8_t ctrl1=CDROM_REG0 &~3;uint8_t response[16];uint8_t responseSize=readResponse(response);uint8_t ctrl2=CDROM_REG0 &~3;CDROM_REG0=1;uint8_t cause1b=CDROM_REG3_UC;cester_assert_uint_eq(3, cause1);cester_assert_uint_eq(0xe0, cause1b);cester_assert_uint_eq(0x38, ctrl1);cester_assert_uint_eq(0x18, ctrl2);cester_assert_uint_eq(8, responseSize);cester_assert_uint_ge(ackTime, 500);cester_assert_uint_lt(ackTime, 7000);ramsyscall_printf("Basic getlocL, ack in %ius\n", ackTime);) CESTER_TEST(cdlGetLocLafterSeekP
cester_assert_uint_eq(5, cause1)
CESTER_BODY(static void hexdump(const void *data_, unsigned size) { const uint8_t *data=(const uint8_t *) data_;char ascii[17];ascii[16]=0;for(unsigned i=0;i< size;i++) { if(i % 16==0) ramsyscall_printf("%08x |", i);ramsyscall_printf("%02X ", data[i]);ascii[i % 16]=data[i] >=' ' &&data[i]<='~' ? data[i] :'.';unsigned j=i+1;if((j % 8==0)||(j==size)) { ramsyscall_printf(" ");if(j % 16==0) { ramsyscall_printf("| %s \n", ascii);} else if(j==size) { ascii[j % 16]=0;if(j % 16<=8) ramsyscall_printf(" ");for(j %=16;j< 16;j++) ramsyscall_printf(" ");ramsyscall_printf("| %s \n", ascii);} } } } static int s_interruptsWereEnabled=0;static uint16_t s_oldMode=0;static uint32_t s_lastHSyncCounter=0;static uint32_t s_currentTime=0;static uint32_t s_oldIMASK=0;static const unsigned US_PER_HBLANK=64;struct LocPResult { uint8_t track, index, m, s, f, am, as, af;uint8_t padding[8];};static uint8_t btoi(uint8_t b) { return(b > > 4) *10+(b &0xf);} static uint8_t itob(uint8_t i) { return(i/10) *16+(i % 10);} static int isValidBCD(uint8_t b) { return(b &0xf)< 10 &&(b > > 4)< 10;} static uint32_t MSF2LBA(uint8_t m, uint8_t s, uint8_t f) { return(m *60+s) *75+f;} static uint8_t readResponse(uint8_t response[16]) { uint8_t responseSize=0;while((CDROM_REG0 &0x20) &&(responseSize< 16)) { response[responseSize++]=CDROM_REG1;} return responseSize;} static uint8_t discardResponse() { uint8_t response[16];return readResponse(response);} static inline void initializeTime() { while(1) { uint32_t init=COUNTERS[1].value;uint32_t counter;while((counter=COUNTERS[1].value)==init);if(counter !=COUNTERS[1].value) continue;s_lastHSyncCounter=counter;break;} s_currentTime=0;} static inline uint32_t updateTime() { uint32_t lastHSyncCounter=s_lastHSyncCounter;uint32_t hsyncCounter;while(1) { hsyncCounter=COUNTERS[1].value;if(hsyncCounter !=COUNTERS[1].value) continue;break;} if(hsyncCounter< lastHSyncCounter) { hsyncCounter+=0x10000;} uint32_t currentTime=s_currentTime=s_currentTime+(hsyncCounter - lastHSyncCounter) *US_PER_HBLANK;s_lastHSyncCounter=hsyncCounter;return currentTime;} static inline uint32_t waitCDRomIRQ() { uint32_t time;do { time=updateTime();} while((IREG &IRQ_CDROM)==0);IREG &=~IRQ_CDROM;return time;} static inline int waitCDRomIRQWithTimeout(uint32_t *timeoutp) { uint32_t time=updateTime();uint32_t timeout= *timeoutp+time;do { time=updateTime();} while(((IREG &IRQ_CDROM)==0) &&(time<=timeout));int ret=(IREG &IRQ_CDROM) !=0; *timeoutp=time;IREG &=~IRQ_CDROM;return ret;} static inline uint8_t ackCDRomCause() { CDROM_REG0=1;uint8_t cause=CDROM_REG3_UC;if(cause &7) { CDROM_REG0=1;CDROM_REG3=7;} if(cause &0x18) { CDROM_REG0=1;CDROM_REG3=cause &0x18;} return cause &7;} int setMode(uint8_t mode) { uint8_t cause;CDROM_REG0=0;CDROM_REG2=mode;CDROM_REG1=CDL_SETMODE;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;return 1;} static inline int resetCDRom() { uint8_t cause;CDROM_REG0=1;CDROM_REG3=0x1f;CDROM_REG0=1;CDROM_REG2=0x1f;CDROM_REG0=0;CDROM_REG1=CDL_INIT;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=2) return 0;initializeTime();while(updateTime()< 10000);return setMode(0);} static int setLoc(uint8_t minute, uint8_t second, uint8_t frame) { uint8_t cause;CDROM_REG0=0;CDROM_REG2=minute;CDROM_REG2=second;CDROM_REG2=frame;CDROM_REG1=CDL_SETLOC;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;return 1;} static int seekPTo(uint8_t minute, uint8_t second, uint8_t frame) { uint8_t cause;CDROM_REG0=0;CDROM_REG2=minute;CDROM_REG2=second;CDROM_REG2=frame;CDROM_REG1=CDL_SETLOC;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;CDROM_REG0=0;CDROM_REG1=CDL_SEEKP;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=2) return 0;return 1;} static int seekLTo(uint8_t minute, uint8_t second, uint8_t frame) { uint8_t cause;CDROM_REG0=0;CDROM_REG2=minute;CDROM_REG2=second;CDROM_REG2=frame;CDROM_REG1=CDL_SETLOC;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;CDROM_REG0=0;CDROM_REG1=CDL_SEEKL;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=3) return 0;waitCDRomIRQ();cause=ackCDRomCause();CDROM_REG1;if(cause !=2) return 0;return 1;} uint8_t getCtrl() { uint8_t cause;CDROM_REG0=0;CDROM_REG1=CDL_NOP;waitCDRomIRQ();ackCDRomCause();uint8_t ctrl=CDROM_REG1;return ctrl;}) CESTER_BEFORE_ALL(cpu_tests
#define SPU_VOICES
Definition spu.h:42
#define SPU_KEY_ON_LOW
Definition spu.h:88
#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 CESTER_MAYBE_TEST
Definition cop0.c:34
ramsyscall_printf("=== e01_kseg1_reads_no_fill ===\n")
int i
Definition gte-regio.c:297
int base
Definition gentable.py:114
cester_assert_true(seekDone)
spu_tests
Definition spu-adpcm-edge.c:189
#define ASSERT_ENVX_NEAR(nominal, step, got)
#define DECAY(shift)
Definition spu-adsr.c:9
#define RELEASE(shift, exp)
Definition spu-adsr.c:17
#define ENVX_MARGIN(step)
#define ADSR_DRAIN_MAX_TICKS
#define SUSTAIN(step, shift, level, direction, exp)
Definition spu-adsr.c:11
#define ATTACK(step, shift, exp)
Definition spu-adsr.c:5
#define ADSR_ONSET_MAX_SPINS
#define SPU_UPLOAD_ADDR
Definition spu-capamp.c:31
void uint32_t(classId, spec)