Mercurial > repos > blastem
comparison pico_pcm.c @ 2436:f50b9ed42ebd
Fix polarity of pico ADPCM busy flag
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 10 Feb 2024 17:28:05 -0800 |
parents | b8d894f7f9dc |
children | e8eba0cd5444 |
comparison
equal
deleted
inserted
replaced
2435:b8d894f7f9dc | 2436:f50b9ed42ebd |
---|---|
1 #include "pico_pcm.h" | 1 #include "pico_pcm.h" |
2 #include "backend.h" | 2 #include "backend.h" |
3 | 3 |
4 #define PCM_RESET 0x8000 | 4 #define PCM_RESET 0x8000 |
5 #define PCM_BUSY PCM_RESET | |
5 #define PCM_INT_EN 0x4000 | 6 #define PCM_INT_EN 0x4000 |
6 #define PCM_ENABLED 0x0800 | 7 #define PCM_ENABLED 0x0800 |
7 #define PCM_FILTER 0x00C0 | 8 #define PCM_FILTER 0x00C0 |
8 #define PCM_VOLUME 0x0007 | 9 #define PCM_VOLUME 0x0007 |
9 | 10 |
15 pcm->output = 0; | 16 pcm->output = 0; |
16 pcm->nibble_store = 0; | 17 pcm->nibble_store = 0; |
17 pcm->counter = 0; | 18 pcm->counter = 0; |
18 pcm->samples = 0; | 19 pcm->samples = 0; |
19 pcm->rate = 0; | 20 pcm->rate = 0; |
20 pcm->ctrl &= 0x7FFF; | 21 pcm->ctrl |= PCM_BUSY; |
21 } | 22 } |
22 | 23 |
23 void pico_pcm_init(pico_pcm *pcm, uint32_t master_clock, uint32_t divider) | 24 void pico_pcm_init(pico_pcm *pcm, uint32_t master_clock, uint32_t divider) |
24 { | 25 { |
25 pcm->audio = render_audio_source("PICO ADPCM", master_clock, divider * 4, 1); | 26 pcm->audio = render_audio_source("PICO ADPCM", master_clock, divider * 4, 1); |
99 if (pcm->scope) { | 100 if (pcm->scope) { |
100 scope_add_sample(pcm->scope, pcm->scope_channel, (pcm->output >> shift) * 32, 0); | 101 scope_add_sample(pcm->scope, pcm->scope_channel, (pcm->output >> shift) * 32, 0); |
101 } | 102 } |
102 #endif | 103 #endif |
103 render_put_mono_sample(pcm->audio, (pcm->output >> shift) * 32); | 104 render_put_mono_sample(pcm->audio, (pcm->output >> shift) * 32); |
104 if (pcm->ctrl & PCM_RESET) { | |
105 //Anpanman Pico: Waku Waku Pan Koujou seems to expect the BUSY/RESET flag | |
106 //to be set for a while after reset | |
107 if (pcm->counter) { | |
108 pcm->counter--; | |
109 continue; | |
110 } else { | |
111 pcm->ctrl &= ~PCM_RESET; | |
112 } | |
113 } | |
114 /* | 105 /* |
115 Unclear what this bit is actually supposed to do | 106 Unclear what this bit is actually supposed to do |
116 But some games expect ADPCM to work with it cleared | 107 But some games expect ADPCM to work with it cleared |
117 Anpanman Pico: Waku Waku Pan Koujou sets the ctrl reg to $6040 | 108 Anpanman Pico: Waku Waku Pan Koujou sets the ctrl reg to $6040 |
118 if (!(pcm->ctrl & PCM_ENABLED)) { | 109 if (!(pcm->ctrl & PCM_ENABLED)) { |
141 //printf("Sample %d, old_state %d, new_state %d, output %d\n", sample, old_state, pcm->adpcm_state, pcm->output); | 132 //printf("Sample %d, old_state %d, new_state %d, output %d\n", sample, old_state, pcm->adpcm_state, pcm->output); |
142 pcm->counter = pcm->rate; | 133 pcm->counter = pcm->rate; |
143 } else { | 134 } else { |
144 uint8_t cmd = pcm_fifo_read(pcm); | 135 uint8_t cmd = pcm_fifo_read(pcm); |
145 if (cmd) { | 136 if (cmd) { |
146 pcm->ctrl |= 0x8000; | 137 pcm->ctrl &= ~PCM_BUSY; |
147 } else { | 138 } else { |
148 pcm->ctrl &= 0x7FFF; | 139 pcm->ctrl |= PCM_BUSY; |
149 } | 140 } |
150 switch (cmd & 0xC0) | 141 switch (cmd & 0xC0) |
151 { | 142 { |
152 case 0: | 143 case 0: |
153 pcm->output = 0; | 144 pcm->output = 0; |
187 // V: volume, probably attenuation value since converter defaults to "0" | 178 // V: volume, probably attenuation value since converter defaults to "0" |
188 void pico_pcm_ctrl_write(pico_pcm *pcm, uint16_t value) | 179 void pico_pcm_ctrl_write(pico_pcm *pcm, uint16_t value) |
189 { | 180 { |
190 if (value & PCM_RESET) { | 181 if (value & PCM_RESET) { |
191 pico_pcm_reset(pcm); | 182 pico_pcm_reset(pcm); |
192 pcm->counter = 2; | 183 } |
193 } | 184 pcm->ctrl &= PCM_BUSY; |
194 pcm->ctrl = value; | 185 pcm->ctrl |= value & ~(PCM_BUSY); |
195 //TODO: update low-pass filter | 186 //TODO: update low-pass filter |
196 } | 187 } |
197 | 188 |
198 void pico_pcm_data_write(pico_pcm *pcm, uint16_t value) | 189 void pico_pcm_data_write(pico_pcm *pcm, uint16_t value) |
199 { | 190 { |