Skip to content

Commit 5e0faae

Browse files
committed
Backport fixes and improvements from D32XR
1 parent 22da0b2 commit 5e0faae

File tree

9 files changed

+234
-77
lines changed

9 files changed

+234
-77
lines changed

cd/crt.s

+11-14
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ SPMain:
5555

5656
| wait for command in main comm port
5757
WaitCmd:
58+
tst.b updates_suspend
59+
bne WaitCmdPostUpdate
60+
5861
jsr S_Update
5962

63+
WaitCmdPostUpdate:
6064
tst.b 0x800E.w
6165
beq.b WaitCmd
6266
cmpi.b #'D,0x800E.w
@@ -92,8 +96,8 @@ WaitCmd:
9296
beq SfxStopSource
9397
cmpi.b #'G,0x800E.w
9498
beq SfxGetSourcePosition
95-
cmpi.b #'Y,0x800E.w
96-
beq SfxSourceIsPlaying
99+
cmpi.b #'E,0x800E.w
100+
beq SfxSuspendUpdates
97101

98102
move.b #'E,0x800F.w /* sub comm port = ERROR */
99103
WaitAck:
@@ -315,7 +319,6 @@ SfxUpdateSource:
315319
SfxGetSourcePosition:
316320
| void S_GetSourcePosition(uint8_t src_id);
317321
moveq #0,d0
318-
319322
move.w 0x8010.w,d0
320323
move.l d0,-(sp) /* src_id */
321324

@@ -327,17 +330,8 @@ SfxGetSourcePosition:
327330
move.b #'D,0x800F.w /* sub comm port = DONE */
328331
bra WaitAck
329332

330-
SfxSourceIsPlaying:
331-
| uint8_t S_SourceIsPlaying(uint8_t src_id);
332-
moveq #0,d0
333-
334-
move.w 0x8010.w,d0
335-
move.l d0,-(sp) /* src_id */
336-
337-
jsr S_SourceIsPlaying
338-
lea 4(sp),sp /* clear the stack */
339-
340-
move.b d0,0x8020.w /* state */
333+
SfxSuspendUpdates:
334+
move.b 0x8010.w,updates_suspend
341335

342336
move.b #'D,0x800F.w /* sub comm port = DONE */
343337
bra WaitAck
@@ -379,5 +373,8 @@ drive_init_parms:
379373
track_number:
380374
.word 0
381375

376+
updates_suspend:
377+
.byte 0
378+
382379
.global _start
383380
_start:

cd/s_channels.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ int8_t S_Chan_FrontBuffer(sfx_channel_t *chan) {
2020
return 1;
2121
}
2222
volatile uint8_t *ptr = S_Chan_RAMPtr(chan);
23+
uint16_t lo = *(ptr + 0); // LSB of PCM RAM location
2324
uint16_t hi = *(ptr + 2); // MSB of PCM RAM location
24-
return (hi & 0x8) != 0;
25+
if (CHBUF_SHIFT <= 8)
26+
return (lo & (1<<(CHBUF_SHIFT-1))) != 0;
27+
return (hi & (1<<(CHBUF_SHIFT-8))) != 0;
2528
}
2629

2730
// buffer we can paint to

cd/s_channels.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#define S_MAX_CHANNELS 8
88

9-
#define CHBUF_SHIFT 11
9+
#define CHBUF_SHIFT 9
1010
#define CHBUF_SIZE (1<<CHBUF_SHIFT)
1111
#define CHBUF_POS(b) ((b)<<CHBUF_SHIFT)
1212

cd/s_main.c

+7-20
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ void S_Clear(void)
3030
void S_Update(void)
3131
{
3232
static int s_upd = 0;
33+
sfx_source_t *src;
34+
3335
if (s_upd >= S_MAX_SOURCES) {
3436
s_upd = 0;
3537
}
36-
if (S_Src_Paint(&s_sources[ s_upd ])) {
37-
s_upd++;
38-
}
38+
39+
src = &s_sources[ s_upd++ ];
40+
S_Src_Paint(src);
3941
}
4042

4143
void S_SetBufferData(uint16_t buf_id, uint8_t *data, uint32_t data_len)
@@ -74,9 +76,9 @@ uint8_t S_PlaySource(uint8_t src_id, uint16_t buf_id, uint16_t freq, uint8_t pan
7476
src = &s_sources[ src_id - 1 ];
7577
buf = &s_buffers[ buf_id - 1 ];
7678

77-
S_Src_Stop( src );
79+
S_Src_Stop(src);
7880

79-
S_Src_Play( src, buf, freq, pan, vol, autoloop );
81+
S_Src_Play(src, buf, freq, pan, vol, autoloop);
8082

8183
if (!src->buf) {
8284
// refused to start
@@ -92,7 +94,6 @@ void S_UpdateSource(uint8_t src_id, uint16_t freq, uint8_t pan, uint8_t vol, uin
9294
if (src_id == 0 || src_id > S_MAX_SOURCES) {
9395
return;
9496
}
95-
9697
S_Src_Update(src, freq, pan, vol, autoloop);
9798
}
9899

@@ -103,7 +104,6 @@ void S_RewindSource(uint8_t src_id)
103104
if (src_id == 0 || src_id > S_MAX_SOURCES) {
104105
return;
105106
}
106-
107107
S_Src_Rewind(src);
108108
}
109109

@@ -124,7 +124,6 @@ void S_StopSource(uint8_t src_id)
124124
if (src_id == 0 || src_id > S_MAX_SOURCES) {
125125
return;
126126
}
127-
128127
S_Src_Stop( src );
129128
}
130129

