annotate pico_pcm.c @ 2496:187bc857a76a default tip

Fix bug in MED mapper protection bit implementation
author Michael Pavone <pavone@retrodev.com>
date Sun, 28 Apr 2024 23:33:11 -0700
parents e8eba0cd5444
children
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
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 }