Skip to content

Commit

Permalink
Improved the way sample data requests from arm7 to arm9 are handled
Browse files Browse the repository at this point in the history
  • Loading branch information
Gericom committed Aug 19, 2019
1 parent 6609ad3 commit 70aeb4d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 149 deletions.
105 changes: 21 additions & 84 deletions arm7/source/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,17 @@ static void gba_sound_update_ds_channels()
//soundBufferVirtualReadOffset = 0;
//soundBufferVirtualWriteOffset = soundBufferWriteOffset;


REG_SOUND[0].CNT = 0;
REG_SOUND[1].CNT = 0;
REG_SOUND[0].SAD = (u32)&soundBuffer[0];
REG_SOUND[1].SAD = (u32)&soundBuffer[0];
REG_SOUND[0].TMR = (u16)(-(33513982 / 2) / sampleFreq); //(u16)-1253;//-1594; //-1253
REG_SOUND[1].TMR = (u16)(-(33513982 / 2) / sampleFreq); //(u16)-1253;//-1594; //-1253
REG_SOUND[0].TMR = sTimerReloadVals[sChannelATimer]; //(u16)-1253;//-1594; //-1253
REG_SOUND[1].TMR = sTimerReloadVals[sChannelATimer]; //(u16)-1253;//-1594; //-1253
REG_SOUND[0].PNT = 0;
REG_SOUND[1].PNT = 0;
REG_SOUND[0].LEN = SOUND_BUFFER_SIZE >> 2; //396 * 10;
REG_SOUND[1].LEN = SOUND_BUFFER_SIZE >> 2; //396 * 10;
REG_SOUND[0].CNT = 0;
REG_SOUND[1].CNT = 0;

//REG_TM[2].CNT_L = TIMER_FREQ(13378);

Expand All @@ -100,57 +101,7 @@ static void gba_sound_update_ds_channels()

void gba_sound_notify_reset()
{
return;
/*if(sampleFreq <= 0)
return;
if(!(*((vu32*)0x04000136) & 1))
gba_sound_resync();
//old value
u16 count = REG_TM[1].CNT_L; //in samples
if(count < 20)
return;//ignore
//reset
REG_TM[0].CNT_H = 0;
REG_TM[1].CNT_H = 0;
REG_TM[0].CNT_L = TIMER_FREQ(sampleFreq);///*10512);///13378);//10512);
REG_TM[1].CNT_L = 0;
REG_TM[1].CNT_H = REG_TMXCNT_H_E | REG_TMXCNT_H_CH;
REG_TM[0].CNT_H = REG_TMXCNT_H_E;
uint32_t newSamplesPerBlock = (count + 8) & ~0xF;
if(newSamplesPerBlock > samplesPerBlock * 3)
gba_sound_resync();
//if(samplesPerBlock == 0)
samplesPerBlock = newSamplesPerBlock;
//else
// samplesPerBlock = /*(((3 * samplesPerBlock + (/(count + 8) & ~0xF;//)) / 4) + 8) & ~0xF;//(u32)(((u64)count * 598261ull + 298685ull) / 597370ull);
//append the block to the ringbuffer
if(samplesPerBlock == 0 || samplesPerBlock > SOUND_BUFFER_SIZE)
{
gba_sound_resync();
return;
}
if(SOUND_BUFFER_SIZE - soundBufferWriteOffset >= samplesPerBlock)
{
while(dmaBusy(2));
dmaCopyWordsAsynch(2, (void*)0x23F8000, &soundBuffer[soundBufferWriteOffset], samplesPerBlock);
//memcpy(&soundBuffer[soundBufferWriteOffset], (void*)0x23F8000, samplesPerBlock);
}
else
{
//wrap around
uint32_t left = SOUND_BUFFER_SIZE - soundBufferWriteOffset;
while(dmaBusy(2));
dmaCopyWordsAsynch(2, (void*)0x23F8000, &soundBuffer[soundBufferWriteOffset], left);
while(dmaBusy(3));
dmaCopyWordsAsynch(3, (void*)(0x23F8000 + left), &soundBuffer[0], samplesPerBlock - left);
//memcpy(&soundBuffer[soundBufferWriteOffset], (void*)0x23F8000, left);
//memcpy(&soundBuffer[0], (void*)(0x23F8000 + left), samplesPerBlock - left);
}
soundBufferWriteOffset += samplesPerBlock;
if(soundBufferWriteOffset >= SOUND_BUFFER_SIZE)
soundBufferWriteOffset -= SOUND_BUFFER_SIZE;
//soundBufferVirtualWriteOffset += samplesPerBlock;
gba_sound_update_ds_channels();*/

}

