Mercurial > repos > blastem
annotate pico_pcm.c @ 2673:2c8f541af3c5
Get Pico games running with new 68K core
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 08 Mar 2025 21:09:54 -0800 |
parents | e8eba0cd5444 |
children |
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 |
2436
f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
Michael Pavone <pavone@retrodev.com>
parents:
2435
diff
changeset
|
5 #define PCM_BUSY PCM_RESET |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 #define PCM_INT_EN 0x4000 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 #define PCM_ENABLED 0x0800 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 #define PCM_FILTER 0x00C0 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 #define PCM_VOLUME 0x0007 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 void pico_pcm_reset(pico_pcm *pcm) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 pcm->fifo_read = sizeof(pcm->fifo); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 pcm->fifo_write = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 pcm->adpcm_state = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 pcm->output = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 pcm->nibble_store = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 pcm->counter = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 pcm->samples = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 pcm->rate = 0; |
2436
f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
Michael Pavone <pavone@retrodev.com>
parents:
2435
diff
changeset
|
21 pcm->ctrl |= PCM_BUSY; |
2431
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 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 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
|
25 { |
2486
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
26 pcm->clock_inc = divider * 4; |
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
27 pcm->audio = render_audio_source("PICO ADPCM", master_clock, pcm->clock_inc, 1); |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 pcm->scope = NULL; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 pcm->scope_channel = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 pico_pcm_reset(pcm); |
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 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 void pico_pcm_free(pico_pcm *pcm) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 render_free_source(pcm->audio); |
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 |
2486
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
38 void pico_pcm_adjust_master_clock(pico_pcm *pcm, uint32_t master_clock) |
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
39 { |
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
40 render_audio_adjust_clock(pcm->audio, master_clock, pcm->clock_inc); |
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
41 } |
e8eba0cd5444
Implement turbo/slow for Pico and Copera
Michael Pavone <pavone@retrodev.com>
parents:
2436
diff
changeset
|
42 |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 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
|
44 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 #ifndef IS_LIB |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 pcm->scope = scope; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 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
|
48 #endif |
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 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 static uint8_t pcm_fifo_read(pico_pcm *pcm) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 if (pcm->fifo_read == sizeof(pcm->fifo)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 return 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 uint8_t ret = pcm->fifo[pcm->fifo_read++]; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 pcm->fifo_read &= sizeof(pcm->fifo) - 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 if (pcm->fifo_read == pcm->fifo_write) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 pcm->fifo_read = sizeof(pcm->fifo); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 return ret; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 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
|
65 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 //Tables from MAME |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 static const int16_t sample_delta[256] = { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 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
|
69 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
|
70 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
|
71 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
|
72 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
|
73 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
|
74 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
|
75 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
|
76 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
|
77 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
|
78 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
|
79 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
|
80 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
|
81 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
|
82 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
|
83 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
|
84 }; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 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
|
86 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
|
87 int diff = state_delta[sample]; |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 if (diff >= 0 || *state > 0) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 *state += diff; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 if (*state > 15) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 *state = 15; |
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 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 return ret; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 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
|
98 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 while (pcm->cycle < cycle) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 pcm->cycle += pcm->clock_inc; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 //TODO: Figure out actual attenuation |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 int16_t shift = pcm->ctrl & PCM_VOLUME; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 #ifndef IS_LIB |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 if (pcm->scope) { |
2432
18816c5c11d4
Fix Pico ADPCM decoding and get relative volume approximately correct
Michael Pavone <pavone@retrodev.com>
parents:
2431
diff
changeset
|
106 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
|
107 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 #endif |
2432
18816c5c11d4
Fix Pico ADPCM decoding and get relative volume approximately correct
Michael Pavone <pavone@retrodev.com>
parents:
2431
diff
changeset
|
109 render_put_mono_sample(pcm->audio, (pcm->output >> shift) * 32); |
2434
2ee25a487e2b
Fix some Pico ADPCM behaviors
Michael Pavone <pavone@retrodev.com>
parents:
2432
diff
changeset
|
110 /* |
2ee25a487e2b
Fix some Pico ADPCM behaviors
Michael Pavone <pavone@retrodev.com>
parents:
2432
diff
changeset
|
111 Unclear what this bit is actually supposed to do |
2ee25a487e2b
Fix some Pico ADPCM behaviors
Michael Pavone <pavone@retrodev.com>
parents:
2432
diff
changeset
|
112 But some games expect ADPCM to work with it cleared |
2ee25a487e2b
Fix some Pico ADPCM behaviors
Michael Pavone <pavone@retrodev.com>
parents:
2432
diff
changeset
|
113 Anpanman Pico: Waku Waku Pan Koujou sets the ctrl reg to $6040 |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 if (!(pcm->ctrl & PCM_ENABLED)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 continue; |
2434
2ee25a487e2b
Fix some Pico ADPCM behaviors
Michael Pavone <pavone@retrodev.com>
parents:
2432
diff
changeset
|
116 }*/ |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 if (pcm->counter) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 pcm->counter--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
119 } else if (pcm->samples) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 pcm->samples--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 uint8_t sample; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 if (pcm->nibble_store) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 sample = pcm->nibble_store & 0xF; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 pcm->nibble_store = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 } else { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 uint8_t byte = pcm_fifo_read(pcm); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 sample = byte >> 4; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 pcm->nibble_store = 0x80 | (byte & 0xF); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 uint8_t old_state = pcm->adpcm_state; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 pcm->output += upd7755_calc_sample(sample, &pcm->adpcm_state); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 if (pcm->output > 255) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
133 pcm->output = 255; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 } else if (pcm->output < -256) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 pcm->output = -256; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 //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
|
138 pcm->counter = pcm->rate; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 } else { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 uint8_t cmd = pcm_fifo_read(pcm); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 if (cmd) { |
2436
f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
Michael Pavone <pavone@retrodev.com>
parents:
2435
diff
changeset
|
142 pcm->ctrl &= ~PCM_BUSY; |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 } else { |
2436
f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
Michael Pavone <pavone@retrodev.com>
parents:
2435
diff
changeset
|
144 pcm->ctrl |= PCM_BUSY; |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 switch (cmd & 0xC0) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 case 0: |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 pcm->output = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 pcm->adpcm_state = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 pcm->counter = (cmd & 0x3F) * 160; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 case 0x40: |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 pcm->rate = (cmd & 0x3F); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
155 pcm->samples = 256; |
2435
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
156 pcm->nibble_store = 0; |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 case 0x80: |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 pcm->rate = (cmd & 0x3F); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 //FIXME: this probably does not happen instantly |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 pcm->samples = pcm_fifo_read(pcm) + 1; |
2435
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
162 pcm->nibble_store = 0; |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 case 0xC0: |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 //FIXME: this probably does not happen instantly |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 //TODO: Does repeat mode even work on this chip? |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 // Does it work on a uPD7759 in slave mode? |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 // Is this correct behavior if it does work? |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 pcm->counter = pcm->rate = pcm_fifo_read(pcm) & 0x3F; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 pcm->samples = (pcm_fifo_read(pcm) + 1) * ((cmd & 7) + 1); |
2435
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
171 pcm->nibble_store = 0; |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
173 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
174 } |
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 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 // RI??E???FF???VVV |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 // R: 1 = Reset request, 0 = normal operation |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 // I: 1 = interrupts enabled, 0 = disabled |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 // 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
|
182 // 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
|
183 // 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
|
184 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
|
185 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 if (value & PCM_RESET) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 pico_pcm_reset(pcm); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 } |
2436
f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
Michael Pavone <pavone@retrodev.com>
parents:
2435
diff
changeset
|
189 pcm->ctrl &= PCM_BUSY; |
f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
Michael Pavone <pavone@retrodev.com>
parents:
2435
diff
changeset
|
190 pcm->ctrl |= value & ~(PCM_BUSY); |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 //TODO: update low-pass filter |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 } |
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 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
|
195 { |
2435
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
196 if (pcm->fifo_read == pcm->fifo_write) { |
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
197 puts("ADPCM fifo overflow"); |
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
198 } |
2431
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 pcm->fifo_read = pcm->fifo_write; |
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 pcm->fifo[pcm->fifo_write++] = value >> 8; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 pcm->fifo_write &= sizeof(pcm->fifo)-1; |
2435
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
204 if (pcm->fifo_read == pcm->fifo_write) { |
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
205 puts("ADPCM fifo overflow"); |
b8d894f7f9dc
Fix playback of ADPCM blocks with an odd number of samples
Michael Pavone <pavone@retrodev.com>
parents:
2434
diff
changeset
|
206 } |
2431
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
207 pcm->fifo[pcm->fifo_write++] = value; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
208 pcm->fifo_write &= sizeof(pcm->fifo)-1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
209 } |
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 uint16_t pico_pcm_ctrl_read(pico_pcm *pcm) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
212 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
213 return pcm->ctrl; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
214 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
215 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
216 uint16_t pico_pcm_data_read(pico_pcm *pcm) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
217 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
218 if (pcm->fifo_read == sizeof(pcm->fifo)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
219 return sizeof(pcm->fifo) - 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
220 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
221 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
|
222 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
223 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 #define FIFO_THRESHOLD 48 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 uint32_t pico_pcm_next_int(pico_pcm *pcm) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
227 if (!(pcm->ctrl & PCM_INT_EN)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
228 return CYCLE_NEVER; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
230 uint32_t fifo_bytes; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
231 if (pcm->fifo_read == sizeof(pcm->fifo)) { |
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 if (pcm->fifo_read == pcm->fifo_write) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
234 fifo_bytes = sizeof(pcm->fifo); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
235 } else { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
236 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
|
237 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
238 if (fifo_bytes < FIFO_THRESHOLD) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
239 return pcm->cycle; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
240 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
241 uint32_t cycles_to_threshold = pcm->counter + 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
242 if (pcm->samples) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
243 uint16_t samples = pcm->samples; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
244 if (pcm->nibble_store) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
245 cycles_to_threshold += pcm->rate + 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
246 samples--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
247 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
248 uint16_t bytes = (samples >> 1) + (samples & 1); |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
249 if (bytes > (fifo_bytes - FIFO_THRESHOLD)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
250 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
|
251 fifo_bytes = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
252 } else { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
253 cycles_to_threshold += bytes * (pcm->rate + 1) * 2; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
254 fifo_bytes -= bytes; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
255 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
256 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
257 uint8_t fifo_read = pcm->fifo_read; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
258 uint8_t cmd = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
259 while (fifo_bytes >= FIFO_THRESHOLD) |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
260 { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
261 if (cmd) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
262 switch(cmd & 0xC0) |
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 case 0: |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
265 cycles_to_threshold += 640 * (cmd & 0x3F) + 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
266 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
267 case 0x40: |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
268 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
|
269 fifo_bytes = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
270 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
271 case 0x80: { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
272 uint32_t samples = pcm->fifo[fifo_read++]; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
273 fifo_bytes--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
274 fifo_read &= sizeof(pcm->fifo) - 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
275 if (fifo_bytes < FIFO_THRESHOLD) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
276 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
277 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
278 uint32_t bytes = (samples +1) >> 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
279 if (bytes > (fifo_bytes - FIFO_THRESHOLD)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
280 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
|
281 fifo_bytes = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
282 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
283 break; } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
284 case 0xC0: { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
285 uint32_t rate = pcm->fifo[fifo_read++] & 0x3F; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
286 fifo_bytes--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
287 fifo_read &= sizeof(pcm->fifo) - 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
288 uint32_t samples = pcm->fifo[fifo_read++] & 0x3F; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
289 fifo_bytes--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
290 fifo_read &= sizeof(pcm->fifo) - 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
291 if (fifo_bytes < FIFO_THRESHOLD) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
292 break; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
293 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
294 samples++; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
295 samples *= (cmd & 7) + 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
296 uint32_t bytes = (samples + 1) >> 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
297 if (bytes > (fifo_bytes - FIFO_THRESHOLD)) { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
298 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
|
299 fifo_bytes = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
300 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
301 break; } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
302 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
303 cmd = 0; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
304 } else { |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
305 cycles_to_threshold++; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
306 cmd = pcm->fifo[fifo_read++]; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
307 fifo_bytes--; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
308 fifo_read &= sizeof(pcm->fifo) - 1; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
309 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
310 } |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
311 |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
312 return pcm->cycle + cycles_to_threshold * pcm->clock_inc; |
61c0bfe10887
Somewhat busted support for Pico ADPCM
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
313 } |