annotate pico_pcm.c @ 2432:18816c5c11d4

Fix Pico ADPCM decoding and get relative volume approximately correct
author Michael Pavone <pavone@retrodev.com>
date Wed, 07 Feb 2024 20:03:23 -0800
parents 61c0bfe10887
children 2ee25a487e2b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2431
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include "pico_pcm.h"
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include "backend.h"
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #define PCM_RESET 0x8000
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5 #define PCM_INT_EN 0x4000
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 #define PCM_ENABLED 0x0800
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 #define PCM_FILTER 0x00C0
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 #define PCM_VOLUME 0x0007
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 void pico_pcm_reset(pico_pcm *pcm)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 pcm->fifo_read = sizeof(pcm->fifo);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13 pcm->fifo_write = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 pcm->adpcm_state = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 pcm->output = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 pcm->nibble_store = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 pcm->counter = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 pcm->samples = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 pcm->rate = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 pcm->ctrl &= 0x7FFF;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 void pico_pcm_init(pico_pcm *pcm, uint32_t master_clock, uint32_t divider)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 pcm->audio = render_audio_source("PICO ADPCM", master_clock, divider * 4, 1);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 pcm->scope = NULL;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 pcm->scope_channel = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 pcm->clock_inc = divider * 4;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 pico_pcm_reset(pcm);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 void pico_pcm_free(pico_pcm *pcm)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 render_free_source(pcm->audio);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 void pico_pcm_enable_scope(pico_pcm *pcm, oscilloscope *scope, uint32_t master_clock)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 #ifndef IS_LIB
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 pcm->scope = scope;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 pcm->scope_channel = scope_add_channel(scope, "PICO ADPCM", master_clock / pcm->clock_inc);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 #endif
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 static uint8_t pcm_fifo_read(pico_pcm *pcm)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 if (pcm->fifo_read == sizeof(pcm->fifo)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 return 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 uint8_t ret = pcm->fifo[pcm->fifo_read++];
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 pcm->fifo_read &= sizeof(pcm->fifo) - 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 if (pcm->fifo_read == pcm->fifo_write) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 pcm->fifo_read = sizeof(pcm->fifo);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 return ret;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 int16_t upd7755_calc_sample(uint8_t sample, uint8_t *state)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 //Tables from MAME
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 static const int16_t sample_delta[256] = {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 0, 0, 1, 2, 3, 5, 7, 10, 0, 0, -1, -2, -3, -5, -7, -10,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 0, 1, 2, 3, 4, 6, 8, 13, 0, -1, -2, -3, -4, -6, -8, -13,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 0, 1, 2, 4, 5, 7, 10, 15, 0, -1, -2, -4, -5, -7, -10, -15,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 0, 1, 3, 4, 6, 9, 13, 19, 0, -1, -3, -4, -6, -9, -13, -19,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 0, 2, 3, 5, 8, 11, 15, 23, 0, -2, -3, -5, -8, -11, -15, -23,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 0, 2, 4, 7, 10, 14, 19, 29, 0, -2, -4, -7, -10, -14, -19, -29,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 0, 3, 5, 8, 12, 16, 22, 33, 0, -3, -5, -8, -12, -16, -22, -33,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 1, 4, 7, 10, 15, 20, 29, 43, -1, -4, -7, -10, -15, -20, -29, -43,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 1, 4, 8, 13, 18, 25, 35, 53, -1, -4, -8, -13, -18, -25, -35, -53,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 1, 6, 10, 16, 22, 31, 43, 64, -1, -6, -10, -16, -22, -31, -43, -64,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 2, 7, 12, 19, 27, 37, 51, 76, -2, -7, -12, -19, -27, -37, -51, -76,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 2, 9, 16, 24, 34, 46, 64, 96, -2, -9, -16, -24, -34, -46, -64, -96,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 3, 11, 19, 29, 41, 57, 79, 117, -3, -11, -19, -29, -41, -57, -79, -117,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 4, 13, 24, 36, 50, 69, 96, 143, -4, -13, -24, -36, -50, -69, -96, -143,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 4, 16, 29, 44, 62, 85, 118, 175, -4, -16, -29, -44, -62, -85, -118, -175,
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 6, 20, 36, 54, 76, 104, 144, 214, -6, -20, -36, -54, -76, -104, -144, -214
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 };
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79 static const int state_delta[16] = {-1, -1, 0, 0, 1, 2, 2, 3, -1, -1, 0, 0, 1, 2, 2, 3};
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 int16_t ret = sample_delta[(*state << 4) + sample];
2432
18816c5c11d4 Fix Pico ADPCM decoding and get relative volume approximately correct
Michael Pavone <pavone@retrodev.com>
parents: 2431
diff changeset
81 int diff = state_delta[sample];
2431
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 if (diff >= 0 || *state > 0) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 *state += diff;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 if (*state > 15) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
85 *state = 15;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
88 return ret;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 void pico_pcm_run(pico_pcm *pcm, uint32_t cycle)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93 while (pcm->cycle < cycle)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 pcm->cycle += pcm->clock_inc;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96 //TODO: Figure out actual attenuation
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97 int16_t shift = pcm->ctrl & PCM_VOLUME;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98 #ifndef IS_LIB
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99 if (pcm->scope) {
2432
18816c5c11d4 Fix Pico ADPCM decoding and get relative volume approximately correct
Michael Pavone <pavone@retrodev.com>
parents: 2431
diff changeset
100 scope_add_sample(pcm->scope, pcm->scope_channel, (pcm->output >> shift) * 32, 0);
2431
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 #endif
2432
18816c5c11d4 Fix Pico ADPCM decoding and get relative volume approximately correct
Michael Pavone <pavone@retrodev.com>
parents: 2431
diff changeset
103 render_put_mono_sample(pcm->audio, (pcm->output >> shift) * 32);
2431
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 if (!(pcm->ctrl & PCM_ENABLED)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 continue;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 if (pcm->counter) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 pcm->counter--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109 } else if (pcm->samples) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 pcm->samples--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 uint8_t sample;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 if (pcm->nibble_store) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 sample = pcm->nibble_store & 0xF;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 pcm->nibble_store = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115 } else {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 uint8_t byte = pcm_fifo_read(pcm);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 sample = byte >> 4;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
118 pcm->nibble_store = 0x80 | (byte & 0xF);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
120 uint8_t old_state = pcm->adpcm_state;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
121 pcm->output += upd7755_calc_sample(sample, &pcm->adpcm_state);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
122 if (pcm->output > 255) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
123 pcm->output = 255;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
124 } else if (pcm->output < -256) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
125 pcm->output = -256;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127 //printf("Sample %d, old_state %d, new_state %d, output %d\n", sample, old_state, pcm->adpcm_state, pcm->output);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 pcm->counter = pcm->rate;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129 } else {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 uint8_t cmd = pcm_fifo_read(pcm);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 if (cmd) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 pcm->ctrl |= 0x8000;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
133 } else {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 pcm->ctrl &= 0x7FFF;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
135 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 switch (cmd & 0xC0)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 case 0:
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139 pcm->output = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
140 pcm->adpcm_state = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 pcm->counter = (cmd & 0x3F) * 160;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 case 0x40:
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
144 pcm->rate = (cmd & 0x3F);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
145 pcm->samples = 256;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
146 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 case 0x80:
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148 pcm->rate = (cmd & 0x3F);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 //FIXME: this probably does not happen instantly
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
150 pcm->samples = pcm_fifo_read(pcm) + 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
152 case 0xC0:
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
153 //FIXME: this probably does not happen instantly
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
154 //TODO: Does repeat mode even work on this chip?
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 // Does it work on a uPD7759 in slave mode?
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
156 // Is this correct behavior if it does work?
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
157 pcm->counter = pcm->rate = pcm_fifo_read(pcm) & 0x3F;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 pcm->samples = (pcm_fifo_read(pcm) + 1) * ((cmd & 7) + 1);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
163 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
164
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 // RI??E???FF???VVV
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
166 // R: 1 = Reset request, 0 = normal operation
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
167 // I: 1 = interrupts enabled, 0 = disabled
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
168 // E: 1 = Enabled? Sega code always sets this to 1 outside of reset
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
169 // F: Low-pass Filter 1 = 6 kHz, 2 = 12 kHz 3 = 16 kHz
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
170 // V: volume, probably attenuation value since converter defaults to "0"
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 void pico_pcm_ctrl_write(pico_pcm *pcm, uint16_t value)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173 if (value & PCM_RESET) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 pico_pcm_reset(pcm);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 pcm->ctrl &= 0x8000;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
177 pcm->ctrl |= value & ~PCM_RESET;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 //TODO: update low-pass filter
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
179 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
180
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
181 void pico_pcm_data_write(pico_pcm *pcm, uint16_t value)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
182 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
183 if (pcm->fifo_read == sizeof(pcm->fifo)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
184 pcm->fifo_read = pcm->fifo_write;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
185 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186 pcm->fifo[pcm->fifo_write++] = value >> 8;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 pcm->fifo_write &= sizeof(pcm->fifo)-1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
188 pcm->fifo[pcm->fifo_write++] = value;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
189 pcm->fifo_write &= sizeof(pcm->fifo)-1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
191
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
192 uint16_t pico_pcm_ctrl_read(pico_pcm *pcm)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
193 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
194 return pcm->ctrl;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
195 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
196
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
197 uint16_t pico_pcm_data_read(pico_pcm *pcm)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
198 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
199 if (pcm->fifo_read == sizeof(pcm->fifo)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
200 return sizeof(pcm->fifo) - 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
201 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
202 return (pcm->fifo_read - pcm->fifo_write) & (sizeof(pcm->fifo)-1);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
203 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
204
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
205 #define FIFO_THRESHOLD 48
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
206 uint32_t pico_pcm_next_int(pico_pcm *pcm)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
207 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
208 if (!(pcm->ctrl & PCM_INT_EN)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
209 return CYCLE_NEVER;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
210 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
211 uint32_t fifo_bytes;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
212 if (pcm->fifo_read == sizeof(pcm->fifo)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
213 fifo_bytes = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
214 } else if (pcm->fifo_read == pcm->fifo_write) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
215 fifo_bytes = sizeof(pcm->fifo);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
216 } else {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
217 fifo_bytes = (pcm->fifo_write - pcm->fifo_read) & (sizeof(pcm->fifo) - 1);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
218 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
219 if (fifo_bytes < FIFO_THRESHOLD) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
220 return pcm->cycle;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
221 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
222 uint32_t cycles_to_threshold = pcm->counter + 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
223 if (pcm->samples) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
224 uint16_t samples = pcm->samples;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
225 if (pcm->nibble_store) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
226 cycles_to_threshold += pcm->rate + 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
227 samples--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
228 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
229 uint16_t bytes = (samples >> 1) + (samples & 1);
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
230 if (bytes > (fifo_bytes - FIFO_THRESHOLD)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
231 cycles_to_threshold += (fifo_bytes - FIFO_THRESHOLD + 1) * (pcm->rate + 1) * 2;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
232 fifo_bytes = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
233 } else {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
234 cycles_to_threshold += bytes * (pcm->rate + 1) * 2;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
235 fifo_bytes -= bytes;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
236 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
237 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
238 uint8_t fifo_read = pcm->fifo_read;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
239 uint8_t cmd = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
240 while (fifo_bytes >= FIFO_THRESHOLD)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
241 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
242 if (cmd) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
243 switch(cmd & 0xC0)
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
244 {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
245 case 0:
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
246 cycles_to_threshold += 640 * (cmd & 0x3F) + 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
247 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
248 case 0x40:
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
249 cycles_to_threshold += (fifo_bytes - FIFO_THRESHOLD + 1) * ((cmd & 0x3F) + 1) * 2;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
250 fifo_bytes = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
251 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
252 case 0x80: {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
253 uint32_t samples = pcm->fifo[fifo_read++];
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
254 fifo_bytes--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
255 fifo_read &= sizeof(pcm->fifo) - 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
256 if (fifo_bytes < FIFO_THRESHOLD) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
257 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
258 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
259 uint32_t bytes = (samples +1) >> 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
260 if (bytes > (fifo_bytes - FIFO_THRESHOLD)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
261 cycles_to_threshold += (fifo_bytes - FIFO_THRESHOLD + 1) * ((cmd & 0x3F) + 1) * 2;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
262 fifo_bytes = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
263 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
264 break; }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
265 case 0xC0: {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
266 uint32_t rate = pcm->fifo[fifo_read++] & 0x3F;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
267 fifo_bytes--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
268 fifo_read &= sizeof(pcm->fifo) - 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
269 uint32_t samples = pcm->fifo[fifo_read++] & 0x3F;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
270 fifo_bytes--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
271 fifo_read &= sizeof(pcm->fifo) - 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
272 if (fifo_bytes < FIFO_THRESHOLD) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
273 break;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
274 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
275 samples++;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
276 samples *= (cmd & 7) + 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
277 uint32_t bytes = (samples + 1) >> 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
278 if (bytes > (fifo_bytes - FIFO_THRESHOLD)) {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
279 cycles_to_threshold += (fifo_bytes - FIFO_THRESHOLD + 1) * ((cmd & 0x3F) + 1) * 2;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
280 fifo_bytes = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
281 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
282 break; }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
283 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
284 cmd = 0;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
285 } else {
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
286 cycles_to_threshold++;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
287 cmd = pcm->fifo[fifo_read++];
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
288 fifo_bytes--;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
289 fifo_read &= sizeof(pcm->fifo) - 1;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
290 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
291 }
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
292
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
293 return pcm->cycle + cycles_to_threshold * pcm->clock_inc;
61c0bfe10887 Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
294 }