@@ -135,17 +134,5 @@ uint16_t S_GetSourcePosition(uint8_t src_id)
135134
if (src_id == 0 || src_id > S_MAX_SOURCES) {
136135
return 0xffff;
137136
}
138-
139137
return S_Src_GetPosition(src);
140138
}
141-
142-
uint8_t S_SourceIsPlaying(uint8_t src_id)
143-
{
144-
sfx_source_t *src = &s_sources[ src_id - 1 ];
145-
146-
if (src_id == 0 || src_id > S_MAX_SOURCES) {
147-
return 0;
148-
}
149-
150-
return src->buf != 0/* && src->painted > 0*/;
151-
}

cd/s_main.h

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ void S_RewindSource(uint8_t src_id);
2222
void S_StopSource(uint8_t src_id);
2323
void S_PUnPSource(uint8_t src_id, uint8_t pause);
2424
uint16_t S_GetSourcePosition(uint8_t src_id);
25-
uint8_t S_SourceIsPlaying(uint8_t src_id);
2625

2726
#ifdef __cplusplus
2827
}

cd/s_sources.c

+82-39
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,40 @@
33
#include "s_buffers.h"
44
#include "pcm.h"
55

6-
#define S_PAINT_CHUNK 128 // the number of samples to paint in a single call of S_Src_Paint
6+
#define S_PAINT_CHUNK CHBUF_SIZE // the number of samples to paint in a single call of S_Src_Paint
77

88
sfx_source_t s_sources[ S_MAX_SOURCES ] = { { 0 } };
99

1010
void S_Src_Init(sfx_source_t *src)
1111
{
1212
src->buf = NULL;
1313
src->num_channels = 0;
14-
src->channels[0] = src->channels[1] = 0;
1514
src->rem = 0;
1615
src->eof = 0;
16+
src->backbuf = -1;
1717
}
1818

1919
void S_Src_Stop(sfx_source_t *src)
2020
{
2121
int i;
22+
23+
if (!src->buf) {
24+
return;
25+
}
26+
2227
for (i = 0; i < src->num_channels; i++) {
2328
S_Chan_Clear( &s_channels[ src->channels[ i ] ] );
2429
}
30+
2531
src->buf = NULL;
2632
src->freq = 0;
2733
src->painted = 0;
2834
src->num_channels = 0;
2935
src->rem = 0;
3036
src->eof = 1;
37+
src->backbuf = -1; // force data refresh on the next update
38+
39+
S_UpdateSourcesStatus();
3140
}
3241

3342
void S_Src_Rewind(sfx_source_t *src)
@@ -125,7 +134,7 @@ uint16_t S_Src_LoadSamples(sfx_source_t *src, uint16_t *pos, uint16_t len)
125134
return painted;
126135
}
127136

