Skip to content

Commit

Permalink
Patch sound mixing code in the .data segment in runtime to save some …
Browse files Browse the repository at this point in the history
…cycles on memory reads and writes
  • Loading branch information
viciious committed Jul 11, 2023
1 parent 09f894b commit a5184cb
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 17 deletions.
7 changes: 6 additions & 1 deletion marshw.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ int Mars_GetWDTCount(void);
} \
} while (0)

#endif
#endif

#define Mars_PatchRAMCode(loc,inst) do {\
__asm volatile("mov.w %0, %1\n\t" : : "r"(inst), "m"(loc) : "memory"); \
Mars_ClearCacheLine(loc); \
} while(0)

uint16_t *Mars_FrameBufferLines(void);

Expand Down
76 changes: 60 additions & 16 deletions marssound.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,15 @@ int samplecount = 0;

static marsrb_t soundcmds = { 0 };

extern uintptr_t paintchan_movr5r1;
extern uintptr_t paintchan_movr5r1_ima;
extern uintptr_t paintchan_movr5r1_ima2x_1, paintchan_movr5r1_ima2x_2;

static void S_StartSoundReal(mobj_t* mobj, unsigned sound_id, int vol, getsoundpos_t getpos) ATTR_DATA_CACHE_ALIGN;
int S_PaintChannel4IMA(void* mixer, int16_t* buffer, int32_t cnt, int32_t scale) ATTR_DATA_CACHE_ALIGN;
int S_PaintChannel4IMA2x(void* mixer, int16_t* buffer, int32_t cnt, int32_t scale) ATTR_DATA_CACHE_ALIGN;
void S_PaintChannel8(void* mixer, int16_t* buffer, int32_t cnt, int32_t scale) ATTR_DATA_CACHE_ALIGN;
static void S_PaintChannel(sfxchannel_t *ch, int16_t* buffer) ATTR_DATA_CACHE_ALIGN;
static int S_PaintChannel(sfxchannel_t *ch, int16_t* buffer, int painted) ATTR_DATA_CACHE_ALIGN;
static void S_SpatializeAt(fixed_t*origin, mobj_t* listener, int* pvol, int* psep) ATTR_DATA_CACHE_ALIGN;
static void S_Spatialize(mobj_t* mobj, int* pvol, int* psep, getsoundpos_t getpos) ATTR_DATA_CACHE_ALIGN;
static void S_Update(int16_t* buffer) ATTR_DATA_CACHE_ALIGN;
Expand Down Expand Up @@ -569,10 +573,25 @@ static void S_UpdatePCM(void)
}
}

static void S_PaintChannel(sfxchannel_t *ch, int16_t* buffer)
static int S_PaintChannel(sfxchannel_t *ch, int16_t* buffer, int painted)
{
boolean patch;
const int mov0r1 = 0xE100;
const int movpr5r1 = 0x6152;
const int movp4r5r1 = 0x5151;

if (!ch->data)
return;
return 0;

patch = painted == 0;
if (patch)
{
/* PATCH */
Mars_PatchRAMCode(paintchan_movr5r1, mov0r1); /* mov #0,r1 */
Mars_PatchRAMCode(paintchan_movr5r1_ima, mov0r1); /* mov #0,r1 */
Mars_PatchRAMCode(paintchan_movr5r1_ima2x_1, mov0r1); /* mov #0,r1 */
Mars_PatchRAMCode(paintchan_movr5r1_ima2x_2, mov0r1); /* mov #0,r1 */
}

if (ch->width == 4)
{
Expand Down Expand Up @@ -622,6 +641,8 @@ static void S_PaintChannel(sfxchannel_t *ch, int16_t* buffer)

i = paintch(ch, (int16_t *)(end - i), i, 64);
} while (i > 0);

painted = MAX_SAMPLES - i;
}
else
{
Expand All @@ -630,7 +651,30 @@ static void S_PaintChannel(sfxchannel_t *ch, int16_t* buffer)
{
ch->data = NULL;
}

painted = MAX_SAMPLES;
}

if (patch)
{
int j;
int32_t *b2;

/* PATCH BACK */
Mars_PatchRAMCode(paintchan_movr5r1, movpr5r1); /* mov @r5,r1 */
Mars_PatchRAMCode(paintchan_movr5r1_ima, movpr5r1); /* mov @r5,r1 */
Mars_PatchRAMCode(paintchan_movr5r1_ima2x_1, movpr5r1); /* mov @r5,r1 */
Mars_PatchRAMCode(paintchan_movr5r1_ima2x_2, movp4r5r1); /* mov @(4,r5),r1 */

/* clear the remaining buffer */
b2 = (int32_t *)buffer + painted;
for (j = painted; j < MAX_SAMPLES; j++)
{
*b2++ = 0;
}
}

return painted;
}

static void S_Update(int16_t* buffer)
Expand All @@ -639,6 +683,7 @@ static void S_Update(int16_t* buffer)
int32_t *b2;
int c, l, h;
mobj_t* mo;
int painted = 0;
boolean spatialize;

S_UpdatePCM();
Expand Down Expand Up @@ -668,19 +713,8 @@ static void S_Update(int16_t* buffer)
return;
}

b2 = (int32_t *)buffer;
for (i = 0; i < MAX_SAMPLES / 8; i++)
{
*b2++ = 0, *b2++ = 0, *b2++ = 0, *b2++ = 0;
*b2++ = 0, *b2++ = 0, *b2++ = 0, *b2++ = 0;
}
for (i *= 8; i < MAX_SAMPLES; i++)
{
*b2++ = 0;
}

/* keep updating the channel until done */
S_PaintChannel(&pcmchannel, buffer);
painted += S_PaintChannel(&pcmchannel, buffer, painted);

spatialize = samplecount >= SPATIALIZATION_SRATE;
if (samplecount >= SPATIALIZATION_SRATE)
Expand Down Expand Up @@ -738,7 +772,17 @@ static void S_Update(int16_t* buffer)
ch->pan = sep;
}

S_PaintChannel(ch, buffer);
painted += S_PaintChannel(ch, buffer, painted);
}

// clear the buffer if we painted nothing
if (!painted)
{
b2 = (int32_t *)buffer;
for (i = 0; i < MAX_SAMPLES; i++)
{
*b2++ = 0;
}
}

#ifdef MARS
Expand Down
9 changes: 9 additions & 0 deletions sh2_mixer.s
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ mix_loop:
/* scale sample for left output */
muls.w r3,r13
add r10,r9 /* position += increment */
.global _paintchan_movr5r1
_paintchan_movr5r1:
mov.l @r5,r1
sts macl,r0

/* scale sample for right output */
Expand Down Expand Up @@ -270,6 +273,8 @@ mix4_gets:

/* scale sample for left output */
muls.w r3,r13
.global _paintchan_movr5r1_ima
_paintchan_movr5r1_ima:
mov.l @r5,r1
add r10,r9 /* position += increment */
sts macl,r0
Expand Down Expand Up @@ -462,6 +467,8 @@ mix4_gets2x:

/* scale sample for left output */
muls.w r3,r13
.global _paintchan_movr5r1_ima2x_1
_paintchan_movr5r1_ima2x_1:
mov.l @r5,r1
dt r6
add r10,r9 /* position += increment */
Expand All @@ -484,6 +491,8 @@ mix4_gets2x:
add r3,r1
mov.l r1,@r5

.global _paintchan_movr5r1_ima2x_2
_paintchan_movr5r1_ima2x_2:
mov.l @(4,r5),r1
cmp/hs r11,r9
add r3,r1
Expand Down

0 comments on commit a5184cb

Please sign in to comment.