void gba_sound_vblank()
Expand All @@ -159,17 +110,10 @@ void gba_sound_vblank()

void gba_sound_fifo_update()
{
while (vram_cd->sound_emu_work.resp_size > 0)
while (vram_cd->sound_emu_work.resp_read_ptr != vram_cd->sound_emu_work.resp_write_ptr)
{
gba_sound_fifo_write16((u8*)&vram_cd->sound_emu_work.resp_queue[vram_cd->sound_emu_work.resp_read_ptr][0]);
vram_cd->sound_emu_work.resp_read_ptr++;
if (vram_cd->sound_emu_work.resp_read_ptr >= SOUND_EMU_QUEUE_LEN)
vram_cd->sound_emu_work.resp_read_ptr -= SOUND_EMU_QUEUE_LEN;
lock_lock(&vram_cd->sound_emu_work.resp_size_lock);
{
vram_cd->sound_emu_work.resp_size--;
}
lock_unlock(&vram_cd->sound_emu_work.resp_size_lock);
vram_cd->sound_emu_work.resp_read_ptr = (vram_cd->sound_emu_work.resp_read_ptr + 1) & (SOUND_EMU_QUEUE_LEN - 1);
}
gba_sound_update_ds_channels();
}
Expand All @@ -181,23 +125,17 @@ extern "C" void timer3_overflow_irq()
if (sampcnter == 0) //(FIFO_BLOCK_SIZE - 1))
{
gba_sound_fifo_update();
if (vram_cd->sound_emu_work.req_size < SOUND_EMU_QUEUE_LEN)
int writeLength = vram_cd->sound_emu_work.req_read_ptr - vram_cd->sound_emu_work.req_write_ptr - 1;
if (writeLength < 0)
writeLength += SOUND_EMU_QUEUE_LEN;
if (writeLength != 0)
{
vram_cd->sound_emu_work.req_queue[vram_cd->sound_emu_work.req_write_ptr] = srcAddress;
vram_cd->sound_emu_work.req_write_ptr++;
if (vram_cd->sound_emu_work.req_write_ptr >= SOUND_EMU_QUEUE_LEN)
vram_cd->sound_emu_work.req_write_ptr -= SOUND_EMU_QUEUE_LEN;
lock_lock(&vram_cd->sound_emu_work.req_size_lock);
{
vram_cd->sound_emu_work.req_size++;
}
lock_unlock(&vram_cd->sound_emu_work.req_size_lock);
//invoke an irq on arm9
*((vu32*)0x04000180) |= (1 << 13);
vram_cd->sound_emu_work.req_write_ptr = (vram_cd->sound_emu_work.req_write_ptr + 1) & (SOUND_EMU_QUEUE_LEN - 1);
}
else
{
vram_cd->sound_emu_work.req_queue[vram_cd->sound_emu_work.req_write_ptr] = srcAddress;
/*vram_cd->sound_emu_work.req_queue[vram_cd->sound_emu_work.req_write_ptr] = srcAddress;
vram_cd->sound_emu_work.req_read_ptr++;
if (vram_cd->sound_emu_work.req_read_ptr >= SOUND_EMU_QUEUE_LEN)
vram_cd->sound_emu_work.req_read_ptr -= SOUND_EMU_QUEUE_LEN;
Expand All @@ -211,11 +149,10 @@ extern "C" void timer3_overflow_irq()
soundBufferWriteOffset += FIFO_BLOCK_SIZE;
if (soundBufferWriteOffset >= SOUND_BUFFER_SIZE)
soundBufferWriteOffset -= SOUND_BUFFER_SIZE;
gba_sound_update_ds_channels();

//invoke an irq on arm9
*((vu32*)0x04000180) |= (1 << 13);
gba_sound_update_ds_channels();*/
}
//invoke an irq on arm9
*((vu32*)0x04000180) |= (1 << 13);
srcAddress += FIFO_BLOCK_SIZE; //16;
}
sampcnter++;
Expand All @@ -234,11 +171,11 @@ void gbas_updateChannelATimer()
REG_TM[3].CNT_H = 0;
if (sampleFreq != 0)
{
REG_TM[3].CNT_L = TIMER_FREQ(sampleFreq);
REG_TM[3].CNT_L = ((s16)sTimerReloadVals[sChannelATimer]) << 1;
REG_TM[3].CNT_H = REG_TMXCNT_H_E | REG_TMXCNT_H_I;
REG_IE |= (1 << 6);
REG_SOUND[0].TMR = (u16)(-(33513982 / 2) / sampleFreq);
REG_SOUND[1].TMR = (u16)(-(33513982 / 2) / sampleFreq);
REG_SOUND[0].TMR = sTimerReloadVals[sChannelATimer];
REG_SOUND[1].TMR = sTimerReloadVals[sChannelATimer];
REG_SOUND[0].CNT = REG_SOUNDXCNT_E | REG_SOUNDXCNT_FORMAT(REG_SOUNDXCNT_FORMAT_PCM8) |
REG_SOUNDXCNT_REPEAT(REG_SOUNDXCNT_REPEAT_LOOP) | REG_SOUNDXCNT_PAN(0) | REG_SOUNDXCNT_VOLUME(0x7F);
REG_SOUND[1].CNT = REG_SOUNDXCNT_E | REG_SOUNDXCNT_FORMAT(REG_SOUNDXCNT_FORMAT_PCM8) |
Expand Down Expand Up @@ -291,7 +228,7 @@ void gba_sound_set_src(uint32_t address)
//timer3_overflow_irq();
if (sampleFreq != 0)
{
REG_TM[3].CNT_L = TIMER_FREQ(sampleFreq); // * FIFO_BLOCK_SIZE;//* 64 / FIFO_BLOCK_SIZE);//16);
REG_TM[3].CNT_L = ((s16)sTimerReloadVals[sChannelATimer]) << 1; // * FIFO_BLOCK_SIZE;//* 64 / FIFO_BLOCK_SIZE);//16);
REG_TM[3].CNT_H = REG_TMXCNT_H_E | REG_TMXCNT_H_I; // | REG_TMXCNT_H_PS_64;
REG_IE |= (1 << 6);
}
Expand Down
121 changes: 60 additions & 61 deletions arm9/source/emu/irq.s
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,6 @@ write_address_ie_if:
irq_handler:
STMFD SP!, {R0-R3,R12,LR}

//check for arm7 interrupt

//make use of the backwards compatible version
//of the data rights register, so we can use 0xFFFFFFFF instead of 0x33333333
mov r0, #0xFFFFFFFF
Expand All @@ -183,37 +181,54 @@ irq_handler:
tst r1, #0x80000000
beq cap_control
irq_cont:
ldr r1, [r12, #0x214]
ldr r1, [r12, #0x214]
ldr r3, [r12, #0x210]
and r1, r3
tst r1, #(1 << 1) //hblank
beq 1f
ldrh r2, [r12, #6]
cmp r2, #160
blt 1f //gba normal scanlines
blt irq_cont_handle_gba //1f //gba normal scanlines
cmp r2, #192
bge 1f //vblank
bge irq_cont_handle_gba //1f //vblank

//clear hblank irq flag
mov r2, #(1 << 1)
str r2, [r12, #0x214]

//check if any irqs are left
bic r1, #(1 << 1)
ldr r3, [r12, #0x210]
tst r1, r3
bics r1, #(1 << 1)
beq finish_nohandle

1:
//vcount irq priority
tst r1, #(1 << 2)
bne irq_cont_handle_gba

//test for arm7->arm9 irq
tst r1, #(1 << 16)
bne irq_handler_arm7_irq

irq_cont_handle_gba:
ldr r2, [r12, #0x210]
bic r2, #(1 << 16)
ldr r1,= pu_data_permissions
str r2, [r12, #0x210]
mcr p15, 0, r1, c5, c0, 2

ADR LR, loc_138
LDR PC, [R12,#-4]
loc_138:

mov r0, #0xFFFFFFFF
mcr p15, 0, r0, c5, c0, 0
mov r12, #0x04000000
ldr r1, [r12, #0x210]
ldr r2,= pu_data_permissions
orr r1, #(1 << 16)
str r1, [r12, #0x210]
mcr p15, 0, r2, c5, c0, 2

LDMFD SP!, {R0-R3,R12,LR}
SUBS PC, LR, #4

Expand All @@ -224,64 +239,48 @@ irq_handler_arm7_irq:
beq sdsave_request

ldr r12,= sound_sound_emu_work_uncached
1:
ldrb r2, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 1)]
cmp r2, #SOUND_EMU_QUEUE_LEN
bge 4f

ldrb r2, [r12, #1]
cmp r2, #0
beq 4f

ldrb r2, [r12, #3]
add r3, r2, #1
cmp r3, #SOUND_EMU_QUEUE_LEN
subge r3, #SOUND_EMU_QUEUE_LEN
strb r3, [r12, #3]
ldrb lr, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 2)] //resp_write_ptr
//1:
ldrb r3, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 3)] //resp_read_ptr
add r2, lr, #1
subs r2, r3, r2
addmis r2, #SOUND_EMU_QUEUE_LEN
beq 4f //response queue full

add r3, r12, r2, lsl #2
ldr r1, [r3, #4]
ldrb r2, [r12, #2] //req_write_ptr
ldrb r3, [r12, #3] //req_read_ptr
cmp r2, r3
beq 4f //request queue empty

ldrb lr, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 2)]
add r2, lr, #1
cmp r2, #SOUND_EMU_QUEUE_LEN
subge r2, #SOUND_EMU_QUEUE_LEN
strb r2, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 2)]
add r0, r12, r3, lsl #2
ldr r1, [r0, #4] //read address from req_queue

ldmia r1, {r0, r1, r2, r3}
add r3, #1
and r3, #(SOUND_EMU_QUEUE_LEN - 1)
strb r3, [r12, #3] //req_read_ptr

ldmia r1, {r0, r1, r2, r3} //fetch 16 samples
add lr, r12, lr, lsl #4
add lr, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 4)
stmia lr, {r0, r1, r2, r3}
stmia lr, {r0, r1, r2, r3} //store in resp_queue

mov r1, #1
add r3, r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4))
2:
swpb r1, r1, [r3]
cmp r1, #0
bne 2b
ldrb r2, [r3, #1]
add r2, #1
strb r2, [r3, #1]
strb r1, [r3]

mov r1, #1
3:
swpb r1, r1, [r12]
cmp r1, #0
bne 3b
ldrb r2, [r12, #1]
sub r2, #1
strb r2, [r12, #1]
strb r1, [r12]

cmp r2, #0
bgt 1b
4:
ldrb lr, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 2)] //resp_write_ptr
add lr, #1
and lr, #(SOUND_EMU_QUEUE_LEN - 1)
strb lr, [r12, #(4 + (SOUND_EMU_QUEUE_LEN * 4) + 2)] //resp_write_ptr
//b 1b

ldrb r2, [r12, #2] //req_write_ptr
ldrb r3, [r12, #3] //req_read_ptr
mov r12, #0x04000000
cmp r2, r3
bne 5f //request queue not empty, don't clear irq

4:
mov r1, #(1 << 16)
str r1, [r12, #0x214]

5:
ldr r3, [r12, #0x210]

ldr r2,= fake_irq_flags
Expand All @@ -297,6 +296,11 @@ irq_handler_arm7_irq:
orrne r1, #(1 << 10) //dma 2

str r1, [r2]

ldr r2, [r12, #0x214]
bic r2, #(1 << 16)
orr r1, r2


//enable icache by pressing the R button
#if defined(ENABLE_WRAM_ICACHE) && defined(POSTPONED_ICACHE)
Expand All @@ -311,6 +315,7 @@ irq_handler_arm7_irq:

bne irq_cont_handle_gba

finish_nohandle:
ldr r1,= pu_data_permissions
mcr p15, 0, r1, c5, c0, 2
LDMFD SP!, {R0-R3,R12,LR}
Expand All @@ -324,12 +329,6 @@ sdsave_request:
ldr r12,= sd_write_save
blx r12

finish_nohandle:
ldr r1,= pu_data_permissions
mcr p15, 0, r1, c5, c0, 2
LDMFD SP!, {R0-R3,R12,LR}
SUBS PC, LR, #4

cap_control:
eor r1, #0x00010000
tst r1, #0x00010000
Expand Down
8 changes: 4 additions & 4 deletions common/sound_emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ typedef struct
{
volatile u8 req_size_lock;
volatile u8 req_size;
u8 req_write_ptr;
u8 req_read_ptr;
volatile u8 req_write_ptr;
volatile u8 req_read_ptr;
u32 req_queue[SOUND_EMU_QUEUE_LEN];
volatile u8 resp_size_lock;
volatile u8 resp_size;
u8 resp_write_ptr;
u8 resp_read_ptr;
volatile u8 resp_write_ptr;
volatile u8 resp_read_ptr;
u32 resp_queue[SOUND_EMU_QUEUE_LEN][4];
//sound registers
u16 reg_gb_nr10;
Expand Down

0 comments on commit 70aeb4d

Please sign in to comment.