128-
int S_Src_Paint(sfx_source_t *src)
137+
void S_Src_Paint(sfx_source_t *src)
129138
{
130139
int i;
131140
uint16_t painted, rem;
@@ -135,21 +144,23 @@ int S_Src_Paint(sfx_source_t *src)
135144
// stream data
136145
if (!src->buf || !src->num_channels) {
137146
S_Src_Stop(src);
138-
return 1;
147+
return;
139148
}
140149

141150
// use position of the primary channel to determine backbuffer id
142151
prichan = &s_channels[ src->channels[ 0 ] ];
143152

144153
int8_t backbuf = S_Chan_BackBuffer( prichan );
145154
if (src->backbuf != backbuf) {
146-
if (src->eof) {
155+
if (src->eof > 1) {
147156
S_Src_Stop(src);
148-
return 1;
157+
return;
149158
}
150159

151160
src->backbuf = backbuf;
152161
src->rem = CHBUF_SIZE;
162+
if (src->eof)
163+
src->eof++;
153164

154165
for (i = 0; i < src->num_channels; i++ ) {
155166
uint16_t startblock;
@@ -161,7 +172,7 @@ int S_Src_Paint(sfx_source_t *src)
161172
}
162173
else {
163174
if (src->rem == 0) {
164-
return 1;
175+
return;
165176
}
166177
}
167178

@@ -206,43 +217,44 @@ int S_Src_Paint(sfx_source_t *src)
206217
src->rem = 0;
207218
}
208219

209-
if (src->rem == 0) {
210-
// copy channel parameters from source and update
211-
for (i = 0; i < src->num_channels; i++) {
212-
chan = &s_channels[ src->channels[ i ] ];
213-
chan->freq = src->freq;
214-
chan->env = src->env;
215-
chan->pan = src->pan[i];
216-
S_Chan_Update(chan);
217-
}
218-
219-
return 1;
220+
if (src->rem != 0) {
221+
return;
220222
}
221223

222-
return 0;
224+
// copy channel parameters from source and update
225+
for (i = 0; i < src->num_channels; i++) {
226+
chan = &s_channels[ src->channels[ i ] ];
227+
chan->freq = src->freq;
228+
chan->env = src->env;
229+
chan->pan = src->pan[i];
230+
S_Chan_Update(chan);
231+
}
223232
}
224233

225234
void S_Src_Play(sfx_source_t *src, sfx_buffer_t *buf, uint16_t freq, uint8_t pan, uint8_t vol, uint8_t autoloop)
226235
{
227236
int i;
228237
sfx_channel_t *chan;
229238

239+
if (src->num_channels > 0 && src->num_channels != buf->num_channels) {
240+
// we need to re-allocate channels for this source
241+
S_Src_Stop(src);
242+
}
243+
230244
src->buf = buf;
231-
src->backbuf = -1; // force data refresh on the next update
232245
src->pan[0] = S_Chan_MidiPan(pan);
233246
src->env = vol;
234247
src->autoloop = autoloop;
235-
src->channels[ 0 ] = 0;
236-
src->channels[ 1 ] = 0;
237248
src->freq = freq ? freq : buf->freq;
238249
src->paused = 0;
239250
src->eof = 0;
251+
src->painted = 0;
252+
//src->backbuf = -1;
240253

241254
if (!buf || !buf->num_channels || !buf->data || !src->freq) {
242255
goto noplay;
243256
}
244257

245-
src->num_channels = buf->num_channels;
246258
src->adpcm.codec = buf->adpcm_codec;
247259
src->adpcm.block_size = buf->adpcm_block_size;
248260

@@ -252,29 +264,40 @@ void S_Src_Play(sfx_source_t *src, sfx_buffer_t *buf, uint16_t freq, uint8_t pan
252264
src->pan[1] = 0b10000000; // right
253265
}
254266

255-
for (i = 0; i < buf->num_channels; i++) {
256-
src->channels[ i ] = S_AllocChannel();
257-
if (!src->channels[ i ]) {
258-
// out of free channels
259-
break;
267+
if (src->num_channels != buf->num_channels) {
268+
for (i = 0; i < buf->num_channels; i++) {
269+
src->channels[ i ] = S_AllocChannel();
270+
if (!src->channels[ i ]) {
271+
// out of free channels
272+
break;
273+
}
274+
chan = &s_channels[ src->channels[ i ] ];
275+
chan->freq = src->freq;
260276
}
261-
chan = &s_channels[ src->channels[ i ] ];
262-
chan->freq = src->freq;
263-
}
264277

265-
if (i < buf->num_channels) {
266-
// deallocate channels, exit
267-
while (i-- > 0) {
278+
src->num_channels = buf->num_channels;
279+
280+
if (i < buf->num_channels) {
281+
// deallocate channels, exit
282+
while (i-- > 0) {
283+
chan = &s_channels[ src->channels[ i ] ];
284+
chan->freq = 0;
285+
}
286+
noplay:
287+
S_Src_Stop(src);
288+
return;
289+
}
290+
}
291+
else {
292+
for (i = 0; i < buf->num_channels; i++) {
268293
chan = &s_channels[ src->channels[ i ] ];
269-
chan->freq = 0;
294+
chan->freq = src->freq;
270295
}
271-
noplay:
272-
src->buf = NULL;
273-
src->num_channels = 0;
274-
return;
275296
}
276297

277298
S_Src_Rewind(src);
299+
300+
S_UpdateSourcesStatus();
278301
}
279302

280303
void S_Src_Update(sfx_source_t *src, uint16_t freq, uint8_t pan, uint8_t vol, uint8_t autoloop)
@@ -308,6 +331,7 @@ void S_InitSources(void)
308331
for (i = 0; i < S_MAX_SOURCES; i++) {
309332
S_Src_Init(&s_sources[ i ]);
310333
}
334+
S_UpdateSourcesStatus();
311335
}
312336

313337
void S_StopSources(void)
@@ -332,3 +356,22 @@ int S_AllocSource(void)
332356
}
333357
return 0;
334358
}
359+
360+
void S_UpdateSourcesStatus(void)
361+
{
362+
int i;
363+
uint8_t status, bit;
364+
365+
// update playback status register: for all active
366+
// sources, the matching bit will be set to 1
367+
bit = 1;
368+
status = 0;
369+
for (i = 0; i < S_MAX_SOURCES; i++) {
370+
sfx_source_t *src = &s_sources[ i ];
371+
if (src->buf != NULL) {
372+
status |= bit;
373+
}
374+
bit += bit;
375+
}
376+
*(volatile uint8_t *)0xFF802F = status;
377+
}

0 commit comments

Comments
 (0)