1
0
Fork 0
forked from len0rd/rockbox

Archos recorders: New recording data transfer routine. Not asm optimised this time, but it should lower the possibility of broken recordings a little.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6511 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2005-05-23 18:56:15 +00:00
parent ac31e6af87
commit ff3add9f20

View file

@ -525,35 +525,16 @@ static unsigned long num_recorded_frames;
static void drain_dma_buffer(void) static void drain_dma_buffer(void)
{ {
asm ( while (PBDRH & 0x40)
"mov #0x40,r2 \n" /* mask for EOD check */ {
"bra .d_start \n" xor_b(0x08, &PADRH);
"mov.b @%0,r1 \n" /* read PBDR (first time) */
".d_loop: \n" while (PBDRH & 0x80);
"xor.b #0x08,@(r0,gbr) \n" /* set PR active */
".d_wait1: \n"
"mov.b @%0,r1 \n" /* read PBDR */
"cmp/pz r1 \n" /* and wait for PRTW */
"bf .d_wait1 \n"
"xor.b #0x08,@(r0,gbr) \n" /* reset PR to inactive */ xor_b(0x08, &PADRH);
".d_wait2: \n"
"mov.b @%0,r1 \n" /* read PBDR */
"cmp/pz r1 \n" /* and wait for /PRTW */
"bt .d_wait2 \n"
".d_start: \n" while (!(PBDRH & 0x80));
"tst r1,r2 \n" /* EOD low? */ }
"bf .d_loop \n" /* no: next pass */
: /* outputs */
: /* inputs */
/* %0 */ "r"(PBDR_ADDR),
/* %1 = r0 */ "z"(&PADRH)
: /* clobbers */
"r1","r2"
);
} }
void rec_tick (void) __attribute__ ((section (".icode"))); void rec_tick (void) __attribute__ ((section (".icode")));
@ -561,67 +542,44 @@ void rec_tick(void)
{ {
int i; int i;
int num_bytes; int num_bytes;
if(is_recording && (PBDR & 0x4000)) int delay;
char data;
if(is_recording && (PBDRH & 0x40))
{ {
#ifdef DEBUG #ifdef DEBUG
timing_info[timing_info_index++] = current_tick; timing_info[timing_info_index++] = current_tick;
TCNT2 = 0; TCNT2 = 0;
#endif /* #ifdef DEBUG */ #endif /* #ifdef DEBUG */
/* We read as long as EOD is high, but max 30 bytes. */ i = 0;
asm ( while (PBDRH & 0x40) /* We try to read as long as EOD is high */
"mov #30,r3 \n" /* i_max = 30 */ {
"mov #0x40,r2 \n" /* mask for EOD check */ xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
"mov #0,%0 \n" /* i = 0; */
"add %2,%1 \n" /* audiobuf_write -> cur_addr */
"add %2,%3 \n" /* audiobuflen -> end_addr */
"bra .r_start \n"
"mov.b @%4,r1 \n" /* read PBDR (first time) */
".align 2 \n" delay = 0;
while (PBDRH & 0x80) /* Wait until /RTW becomes active */
{
delay++;
if (delay > 100) /* Bail out if we have to wait too long */
{ /* i.e. the MAS doesn't want to talk to us */
xor_b(0x08, &PADRH); /* Set PR inactive */
goto transfer_end; /* and get out of here */
}
}
".r_loop: \n" data = *(unsigned char *)0x04000000; /* read data byte */
"xor.b #0x08,@(r0,gbr) \n" /* set PR active */
".r_wait1: \n"
"mov.b @%4,r1 \n" /* read PBDR */
"cmp/pz r1 \n" /* and wait for PRTW */
"bf .r_wait1 \n"
"mov.b @%6,r1 \n" /* read byte from mas */ xor_b(0x08, &PADRH); /* Set PR inactive */
"add #1,%0 \n" /* i++; */
"mov.b r1,@%1 \n" /* store byte */
"add #1,%1 \n" /* increment current address */
"cmp/hi %1,%3 \n" /* end address reached? */ audiobuf[audiobuf_write++] = data;
"bt .r_nowrap \n" /* no: do nothing */
"mov %2,%1 \n" /* yes: reset to start address */
".r_nowrap: \n"
"xor.b #0x08,@(r0,gbr) \n" /* set PR inactive again */ if (audiobuf_write >= audiobuflen)
".r_wait2: \n" audiobuf_write = 0;
"mov.b @%4,r1 \n" /* read PBDR */
"cmp/pz r1 \n" /* and wait for /PRTW */
"bt .r_wait2 \n"
".r_start: \n" i++;
"tst r2,r1 \n" /* EOD low? */ }
"bt .r_end \n" /* yes: end of transfer */ transfer_end:
"cmp/hi %0,r3 \n" /* i < i_max? */
"bt .r_loop \n" /* yes: next pass */
".r_end: \n"
"sub %2,%1 \n" /* cur_addr -> audiobuf_write */
: /* outputs */
/* %0 */ "=&r"(i),
/* %1, in & out */ "+r"(audiobuf_write)
: /* inputs */
/* %2 */ "r"(audiobuf),
/* %3 */ "r"(audiobuflen),
/* %4 */ "r"(PBDR_ADDR),
/* %5 = r0 */ "z"(&PADRH),
/* %6 */ "r"(0x4000000)
: /* clobbers */
"r1","r2","r3"
);
#ifdef DEBUG #ifdef DEBUG
timing_info[timing_info_index++] = TCNT2 + (i << 16); timing_info[timing_info_index++] = TCNT2 + (i << 16);
timing_info_index &= 0x3ff; timing_info_index &= 0x3ff;